././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.3741212 os-ken-2.10.0/0000775000175000017500000000000000000000000013011 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/.coveragerc0000664000175000017500000000010300000000000015124 0ustar00zuulzuul00000000000000[run] branch = True source = os_ken [report] ignore_errors = True ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/.mailmap0000664000175000017500000000013100000000000014425 0ustar00zuulzuul00000000000000# Format is: # # ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/.pre-commit-config.yaml0000664000175000017500000000154700000000000017301 0ustar00zuulzuul00000000000000--- default_language_version: # force all unspecified python hooks to run python3 python: python3 repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.5.0 hooks: - id: trailing-whitespace - id: mixed-line-ending args: ['--fix', 'lf'] exclude: '.*\.(svg)$' - id: check-byte-order-marker - id: check-executables-have-shebangs - id: check-merge-conflict - id: debug-statements - id: check-yaml - repo: https://github.com/lucas-c/pre-commit-hooks rev: v1.5.4 hooks: - id: remove-tabs exclude: '.*\.(svg)$' - repo: local hooks: - id: flake8 name: flake8 additional_dependencies: - hacking>=3.2.0,<3.3.0 language: python entry: flake8 files: '^.*\.py$' exclude: '^(doc|releasenotes|tools)/.*$' ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/.pylintrc0000664000175000017500000000112500000000000014655 0ustar00zuulzuul00000000000000[Messages Control] # PyLint Messages http://pylint-messages.wikidot.com/all-messages # C0111: Don't require docstrings on every method # W0511: TODOs in code comments are fine. # W0142: *args and **kwargs are fine. # E0602: Undefined variable %r # C0103: Invalid name "%s" (should match %s) # E1101: %s %r has no %r member # R0903: Too few public methods (%s/%s) # W0614: Unused import %s from wildcard import # R0801: Similar lines in %s files disable=C0111,W0511,W0142,E0602,C0103,E1101,R0903,W0614,R0801 msg-template={path}:{line}: [{msg_id}({symbol}), {obj}] {msg} reports=yes files-output=no ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/.stestr.conf0000664000175000017500000000007700000000000015266 0ustar00zuulzuul00000000000000[DEFAULT] test_path=${OS_TEST_PATH:-./os_ken/tests} top_dir=./ ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/.travis.yml0000664000175000017500000000140400000000000015121 0ustar00zuulzuul00000000000000language: python matrix: include: - python: 3.6 env: TOX_ENV=pycodestyle - python: 3.6 env: TOX_ENV=py36 - python: 3.6 env: TOX_ENV=autopep8 - python: 2.7 env: TOX_ENV=pycodestyle - python: 2.7 env: TOX_ENV=py27 - python: 3.4 env: TOX_ENV=py34 - python: 3.5 env: TOX_ENV=py35 - python: 3.7-dev env: TOX_ENV=py37 # This is disabled because of trouble running on travis CI. # - python: pypy # env: TOX_ENV=pypy services: - docker sudo: required # Required to enable Docker service install: - pip install tox coveralls - bash os_ken/tests/integrated/common/install_docker_test_pkg_for_travis.sh script: - NOSE_VERBOSE=0 tox -e $TOX_ENV after_success: - coveralls ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/.zuul.yaml0000664000175000017500000000066400000000000014760 0ustar00zuulzuul00000000000000- project: templates: - openstack-python3-jobs - publish-openstack-docs-pti - release-notes-jobs-python3 - check-requirements check: jobs: - neutron-ovs-tempest-dvr - neutron-tempest-plugin-dynamic-routing: voting: false gate: jobs: - neutron-ovs-tempest-dvr periodic-weekly: jobs: - openstack-tox-py311 - openstack-tox-py312 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334545.0 os-ken-2.10.0/AUTHORS0000664000175000017500000001457500000000000014075 0ustar00zuulzuul00000000000000Aeschlimann Philipp Akihiro Motoki Akihiro Suda Alan Quillin Albert Siersema Anantha Ramaiah Andreas Jaeger Andrew Ragusa Atzm Watanabe Atzm Watanabe Benjamin Beasley Benjamin Eggerstedt Benjamin Villain via Ryu-devel Bernard Cafarelli Brad Cowie Brian Haley Can Zhang Charles M.C. Chan Charlie Lewis Che-Wei Lin Chia-Lin Cho Chiu,Cheng-Han Chris MacNaughton Chris Small Christopher Scherb Claudio Pisa Claudiu Belu Corey Bryant Dingyuan Hu Doug Hellmann Dr. Jens Harbott Eder Leão Fernandes EisukeTAKAHASHI Eran Evan Gray FUJITA Tomonori FUJITA Tomonori Fadi Moukayed Felician Nemeth Fumihiko Kakuma Gal Sagie Ghanshyam Mann Glenn McGuire HIYAMA Manabu Henkel, Michael Hervé Beraud Hiroaki KAWAI Hiroshi Yokoi Hisaharu Ishii Hiyama Manabu Hongbin Lu ISHIDA Wataru IWAMOTO Toshihiro IWASE Yusuke Isaku Yamahata Isaku Yamahata Iwase Yusuke Jan Keler Jason Kölker Jerico Moeyersons Jerry Cen Joe Mader John-Lin Jonas Grunert Josh Bailey KAWAI Hiroaki KONDOH Tasuku Kawai, Hiroaki Kei Ohmura Kiyonari Harigae Krzysztof Rutka Kyle Mestery MORITA Kazutaka Manu B Marcin Chron Mark Lentczner Michael Haro Michał Rzepka Minoru TAKAHASHI Monthadar Al-Jaberi MrCocoaCat Nate Johnston OHMURA Kei Olivier DESNOE Omer Anson OpenStack Release Bot Oren Spector Ozgur Yurekten Palubinskas Vilius Peng Xiao Philipp Aeschlimann Rob Udechukwu Rodolfo Alonso Hernandez Rom Sahid Orentino Ferdjaoui Satoshi Fujimoto Satoshi KOBAYASHI Satoshi Kobayashi Scott Sean McGinnis Shaun Crampton Shinpei Muraoka Shu Shen Shu Shen Simon Horman Slawek Kaplonski Srini Seetharaman Sriram Natarajan Sriram Natarajan Steffen Gebert Stephen Finucane Takashi Kajinami Takeshi Thomas Bechtold Thomas Boros Thomas Goirand Toshiki Tsuboi Travis Gockel Victor J. Orlikowski Victor Orlikowski WATANABE Fumitaka WATANABE Fumitaka Wataru ISHIDA Wataru Ishida Wei-Li Tang Xiao Peng YAMADA Hideki YAMAMOTO Takashi YAMAMOTO Takashi YAMAMOTO Takashi YAMAMOTO Takashi Ygor Amaral Ygor Amaral Yi Tseng Yi Yang Yoshiharu Yamashita Yoshihiro Kaneko Yuichi Ito Yuichi Sudo Yuji Oshima Yury Kulazhenkov Yusuke Iwase Zhang Dongya alex blacksheeep elajkat fortitude.zhang fumihiko kakuma gugug ishida wataru likui marcelo mgrex97 morland niuke qingszhao surlyjake takahashi.minoru tungyueh wangjiaqi07 watanabe.fumitaka watanabe.fumitaka wu.chunyang yatinkarel yuta-hamada 张东亚 竹下昇 胡鼎原 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/CONTRIBUTING.rst0000664000175000017500000000116700000000000015457 0ustar00zuulzuul00000000000000If you would like to contribute to the development of OpenStack, you must follow the steps in this page: https://docs.openstack.org/infra/manual/developers.html If you already have a good understanding of how the system works and your OpenStack accounts are set up, you can skip to the development workflow section of this documentation to learn how changes to OpenStack should be submitted for review via the Gerrit tool: https://docs.openstack.org/infra/manual/developers.html#development-workflow Pull requests submitted through GitHub will be ignored. Bugs should be filed on Launchpad: https://bugs.launchpad.net/neutron ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334545.0 os-ken-2.10.0/ChangeLog0000664000175000017500000046602200000000000014575 0ustar00zuulzuul00000000000000CHANGES ======= 2.10.0 ------ * Remove old excludes * Add periodic weekly job for os-ken 2.9.0 ----- * Raise ValueError in case unpack\_from returns zero length * Add pre-commit configuration * Remove executable from python files which don't really needs it * Remove trailing whitespaces and tabs * Fix calls of the print function * reno: Update master for unmaintained/zed * Update master for stable/2024.1 * reno: Update master for unmaintained/xena * reno: Update master for unmaintained/wallaby * reno: Update master for unmaintained/victoria 2.8.1 ----- * reno: Update master for unmaintained/yoga * tox: Drop envdir * Update python classifier in setup.cfg * Use importlib not imp 2.8.0 ----- * Avoid RuntimeError caused by iteration over sys.modules * Fix python shebang * Update master for stable/2023.2 * Remove duplicate requirements files * Remove unused requirements file * [CI] Run a ml2/ovs job 2.7.0 ----- * Add Python 3.10 support to setup.cfg * Remove superfluous sudo * Cleanup py27 support * Add releasenote for quagga fix * Fix quagga container * Make neutron-dynamic-routing job non-voting * Update master for stable/2023.1 * Docs build: Add requirements.txt to deps * Fix tox.ini for tox4 2.6.0 ----- * Update nx\_actions.py, fixing a typo on example * Add msgpack 1.0 support * Enforce new msgpack format (use\_bin\_type=True) * Switch to 2023.1 Python3 unit tests and generic template name * Update master for stable/zed 2.5.0 ----- * Use py3 as the default runtime for tox * remove unicode prefix from code * Remove "six" library * Remove "nose" library 2.4.0 ----- * Remove "distutils" dependency * Fix typo * Update python testing as per zed cycle teting runtime * Drop lower-constraints.txt and its testing * Update master for stable/yoga 2.3.1 ----- * Avoid missing key 'password' for neighbor\_add * Avoid logging MD5 password for BGP add neighbor * Add requirements.txt to tox environment 2.3.0 ----- * Bump min eventlet version to 0.26.1 * Add support for the MTU ND option * Allow user to set cipher list * Bugfix now multiple switches can connect with TLS * Msgpack version upgrade to 1.0.0 * Choose the highest TLS version * updated jsonrpc.Session call to have correct arguments for latest version of ovs * Update bridge.py * Add support for revised RFC8227 withdraw labels * nx\_action\_encap and nx\_action\_decap classes are defined * add ofproto 1.3 coverage, check key-error and attribute-error * Fix major bug in child thread cleanup logic * Fix bug where path.source is set to VRF\_TABLE (in vrf.py) * Use constants imported from API base * Patch to add 2 parameters for controlling specific fields in EVPN rou… * fix NXActionRegLoad action\_to\_str * Fix convertion of ipv4 to string on i386 and arch * mrtlib: Define JSON representation types * mrtlib: Support RFC8050 * Enabled point-to-multipoint links in topology discovery * Add support for Adj-RIB-Out (draft-ietf-grow-bmp-adj-rib-out-03) 2.2.0 ----- * app/ofctl: fix possible deadlock * app/ofctl: fix possible deadlock when the datapath disconnects * mrtlib: Missing subclass for SUBTYPE\_RIB\_\*\_MULTICAST * Add Python3 yoga unit tests * Update master for stable/xena 2.1.0 ----- * Changed minversion in tox to 3.18.0 * Enhance os-ken to support Nicira PacketIn2 * setup.cfg: Replace dashes with underscores * Replace deprecated UPPER\_CONSTRAINTS\_FILE variable 2.0.0 ----- * pdf-docs: use UPPER\_CONSTRAINTS\_FILE for doc build * Add Python3 xena unit tests * Update master for stable/wallaby * Add requirements-check job for os-ken * Remove os\_ken/app and os\_ken/services/protocols/bgp/api/jsonrpc modules 1.4.0 ----- * Fix lower-constraints job 1.3.0 ----- * Use TOX\_CONSTRAINTS\_FILE * Add basic tempest-integrated-networking job to os-ken ci * Limit sockaddr UT to little-endian systems * Add Python3 wallaby unit tests * Update master for stable/victoria * Fix lower-constraints and pep8 for Focal 1.2.0 ----- * Fix sockaddr lib with python 3 * Clean python2 remained stuff * Update some URLs in README and tox * Remove elementtree deprecated methods * Monkey patch original current\_thread \_active * Stop to use the \_\_future\_\_ module * Remove translation sections from setup.cfg 1.1.0 ----- * Use unittest.mock instead of mock * Switch to newer openstackdocstheme and reno versions * Bump default tox env from py37 to py38 * Add py38 package metadata * Use unittest.mock instead of third party mock * Add Python3 victoria unit tests * Update master for stable/ussuri 1.0.0 ----- * Replace deprecated brctl with ip commands * Drop Python2 support and testing * doc: Improve the document structure * Update master for stable/train * PDF documentation build 0.4.1 ----- * Add Python 3 Train unit tests 0.4.0 ----- * Dropping the py35 testing * OpenDev Migration Patch * Fix import for oskenbgp * Remove oslosphinx from lower-constraints * Do not raise exception if Activity is already stopped * Update master for stable/stein * add python 3.7 unit test job * Fix pep8 errors in os-ken * Remove requirements unit tests module 0.3.1 ----- * Add CLI scripts from osken to be installed via setup.cfg * Change openstack-dev to openstack-discuss 0.3.0 ----- * Rename "ryu" to "os\_ken" everywhere * Remove all files in /debian directory * Move constraint from install\_command to deps 0.2.0 ----- * Add constraint for nose in test requirements * Remove autopep8 and formencode from test-requirements.txt * Add jobs for publishing docs * Fixup the docs building * Add minimum constraint for some requirements * Add job for publishing release notes * Add job for running unit tests * import zuul job settings from project-config * Convert namespace from 'ryu' to 'os\_ken' * Add pep8 job for code style checking 0.1.0 ----- * build universal wheels * fix tox python3 overrides * Move files from ryu/\* to os\_ken/\* * Apply OpenStack Cookiecutter template * Ryu 4.27 * Declare support of recent python3 versions * Test more python versions on travis CI * Bump oslo.config to 2.5.0 * Fix UT when running in python 3.7 env * lib/ovs/bridge: Return multiple controllers * BGPSpeaker: Enable to specify remote port for neighbor * switch.tester: Fix name shadowing * gui\_topology: Avoid wildcard URL matching * Ryu 4.26 * nx\_actions: Fix NXActionSetTunnel docstring * Fix pycodestyle W605 warnings * BGPSpeaker: Fix BGP state string conversion * pycodestyle: Ignore W504 * BGPSpeaker: Advertise local routes to RR clients * pip: Blacklist eventlet 0.23.0 * lldp: Remove remaining SystemCapabilities.subtype from tests * lldp: fixed SystemCapabilities TLV * Ryu 4.25 * allow versions of eventlet > 0.21.0 * Ryu 4.24 * ofproto: add Nicira extension ct\_clear action * ofproto: Encode data field on OFPErrorMsg * ofp\_handler: Close socket when HELLO failed * controller: Wait for switch to disconnect connection * controller: Option to close socket after sending Message * controller: Improve pylint result * test\_requirements: Avoid using pip as library * utils: Remove "parse\_requirements" function * Switch to msgpack in pip-requires * nicira\_ext: Support DEC\_NSH\_TTL action * nicira\_ext: Support Network Service Header match * doc: Fix unexpected indent in ofctl.api doc * Ryu 4.23 * doc: Document for ryu.lib.ovs * lib/ovs: Fix a typo of "--may-exist" option * Ryu 4.22 * bgp/application: Add note for BGPSpeaker API reference * BGPSpeaker: Move docstring from \_\_init\_\_ to class * BGPSpeaker: Enable to notify adj-RIB-in changed * ofctl: Enable to get all datapath objects * confroller/dpset: Add usage example of instantiation * test\_rpc: Adopt to msgpack-python>=0.50 * doc: Usage for ryu/services/protocols/bgp/application.py * Ryu 4.21 * \*: Apply autopep8 * travis: Introduce autopep8 test * \*: Adopt to pycodestyle's checks * pycodestyle: Replace pep8 * ofproto\_v1\_5\_parser: oxm\_ids with name str in OFPActionCopyField * ofproto\_v1\_5\_parser: Missing trailing pads of OFPActionCopyField * ofproto\_v1\_5\_parser: Fix length calculation of OFPOxmId * ovsdb: Fix small bug * packet\_data\_generator3: Generate OF13 Ext-230 bundle packets * packet\_data\_generator3: Support ovs-2.8 * ofproto\_v1\_3: Add bundle extension * ofproto: Correct OFPBundle{Ctrl, Add}Msg docstrings * rest\_vtep: Add some descriptions for troubleshooting * topology: Enable to detect migrations of hosts * Ryu 4.20 * fix bug in the example of flow\_stats\_reply * app: added simple switch with openflow 1.5 support * ofproto\_v1\_5\_parser: Change default of command\_bucket\_id * app: Fix simple\_switch for multi switch env * doc: fix typo * test\_icmpv6: Catch proper Exception * packet/icmp: Avoid TypeError when calculating length * \*: Reject Binary Represented IP Addresses * serivice/bgp: Fix ssh connection problem in Python 2.7 * flags: Inject \_\_class\_\_ attribute to LooseVersion * library\_ovsdb\_manager: Descriptions for OVS configs * app/ofctl: Enable to send single BarrierRequest * packet/zebra: Support FRRouting version 3.0 * of14: Implement OFPBundleCtrlMsg parser * rest\_qos: Avoid None when deleting OVSDB addr * lib/ovs/vsctl: Function for validate OVSDB address * Ryu 4.19 * BGPSpeaker: Enable to specify local listen addresses * bgp/application: Enhance arguments handling for BGPSpeaker * test\_controller: Test cases for \_split\_addr() * controller: APIs to register switch address dynamically * controller: Support proactive connection * Ryu 4.18 * zclient/zserver: Support FRRouting messages format * test\_zebra: Enhance test cases * packet/zebra: Support MPLS Labels messages * packet/zebra: Support Interface Router Advertisement messages * packet/zebra: Support VRF related messages * packet/zebra: Support BFD Destination messages * packet/zebra: Support Neighbor Connected Address messages * test\_zebra: Add pcap for API version 4 on FRR v2.0 * packet/zebra: Support some FRRouting messages format * packet/zebra: Constants for supporting FRRouting format * packet/zebra: Support asymmetric structure of ZEBRA\_\*\_IMPORT\_LOOKUP * packet/zebra: Parse messages based on Zebra API version * packet/zebra: Missing bw\_cls\_num in InterfaceLinkParams * packet/zebra: Constants for Link Parameters Status * packet/zebra: Constants for Interface Address Flags * packet/zebra: Return "ZebraMessage" for message from Zebra * packet/zebra: Fix unresolved reference for \_serialize\_nexthops * Only import pip if needed * Ryu 4.17 * topology/switches: Fix delete port can't immediately remove link * BGPSpeaker/net\_ctrl: Close activity for each session * packet/bmp: Correctly parse peer address with IPv4 * rest\_qos: Avoid discarding Queues info for each request * services/ovsdb: Listen on IPv6 Address * packet/icmpv6: Assert length in options are valid * packet/icmpv6: Fix parsing undefined nd\_option fails * ofp\_event: Timestamp when OpenFlow event was generated * Ryu 4.16 * doc: Fix unexpected indent in ryu/lib/packet/bgp.py * doc: Deprecated option html\_use\_smartypants * ofproto: Avoid emitting illegal instruction sets * doc: Minor grammar changes in ryu\_app\_api * unit/ofproto: Adopt to rename of OFPErrorExperimenterMsg * ofproto: Handle OFPErrorExperimenterMsg * bgp\_sample\_conf: absolute\_import to suppress warnings * service/ovsdb: get socket from RemoteOvsdb * Ryu 4.15 * Revert "tests: Separate test files from Ryu module" * tests: Separate test files from Ryu module * service/ovsdb: Use dict.items() instead of six.iteritems() * doc/ovsdb\_manager: Update Sample Code * service/ovsdb: Use Python 2/3 compatible code * service/ovsdb: Avoid to use dict as default argument * service/ovsdb: Add properties to EventNewOVSDBConnection * test\_vsctl: Strip unexpected double quote * pip: OpenStack updated requirements of eventlet again * manager: Introduce user flags option * CONTRIBUTING: Update info of Python ver/lib and links * CONTRIBUTING: Update procedure for running tests * CONTRIBUTING: Update procedure for submitting patches * README: Dependencies for installing optional requirements * service/ovsdb: Default of controller\_info in set\_controller * Ryu 4.14 * doc: fix error in ovsdb\_manager.rst code * fix dhcp6.py bug using python3 * pip: OpenStack avoids newer eventlet * ofctl: Add some tests for ofp\_instruction\_from\_str * ofctl: Add ovs-ofctl style action string parser * nicira\_ext: Define some CT constants * BGPSpeaker/SSH: Support to show L2VPN Flow Spec routes * BGPSpeaker: Support IPv6 Flow Spec update messages * BGPSpeaker/info\_base: Add tables for L2VPN Flow Spec * utils/test\_bgp: Add unit tests for L2VPN Flow Spec * test\_table\_manager: Add unit tests for L2VPN Flow Spec * test\_bgpspeaker: Add unit tests for L2VPN Flow Spec * packet/bgp: Support L2VPN Flow Spec * packet/bgp: Properly calculate length for FlowSpec * test\_bgp: Add test cases for L2VPN Flow Spec * BGPSpeaker/SSH: Support to show IPv6 Flow Spec routes * BGPSpeaker: Support IPv6 Flow Spec update messages * BGPSpeaker/info\_base: Add tables for IPv6 Flow Spec * utils/test\_bgp: Add unit tests for IPv6 Flow Spec * test\_table\_manager: Add unit tests for IPv6 Flow Spec * test\_bgpspeaker: Add unit tests for IPv6 Flow Spec * packet/bgp: Support IPv6 Flow Spec * test\_bgp: Add test cases for IPv6 Flow Spec * ofproto: Allow CIDR notation for ipv[46]\_{src, dst} * utils.import\_module: Prefer filepath than Python module * library\_packet\_ref: Separate ref into each protocol * lib/packet: Use literal block for diagram in pydoc * packet/bgp: Omit description of default value * packet/lldp: Add description for each class * packet/arp: Update description for arguments * BGPSpeaker/info\_base/base: Unify documentation format * BGPSpeaker: Unify documentation format * BGPSpeaker: Improve EVPN Redundancy Mode validation * bgp: Enable to configure default local preference * packet/zebra: Support IP\_ROUTE message from Zebra * lib/hub: Workaround for issue of eventlet * Ryu 4.13 * nicira\_ext: Constants for IP fragment matching * bgp/info\_base: Refactor has\_nexthop() method * bgp/peer: Fix invalid NEXT\_HOP in UPDATE message * ofctl\_v1\_5: Fix lack of arguments for modify role API * ofctl\_rest: Add get role API * ofctl: Fix type of fields of DescStat * utils/test\_bgp: Add unit tests for Flow Specification * core\_managers/test\_table\_manager: Add unit tests for Flow Specification * test\_bgpspeaker: Add unit tests for Flow Specification * library\_packet\_ref: Add description of action for Flow Specification * BGPSpeaker: Support Flow Specification update messages * BGPSpeaker/SSH: Supports display of Flow Specification RIB * BGPSpeaker/info\_base: Add tables for Flow Specification * packet/bgp: Implement the utility of Flow Specification for BGPSpeaker * packet/bgp: Fix subtype for Traffic Filtering Actions of Flow Specification * packet/bgp: Unify variable names for Flow Specification * packet/bgp: Add the address converter for Flow Specification * packet/bgp: Fix data structure for VPNv4 Flow Specification * library\_packet\_ref:Add bgp reference for Flow Specification * test\_bgp: Add test cases for user interface of Flow Specification * packet/bgp: Implement user interface of Flow Specification * Ryu 4.12 * hub.StreamServer: Ommit validation for IPv4 address * wsgi: Change default wsgi listen host to "0.0.0.0" * zebra: Add sample application for Zebra server service * zebra: Implement Server APIs for Zebra protocol service * zebra: Implement database for Zebra protocol service * tools/optional-requires: SQLAlchemy for Zebra service * lib/netdevice: Constants defined in netdevice(7) * controller: Change default OPF listen host to "0.0.0.0" * hub: Enable StreamServer to listen Unix domain socket * zebra: Add sample application for Zebra client service * Implement Zebra protocol client service * bgp/utils/bgp: Use lib/ip for Python 3 compatibility * BGPSpeaker: Use isinstance(\*, bool) for boolean check * BGPSpeaker: Support Route Reflector features [RFC4456] * packet/zebra: Enable to specify "prefix" arg in str * lib/ip: Add wrapper for netaddr.valid\_ipv4/6 * allow\_local\_as\_in\_count : allow local ASN in AS patch, e.g. "rd auto/route-target both auto" * BGPSpeaker: Advertise VNI on EVPN Multicast Ethernet-Tag * BGPSpeaker: Allow empty IP Address in EVPN advertisement * RyuBGPSpeaker: Enable to notify BGP events * ofctl\_v1\_\*: Use utility functions of ofctl\_utils * ofctl\_v1\_\*: Use str\_to\_int instead of builtin int * test\_bgp: Add test cases for Flow Specification * packet/bgp: Support Flow Specification * pakcket/bgp: pylint * BGPSpeaker: Support to advertise Type 1, 2 Route Target * Ryu 4.11 * utils: Re-implement parse\_requirements * docker\_base.py: fix an ip option of "docker network connect" * library\_packet\_ref: Add doc for Zebra packet library * test\_zebra: Unit tests for Zebra packet library * packet/zebra: Add Zebra protocol parser * bgp\_scenario\_test: Clean previous builds before installing * sync ryu.services.protocols.ovsdb.client.Idl code with ovs lib * packet lib: adding DHCPv6 support * doc: library\_packet\_ref: Add reference of openflow * test\_openflow: Add unit tests for OpenFlow packet library * packet lib: Add packet library of OpenFlow * Ryu 4.10 * library\_packet\_ref: Update dhcp reference method * test\_dhcp: Extend unit test for fragmented options * packet/dhcp: Revert b'str' conversion * packet/dhcp: Support fragmented options * BGPSpeaker/net\_ctrl: Support multiple RPC sessions * BGPSpeaker/base: Stop child activity by name * BGPSpeaker/net\_ctrl: Move \_send\_\*\_response() function * BGPSpeaker/net\_ctrl: Close RPC session when disconnected * BGPSpeaker/net\_ctrl: Pylint and fixes of typos * rpc\_cli: Avoid to use eval() * rpc\_cli: Close peer connections when exiting prompt * rpc\_cli: Enable to execute a single command * ryu/app: Use Request/Response wrappers in REST Apps * wsgi: Wrapper classes of Request/Response in WebOb * library\_bgp\_speaker\_ref: Fix unexpected unindent * optional-requires: Specify lxml version for OpenStack * ryu-client: Remove client for OpenStack plugin/agent * doc: Deprecate OpenStack plugin ref * test\_geneve: Add unit tests for Geneve * packet lib: Add packet library of Geneve * test\_gre: Add unit tests for NVGRE * packet/gre: Support NVGRE extension * doc: library\_packet\_ref: Update references * rest\_router: Fix ARP THA in reply message * install\_docker\_test\_pkg: Remove unnecessary pip pacakges * tox: Move dependencies installation to .travis.yml * bgp\_scenario\_test: Switch Python version * test\_requirements: Test cases for checking requirements * tox: Test ryu-manager without additional requirements * pip: Add doc requirements for convenience * library\_bgp\_speaker\_ref: Fix unexpected indentation * doc: Add MRT file library reference * test\_mrtlib: Add unit tests for MRT paser * mrtlib: Add parser for MRT format [RFC6396] * packet/ospf: Reduce Pylint warnings * type\_desc: Define TypeDisp class for re-usability * bgp\_scenario\_test/bgp: Pylint * bgp\_scenario\_test/common: Pylint * Delete an unnecessary function * Get some debug information * Add DHCP options constants to DHCP lib * lib/ofctl\_v\_\*: Enable to filter flow stats by priority * packet/bgp: Fix default of esi for IP Prefix route * BGPSpeaker: ESI to be optional arg in MAC/IP Adv route * packet/bgp: Support multiple next\_hop in BGPPathAttributeMpReachNLRI * packet/bgp: Unpack mpls\_label in BGPPathAttributePmsiTunnel * stringify: Add optional attributes list to be displayed * packet/bgp: Support multiple BGP messages in a packet * BGPSpeaker: Support Ethernet A-D Route and Ethernet Segment Route * packet/bgp: Fix the ESI Label Extended Community to use mpls\_label * Ryu 4.9 * scenario test: Fix the wrong retry check in command execution * Enable to run a scenario test with a specific python version * rest\_firewall: Compare reserved port in str representation * test\_vsctl: Use osrg/ryu-book image as Mininet container * test\_vsctl: Wait for loading OVS kernel module * integrated/bgp: Use Ubuntu:16.04 for base image * docker\_base: Update base image to Ubuntu:16.04 * BGPSpeaker: Confirm SSH feature to be optional * docker\_base: Add missing requirements for test-requires * README: Use pip to resolve dependencies * pip: Separate test-requires * RPC: Specify encoding to msgpack.Packer/Unpacker * test\_rpc: Use numbers.Integral instead of long type * wsgi: Avoid using inspect.getargspec * wsgi: Reduce pylint warnings * wsgi: Use six.text\_type instead of unicode * contrib: Revert module path to ryu.contrib * protocols/bgp/base: Add missing \_\_next\_\_ method * BGPSpeaker: Support to advertise EVPN IP Prefix route * packet/bgp: Support for IP Prefix Route encoding * packet/bgp: Fix the EvpnNLRI to use the ryu.lib.packet.vxlan * packet/bgp: Fix the EvpnNLRI to use the ryu.lib.packet.mpls * packet/bgp: Fix the EvpnNLRI to use the ryu.lib.ip * BGPSpeaker: Enable to set capability for IPv6 * test\_bgp: Add test cases for IPv6 and VPNv6 routes * test\_bgp: Enable to check parsed BGP message * packet/bgp: Refactor MP\_REACH\_NLRI and MP\_UNREACH\_NLRI * lib/ip: Add method to convert IPv4/IPv6 to int * test\_bgp: Uncomment out test case for UPDATE * packet/bgp: Enable Extended Length flags if specified * pip: Move tinyrpc to pip-requires * Ryu 4.8 * contrib/tinyrpc: Remove embedded tinyrpc, use upstream * contrib/ncclient: Remove embedded ncclient, use upstream * ut/ovs: Add UT using Docker for ryu.lib.ovs * BGPSpeaker: Support to advertise PMSI Tunnel Attribute * packet/bgp: Add PMSI Tunnel Attribute * packet/vxlan: Add method to convert the format of vni * packet/mpls: Add method to convert the format of label * lib/ip: Add method to convert the format of Ipv4 or Ipv6 * Enable to run a scnario test for ryu bgp on travis * Add scripts which install a dependency package * Add bgp scenario tests * Add bgp scenario tests tool * bgp/application: Re-implement base BGP application * flags: Add CLI options for BGP application * BGPSpeaker: Enable to specify settings for SSH CLI * bgp/operator/ssh: Enable to quit gracefully * bgp/operator/ssh: Reduce pylint warnings * BGPSpeaker: Use dictConfig in the standard library * utils: Backward compatibility for 'imp.load\_source' * Log OFPErrorMsg.data as ascii when type is OFPET\_HELLO\_FAILED * ovs/vsctl: Fix API for parsing column/key/value set * ovs/vsctl: Add missing Controller commands in OVS v2.6.0 * ovs/vsctl: Add missing Port commands in OVS v2.6.0 * ovs/vsctl: Add missing Interface commands in OVS v2.6.0 * ovs/vsctl: Add missing Bridge commands in OVS v2.6.0 * ovs/vsctl: Sort out commands order * ovs/bridge: Add APIs for missing Database commands * ovs: Add API corresponding to ovs-vsctl remove command * ovs: Add API corresponding to ovs-vsctl add command * ovs: Add API corresponding to ovs-vsctl list command * ovs: Add API corresponding to ovs-vsctl add-bond command * ovs/vsctl: Update command list with OVS v2.6.0 * ovs/vsctl: Avoid applying next() to non-iterator object * ovs/vsctl: Add missing required argument for find\_vlan\_bridge * ovs: Reduce pylint warnings * ovs: Revert ovs module path * ovs/vsctl: Fix VSCtlCommand to inherit StringifyMixin * ovs/vswitch\_idl: Update OVSDB schema with v7.14.0 * ovs/vsctl: Change log level of redundant messages * rest\_router: Fix conversion of Packet Library to dict * dpset: Fix iteration error when disconnecting switches * test\_parser: Add an truncate packet test * test\_parser: Enable tests for truncated packets * ofproto\_v1\_3\_parser: Raise OFPTruncatedMessage exception on truncated messages * ofproto/nicira\_ext: Add missing NXMs in OVS v2.6.0 * ryu/lib/ofctl\_v1\_3: port name decoding fix * BGPSpeaker: Enhance APIs for operator.show * Ryu 4.7 * BGPSpeaker: Fix to enable to notify peer down * use old cryptography version * packet: Avoid parsing an empty buffer * pip-requires: Add ovs>=2.6.0 * doc: Add API reference for REST EVPN switch * app: Add sample application for REST EVPN switch * app: Integrate aplication of Ryu-book * ovs/bridge: Enable to request tunnel port number * ovs/bridge: Add utility method to create VXLAN port * ovs/bridge: Make local\_ip to optional field for tunnel * ovs/vsctl: Catch the default tag type in Port Table * stplib: Fix to store current OFPPort status * stplib: Fix to compare MAC address and Bridge ID * BGPSpeaker/api/operator: Simplify registration decorator * BGPSpeaker: Fix typos * ofproto/ofproto\_v1\_5\_parser: OFPMultipartReply malformed message offset fix * tests/switch: fix bug in \_diff\_packets function * Add Nicira extension vlan\_tci field * BGPSpeaker: Shutdown BGPSpeaker gracefully * BGPSpeaker: Enable to get path from EventPrefix * BGPSpeaker/vrf: Handle non MPLS labled NLRI * BGPSpeaker: Add EVPN routes from Global to VRF Table * table\_manager: Fix conversion of De Morgan's laws * test\_bgpspeaker: Add UT for advertising VNI for EVPN * BGPSpeaker: Extend to advertise VNI for EVPN routes * BGPSpeaker: Support to advertise Tunnel Encapsulation * packet/bgp: Add BGP Encapsulation Extended Community * doc: specify OFP v1.0 for sample application * add modify role API in ofctl\_rest * lib/ofctl\_v1\_4: correct argument order for OFPFlowMod constructor * Ryu 4.6 * Validate OpenFlow message length in header, to prevent controller receive loop DoS * PyInstaller: Enable to build stand-alone executables * handler: Fix for frozen builds * BGPSpeaker: Suppress RD in EVPN VRF on SSH console * doc: Update the API Reference for BGPSpeaker * test\_validation: Add unit tests for validation utilities * BGPSpeaker: Enable validation for optional arguments * BGPSpeaker: Raise exception when validation fails * BGPSpeaker: Improve validation utility methods * BGPSpeaker: Resolve unused argumet 'multi\_exit\_disc' * BGPSpeaker: Reduce Pylint warnings * test\_table\_manager: Add UTs for the Global Table API * table\_manager: Rename internal API for consistency * test\_table\_manager: Add UTs for the VRF Table API * BGPSpeaker: Support VRF Table for Ethernet VPN * test\_bgpspeaker: Add unit test for the API of EVPN * BGPSpeaker: Support Ethernet VPN update messages * packet/bgp: Fix to serialize BGPNotification on Python3 * BGPSpeaker/info\_base: Add comparison methods for Python3 * BGPSpeaker: Support Python3 on SSH console * test\_bgp: Add unit tests for Ethernet VPN * packet/bgp: Support MPLS-Based Ethernet VPN (RFC7432) * packet/bgp: Enable to parse the entire packet data * tests: Add tests for specifying Packet library for OFPPacketOut.data * lib/packet: Support the Json format data * ofproto: Enable to specify packet library for OFPPacketOut.data * lib: Reduce Pylint warnings * stringify: Fix to utilise six.moves.builtins * ofctl\_nicira\_ext: Fix not enough arguments for format string * ofctl\_nicira\_ext: Resolve not initialized values * Ryu 4.5 * Ensure that send() and send\_msg() in controller return status to calling applications * Clean up stale Datapath objects in the ofctl\_service application * packet lib: Add packet library of GRE * ofproto/nx\_actions: Update argument of NXActionCT * ofproto/nx\_actions: Revert API of NXAction * manager: Except KeyboardInterrupt to suppress traceback * stplib: Handle the port state not changed events * stplib: Adopt to Python3 * rest\_qos: Fix to handle the case without QoS action * packet: support relayed DHCP packet * Fix: LLDP.OrganizationallySpecific not ignoring info field * test\_parser: Add test data for some NXAction * ofproto/nx\_actions: Support some NXAction * ofproto/nx\_actions: Add comment for Ryu documents * test\_parser: Add test data for missing NXAction * ofproto/nx\_actions: Support missing NXAction * ofproto/nx\_actions: Update arguments to be compatible with ovs-ofctl * test\_parser: Add test data for NXAction used only in OpenFlow1.0 * ofproto/nx\_actions: Add NXAction used only in OpenFlow1.0 * test\_packet: Avoid to use array.array as input binary * packet: Fix minimum ethernet frame length * test\_peer: Unit test for peer.py of BGPSpeaker * BGPSpeaker: Support Four-Octet AS number * packet/bgp: Support Four-Octet AGGREGATOR Path Attribute * BGPSpeaker: Fix capability check when MP-BGP not supported * fix of13 VLAN\_PCP test case * Ryu 4.4 * topology: ignore cfm packets on packet in * topology: pep8 fixes * ofproto: Fix example of OFPSetAsync message * Update the readthedoc URL * lib/ofctl\_utils: Log the datapath sent to * Avoid parallel executions of AppManager.close() * python3: Use six.add\_metaclass for metaclass * python3: Use six.string\_types instead of basestring * python3: Improve Table class in services.protocols.bgp.info\_base.base * python 3: Replace deprecated logging.warn with logging.warning * Python3: Explicit string type encoding * BGPSpeaker: Remove unused utility modules * BGPSpeaker: Fix unresolved references in Python3 * BGPSpeaker: Support Per-Peer AS * packet\_data\_generator3/gen: Add some NXAction packets * ofproto/nicira\_ext: Move the variable and method for Nicira Extension * tests/test\_parser\_v10: Update test parameter * ofproto/nx\_actions: Update arguments to be compatible with ovs-ofctl * ofproto/ofproto\_v1\_0: Delete some NX actions * ofproto/nx\_actions: Porting the NX Action definition of ofproto\_v1\_0\_parser * ofproto/nx\_actions: Update serialize and parse * Extend OVSDB api * Fix RuntimeError of lldp\_packet\_in\_handler * Ryu 4.3 * nx\_match: add tun\_ipv6\_{src,dst} * packet\_data\_generator3: Clear xid into zero * ofproto: Implement OFPFlowMod parser * doc: Add PCAP file library reference * test\_pcaplib: Add unit tests for pcaplib * pcaplib: Reduce Pylint warnings * test\_bgp: Enable to test parser with pcap file * packet/bgp: Reduce Pylint warnings * bgp: fix typos * test-requires: Update to use the latest Pylint * test-requires: Add tinyrpc for RPC controller in wsgi * Make ovs optional * packet: Add VXLAN parser * packet/bgp: Add missing \_\_hash\_\_ function * controller: Add backward compatibility for 6633 port * Update default OpenFlow port to 6653 * BGP: Make RouteFamily class hashable * doc: Remove warnings when building doc pages * doc: Move Ryu App API doc into each source code * network: Fix unresolved reference * doc: Add description for EventOFPPortStateChange * controller: Implement EventOFPPortStateChange * doc/app/ofctl\_rest: Remove unused match field * doc/source/conf: Set the False to SmartyPants * doc/app/ofctl\_rest: Add a description for openflow1.5 * doc/app/ofctl\_rest: Update the optional parameter of the message * doc/app/ofctl\_rest: Add pbb\_uca to match field * doc/app/ofctl\_rest: Update the description method of Example * doc/app/ofctl\_rest: Add Openflow version * Bump version requirement for oslo.config, given usage of min parameter to IntOpt * tox: Integrate Coveralls.io * tox: Add Python 3.5 * test\_ofctl: Add test cases for new Actions of of15 * test\_ofctl\_rest: Add unit tests for ofctl\_rest * test\_ofctl: Add test cases for OpenFlow 1.5 * ofctl\_rest: Support OpenFlow 1.5 * lib/ofctl: Support OpenFlow 1.5 * ofproto\_v1\_5\_parser: Fix serialized length of OFPActionCopyField * ofctl\_v1\_4: Port some improvements from ofctl\_v1\_3 * ofctl\_v1\_4: Rename to get\_queue\_desc for uniformity * ofctl\_v1\_4: Support request parameters * ofctl\_utils: Enhance user value conversion * REST Apps: Adopt to Python 3 * topology: Adopt to Python 3 * ofctl\_rest: Enable to omit port\_no and queue\_id * ofctl\_rest: Adopt decorator to simplify * test\_ofctl: Test cases for omitting port\_no in get\_queue\_config * lib/ofctl\_v1\_[23]: Unify the arguments order * ofctl\_utils: Confirm binary type data in send\_experimenter * test\_import\_module: Update test cases * utils: fix for temporarily storing the value of sys.path * Ryu 4.2 * Enable filtering the OVSDB schema tables/columns * tox: Upgrade PyPy version to 2.6 * Eventlet throws a subclass of IOError when an SSL read timeout occurs. Ensure that the read loop continues in this case * Added support for the tcp flags nicira extension * Removes unnecessary Windows requirements * Ryu 4.1 * doc/app/ofctl\_rest: Update example of set-field action * doc/app/ofctl\_rest: Update the code-block language of response data * doc/app/ofctl\_rest: Update the ryu.app.ofctl\_rest version from openflow1.3 to openflow1.4 * lib/ofctl\_v1\_[234]: Consolidate send\_experimenter * lib/ofctl\_v1\_[34]: Consolidate common functions * lib/ofctl\_v1\_3: Support nicira extensions * lib/ofctl\_v1\_3: Allow caller to disable conversion * lib/ofctl\_\*: Consolidate \`send\_stats\_requst\` * lib/ofctl\_\*: Log the xid of messages being sent * unit/lib/test\_ofctl: Fix Flake8 [e731] * ofproto/ofproto\_v1\_4\_parser: Flake8 Fixes * ofproto/ofproto\_v1\_3\_parser: Flake8 Fixes * ofproto/ofproto\_v1\_2\_parser: Flake8 Fixes * ofproto/ofproto\_v1\_0\_parser: Flake8 Fixes * ofproto/nx\_actions: Flake8 Fixes * lib/ofctl\_v1\_4: Flake8 Fixes * lib/ofctl\_v1\_3: Flake8 Fixes * lib/ofctl\_v1\_2: Flake8 Fixes * lib/ofctl\_v1\_0: Flake8 Fixes * pip-requires: force ovs>=2.6.0dev0 for everyone * packet/tcp: Add TCP Control Flags * lib/ofctl\_utils: Add a deprecated value * lib/ofctl\_v1\_4: Fix json format of queue\_desc\_reply * lib/ofctl\_v1\_4: Fix an omission in OFPTFPT\_\* * lib/ofctl\_v1\_4: Fix a small bug in mod\_group\_entry() * lib/ofctl\_v1\_0: Fix a small bug in get\_desc\_stats() and get\_aggregate\_flow\_stats() * protocols/ovsdb: Add api for systemd\_id lookup * protocols/ovsdb: Add bulk read support * protocols/ovsdb: Fix shadow variables * protocols/ovsdb: Update wrapped Idl() * protocols/ovsdb: Remove patched ovs.vlog * test\_ofctl: Add test cases * doc/app/ofctl\_rest: Add the attribute for message * ofctl\_rest: Support port number and queue id in get\_queue\_stats() * ofctl\_rest: Support meter id in get\_meter\_config() * ofctl\_rest: Support meter id in get\_meter\_stats() * ofctl\_rest: Support group id in get\_group\_stats() * ofctl\_rest: Support port number in get\_port\_stats() * hub: Preserve functions return value * protocols/ovsdb: Improve non-blocking performance * contrib/ovs: Remove embeded ovs, use upstream * protocols/ovsdb: Fix variable name issue * protocols/ovsdb: Allow setting backoff settings * Cleanups to controller.py * protocols/ovsdb: Allow setting probe interval * protocols/ovsdb: Fix shadow loop variables [F402] * protocols/bgp: PEP-8 and Python3 fixes * packet/bgp: PEP-8 and Python3 fixes * doc/app/ofctl\_rest: Update description for action type of experimenter * ofctl\_v1\_3: Add support for using action experimenter * ofproto\_v1\_3: Add unit test cases for action experimenter * ofproto\_v1\_5: Reduce an unnecessary code * ofproto\_v1\_5: Add test case for OFPExperimenter * Ryu 4.0 * Typo fixes * of: add echo request support * make socket-timeout config file option * Clean up socket close() handling * Wrap handler calls in the event loop in a try/except and log exceptions * Use a slightly lighter Queue implementation * Protect events queue with a semaphore * .pylintrc: Remove deprecated output format feature * run\_mininet: Specify the controller port * run\_mininet: Adopt utility methods of Mininet class * run\_mininet: Support protocols option of ovs-vsctl * ofp\_handler: Handle empty data field in OFPErrorMsg * lib/ofctl: add test files for ofctl\_v14 * lib/ofctl: add ofctl\_v1\_4 library * app/ofctl\_rest: support OpenFlow1.4 * ofproto: Fixes invalid async config property types * simple\_switch: Separate simple\_switch for beginners * drop python2.6 support * Fix i386 test failures * test\_parser: add an NXActionRegLoad test * packet\_data\_generator3: generate an NXActionRegLoad packet * Implement NXActionRegLoad * test\_parser: Fix ofp\_multipart\_type in OFPFlowStatsRequest * ofproto\_v1\_5\_parser: Add missing field in OFPMeterFeaturesStats * ofproto\_v1\_5\_parser: Fix unresolved structure references * test\_parser: Add missing packet data for OFP15 * tox: Adapt to PyPy interpreter * of12/3/4/5: fix to\_jsondict of OFPActionSetField * protocols/bgp: Log socket creation error * Ryu 3.30 * Update conntrack test json and binary packets * test\_parser: add conntrack NAT tests * packet\_data\_generator3: add a couple of conntrack packets * Implement NXActionNAT * rest\_router: Ensure that usage of icmp.dest\_unreach and icmp.TimeExceeded complies with RFC 4884 * packet: Better validate parameters to constructors better icmp * doc: remove obsolete OpenStack info * bgp: Clean up syntax in services/protocols/bgp/operator/views/base.py to avoid SyntaxErrors * Reconnected event additions and cleanups * test: Yet another typo fix * test: ImportError fix, error caused by unordered import Link * topology: Make sure the last IP in the list is the newest IP * Message cleanup in ofproto\_parser * Typo cleanup * Typo fixes in lib/packet/bgp.py * Fix: "AddrFormatError: address '...' is not an EUIv48" * packet/bgp: Gaurd against extra data in the buffer * protocols/ovsdb: Forcably kill the main\_thread * protocols/ovsdb: Handle accept() errors * protocols/ovsdb: Handle disconnects gracefully * test: disable rpc unittest with large file for now * ofproto/NXAction: Fix NXActionUnknown parsing * of14\_parser: unify OFPActionExperimenter implementation * test\_ofctl: Update json representations * test\_ofctl\_utils: Add unit tests for ofctl\_utils.py * lib/ofctl: Add utility library for ofctl\_v1\_\*.py * doc: Add Nicira Extension Structures references * doc: ofproto\_ref: Update supported actions/matches list * packet\_data: regen * test\_parser: Add expected json representations * packet\_data\_generator2: Add some OFP13/15 messages * lib/ofctl\_v1\_\*: Confirm hw\_addr is str in mod\_port\_behavior * test\_ofctl: Compare sent messages in json representation * Remove old link when link updates * fixes for mutable default arguments * Cleanup variable name for clarity * cap oslo.config version only in python2.6 * Ryu 3.29 * Generate new datapath event for switch connecting multiple times * Fix handling of state transition to config mode * Clean up for stability patch submitted previously * Ensure to terminate threads where RyuApp.start() gives a thread object * ofctl\_v1/2/3: Some improvements * of14: Add action experimenter to flow stats reply unit test * test\_tcp: Update test cases for tcp option * lib/packet/tcp: Parse TCP Option field * bgp: fix handling unknown and unsupported transitive path * ofp\_handler: Remove sending SET\_CONFIG message * lib/ofctl: Add test cases for ofctl\_v1\_0 * lib/ofctl: Add test cases for ofctl\_v1\_2 * lib/ofctl: Add test cases for ofctl\_v1\_3 * lib/ofctl: Implement unit test for sending messages * lib/ofctl: Rename unit test for action/match * lib/ofctl: Confirm UTF-8 in binary fields * ofproto\_v1\_[23]\_parser: Add default arguments in OFPQueueProp * test\_parser: Add some expected json representations * packet\_data: Regen * packet\_data\_generator: Add ofp\_group\_stats messages for OF1.2 * ofproto\_v1\_[2345]\_parser: Set default length field * avoid oslo.config 3.1.0 and later for python2.6 support * test\_controller: Add unit test for \_recv\_loop() * controller: Split received message buffer * Fix a stability issue relating to switch disconnection/re-connection events * Ryu 3.28 * test\_parser: add conntrack tests * packet\_data\_generator3: add a couple of conntrack packets * Implement NXActionCT and related ct\_\* matches * tox: disable wheel cache * python3: implicit relative import was deprecated * python3: itertools.ifilter() doesn't exist * python3: iter#next() doesn't exist * python3: #func\_name is renamed to \_\_name\_\_ * python3: import \_\_future\_\_ for just in case * python3: StandardError doesn't exist * ofctl\_v1\_3: Fix unsuitable error log in mod\_meter\_entry() * Ryu 3.27 * bgp: fix of sending "Start-of-RIB" and "End-of-RIB" in Enhanced Route-Refresh * doc/app/ofctl\_rest: Add description for OFPTableStats message * doc/app/ofctl\_rest: Add description for OFPQueueGetConfig message * doc/app/ofctl\_rest: Add description for OFPTableFeaturesStats message * ofctl\_rest: support OFPQueueGetConfig Message * ofctl\_rest: support OFPTableFeaturesStats Message * ofctl\_rest: support OFPTableStats Message * vrrp: fix param of virtual\_ip\_address for rpc\_api * tester: Reduce pylint warnings * tester: Add test cases for OpenFlow1.0 * tester: Support to test OpenFlow1.0 switch * packet\_data: Fix wildcarded match value in OF1.0 * of10: Human readable address field in json Match/Action * Try logging.config.dictConfig before in-tree version * Python3: use int instead of long * Python3: complete previous removal of types usage * Python3: use dict instead of types.DictType * doc: Change Sphinx html\_theme to sphinx\_rtd\_theme * bgp: support of CAP\_ENHANCED\_REFRESH for vpnv4 * tester: Use six.binary\_type for binary data comparison * tester: Enable to sort instructions instance by type * tester: Remove too broad exception handling * tester: Strict string argument encoding in Python3 * tester: Adapt to Python3 dictview * packet\_data: Regen * test\_parser: Add expected json for OFP13/15 Messages * packet\_data\_generator2: Add OFP13/15 Messages * packet\_data\_generator2: Sort by OF1.5 index order * packet\_data\_generator2: Fix to use struct eth\_addr * doc: Add openflow api reference for of1.0 * ofproto\_v1\_0\_parser: Add comments for OF1.0 protocol * doc: Handle ERROR of unexpected indentation * test\_ip: Add tests for IPv4-int conversion * of10: Add \_\_contains\_\_ method into OFPMatch * test\_parser\_v10: Fix wildcards param for unit test * of10: Support human readable MAC/IPv4 address in OFPMatch * Ryu 3.26 * switch/tester: Add sleep interval for each test case * ofproto\_v1\_[45]\_parser: Add parser() for OFPRequestForward * remove old Ryu OpenStack plugin stuff * packet: lldp: python3 fix * bgp: support disabling listening socket * bgp: python3 fixes * test\_parser\_ofpmatch: Add tests for Experimenter OXMs * OXM/OXS: Enable to sort Experimenter oxm\_type/oxs\_type in Python3 * test\_parser\_ofpmatch: Add test cases for OF1.4 and OF1.5 * .travis.yml: Suppress the output of unit tests * ofproto: Sort out the NX OXMs definition * ofproto: Refine module import * ofproto\_v1\_[45]\_parser: Remove unused OFPMatchField * doc/ofproto\_v1\_2\_ref: Add description for Port Structures * doc/ofproto\_v1\_3\_ref: Add description for Port Structures * doc/ofproto\_v1\_4\_ref: Add description for Port Structures * doc/ofproto\_v1\_5\_ref: Add description for Port Structures and Controller Status Structure * Examples contain invalid MAC addresses * ofproto\_v1\_0\_parser: Add \_\_getitem\_\_ method into OFPMatch * test\_parser\_v10: Add test case for \_\_getitem\_\_ of OFPMatch * doc/app/ofctl\_rest: Add command examples for WRITE/CLEAR\_ACTIONS * Uncap pbr version * topology: Fixed conditional statement * ofproto\_v1\_5: Add OFPBAC\_BAD\_METER * bgp: enable nexthop\_self for locally generated routes * test\_ofctl: improving readability * test\_ofctl: Add unit test for OFPIT\_[WRITE/CLEAR]\_ACTIONS * ofctl\_v1\_[23]: Add support for OFPIT\_[WRITE/CLEAR]\_ACTIONS * ofp\_handler: Output human readable error msg ev log * ofproto\_parser: Unify str representation of MsgBase * utils: Add binary\_str() method to print binary data * utils: Unify output str format of hex\_array() * doc: Add some JSON examples to openflow api reference for of1.5 * test\_parser: Add expected json outputs for OF1.5 * doc: Add openflow api reference for of1.5 * test\_parser: Add test case for OFP15 table\_features\_reply * Ryu 3.25 * packet: dhcp should set \_MIN\_LEN * packet: udp should detect dhcp * ofctl\_v1\_[23]: Fix the output result of get\_flow\_stats() * ofctl\_v1\_[23]: Convert masked match value into str * packet/igmp: Python 3: truncate IGMP timer fields to integers before packing * doc: ofctl\_rest: Add table of contents * README.rst: add OF 1.5 support * bgp: Added support to indicate the next hop IP address for the BGP module * bgp: add neighbor\_state\_get method * Remove hosts from edge port when link added * ofproto\_v1\_5\_parser: Fix typo in comment * ofproto\_v1\_4\_parser: Fix typo in comment * ofproto\_v1\_3\_parser: Fix typo in comment * ofproto\_v1\_2\_parser: Fix typo in comment * python3: Fix relative imports * doc: Include snort\_integrate page into toctree * Add missing comment to rest\_topology * Add EventHostAdd handler for web socket application * test\_parser: Add test case for OFPQueuePropExperimenter * ofproto\_v1\_3\_parser: Add OFPQueuePropExperimenter support * ofproto\_v1\_3\_parser: Backport OFPTableFeatureProp class * ofproto\_v1\_[45]\_parser: Add missing OFPTFPT\_EXPERIMENTER\_MISS * ofproto\_v1\_3\_parser: Backport OFPPropBase/OFPPropCommonExperimenter4ByteData * test\_parser: Fix some expected json representations * ofproto\_v1\_[45]\_parser: Fix to parse experimenter\_data * ofproto\_v1\_[345]: Define common structure for experimenter property * ofproto\_v1\_4\_parser: Move utility method to OFPPropBase * test\_parser: Add test case for OFP15 packet\_out * ofproto\_v1\_5\_parser: Enable setting OFPMatch in OFPPacketOut message * test\_parser: Add test case for OFP15 controller connection status messages * test\_parser: Add implemented type for OFPT\_CONTROLLER\_STATUS * ofproto\_v1\_5\_parser: Add OFPControllerStatusStats support * ofproto\_v1\_5\_parser: Add OFPControllerStatus support * ofproto\_v1\_5\_parser: Add OFPControllerStatusProp support * ofproto\_v1\_5\_parser: Enable OFPRoleRequest to set short\_id * Add register\_service to topology events * Add EventHostAdd event * Allow specifing match fields in ClsRule.\_\_init\_\_ * Sprinkle StringifyMixin * PEP8 Line length * Remove unused import * Stop old app on reconnection * Use system\_id from event * Handle disconnection during discover\_system\_id * test\_parser: Add tests generated by packet\_data\_generator3 * Introduce packet\_data\_generator3 * test\_parser: prepare for tests with packet\_data\_generator3 * Add register0 for nicira extensions * packet\_data\_generator2: Add Makefile for GNU environment * use idle timeout in ofctl to avoid incomplete querying * Python 3: Fix search for bound methods * Python 3: Filter out None values returned by getmodule(...) to fix the stack inspection * ofproto\_v1\_5\_parser: Add OFPBundleFeaturesStats support * ofproto\_v1\_5\_parser: Support new OFPTableFeaturesStats structure * ofproto\_v1\_5\_parser: Add OFPBundlePropTime support * test\_parser: Add test case for OFP15 bundle\_features request/reply * test\_parser: Add test case for OFP15 table\_features\_request * ofproto\_v1\_5\_parser: Add OFPBundleFeaturesProp support * ofproto\_v1\_5\_parser: Add new table feature properties support * test\_parser: Regen OFP15 port\_desc request packet * test\_parser: Regen OFP15 group\_desc request packet * test\_parser: Add test case for OXS related messages in OF1.5 * ofproto\_v1\_5\_parser: Add OFPFlowDesc support * ofproto\_v1\_5\_parser: Fix OFPFlowStats/OFPAggregateStats to use OFPStats * ofproto\_v1\_5\_parser: Fix OFPFlowRemoved to use OFPStats * ofproto\_v1\_5\_parser: Use b'str' for binary data * ofproto\_v1\_5\_parser: Use six.binary\_type instead of buffer * test\_parser: Add test case for OFP15 group\_desc reply * test\_parser: Add expected json representations of OF1.5 GroupMod * packet\_data: Regen * packet\_data\_generator2: Generate OF1.5 GroupMod packets * ofproto\_v1\_5\_parser: Support OF1.5 OFPGroupDescStats structure * ofproto\_v1\_[345]: Fix backward compatibility for OFPGroupDescStats * ofproto\_v1\_5\_parser: Support OF1.5 OFPGroupMod structure * ofproto\_v1\_5\_parser: Add OFPGroupProp support * ofproto\_v1\_5\_parser: Add OFPGroupBucketProp support * ofproto\_v1\_5: Fix a typo * Ryu 3.24 * ospf: fix serialize() to work with packet.Packet() * of1.5: Multipart METER\_CONFIG was renamed to METER\_DESC * of1.5: Meter statistics field flow\_count was renamed to ref\_count * test\_parser: Add test case for OFP15 port\_desc request * of1.5: port statistics and port descriptions use a common request format * test\_parser: Add test case for OFP15 group\_desc request * of1.5: group statistics and group descriptions use a common request format * test\_parser: Add test case for OFP15 queue\_desc request * of1.5: queue statistics and queue descriptions use a common request format * ofproto\_v1\_[2345]\_parser: Add items method to OFPMatch/OFPStats * Add OVSDB manager protocol application * OF: send fin/ack in response to fin packet * packet\_data\_generator2: Adopt upgrade of ofputil\_packet\_in * test\_ofctl: Add some test cases of OF1.0 actions * ofctl\_v1\_0: fix output string of ENQUEUE * OXM/OXS: Initialize exp\_type with oxm\_field * ofproto\_v1\_5\_parser: Add OFPPortDescPropRecirculate class * ofproto\_v1\_5\_parser: Add OFPPortDescPropOxm class * ofproto\_v1\_5\_parser: Move utility method to OFPPropBase * ofproto\_v1\_[45]\_parser: Sort out the inheritance relation of OFP\*Prop * ofproto\_v1\_[45]\_parser: Correct example of OFPPortMod * ofproto\_v1\_[45]\_parser: Rename Port Description Properties class * ofproto\_v1\_5\_parser: Enable setting mask in OFPActionSetField * ofproto\_v1\_5\_parser: Add OFPActionCopyField support * ofproto\_v1\_5\_parser: Add OFPInstructionStatTrigger support * add host restful api * add host discovery functions * ignore lldp packet to avoid wrong links * bgp: fix withdrawn label handling again * ignore lldp packet to avoid wrong links * declare python3 support * bgp: fix bug of not taking care of withdrawn label * Add registers 1-7 as nicira extensions for matching and setting * Implement NX Resubmit-table action * travis: run tests with python3 * python3: Convert chr to six.int2byte * Fix test packet data generation * Use the asciilist type for lists of ip addresses * python3: Misc str related fixups * python3: Round time() return value to microseconds * python3: Adapt to iterator change * python3: Use b'str' for binary data * python3: Convert str to six.binary\_type * packet\_utils: Remove checksum() side-effect * python3: Use {encode, decode}('ascii') for text packet data * python3: Partially revert b'str' conversion * python3: Use six.indexbytes for extracting single byte of data * python3: Store AsciiStringType class data as str * Ryu 3.23 * python3: fix bgp reggression * python3: Misc. python3 fix * python3: Make stringify test functional * python3: Make ryu.utils.hex\_array functional * python3: Use b'str' for binary data * python3: Use six.binary\_type for I/O of ryu.lib.rpc * python3: Use 'str' not b'str' for user test data * python3: Restore original str()s where six.binary\_type shouldn't be used * python3: fix bgp reggression * Avoid string exception raising * packet.ospf: Avoid parameter 'cls' reassignment * Remove duplicated definitions * test\_ofctl: Fix dynamic addition of test cases * test\_ofctl: Some improvement * test\_ofctl: Remove unused codes * test\_ofctl: Add unit test for ofctl\_v1\_0 * python3: Don't use str.encode * python3: Remove harmful AsciiStringType.{encode, decode} * python3: Decode return value of b64encode into str * python3: More b'str' conversion * python3: Calculate the number of ports as integer * python3: encode from string to bytes for s type of pack format * python3: Modify a literal argument in a bytes method call to bytes type * Add support for pkt\_mark nicira ext (NXM\_NX\_PKT\_MARK) * python3: Continuous patch to replace buffer to six.binary\_type * python3: Continuous patch to replace str to six.binary\_type * python3: Convert str to six.binary\_type * python3: More b'str' conversion * python3: Apply "2to3 -f map" * python3: Convert str to six.binary\_type where appropriate * python3: Use six.binary\_type instead of str for binary data * python3: adapt @wsgi.route() * python3: Use items instead of iteritems * python3: Use zip instead of itertools.izip * python3: Avoid applying ord() to integers * python3: Use formencode instead of xml\_compare * python3: Open packet data with binary mode * python3: Fix dynamically added test methods * python3: Use b'str' for binary literals * python3: Remove use of buffer() * python3: Use six.text\_type instead of unicode * eventlet has already supported WebSocket(RFC6455) in stable releases (>= 0.15) * python3: Use integer division where appropriate * python3: Fix import issues with python2 * python3: Use bytes type for binary data * python3: Adapt to new iterator names * python3: Fix starndard library imports * ofproto: Fix ImportError on python3 * tox.ini: Be able to run python3 unit tests * test\_parser\_ofpstats: Add unit test for OFPStats class * ofproto\_v1\_5\_parser: Add OPFStats parser for Flow Stats Structures * test\_oxs: Add unit test for oxs\_fields.py * oxs\_fields: Add OXS class support * Clean up server socket and thread when shutting down * Fixed the function name of out filter * ofctl\_rest: fix error of delete\_flow\_entry * ofctl\_v1\_0: fix output of get\_flow\_stats * Ryu 3.22 * test\_parser: Add some expected json representations * packet\_data: Regen * packet\_data\_generator2: Generate conjunction packets * Implement NXActionConjunction and conj\_id match for OF1.3 and OF1.5 * Add missing ryu.contrib.update\_module\_path calls * Cap pbr version * packet\_data: Regen * packet\_generator2: learn action * test\_parser: Add some expected json representations * ofproto\_v1\_5: Add legacy NXM aliases for some OXMs * ofproto\_v1\_3: Add legacy NXM aliases for some OXMs * Pull nx\_actions for OpenFlow 1.5 * \_NXFlowSpec: Add type annotation for stringify stuff * nx\_actions: Modify \_\_module\_\_ for generated classes for stringify stuff * NXActionRegMove: Add type annotation for stringify stuff * Adapt to namespace-less oslo * test\_lib: Remove a questional exception re-raising * Be able to parse classes that start with "NX" * Ryu 3.21 * Suppress warning * sw test tool: Fix typo * tests: Remove some unnecessary shebangs * packet\_data: Regen * test\_parser: Add expected json representations * packet\_data\_generator2: Generate OF1.3 packets where appropriate * packet\_data\_generator2: Make the list of OF versions per messages * tests: Fix dynamically added test cases * tests: Remove unnecessary shebang and x bit from test\_lib.py * test\_parser\_compat: Fix indent * test\_parser: Try to detect test discovery failures and bail out loudly * MANIFEST.in: Exclude packet\_data\_generator2 * tox.ini: Pass posargs to make "tox -e py27 path.to.test" work * bgpspeaker: Import paramiko only when necessary * README.rst: Correct component which needs paramiko * disable padding check for llc packets * ryu.contrib: Be explicit about sys.path modification * Revert recent py3 changes under ryu/contrib * str to bytes * 'reload' has been renamed to 'imp.reload' in Python 3 * Integers between '/' operation become float in Python 3 * 'string.upper' and 'string.lower' has been deprecated in Python 3 * 'map' returns iterator like object with Python 3 * 'izip' has been deprecated in Python 3 * 'reduce' has been renamed to 'functools.reduce' in Python 3 * 'long' has been deprecated in Python 3 * 'reduce' has been renamed to 'functools.reduce' in Python 3 * 'sys.maxint' has been deprecated in Python 3 * 'itertools.izip()' has been deprecated in Python 3 * 'ConfigParser' is renamed to 'configparser' in Python 3 * '\_\_div\_\_' is renamed to '\_\_truediv\_\_' in Python 3 * app\_manager: Clean up apps harder * Fix ImportError(s) with Python3 * Use range() instead of xrange() * Reduce pep8 warnings with Python3 * Treatment was not enough * '+' operator can't combine no-string object * Avoid invalid dpid and simplify the checking of ofctl version * packet\_data\_generator2: Fix message length field * test\_parser: Add an expected result (bundle\_add) * packet\_data: regen (bundle\_add) * packet\_data\_generator2: Add bundle\_add * test\_parser: Add an expected result (flow\_mod) * packet\_data: regen (flow\_mod) * packet\_data\_generator2: clear XID field * packet\_data\_generator2: Add flow\_mod * test\_parser: Add a expected result (bundle\_ctrl) * packet\_data: regen (bundle\_ctrl) * packet\_data\_generator2: Add bundle\_ctrl * of15: Implement OFPBundleCtrlMsg parser * packet\_data\_generator2: README * Show warning when Datapath#ports is read * Syntax level compatibility with Python 3 * Ryu 3.20 * rest\_firewall: Prevent adding fields which is unrelated to match * ofctl\_v1\_[23]: Ignore unkown match fields * Revert "pip-requires: Remove comments" * test\_parser: Enable OpenFlow 1.5 tests * test\_parser: Add a expected result * packet\_data: regen * packet\_data\_generator2: another packet data generator using libofproto * pip-requires: Remove comments * lib.ovs.vsctl: Fix a crash * bmp: fix bug of logging format in bmpstation * ofctl\_rest: Reduce pylint warnings * doc/app/ofctl\_rest: Fix example of ipv6\_exthdr match field * test\_ofctl: Add unit test for masked ipv6\_exthdr match field * ofctl\_v1\_3: Support masked ipv6\_exthdr match field * requirements: Drop some optional requirements * README.rst: Replace a reference to ryu-plugin with ofagent * pip-requires: Add comments to say what's required by what * UT: Remove unused imports * bgp: Remove an unused import * yet more logging call cleanups * ryu.app.ofctl: Handle a race with connection close * silence pep8 warnings to the previous commit * Reduce logging overhead by cleaning up logging calls * Ryu 3.19 * snortlib: Remove disabled flag MSG\_WAITALL * ryu.cfg: Use a dedicated ConfigOpt instance * snortlib: Fix nw\_sock handling * of: Prevent \_\_str\_\_() methods from raising exceptions * bgp: Prevent \_\_str\_\_() methods from raising exceptions * packet lib: dhcp: Fix to calculate Hardware address length * travis-ci: use container-based infrastructure for faster testings * Move msg\_pack\_into from ofproto to lib * tox.ini: Disable pep8 W503 for now * bgp/bmp: bug fix. remove redundant construction of path attributes * Move the definitions of ether types and inet protocols to lib.packet * ofproto: Fix invalid error code OFPQCFC\_EPERM -> OFPSCFC\_EPERM (EXT-208) * ofproto: Openflow 1.5 support (work-in-progress) * ignore some pep8 errors for now * test\_oxm: Add tests for EXT-109 and EXT-233 * ofproto\_v1\_3: Implement EXT-109 and EXT-233 * oxm\_fields: Rename ONFExperimenter to OldONFExperimenter * oxm\_fields: Update comment for the new version of EXT-256 * bgp: support of new api for "show neighbor" * bgp: Fixed error in bgp implementation with single peer * bgp: fix bug of Path formatting in "show neighbor" * Ryu 3.18 * bgp: bug fix of sending Adj-RIB-Out * ryu-manager: add --enable-debugger option * bgp/cli: fix internel data destruction due to cli show command * bgp: remove unnecessary bgp update construction * bgp: fix bug of NameError: global name 'sent\_route' is not defined * bmpstation: bug fix. stop closing fds which are in use * bgp: don't hold withdrawn routes in adj\_rib\_in * bgp/bmp: send unmodified BGPUpdate to bmp server * Add parsing libpcap and reading/writing PCAP file * nx\_actions: Avoid confusing StringifyMixin * nx\_actions: Implement nx\_action\_learn * test\_nx\_flow\_spec: Add UTs for NX flow\_mod\_spec * nx\_actions: Implement NX flow\_mod\_spec * type\_desc: Separate type conversion classes from oxm\_fields * nx\_actions: Remove redundant initializations * Implement nx\_action\_reg\_move for OpenFlow 1.3 * doc/app/ofctl\_rest: Add description for OFPAggregateStats message * ofctl\_rest: support OFPAggregateStats message * doc/app/ofctl\_rest: Add description for OFPQueueStats message * ofctl\_rest: support OFPQueueStats message * test\_oxm: Add UTs for 64-bit experimenter OXMs * test\_oxm: dedicated UTs for oxm\_fields module * oxm\_fields: Fix 64-bit experimenter OXM support * oxm\_fields: Fix oxm\_length calculation for experimenter OXMs * oxm\_fields: Add header-only variants of serializer/parser * oxm\_fields: Prefix internal functions with \_ for readability * oxm\_fields: Add comments * OF 1.0: Use ofproto\_common.NX\_EXPERIMENTER\_ID instead of NX\_VENDOR\_ID * nicira\_ext: Separate the most of NX definitions from ofproto\_v1\_0 * Cleanup isinstance(foo, (int, long)) * doc/app/ofctl\_rest: Add descriptions for duration\_nsec field * of\_v1\_0: Fixed the flow format logic to set it correctly when registers matches are set * of\_v1\_0: Added support for the NXM\_NX\_TUN\_IPV4\_{SRC & DST}[\_W] fields * ospf: fix wrong OSPF LSA type * bgp: support of understanding assigned mpls-label for prefix\_add in vpnv4 * ofctl\_v1\_0/2/3: Fix unsuitable log level * Ryu 3.17 * ospf: add SummaryLSA class * ofctl\_v1\_2, 3: Fix regression of IP arbitrary bitmask support * bgp: bug fix of timestamps of BMPRouteMonitoring in bmp.py * topology/switches: add of1.2+ support for the drop\_packet function * bgp: Fix filter message variable * bgp: support New best path selecting * ofctl\_rest: Fix clear flow entries command * rest\_qos: fix error of additional a qos rule with "priority" * rest\_qos: fix a comment * bgp: support new handler in case of changing BGP session * doc/app/ofctl\_rest: Add description for capabilities field in OPFMeterFeatures * ofctl\_v1\_3: Fix to parse capabilities field in OPFMeterFeatures * ofproto\_v1\_[234]\_parser: Add notes for vlan\_vid match field * Ryu 3.16 * packet lib: don't crash with bogus ospf packet * bmp: bug fix of peer bgp ID in BMP Message * doc/app/ofctl\_rest: Add command examples for OFPVID\_NONE/PRESENT * ofctl\_v1\_2/3: Fully support the match combinations for VLAN ID * fix security problem of some RESTful apps * Workaround of os.path.samefile * test\_ofctl: Modify to use new match api and field parser * ofctl\_v1\_/2/3: Modify to\_match() to use new match api * ofctl\_v1\_/2/3: Modify match\_to\_str() to use new match field parser * bgp: bug fix of handling nexthop for eBGP peering * test\_utils: Add unit test for ryu.utils * utils: Fix bytearray conversion * test\_ofctl\_v1\_2/3: Add a test case of masked metadata * test\_ofctl\_v1\_2/3: Fix some test cases * bgp: bug fix of Multi Exit Discriminator (MED) * ofctl\_rest: fix some mistypes * doc/app/ofctl\_rest: Correct command examples * fix security problem of some RESTful apps * bgp: support connect modes to choose how to connect to the neighbors * bgp: enable to stop a chile thread by specifying its name * bgp: fix lacking import * bgp/cli: show adjacency rib in/out by show neighbor commands * ofctl\_v1\_0: Add remaining actions * doc: Add tables about match and actions structures * bgp: remove uncommon open msg check * bgp: fix \_OptParamCapability parser * Ryu 3.15 * simple\_switch\_12: handle non-buffering switch * simple\_switch: handle non-buffering switch * simple\_switch\_13.py: Added ability to use buffer\_id in FlowMod * simple\_switch\_13: Added a logging when running in --verbose for truncated packets * bgp: supporting best\_path\_change\_handler for Vpnv4/6 prefix in BGPSpeaker * rest\_router: fix security problem * packet lib: don't crash with truncated dhcp packet * packet lib: don't crash with corrupted lldp packet * ofctl\_v1\_0: match\_to\_str() does not convert nw\_tos correctly * bgp: fix bug of ASPathFilter in case of iBGP peering * stplib.py: Should wildcard non-relevant bits in the mask field of port mod message for OpenFlow 1.2+ * simple\_switch\_14: Update a comment about OVS bug * simple\_switch\_13: Update a comment about OVS bug * Add a simple switch for Openflow 1.4, an easy adaption of SimpleSwitch13 * sw test tool: Fix typos * ofproto\_v1\_4: Add tun\_ipv4\_src and tun\_ipv4\_dst NXMs * test\_parser: Update expected json representations * packet\_data: Regen * packet\_data\_generator: Add tun\_ipv4\_src and tun\_ipv4\_dst for OF1.3 * ofproto\_v1\_3: Add tun\_ipv4\_src and tun\_ipv4\_dst NXMs * oxm\_fields: Add Nicira Extended Match (NXM) support * oxm\_fields: Add comments * oxm\_fields: Avoid shadowing python builtin * travis: Run tests via tox * test\_addrconv: Fix a way to import the tested module * test\_parser: Make this independent from test environment path * tox.ini: Add pep8 environment * pyang\_plugins: pep8 style fix * bgp: fix pep8 warnings * bgp: supporting loopback interface as neighbour\_source\_address for iBGP * bfdlib: follow TTL/hop limit in RFC5881 explicitly * doc: add lib.packet.bfd classes to library\_packet\_ref * lib: add IPv4 single hop BFD (RFC5881) support * unit test for lib.packet.bfd * packet lib: add BFD support * ofctl\_v1\_0/2/3: check lock timeout by lock.is\_set() * test: add unittests for of1.3 parser * of12/3: support setting the oxm\_value to OFPVID\_NONE * ofproto\_v1\_4\_parser: Handle experimenter OXMs in TableFeatures * ofproto\_v1\_3\_parser: Handle experimenter OXMs in TableFeatures * oxm\_fields: Add a comment * bgp: support next\_hop\_self * Ryu 3.14 * doc: Add ryu.app.ofctl\_rest document * of: Fix name of class member variables * gui\_topology: fix to work using WebSocket * bgp: ignore link-local address * bgp: local preference support IPv6, VPNv4/v6 route family * Improve debug messages for unsupported request Log correct debug message * Fix spell check in group feature message Maintain name consistency in meter type in Meter Features message in OF 1.3 Add length field in group statistics reply in OF 1.2 * sw test tool: fix an error caused by changing enum name in of1.4 * ofctl: Add default value to type field of OFPGroupMod * of: Add missing fields in OpenFlow statistics messages * of: Fix Enum Names and Values * of: Fix Enum Name for Bad Instruction Code Corrected Reset Count enum name * bgp: local preference support * sw test tool: add unit test * sw test tool: add a comment about specifying the port number support * sw test tool: support specifying the port number * ofctl\_v1\_0: correct flow modify message * ryu.cfg: Fix a comment * ofa\_neutron\_agent: Add a comment to explain what uses this * ofp\_pktinfilter: add 'logging' option * Snort Integrate: * bgp: rpc-api 'core.start' method in Network Controller * import BGPPathAttributeCommunities in peer manager * bmp: add client information to each bmp message * Ryu 3.13 * ws\_topology: bugfix an event is dropped * bgp: should not use dict comprehension * Snort integrate: Add the snort lib supporting snort integration. Add an sample application simple\_switch\_snort.py which can dump alert message * packet lib: add linux cooked header support * doc: update obsolete Linux kernel SubmittingPatches url * packet bmp: fix Peer Down Reason * bgp: add parameter 'label\_ranges' for 'core.start' method in BGPSpeaker * ofctl\_rest: support OFPFlowStats filtered by fields * bgp: reduce duplicate codes with helper\_function * sw test tool: add a "note" for help to understand * bmpstation: make configurable through environment variables * bgp: make reserved private variable * bgp: encode 'next\_hop' in human readable format * bgp: use \_class\_suffixes to support various AddrPrefix * stringify: introduce \_class\_suffixes for easy jsonize * bgp: move \_TYPE declaration of IPAddrPrefix to the appropriate place * bgp: add support for RFC3107 * fix setup.cfg entry * bgp: simplify CLUSTER\_LIST attribute parser * bgp: fix bug of receiving 'RouteRefresh' Message * bgp: refine the API for connecting to bmp server * bgp: add BGP capability code 64 (graceful restart) * bgp: add attribute ORIGINATOR\_ID and CLUSTER\_LIST * bgp: move ssh configuration to bgp config file * bgp: add route server function to bgpspeaker * bgp: fix bug of labels formatting for show VPNv4 prefix information * bgp: fix bug of Path(Origin) formatting for show VPNv4 prefix information * bgp: show VPNv4 Prefix information * packet/bgp: add open capability code of 128 * bgp: support add/delete vpnv6 prefix * bgp: support add/delete VPNv6 VRF * app/bmpstation: fix to work with empty BMPMessage * packet/bmp: fix bug of BMP Peer Down Notification class * packet/bgp: add 32bit AS number support to BGPPathAttributeAsPath * added parameter for vrfs\_get (in case of format = 'cli') * added parameter for rib\_get * Ryu 3.12 * ofctl\_rest: Add support for strict matching * bgp: fix conflict of PEER\_NEXT\_HOP and NEXT\_HOP value * bgp: add code to handle RD 0:0 at the head of nexthop network address in MP\_REACH\_NLRI path attribute * bgp: add parameter for site\_of\_origins to neighbor\_add and vrf\_add method * bmpstation: add copyright * app: add simple bmp station application * bgp: add bmp client function * bmp: add unit test * packet lib: add bmp(BGP Monitoring Protocol) * packet lib: sctp: fix default arguments * packet lib: udp: fix default arguments * packet lib: tcp: fix default arguments * packet lib: ipv6: fix default arguments * packet lib: ipv4: fix default arguments * bgp: fix bugs related to filter * bgp: fix AttributeError bug * bgp: fix NameError bug * ofproto\_v1\_4\_parser: Remove a stale comment on OFPTableFeaturesStatsReply * ofproto\_v1\_3\_parser: Remove a stale comment on OFPTableFeaturesStatsReply * bgp: make 'core.reset\_neighbor' API asynchronously * bgp: add show neighbor command to ssh client * bgp: refine and fix filter code * bgp: manage filter in a peer instance instead of rtconf * bgp: create adjacent rib in peer instance * bgp: add in-filter function * bgp: enable filter configuration via configuration file * bgp: move filter class under info\_base/ * ofctl\_v1\_2/3: fix unsuitable log * ofctl\_v1\_2/3: fix tcp\_dst/src match fields * unit test for ofctl\_v1\_2/3 * bgp: add neighbor\_reset method to bgpspeaker * bgp: remove an unused variable from bgpspeaker * bgpspeaker: refine logs * bgp: make marker private variable * bgp: fix bug when restart neighbor * bgp: add neighbor\_update * bgp: add med parameter to neighbor\_add * bgp: shut up runtime warning due to configuration file loading * bgp: fix bug in net\_ctrl listen\_tcp * bgp: fix logic for checking BGP capability * bgp: fix the way of getting RouteFamily object * bgp: add out-filter function * ofctl\_rest: enable getting Description of a port * ofctl\_rest: support Port Modification Message * ws\_topology: fix typo * Correct tcp option values in the test set * ofctl\_v1\_2/3: fix POP\_MPLS action and some match fields * adding FloatOpt to the config parser * add --pid-file option to cli * bgp: support specifying nexthop per prefix * pip-requires: gui\_topology requires webob>=1.2 * bgp: fix send\_notificaiton crash * Ryu 3.11 * ospf: describe prefix in one attribute 'prefix' for ease of use * ospf: add segment routing opaque types * ospf: fix bug in encoding * ospf: support for opaque message * bgp: support md5 authentication for re-active sessions * bgp: support md5 authentication for pro-active sessions * bgp: fix withdraw in EventPrefix notification * sw test too: use assured Forwarding behavior DSCP value for dscp\_remark * bgp: support specifying next hop for neighbor * bgp: add IPv6 advertisement support * packet/bgp: fix BGPPathAttributeMpReachNLRI next\_hop parser and serializer * bgp: clean up getpeername() and getsockname() usage * Initializing the variable 's' so that the get\_desc\_stats() call does not cause an exceptions when there are no messages * Add a small library to deal with TCP-MD5 socket option * doc: improve the appearance of the table * doc: leave out too large samples * bgp: add ssh\_console option for bgpspeaker module * document: ryu.app.gui\_topology * sw test tool: Add default test files (of14: new features) * sw test tool: Add default test files (of14: group:all/select) * sw test tool: Add default test files (of14: meter) * sw test tool: Add default test files (of14: match) * sw test tool: Add default test files (of14: action with set-field only) * sw test tool: Add default test files (of14: action without set-field) * sw test tool: run\_mininet: support Open vSwitch with OpenFlow 1.4 * sw test tool: Modify OFPActionSetField to normalize * sw test tool: Modify OFPMatch to normalize * sw test tool: Enable using connected switches to compare * sw test tool: Enable using user-specified versions to parse * sw test tool: Add support for using user-specified versions * ryu/flags: Add config parameters related sw test tool * sw test tool: Modify conditions of ofp\_packet\_in\_reason * bgp: fix ipv6 peering regression * bgp: fix best\_path\_change\_handler for best\_path\_lost * bgp: fix example code * bgp: fix another crash (recv\_open -> recv\_open\_msg) * bgp: fix some leftover of transition to packet lib bgp * bgp: fix a crash in path comparison * library\_bgp\_speaker.rst: make an example more complete * ofa\_neutron\_agent: Change the copyright notice * ofa\_neutron\_agent: Remove unused logger instance * ofa\_neutron\_agent: Use AppManager.run\_apps * AppManager: Add a convenient method to run apps * ofa\_neutron\_agent: Simplify * app\_manager: prevent loading unnecessary RyuApps * package: add python-ryu-doc * sw test tool: Enable IPv6 flow label maskable * document ryu.app.ofctl * ws\_topology: shut up pep8 for long lines in a comment * bgp: support IPv6 peering * Add GUI app * ws\_topology: Handle WebSocket disconnection * ws\_topology: Avoid controller name confliction * add debian files to make packages for Ubuntu * app\_manager: Stop checking h.callers in get\_handlers() * bgp: catch socket error with sendall * bgp: use sendall with lock * bgp: use TCP\_NODELAY for bgp connection * ryu.lib.hub: add logging wrapper for wsgi server * contrib: import tinyrpc library * downgrade required version of msgpack-python * app\_manager: Let application module to use require\_app() * bgp: add bgpspaker module for non Ryu application usage * fix failure of instantiating app * fix: wrong copyright * sw test tool: Improve readability of IP mask values * sw test tool: Improve readability of MAC mask values * sw test tool: Improve readability of padding data * sw test tool: Improve readability of tcp options * rest\_qos: Enable queue setting to interface individually * packet lib: add Connectivity Fault Management Protocol(CFM, IEEE 802.1ag) * app\_manager: Fix a crash in unregister\_handler * Ryu 3.10 * doc: add test-of-config-with-linc page * doc: add test-vrrp page * ofctl\_v1\_2: fix errors of get\_flow\_stats * ofctl\_v1\_2: fix pep8 * bgp: remove unnecessary OutgoingRoute attribute 'bgp4\_format' * bgp: fix typo * bgp: fix bug of exchanging paths between vrf and global\_table * packet/bgp: add route distinguisher classes and refine codes * bgp: keep and use nexthop value as a string internally * ofctl\_v1\_2/3: MAC arbitrary bitmask support * bgp: add 'neighbors.get' and 'show.rib' JSON RPC API * bgp: add JSON RPC API * bgp: set bgp-config-file default None * bgp: fix non configured peer exception * bgp: import lacking constants * doc: add components page * bgp: use host's ssh host key if not specified * sw test tool: Add default test files (group:all/select) * sw test tool: Enable sending packets using random values * sw test tool: Enable parsing OFPGroupMod messages in 'prerequisite' * sw test tool: Add support for confirmation of installed group entries * sw test tool: Add support for installation of group tables * sw test tool: Add support for initialization of group tables * sw test tool: Add a link between switches * wsgi: add ws\_topology application * rest\_topology: use decorator api * sw test tool: pylint * sw test tool: Reduce similar methods of checking entries exist * sw test tool: Reduce similar methods of handling events * sw test tool: Reduce similar methods of initializing flows * sw test tool: Reduce similar methods of deleting flows * sw test tool: Reduce similar classes * sw test tool: Remove an unnecessary wrapper method * simple\_switch\_websocket\_13: Add get\_arp\_table RPC method * pip-requires: WebSocket-RPC requires tinyrpc * Add WebSocket JSON RPC feature * simple\_switch\_websocket\_13: fix typo * New API for WebSocket support * Add PacketIn dumper websocket application * wsgi: Support WebSocket * Import eventlet.websocket from master branch * hub: import semaphore * tester: cleanup the code of couting the results * tester: let each attribute of meter had a chance to be compared * add openflow api reference for of1.4 * app/rest\_qos: fix pep8 * add pep8 options to tox.ini * tests/unit: fix pep8 * tests: fix pep8 * services/protocols: fix pep8 * lib/xflow: fix pep8 * lib/packet: fix pep8 * lib/of\_config: fix pep8 * lib: fix pep8 * controller: fix pep8 * app: fix pep8 * topology/switches: fix pep8 * base/app\_manager: fix pep8 * ofproto: fix pep8 * Added rest\_qos module * packet/bgp: bug fix of route target nlri class * bgp: fix bug of accessing dead socket * bgp: improve how to show rib * bgp: fix typo * packet/bgp: enhanced route refresh support * packet/bgp: fix bug in serializing AS PATH path attribute * bgp: add ssh client * bgp: fix wrong module path * packet/bgp: add helper methods to nlri class for bgp ssh client * bgp: don't block at start method * bgp: bug fix when the peer initiated the connection * bgp: remove unnecessary log message * set default attributes for OFPPortMod * sw test tool: pylint * sw test tool: Remove unused codes * sw test tool: Reduce similar methods * Added queue stats request * Added ovs-vsctl commands of QoS-related * Ryu 3.9 * sw test tool: Modify lengths of pad fields for ARP * sw test tool: Revert changes of test files * tests/integrated: Enable MPLS set-field and push MPLS tests * tests/integrated: Match on MPLS dl\_type for flows with MPLS TTL actions * tests/integrated: Match on MPLS dl\_type for flows with pop MPLS actions * tests/integrated: Match on IP dl\_type for flows with set IPv6 addresses * tests/integrated: Enable ARP tests * tests/integrated: Match on IP dl\_type for flows with set NW TTL actions * tests/integrated: Match on VLAN tag for flows which set VLAN tags * tests/integrated: Match on VLAN tag for flows with pop VLAN TTL actions * tests/integrated: Match on IP dl\_type for flows with dec NW TTL actions * tests/integrated: Do not verify buffer\_id of packet\_in resulting from packet\_out * sw test tool: Modify lengths of pad fields for ARP * packet lib: ipv6: support Routing header (type3) * sw test tool: Fix MAC addresses used in tests * tests/integrated: Use table\_id greater than the current table for goto-table instruction * tests/integrated: Specify table\_id for flow\_mod modify tests * bgp: fix connect timeout error * bgp: add \_\_init\_\_.py files * packet lib: ipv6: Fix to calculate AH length * bgp: fix pep8 * bgp: add sample configuration file * bgp: improve log visibility * bgp: avoid the trouble of having to explicitly specify IDs in configuration * bgp: enable to use system IP addr implicitly for binding * bgp: enable default label range * bgp: make bgpspeaker RyuApp * bgp: use ryu.lib.hub instead of the direct use of eventlet * bgp: clean up codes which constructs an update message * bgp: fix typo * remove obsolete man pages (rpc\_cli and neutron\_ofagent\_agent) * delete bin/neutron-ofagent-agent * delete ryu/tests/bin/of-config-cli * delete bin/rpc-cli * document ryu command * add bin/ryu to PYLINT\_INCLUDE * add bin/ryu * pip-requires: require oslo.config >= 1.2.0 * allow overriding argv and progname * ryu.cfg: re-export some more stuff for convenience * sw test tool: Fix to compare OFPMatch using masks without byte boundary * bgp: remove original bgp packet library * bgp: use ryu bgp packet library instead of original one * bgp: add stuff for integration with bgp speaker * Rename to CONTRIBUTING.rst * of14: set default attributes for group-related classes * of13: set default attributes for group-related classes * of12: set default attributes for group-related classes * sw test tool: Correct the comparison method to treat matches as the set * sw test tool: Fix to compare OFPMatch ignoring fields that masks are all zero bits * sw test tool: Fix to compare OFPMatch ignoring masks that are all one bits * fix pbb itag related tests * RyuApp: delete a key without handlers when unregistering a handler * ryu.app.ofctl: raise exceptions on openflow error messages * ryu.app.ofctl: implement multipart * ryu.app.ofctl: implement reception of reply message * ofp\_event: add a function to find Event class for given OFP class * RyuApp: add methods to observe/unobserve specific event dynamically * RyuApp: allow observing events without having handlers * RyuApp.get\_handlers: restructure code and add a comment * RyuApp: add a method to unregister a handler * controller.handler: simplify code * controller.handler: use normal classes rather than a namedtuple * controller.handler: g/c now unused code * igmplib: Fix a problem that querier stops sending a query message * Ryu 3.8 * bgp: fix pep8 * bgp: enable to propagate ipv4 networks * bgp: improved debug message in neighbor creation * bgp: changed default configuration value for ease of use with bgp4 * bgp: use hub.Event to wait for the core\_service boot instead of sleep * bgp: enable to show ipv4 rib * bgp: send BGP UPDATE msg in BGP4 format when nlri is ipv4 * bgp: handle non-MPBGP UPDATE msg * bgp: remove inappropriate assertion assuming only MPBGP (not BGP4) * bgp: fix wrong path * add BGP daemon feature * ofctl\_v1\_3: Fix to enable using meter flags multiply * stplib: reduce unnecessary constant * sw test tool: Add default test files (meter) * sw test tool: Add support for throughput analysis * sw test tool: Enable throughput analysis * sw test tool: Add support for getting throughput * sw test tool: Add support for installation of flows for throughput analysis * sw test tool: Add support for deletion of flows for throughput analysis * sw test tool: Enable parsing a new 'egress' format * sw test tool: Enable sending packets continuously * sw test tool: Rename STATE\_UNMATCH\_PKT\_SEND to STATE\_SEND\_BARRIER * sw test tool: Refactor packet sending processes * sw test tool: Add support for sending packets continuously * sw test tool: Enable parsing a new 'ingress' format * sw test tool: Enable parsing OFPMeterMod messages in 'prerequisite' * sw test tool: Add support for confirmation of installed meter entries * sw test tool: Add support for installation of meter entries * sw test tool: Add support for initialization of meter tables * sw test tool: Rename STATE\_INIT to STATE\_INIT\_FLOW * remove ryu.cmd.ofa\_neutron\_agent from console\_scripts in setup.cfg * of: set TCP\_NODELAY for secure channel socket * vrrp tests: update comments * vrrp.api: request ryu.services.protocols.vrrp.manager * ryu.topology.api: request ryu.topology.switches * test\_vrrp\_multi.sh: allow overriding ovs-vsctl * vrrp: update after ryu.topology.api change * rest\_topology: update after ryu.topology.api change * topology: split out exported API from the implementation * ofa\_neutron\_agent: no need to load ofctl.service explicitly anymore * ryu.app.ofctl.api: request ryu.app.ofctl.service * app\_manager: add a function to request to load the server application * doc: remove a stale reference * add ryu-manager to PYLINT\_INCLUDE * ofctl\_rest: use multistage @set\_ev\_cls * enable multistage @set\_ev\_cls or @set\_ev\_handler * ofproto: get rid of fragile and slow glob'ing modules * topology/switches: duplicate datapath connections handling * Add request forward message unit test * Add request forward message support * of14: Add bundle add message unit test * of14: Add bundle add message support * Allow messages inside messages * ofctl\_v1\_2:support whole of match fields * rest\_router: fix OFPSetAsync bit mask * ofp\_event: fix a typo * ofctl\_v1\_2/3: IP arbitrary bitmask support * sw test tool: Fix a problem for disconnection * of14: Add bundle control message unit test * of14: Add bundle control message support * of14: Remove incorrect OFP\_ASYNC\_CONFIG\_{PACK\_STR, SIZE} * of14: Update get async reply and set async implementation to follow spec * of14: Add OFPAsyncConfigProp * of14: Add table status unit test * of14: Add table status support * of14: Add flow monitor reply message unit test * of14: Add flow monitor request unit test * packet\_data\_generator: New ofproto dependency for v5 updates * of14: Add flow monitor reply support * of14: Add flow monitor request support * of14: Add OFPFlowUpdate * dpset: absorb \*args, \*\*kwargs passed to \_\_init\_\_ * ofctl\_v1\_2/3: Convert IP fields to string with dotted decimal mask * sw test tool: avoid test termination in initialization * ofctl\_v1\_2: Fix unsuitable log * ofctl\_v1\_3: Fix unsuitable log * library\_packet.rst: fix an example code * pyang plugin to generate of\_config.generated\_classes * fix NX\_EXPERIMENTER\_ID * reduce direct uses of oslo.config.cfg.CONF * ryu.cfg: re-export some frequently used stuff for convenience * add ryu.cfg * ryu.conf: obsoleted argument used in sample configuration * ofctl\_v1\_2/3: IPv4 dotted decimal subnet mask support * Ryu 3.7 * test\_parser: update expected json representation * OFPPropCommonExperimenter4ByteData: change payload to bytes * Apply normalize\_json.py * of14: Correct documentation of table mod flags and properties * of13: Correct documentation of meter mod flags * of13: Correct documentation of flow mod flags * of13: Correct documentation of set config flags * of13: Correct documentation and example of get config reply flags * of14: Correct documentation of flow mod flags * of14: Correct documentation of meter mod flags * of14: Correct documentation of set config flags * of14: Correct documentation and example of get config reply flags * of14: set default attributes for meter-related classes * of13: set default attributes for meter-related classes * fix load\_apps() in AppManager class * six.add\_metaclass requires six>=1.4.0 * of14: Add experimenter property to port mod reply unit test * of14: Add port mod experimenter property * of14: Add optical property to port mod reply unit test * of14: Add port mod optical property * of14: Remove \_PACK\_STR from port mod ethernet property * of14: Add experimenter property to port stats reply unit test * of14: Add port stats experimenter property * of14: Add optical property to port stats reply unit test * of14: Add experimenter property to port status unit test * ofctl\_v1\_3:support whole of match fields * of14: Add port stats optical property * of14: Add experimenter property to queue stats reply unit test * of14: Add queue stats experimenter property * of14: Rename QueueProp as QueueStatsProp * of14: Add experimenter property to table features request unit test * of14: Add experimenter property to table features reply unit test * of14: Add table feature experimenter property * of14: Add table feature table sync from property * of14: Add experimenter property to port desc reply unit test * of14: Add port desc experimenter property * of14: Add optical property to port desc reply unit test * of14: Add optical property to port status unit test * of14: Add port desc optical property * of14: Add action experimenter to flow mod unit test * of14: Add action experimenter support * of13: Add experimenter property to table features reply unit test * of13: Add experimenter property to table features request unit test * of13: Add table feature experimenter property * ofproto\_v1\_3\_parser: update OFPActionSetField docstring * ofproto\_v1\_2\_parser: update OFPActionSetField docstring * ofproto\_v1\_4\_parser: update OFPActionSetField docstring * of14: Remove supruious comment from OFPPropBase * of14: Add role status unit test * packet\_data\_generator: of14: Add role status message * of14: Add role status support * of14: Add OFPRoleProp * of14: Add OFPPropCommonExperimenter4ByteData * of14: Add queue desc reply unit test * packet\_data\_generator: of14: Add queue desc reply * of14: Add queue desc request support * of14: Add queue desc request unit test * packet\_data\_generator: of14: Add queue desc request * of14: Add queue desc request support * of14: Add OFPQueueDesc * of14: Add OFPQueueDescProp * of14: table mod with properties * of14: Add properties support to flow mod * of14: Add OFPTableModProp serialization * of14: Add table desc unit tests * packet\_data\_generator: of14: Add table desc * of14: Add table desc request and reply message support * of14: Add OFPTableDesc * of14: Add OFPTableModProp * sw test tool: fix missing to receive error of PacketOut * of13: support OFPAactionExperimenter with data * sw test tool: fix pop\_pbb action * of14: Document OFPRR\_{METER\_DELETE, EVICTION} reasons for flow removed message * sw test tool: add test report output * ofproto: correct typo * test\_add\_flow\_v12\_actions: fix a typo * rename neutron agent from "ofswitch" to "ofagent" * of13/14: fix OFPFMFC\_TABLE\_FULL typo * ofconfig: add commit and discard\_changes operation support * of\_config: add OFPortStateType class * topology: support OF1.2 and 1.4 * handler.register\_service: comment * use six.add\_metaclass * pip-requires: sort in alphabetical order * of14: set default attributes for OFPMeterMod * of13: set default attributes for OFPMeterMod * neutron-ofswitch-agent man page * setup.cfg: add neutron-ofswitch-agent to console\_scrpits * run\_tests.sh: add neutron-ofswitch-agent to PYLINT\_INCLUDE * neutron-ofswitch-agent: neutron agent for ofswitch ML2 mechanism driver * ofproto\_v1\_3\_parser: add a comment about extensions support * pbb: add a comment * of\_config\_cli: remove a unused import * run\_tests.sh: add of-config-cli to PYLINT\_INCLUDE * ofctl\_v1\_3: let action group can be converted to string * sw test tool: FIX: return the transaction id when flow entries were deleted * sw test tool: correct the comparison method to treat instructions as the set * sw test tool: correct error message * sw test tool: remove unnecessary debug code * of12: fix InstructionWriteMetadata json decoder * sw test tool: fix wrong match(ipv6\_exthdr) value of test file * sw test tool: fix wrong instruction(write metadata) value of test files * test\_ofctl\_v1\_3: replace a hack with ProtocolDesc * test\_parser\_v12: replace a hack with ProtocolDesc * test\_ofp\_pktinfilter: replace a hack with ProtocolDesc * ProtocolDesc: provide supported\_ofp\_version for ofp\_handler * ofproto\_protocol: fix UnboundLocalError * tests: add a test case for ofproto\_protocol * test\_ofp\_pktinfilter: simplify * OFPGroupMod: Fix OFPGC\_\* typo in examples * test\_parser: replace a hack with ProtocolDesc * controller: use ProtocolDesc * ofproto\_protocol: provide a class to describe an openflow version * ofproto\_v1\_3\_parser: import ofproto\_v1\_3 as 'ofproto' * ofproto\_v1\_2\_parser: import ofproto\_v1\_2 as 'ofproto' * ofproto\_v1\_0\_parser: import ofproto\_v1\_0 as 'ofproto' * of14: Add to ofproto unit tests * of14: Add port mod message support * of14: Add queue stats request and reply message support * of14: Add port stats request and reply message support * of14: Add generic OFPropBase class * of14: Rename OFPPortDescPropUnknown as OFPPortPropUnknown * of14: Add port status message support * of14: Add meter mod message support * of14: Add OFPMeterBandDscpRemark and OFPMeterBandExperimenter * of14: Move OFPMeterBand\* to above OFPMeterConfigStats * of14: Add table features stats request and reply message support * of14: Add \_ordered\_fields to .4 OFPMatch * of14: Fix OFPInstructionWriteMetadata JSON decode * of14: set default attributes for OFPMultipartRequest subclasses * of14: add some assertions * Ryu 3.6 * of13: set default attributes for OFPMultipartRequest subclasses * of12: set default attributes for OFPStatsRequest subclasses * allow application to specify its logger name * fix syslogd usage on OSX * vrrp: fix busy timer by the default parameter * of14: fix OFPMatch from\_jsondict method * of14: Fix OFPInstructionMeter json format * of14: default ethernet type for PUSH\_VLAN action * of14: set default ethernet types for MPLS actions * of14: remove of1.2/1.3 old SetField aciton API * doc: announce OF1.4 support in README * Add OF1.4 set async message support * Add OF1.4 get async request and reply support * Add OF1.4 meter features stats request and reply message support * Add OF1.4 meter stats request and reply message support * Add OF1.4 meter config stats request and reply message support * Add OF1.4 meter band drop * Add OF1.4 group mod message supoort * Add OF1.4 table mod message support * Add OF1.4 flow removed message support * Add OF1.4 group desc stats request and reply message support * Add OF1.4 OFPBucket * Add OF1.4 group features stats request and reply message support * Add OF1.4 table stats request and reply message support * Add OF1.4 aggregate stats request and reply message support * Add OF1.4 role request and reply message support * Add OF1.4 barrier request and reply message support * Add OF1.4 experimenter message support * Add OF1.4 error message support * Add OF1.4 echo request and reply message support * Add OF1.4 SetNwTtl action support * Add OF1.4 DecNwTtl action support * Add OF1.4 DecMplsTtl action support * Add OF1.4 PushVlan action support * Add OF1.4 PopVlan action support * Add OF1.4 PushMpls action support * Add OF1.4 PopMpls action support * Add OF1.4 PushPbb action support * Add OF1.4 PopPbb action support * Add OF1.4 CopyTtlIn action support * Add OF1.4 CopyTtlOut action support * Add OF1.4 SetField action support * Add OF1.4 OFPMatchField support * Add OF1.4 desc stats request and reply message support * Add OF1.4 group stats request and reply message support * Add OF1.4 multipart experimenter request and reply message support * packet\_data\_generator: Remove OF1.4 queue set config request and reply message support * Correct OF1.4 OFPMatch JSON serialisation and formatting * Correct OF1.4 OFP\_ACTION\_HEADER\_PACK\_STR * of12: set default ethernet types for MPLS actions * of13: set default ethernet types for MPLS actions * ofproto\_v1\_3\_parser: have a default value for push\_vlan ethertype * ofproto\_v1\_2\_parser: have a default value for push\_vlan ethertype * ofproto\_v1\_3\_parser: put some assertions * ofproto\_v1\_2\_parser: put some assertions * Make type and len class attributes of OFPInstructionMeter * doc: improve RyuApp documentation * doc: update after the sync request change * vrrp: Add RPC API * ofctl.service: fix a crash on error msg * ofctl.service: reduce log level of some messages * ofctl.service: fix some crashes * Fix OFPInstructionWriteMetadata JSON decode * dpset: start up dpset if there are subscribers of dpset events * fix bidirectional event confusion * packet\_data\_generator: Add OF1.4 * ofctl\_v1\_2/3: fix SET\_FIELD action and some match fields * bgp: fix IP/MPLS\_VPN addresses * bgp: comments about notification data * bgp: a comment * bgp: RFC 4486 * bgp: constants for NOTIFICATION code/subcode * bgp: a comment * ryu.app.ofctl: Add a proxy application to send OF messages * test tool: run\_mininet: support CPqD Software Switch * bgp: implement the rest of RFC 3107 * bgp: implement BGPOptParamCapabilityCarryingLabelInfo * bgp: add a constant for enhanced route refresh * safi: add a constant for route target constrain * rest\_firewall: support IPv6 match conditions * ofctl\_v1\_2/3: fix match conditions about ARP * enable OpenFlow 1.4 * packet\_data\_generator: update of\_protocol upstream * test\_bpdu: add unit test * bpdu: handling based on version and type * ofctl\_rest: improve readability of the result of MeterFeatures * ofctl\_rest: support group-related messages * lib.of\_config: import ryu.contrib * tests: add some tests for ryu.lib.of\_config.classes * A happy new year 2014 * Ryu 3.5 * firewall: correct acquisition result of DENY rule * ofctl\_rest: fix mod\_meter\_entry in OpenFlow1.0/1.2 * ofctl\_rest: support OFPExperimenter message * ofctl\_rest: fix delete\_flow\_entry * topology: Setting highest rule priority to LLDP packets * Fix Windows setup dependency bug * add IGMP snooping application * packet lib: icmpv6: support MLD (v1/v2) * packet lib: igmp: support IGMP v3 * firewall: packet blocking log for DENY rule * ofctl\_v1\_2/3: support IPv6 * ofctl\_v1\_2/3: support OXM field names * ofctl\_rest: support OpenFlow1.2 * of\_config\_cli: remove no longer necessary "\_pythonify" stuff * of\_config: allows both of of-config element names and python style names * of\_config\_cli: add add\_queue command * of\_config\_cli: add delete\_config and copy\_config * a simple of-config client command * of\_config.capable\_switch: add delete\_config and copy\_config * tests.integrated.test\_of\_config: update after capable\_switch api change * of\_config.capable\_switch: api tweak * add some convenient OF-Config classes * requires lxml * oxm\_fields: make a crash less cryptic * ofctl\_v1\_3: support OFPMeterConfigStats * ofctl\_v1\_3: fix match for metadata * ofctl\_v1\_3: correct MeterStats and MeterFeatures * topology: add of13 support * ofctl\_v1\_3: support meter * ofctl\_v1\_3: support metadata * packet.ospf: workaround a bytearray vs buffer problem * rest\_firewall: use the explicit max\_len of flow\_mod * lib: ofctl: support the specified max\_len of flow\_mod * packet lib: improve readability of json * add license to ospf files * test tool: add a script to make the test environment on mininet * test tool: add default test files (match) * test tool: add default test files (action with set-field only) * test tool: add default test files (action without set-field) * test tool: add OpenFlowSwitch test tool * unit test for lib.packet.ospf * packet lib: add ospf * lib/packet/packet\_utils: Add a function to calculate fletcher checksum * packet lib: ipv6: correct a default parameter of opt\_header * packet lib: add unittests for reversibility about json * packet lib: slow: fix reversibility about json * packet lib: sctp: fix reversibility about json * packet lib: lldp: fix reversibility about json * packet lib: llc: fix reversibility about json * packet lib: ipv6: fix reversibility about json * packet lib: icmpv6: fix reversibility about json * packet lib: icmp: fix reversibility about json * packet lib: dhcp: fix reversibility about json * packet lib: bpdu: fix reversibility about json * packet lib: bgp: fix reversibility about json * packet lib: packet\_base: add a method which makes '\_class\_prefixes' easy to use * stplib: support OF 1.2/1.3 * stplib: Reduction of the number of threads * add OpenFlow 1.4 definitions * packet lib: igmp: support default parameters * Ryu 3.4 * vrrp: handle interface failure * rpc-cli man page * a simple command line msgpack-rpc client * add rpc.Client.peek\_notification * msgpack-rpc: unit tests * rpc: prefix closed\_by\_peer with \_ as it's private * rpc: If the socket is closed by peer, endpoint stop the serve * msgpack-rpc fixes and improvements * msgpack rpc helper * test\_parser: expected json for onf\_flow\_monitor\_request * packet\_data: regen for onf\_flow\_monitor\_request * packet\_data\_generator: add a case for onf\_flow\_monitor\_request * packet\_data\_generator: update of\_protocol for onf\_flow\_monitor\_request * of13: implement ONFFlowMonitorStatsRequest * ofproto\_parser.StringifyMixin: add "ONF" to the list of class prefixes * of13: EXT-187 definitions * of13 OFPExperimenterStatsRequest: api tweak * of13: add a bunch of ONFERR\_ constants from OF Extensions for 1.3.X * of13 OFPTableFeaturesStatsRequest: remove an unused argument * unit test: test ryu.cmd.manager * vrrp: declare event.py to be dependent for manager.py * vrrp: add statistics support * Add support for admin\_state (role) * fix vrrp utils * register monitor\_linux and monitor\_openflow for VRRPInterfaceMonitor class * vrrp: use sysfs instead of ioctl to get ifindex * rest\_firewall: support OF 1.3 * ofctl\_v1\_3: support some actions * ofctl\_v1\_3: correct the output result of get\_flow\_stats() * rest\_router: support OF 1.3 * ofp: use RyuApp start() to return Greenlet thread * allow RyuApp start() method returns Greenlet thread * Revert "doc: update tls example" * run OFP if no application is specified * fix the regression due to e45f382e51c9a3d57a6d8c01cec9e70f7ca364fd * a script to set up an environment for test\_vrrp\_multi.py * a script to set up an environment for test\_vrrp\_linux\_multi.py * test apps for VRRP service * vrrp service * packet.vrrp: some convenient routines * base/app\_manager: context might be RyuApp * base/app\_manager: create/destroy RyuApp instances dynamically * base/app\_manager: introduce singleton pattern to AppManager * base/app\_manager: RyuApp initialization race at startup * topology.switches: stop abusing Packet.next() * test\_lldp: stop abusing Packet.next() * Packet: fix iterator * skip malformed OF messages and continue instead of stopping * of13: fix wrong comments * test\_parser: update expected json representations for EXT-256 * packet\_data: regen * packet\_data\_generator: add a case for EXT-256 (PBB UCA match field) * packet\_data\_generator: update of\_protocol upstream * of13: implement EXT-256 (PBB UCA match field) * lacplib: reduce unnecessary constant * of13: OFPTableFeaturesStatsRequest: update docstring * of13: OFPOxmId: update comment * ryu.app.client: comments * ryu.app.tunnel\_port\_updater: comments * ryu.app.gre\_tunnel: comments * ryu.app.rest\_quantum: comments * ryu.app.rest\_conf\_switch: comments * ryu.app.rest: comments * doc: update tls example * of12: implment OFPT\_EXPERIMENTER serializer * of13: implment OFPT\_EXPERIMENTER serializer * test\_parser: enable serializer tests for OFPT\_EXPERIMENTER * solve application dependency via @set\_ev\_cls * dpset: fix a reconnect race * doc: hook up dpset * dpset: add some docstrings * dpset: remove dead code * dpset: prefix private methods with \_ * ofproto: fixed comments of ofp\_capabilities * test\_parser: expected json representations for OFPMP\_EXPERIMENTER * packet\_data: regen * packet\_data\_generator: add cases for experimenter mp request/reply * of13: implement OFPMP\_EXPERIMENTER request and reply * packet lib: ipv6: change some default parameters * packet lib: ethernet: support default parameters * bgp: add tests for extended communities * bgp: implement extended communities * test\_parser: test OFPET\_EXPERIMENTER serializer as we now have it * test\_parser: expected json representation * packet\_data: regen * packet\_data\_generator: uncomment ofp\_error\_msg\_experimenter * of13: OFPErrorExperimenterMsg: implement serializer * of12: OFPErrorExperimenterMsg: implement serializer * of13: implement OFPErrorExperimenterMsg * of12: reduce unnecessary diffs from of13 * ofproto\_common: define some experimenter id * add STP application * packet lib: add unittests that use default parameters of IPv4/IPv6 and ICMP/ICMPv6 * packet lib: icmp: support default parameters * packet lib: icmp: support len(icmp.\*) * packet lib: icmpv6: support default parameters and the auto calculation of lengths * packet lib: icmpv6: support len(icmpv6.\*) * packet lib: icmpv6: omit type of nd\_option object * packet lib: icmpv6: include type and length in nd\_option object * packet lib: icmpv6: move ND\_OPTION\_\* constants from classes to the module * packet lib: icmpv6: change the timing of bit shift * packet lib: icmpv6: correct typos * ofctl\_rest.py: Fix compatibily for both OF 1.0 & 1.3 datapaths * ofctl\_v1\_3.py: Add get\_desc\_stats & get\_port\_stats from ofctl\_v1\_0.py * lacplib: set the max priority to LACP flow entries * packet lib: add unittests that use default parameters of IPv4/6 and TCP/UDP/SCTP * packet lib: ipv6: support default parameters and the auto calculation of payload\_length * packet lib: udp: support default parameters * packet lib: tcp: support default parameters and the auto calculation of offset * packet lib: sctp: correct len(sctp) * SubmittingPatches: mention tools/normalize\_json.py * test\_parser: expected json representations for new test cases * packet\_data: regen * packet\_data\_generator: add cases to use all oxm types * packet\_data\_generator: update of\_protocol * normalize \*.json files * Ryu 3.3 * Decoration Based PacketIn Filter * of13: correct variable name same as spec * ofproto\_parser: dump packets if error is encountered during parse * packet lib: support Provider Backbone Bridges (PBB, IEEE 802.1ah) * packet lib: vlan: support Q-in-Q (IEEE 802.1ad) * rest\_router: fix mac address conversion * packet lib: sctp: change the timing of the auto calculation * packet lib: sctp: remove the past 'TODO' comments * rest\_router: bug fix of match parameter * test\_parser: expected json output for ofp\_table\_features\_request/reply * packet\_data: regen * packet\_data\_generator: uncomment ofp\_table\_features\_request * packet\_data\_generator: update of\_protocol upstream * of13: implement table features request/reply * OFPMultipartRequest: remove a wrong assertion * oxm\_fields: allow None values * packet lib: sctp: support default parameters and the auto calculation of lengths * packet lib: sctp: aggregate the same method into the base class * packet lib: sctp: correct typos * packet lib: sctp: correct sphinx document format * correct typos * test\_parser: update expected json output * packet\_data: regen * packet\_data\_generator: use more actions * packet\_data\_generator: update upstream * tests: apply tools/normalize\_json.py * ofproto.test\_parser: fix an expected json output * packet\_data: regen * packet\_data\_generator: adapt to of\_protocol upstream api change * packet\_data\_generator: change of\_protocol upstream * packet lib: sctp: correct comments * of13: support PUSH\_PBB/POP\_PBB actions * of1.0, of1.2, of1.3: Modify the default of max\_len in OFPActionOutput * packet lib: sctp: support the auto calculation of lengths of parameters and causes * packet lib: sctp: fill up lack of decolators * packet lib: sctp: remove unnecessary \_\_init\_\_() * packet lib: sctp: reduce computation * To specify a logging configuration file * bgp: implement communities attribute * bgp: well known communities * bgp: implement multiprotocol capability * bgp: implement MP\_UNREACH\_NLRI * bgp: implement MP\_REACH\_NLRI * bgp: update a comment * packet lib: sctp: add tests for protocol stack * packet lib: sctp: fix problems about padding * lib.packet.sctp: fix misuses of abstractproperty * doc: hook up lib.packet.sctp * packet lib: sctp: add a unittest for SCTP * packet lib: add Stream Control Transmission Protocol * packet lib: icmpv6.nd\_router\_advert: skip unknown options correctly * packet lib: icmpv6: comment * packet lib: ipv6: correct parser() about flow\_label * simple\_switch\_13: using table-miss flow * of13: fix OFPGroupStats * ofproto tests: add expected json outputs * packet\_data: regen * packet\_data\_generator: add of1.3 group\_stats\_request/reply * of10: fix pep8 * of13: correct parser() in several OFPActions * of10: Register TCP\_DST and UDP\_DST headers in NXM * simple\_switch: use packet library * packet.bgp: parse/serialize FOUR OCTET AS NUMBER capability * packet.bgp: parse/serialize ROUTE REFRESH capability * packet.bgp: implement ROUTE REFRESH message * packet lib: some AFI/SAFI constants * packet.bgp: parse/serialize capability options * packet.bgp: some capability related constants * bgp test: appease pep8 * packet.bgp: appease pep8 * of13: fix InstructionMeter parser * Switch how to call the API of Routes for every version * To specify a context of a controller from WSGIApplication#register() * packet.bgp test: parse real packets taken from quagga * packet.bgp test: some on-wire packets snooped from running quagga * packet.bgp: implement RFC 4893 * packet.bgp: parse/serialize path attribute values * python-oslo-config is necessary for Ryu built by RPM * Ryu 3.2 * fix setup from a tarball again * avoid pbr's non multi-version aware script * revert "support setup.py install with git archive tarballs" commit * revert "stick with pbr 0.5.19" commit * Ryu 3.1 * packet lib: dhcp: remove unnecessary import * packet lib: dhcp: add unittest * packet lib: dhcp: use text addresses * packet lib: add get\_protocol API * of1.3: set default arguments for FlowStatsRequest * of1.2: set default arguments for FlowStatsRequest * topology.switches: fix link discovery * ofproto: remove a bogus comment * ofproto: remove unused definitions * ofproto: fix OF1.0 packet\_in parser * packet lib: icmp: rewrite unittest * tests/integrated: fix mac address format * Advanced WSGI API * doc: hook up streaming parser docs * implement BGP-4 streaming parser * streaming parser base class * doc: hook up lib.packet.bgp * unit test for lib.packet.bgp * packet lib: implement basic part of BGP-4 * test\_addrconv: add more test * packet lib: ipv6: avoid dangerous default value [] as argument * packet lib: ipv6: simplify the operations of \_\_init\_\_() * packet lib: ipv6: support udp * packet lib: ipv6: remove unnecessary import * packet lib: icmp: correct parser() of TimeExceeded * unit test for import\_module * import\_module: deal with cases mod.\_\_file\_\_ is not accessible * packet lib: ipv6: correct a comment * packet lib: ipv6: add test for multi extension headers * packet lib: ipv6: support IP Authentication header * packet lib: ipv6: support fragment header * packet lib: ipv6: support destination header * packet lib: ipv6: support Hop-by-Hop Options header * packet lib: ipv6: prepare to support Hop-by-Hop Options header and destination header * packet lib: ipv6: support options for Hop-by-Hop Options header and destination header * packet lib: ipv6: prepare to support extension headers * rest\_firewall: improve REST response * comment on OFP\_xxx\_PORT * vlan: remove unnecessary import * doc: ryu app api overview * document OFPTableFeaturesStatsRequest/OFPTableFeaturesStatsReply * doc: sprinkle of13 json examples * doc: sprinkle of12 json examples * document MsgBase * add some docstring on StringifyMixin and relevant code * lib: lacplib: correct comments * lib: lacplib: add underscore to a protected member * lib: lacplib: support OpenFlow1.2/1.3 * packet lib: Simpler API to assemble a packet * of12, of13: fix OFPActionSetField padding * test: update expected json outputs * packet\_data: regen * tweak packet\_data\_generator * rest\_firewall: remove of unused constant values * rest\_firewall: remove of an unnecessary comma of json response * rest\_firewall: remove of a redundant code * rest\_firewall: bug fix of handling an empty dict * ofproto: raise an exception for unsupported operation * test\_parser: test serializing a message multiple times * ofproto: remove some assertions * ryu-manager: copyright notice * of10: change OFPMatch to support ipv4 src and dst mask when wildcards are omitted in \_\_init\_\_ * Support old style class * simple\_switch: simplify * simple\_switch\_12: reduce difference from simple\_switch\_13 * test: update of12 expected \*.json outputs after utf-8 change * test: update of13 expected \*.json outputs after utf-8 change * test: regen \*.packet after utf-8 changes * packet\_data\_generator: use utf-8 in table name and port name * of13: update expected \*.json outputs for table name change * of13: assume OFPTableFeaturesStats.name UTF-8 * of12: update expected \*.json outputs for table name change * of12: assume OFPTableStats.name UTF-8 * of10: assume OFPTableStats.name UTF-8 * of13: update expected \*.json results for OFPPort.name change * of13: assume OFPPort.name UTF-8 * of12: update expected \*.json results for OFPPort.name change * of12: assume OFPPort.name UTF-8 * of10: update expected \*.json results for OFPPhyPort.name change * of10: assume OFPPhyPort.name UTF-8 * stringify: add 'utf-8' type * packet lib: update icmpv6 doc * use run\_tests.sh -N for Travis CI * Ryu 3.0 * rest\_firewall: blocked packet logging * ofctl v1.0/v1.2: add miss\_send\_len for packet in * restore bin/ryu-manager * packet lib: bpdu: add some constant values * rest\_firewall: bug fix of dict keyError * doc: update format of pages for ofproto * doc: fix warnings * doc: update reference page for ofproto * of12, of13: small update of the document * test\_parser: ensure that "len" "length" fields can be omitted * of13: update after OFPMeterBand changes * of13: make OFPMeterBand's "type" and "len" visible to users * of13: update \*.json after OFPHelloElemVersionBitmap changes * of13: make OFPHelloElemVersionBitmap's "type" and "length" to users * of13: update \*.json after OFPxxxStats.length changes * of13: make OFPxxxStats.length visible to users * of13: update \*.json after multipart request/reply's "type" changes * of13: make multipart request/reply's "type" visible to users * of13: update \*.json after OFPPacketOut.actions\_len changes * of13: make OFPPacketOut.actions\_len visible to users * of13: update \*.json after OFPMatch "type" and "length" changes * of13: make OFPMatch "type" and "length" visible to users * of13: update \*.json after OFPQueuePropHeader.property change * of13: make OFPQueuePropHeader.property visible to user * of13: update \*.json after "len" "type" changes * of13: some "len" "type" attributes visible to user * test\_parser\_v12: update after OFPxxxStats.length changes * of12: update \*.json after OFPxxxStats.length changes * of12: make OFPxxxStats.length visible to users * of12: update \*.json after OFPStatsReply.type changes * of12: make OFPStatsReply.type visible to users * test\_parser\_v12: update after OFPPacketOut.actions\_len changes * of12: update \*.json after OFPPacketOut.actions\_len changes * of12: make OFPPacketOut.actions\_len visible to users * test\_parser\_v12: update after OFPErrorExperimenterMsg.type changes * of12: update \*.json after OFPErrorExperimenterMsg.type changes * of12: make OFPErrorExperimenterMsg.type visible to users * of12: update \*.json after OFPMatch "type" and "length" changes * of12: make OFPMatch "type" and "length" visible to users * of12: update \*.json after OFPQueuePropHeader.property change * test\_parser\_v12: update after OFPQueuePropHeader.property change * of12: make OFPQueuePropHeader.property visible to user * test\_parser\_v12: update after "len" changes * of12: update \*.json after "len" "type" changes * of12: some "len" "type" attributes visible to user * packet lib: icmpv6: add nd\_router messages * add .tox/ to .gitignore * workaround a python bug * stick with pbr 0.5.19 * new way to use pbr * remove bin/ryu-manager from the list of files for pylint/pep8 * move ryu-manager to entrypoints * test\_parser: update expected json results * packet\_data: regen * packet\_data\_generator: follow the recent fixes in of\_protocol upstream * packet\_data\_generator: be specific about versions of dependencies * packet\_data\_generator: move of\_protocol upstream back to the origin * rest\_router: make pep8 comfortable * Revert "packet lib: igmp: add some constant values" * Add a configuration file for tox (http://testrun.org/tox/) * Fix POP\_MPLS of ofctl\_v1\_3.to\_actions() problem * packet lib: igmp: add some constant values * packet lib: bpdu: use text address * packet lib: igmp: add a constant value * packet lib: llc: correct a variable name * of12: add docstrings for openflow messages * of13: add docstrings for openflow messages * packet lib: igmp: add some constant values * add LACP application * rest\_router: convert haddr to bin for OFPActionSetDlSrc/Dst * rest\_router: avoid assertion when ip\_text is 0 * avoid importing a module twice * of13: set default args for FlowMod * of12: set default args for FlowMod * fix of match from\_jsondict mask bug * of13: update expected \*.json output for OFPTableFeaturesStats.name * of13: remove trailing NULs in OFPTableFeaturesStats.name * test\_parser\_v12: update after OFPTableStats.name change * of12: update expected \*.json output for OFPTableStats.name * of12: remove trailing NULs in OFPTableStats.name * of10: remove trailing NULs in OFPTableStats.name * of13: update expected \*.json output after OFPPort.name change * of13: remove trailing NULs in OFPPort.name * of12: update expected \*.json output after OFPPort.name change * of12: remove trailing NULs in OFPPort.name * of10: update expected \*.json output after OFPPhyPort.name change * of10: remove trailing NULs in OFPPhyPort.name * regen after "packet\_data\_generator: fix port names" commit * packet\_data\_generator: fix port names * of13: update expected \*.json after OFPDescStats changes * of13: make OFPDescStats more human readable * of12: update expected \*.json after OFPDescStats changes * of12: make OFPDescStats more human readable * of10: make OFPDescStats more human readable * rest\_router: update after ofproto hw\_addr changes * rest\_router: fix of10 case * a simple script to plot rest\_topology's output * topology.switches: fix bin vs text address problem * of13: update tests * of13: fix json representation of OFPPort.hw\_addr and OFPPortMod.hw\_addr * of12: update tests * of12: fix json representation of OFPPort.hw\_addr and OFPPortMod.hw\_addr * of10: update tests * of10: fix json representation of OFPPhyPort.hw\_addr and OFPPortMod.hw\_addr * stringify: allow user classes to annotate type of their attributes * of13: use text address for OFPPort.hw\_addr and OFPPortMod.hw\_addr * of12: use text address for OFPPort.hw\_addr and OFPPortMod.hw\_addr * of10: use text address for OFPPhyPort.hw\_addr and OFPPortMod.hw\_addr * MANIFEST.in: exclude packet\_data\_generator * add simple learning switch app for OF1.2 * add simple learning switch app for OF1.3 * of13: set ActionOutput default max\_len to zero * of12: set ActionOutput default max\_len to zero * fix the commit 833328a mess-up * lib/packet: update docstrings to fix broken tables in latex/pdf * doc: fix overflow from the page in latex/pdf * of1.2, of1.3: update document for OFPMatch * packet lib: fix ipv6 parser * ofctl lib: Actions is a list * of13: test\_parser: update expected \*.json results * of13: test\_parser: regen \*.packet * of13: packet\_data\_generator: use set\_field action * of13: change OFPActionSetField api, following the recent OFPMatch api * of12: test\_parser: update expected \*.json results * of12: test\_parser: regen \*.packet * of12: packet\_data\_generator: use set\_field action * of12: change OFPActionSetField api, following the recent OFPMatch api * of13: update \*.json after OFPMatch changes * of13: change OFPMatch json representation to match with on-wire * of13: make OFPMatch use oxm\_fields routines * of12: update \*.json after OFPMatch changes * of12: change OFPMatch json representation to match with on-wire * of12: make OFPMatch use oxm\_fields routines * oxm\_fields: add some routines * doc: add reference for ofproto api document * packet\_base: update docstring * doc: fix some sphinx warnings and errors * doc: fix a typo * ofproto\_v1\_3\_parser: add docstring to OFPMatch * normalize json files using tools/normalize\_json.py * a script to normalize json * lib/packet: add Internet Group Management Protocol * test\_parser: stop testing unsupported operations * test\_parser: have a list of operations expected to work * unit test: test OFPMatch.append\_field * unit test for OFPMatch old/new api compatibility * app/rest\_firewall: add API for VLAN configuration * ofproto: \_baseattribute can be class attribute * ofproto: make binary code loadable * packet lib: make vrrp get\_payload robust * packet lib to string: unit tests * packet lib to string: add \_\_str\_\_ to base * packet lib to string: inherits StringifyMixin * unit tests for the new OFPMatch api * of13: fix old parser and serializer of PBB\_ID * of12: stop assuming OFPXMC\_OPENFLOW\_BASIC * dpset: support OF1.3 * packet lib: provide bpdu.\_MIN\_LEN * packet lib: provide llc.\_MIN\_LEN * packet lib: implement lacp.\_\_len\_\_ * packet lib: implement ryu.lib.packet.lldp.lldp.\_\_len\_\_ * packet lib: provide a default impl of \_\_len\_\_ * support setup.py install with git archive tarballs * use d2to1 and pbr for packaging * tests: stop comparing text addresses * correct file permission * note about network address representation * packet lib: pydoc update/improvements after api change * packet lib api: update documentation * rest\_router: update after packet lib api changes * topology.switches: update after packet lib api changes * packet lib: change the api to use text addresses * Ryu 2.2 * sync README with the web site * add 2013 to copyright for documentations * test\_parser: update of13 expected results * of13 OFPMatch: remove now unused code * of13: more OFPMatch old api compat * of13: make OFPMatch.to\_jsondict work on instances composed with old api * of13 OFPMatchField: make this safe to serialize multiple times * of13: OFPMatch api compat * of13: OFPMatch from\_json/to\_json for new api * of13: add OFPMatch.get for convenience * of13: add OFPMatch.iteritems for convenience * of13: new OFPMatch field query api * of13: new match field parser * of13: new OFPMatch composer api * test\_parser: update of12 expected results * of12 OFPMatch: remove now unused code * of12: OFPMatch more old api compat * of12: make OFPMatch.to\_jsondict work on instances composed with old api * of12 OFPMatchField: make this safe to serialize multiple times * of12: OFPMatch api compat * of12: OFPMatch from\_json/to\_json for new api * of12: add OFPMatch.get for convenience * of12: add OFPMatch.iteritems for convenience * of12: new OFPMatch field query api * of12: new match field parser * of12: new OFPMatch composer api * oxm\_fields: accept [value, mask] as well as (value, mask) * oxm\_fields: generate OFPXMT\_OFB\_ and OXM\_OF\_ from a single source * add unit test for packet library llc * update library\_packet\_ref.rst * link to LLC sub layer * lib/packet/llc * lib/packet/bpdu * The trick for installing argparse is deleted * update packet generator code comment * test\_addrconv: fix a copy and paste mistake * Remove contrib/oslo directory * addrconv: remove embedded test code * add a test for ryu.lib.addrconv * regenerate packet\_data for meter\_mod * test\_parser: an expected result for meter\_mod * packet\_data\_generator: uncomment ofp\_meter\_mod * of13 OFPMeterMod: fix \_len vs len mismatch * of13 OFPMeterBandExperimenter: fix super * ryu/app/ofctl\_rest: add of1.3 support * add ofctl\_v1\_3 library * rest\_router: follow packet lib api change * addrconv: use bytes instead of int to represent ipv4 addresses * addrconv: replace bin<->text converters for ipv6 * addrconv: replace bin<->text converters for mac addresses * addrconv: binary <-> text conversion of mac/ipv4/ipv6 addresses * lib/packet: add Link Aggregation Control Protocol * of-wire json test: a program to generate test data for unit tests * dist: pypi tar ball misses tools directory * stringify.StringifyMixin.\_\_str\_\_: simplify * rest\_router: stop catching Exception * of-wire json test: unit test * of-wire json test: generated \*.packet * of-wire json test: expected results * of-wire json: adapt OF13 OFPMeterBand * of-wire json: adapt OF13 OFPTableFeaturesStatsReply * of-wire json: adapt OF13 OFPPortDescStatsReply * of13: fix OFPTableFeaturesStats.parser * of13: fix OFP\_TABLE\_FEATURES\_PACK\_STR * of1.3: fix OFPort parser * appease pep8 * add router Ryu application * app/quantum\_adapter: Lazily initialize neutron client * ofproto v1.3: implement MeterBand parsers * Send MeterMod messages * quantum\_adapter: race between ovs port deletion and plugin port deletion * simple\_vlan.py: race condition * gre\_tunnel.py: race condition * network: add a helper function to list ports that doesn't raise * gre\_tunnel: exception due to race condition * network.py: exception in Networks.remove\_port() * network: sort out order between event and actual deletion of network * network.py: sort out order between event and actual deletion of port * app/gre\_tunnel.py: typo has\_network -> has\_networks * app/quantum\_adapter: pylint * app/simple\_vlan: pylint * controller/network: pylint * add a test for ryu.lib.stringify * test\_parser\_v12: abuse this to test to\_jsondict and from\_jsondict * of1.3: omit mask attribute from str() when appropriate * of1.3: of-wire json adapt * of1.2: omit mask attribute from str() when appropriate * of1.2: of-wire json adapt * of1.0: of-wire json adapt * StringifyMixin: json support * ryu/flags: rename config paramerters related to openstack * app/quantum\_adapter: fix missing change to neutron * app/quantum\_adapter: project rename quantum -> neutron * app/client: update for quantum->neutron change * fix comment typos (ofprotp -> ofproto) * fix typos (mpls\_lable -> mpls\_label) * base/app\_manager: teach event dispatcher state * use ofproto.OFP\_NO\_BUFFER in some places * define OFP\_NO\_BUFFER * ryu/app/conf\_switch\_key: fix a comment * update the site url * man: remove man page of ryu client * packege: rpmlint warning * MANIFEST.in: fix up to address warning * openstack copyright notice * lib/packet: teach packet library to truncate padding octet * lib/packet: make packet\_base.parser abstract method * lib/packet: make protocol\_name property instead of attributes * Ryu 2.1 * rename ryu-client under ryu/tests * of1.3: fix OFPSetConfig default arguments * of1.2: OFPGroupFeaturesStats: tuple -> list * of1.3: fix OFP\_GROUP\_DESC\_STATS\_PACK\_STR * of1.3: fix OFPMeterStats * topology/switches: exception during serialization * topology/switches: packet in handler * packet lib: stop tlv parsing when finding LLDP\_TLV\_END * packet lib: add ICMP sub encoder/decoder class * ofctl\_v1\_2.actions\_to\_str: ignore unknown instructions * of13: prefix private attributes of OFPMatch with \_ * of12: prefix private attributes of OFPMatch with \_ * nx\_match: some comments * datapath\_connection\_factory deal with None datapath.id * of13: Added InstructionMeter * packet lib: avoid exception for bogus protocol header parsing * quantum\_adapter: check if quantum\_controller\_addr is valid * of13 OFPBucket: fix a fatal typo * of13 OFPGroupDescStats: fix super call * of13 OFPExperimenter: fix parser and remove completely broken serializer * of13 fix OFPQueueProp parsing * of13 fix multipart reply parsing * of13 fix OFPGroupFeaturesStats parser * of13: add missing itertools import * of12 OFPGroupFeaturesStats: add missing self.length * of12: fix OFPExperimenter parser * of1.3: Fix parsing of OFP\_QUEUE\_GET\_CONFIG\_REPLY * packet lib: packet class supports get\_protocol method * packet lib: add Packet.\_\_contains\_\_ * packet lib: packet class accepts protocols list argument * packet lib: arp default args * packet lib: vlan default args * packet lib: mpls default args * packet lib: ipv4 default args * packet lib: icmp support time exceeded type * of1.2: fix OFPSetConfig default arguments * fix travis config file * Add config file for Travis * packet lib: allow packet type to be specified when parsing packet * packet lib: For convenience, make packet into a sequence type * Ryu 2.0 * of1.3: various fixes * fix 77effb29 regression * packet lib: make test\_packet work stand-alone * Add Packet library API Reference * lib/packet: DHCP packet parser/serializer * ofproto/ofproto\_parser: pylint * of1.0: use tun\_id instead of tun\_id\_ * docs: fix ryu module import * tests/unit/packet/test\_vrrp: add tests for is\_valid() * lib/packet/vrrp: fix is\_valid() * test\_parser\_v10: remove tests for \_\_str\_\_ * of13: Fix for OFPQueueGetConfigReply/Request * run\_tests: make python interpreter overridable * app/gre\_tunnel: pylint * app/quantum\_adapter: unbreak quantum change * of10: sprinkle StringifyMixin * of: StringifyMixin * use dpid\_to\_str in some places * tests/ofproto: add unit test for ofproto automatic detection * ofproto: exception during startup related ofp module detaction * tests/ofproto: add unit test for ofproto automatic detection * ofproto: exception during startup related ofp module detaction * of13: add missing UINTxx\_MAX * controller/ofp\_event: don't hardcode supported OFP parser module * ofproto: detect supported OFP versions automatically * ofproto\_parser: simplify msg\_str\_attr() a bit * update requirements * Support bind IPv6 addresses in StreamServer * Revert "add eventlet to test requirement" * ofproto: change the way \_\_str\_\_ is implemented for of-wire messages * controller: stop catching GreenletExit * hub: add some more tests * hub: handle GreenletExit internally * hub: comment * of1.0: simplify NXAction initialization * of1.0: simplify OFPActionVendor * of1.0: NXActionHeader should be subclass of OFPActionVendor * of1.3: fix OFPPortStatus parser * of1.3: fix parser of OFPGetAsyncReply * of1.3: fix serializer of OFPSetAsync * of1.3: fix wrong method name in OFPQueueGetConfigRequest * of1.3: fix pack string of OFPMeterStatsRequest * of1.3: fix wrong class name in OFPGroupFeaturesStatsRequest.\_\_init\_\_() * of1.3: fix attribute name of OFPGroupDescStats * of1.3: fix lacking argument in OFPAggregateStatsRequest.\_\_init\_\_() * add eventlet to test requirement * lib/hub: Event.wait should return its internal flag * of1.0: match accepts partial parameters * limit the size of ryu app's event queue * controller: fix send queue draining again * sweep the tree to change from gevent to ryu.lib.hub * add a threading hub module * Ryu 1.9 * of1.0: add nx\_aggregate\_stats support * of1.0: OFPMatch support keyword-style parameters * ovs.poller: workaround a bug in eventlet * run\_tests.sh: support integrated tests * tests/integrated: auto testing script using Mininet and OVS * tests/integrated: Skip MPLS related test * Fix typo in comments in GRE tunnel class * ryu/app/simple\_vlan: fix typo * add a template for ryu.lib.packet class documentation * ryu.lib.packet: docstring tweaks for better rendering * nx\_match: support IPv4 mask * rest\_tunnel: fix comment typos * of1.3: parser should return msg, not implicit None * nx\_match: remove an unnecessary import * of1.3: remove port\_no argument * of1.3: fix typos in ofproto\_v1\_3.py * ryu/app/rest\_firewall.py: handling of no switch connection * ryu.lib.packet: docstring * ryu.lib.packet: docstring * of1.0: add nx\_match to NXFlowStatsRequest * lib: ip address presentation convert helper methods * g/c a stale reference to find\_protocol * packet lib: docstring * tests/unit, lib/packet/vrrp: unit test for vrrp packet parser/serializer * lib/packet: VRRP packet parser/serializer * lib/packet/ipv6: add constants for parse/serialize * lib/packet/ipv4: add constants for parse/serialize * ofproto/inet: add VRRP protocol number * lib/packet/arp.py: add convenience function to create arp for ip * ofproto/nx\_match: pep8 * doc: fix the mailing list address * of1.3: Add special group identifier values defined on OpenFlow 1.3.1 * lib/packet/lldp.py: pylint * ryu/lib/packet/lldp.py: remove \_\_str\_\_ method from class LLDPBasicTLV and class lldp * tests/integrated/test\_of\_config: comment on how to run * tests/integrated/test\_of\_config: disable known host check * setup.py: install xsd files * nx: match\_tuple() function now handles nw src/dst * nx: make pack string of IPv6 address consistent with OF1.2/1.3 * topology/dumper: define contexts to receive events * ryu/topology/switches: simplify Switches with RyuApp.reply\_to\_request * ryu/base/app\_manager: introduce RyuApp:replay\_to\_request() * base/app\_manager.py: sort out registering bricks * ryu/base/app\_manager: pylint unused variables * topology/dumper: use handler.set\_ev\_cls instead of set\_ev\_handler * remove openstack related document * ryu/lib/packet/packet.py: should use isinstance instead of \_\_class\_\_.\_\_base\_\_ * lib/packet/packet\_utils: optimize checksum * Ryu 1.8 * rest\_firewall: fix comments * topology/dumper: fix RyuApp.\_\_init\_\_ signature * doc: fix a program name * of1.0: fix import error * of1.0: utils.round\_up cleanup * lib/packet/tcp: use checksum\_ip() * lib/packet/udp: use checksum\_ip() * lib/packet/icmpv6: use checksum\_ip() * lib/packet: checksum function with pseudo ipv4/ipv6 header * lib/packet/packet\_utils: improve checksum byteswap * lib/packet/packet\_utils: improve checksum padding * tests/unit/packet/test\_tcp.py: typo UDP -> TCP * test\_icmpv6: correct icmpv6 checksum * ryu-client: print http response * ryu-client: support Topology REST API * topology: Add REST API * topology: exported function returns Switch/Link list instead of event * lib/port\_no: handling port\_no as string * support parse OFPAction in NXFlowStats * test\_parser\_v10: fix unittest breakage * lib/packet/packet\_base: fix signature of PacketBase.{parser, serialize} * of1.0: fix NXActionHeader typo * lib ofctl\_v1\_2: add VLAN\_ID setting means * ofproto\_v1\_0\_parser: add nx\_flow\_stats\_{request, reply} * ofproto\_v1\_0: add nx\_stats constants * nx\_match: add MFField parser * lib ofctl\_v1\_2: fix file modes * add ofctl\_v1\_2 library * update ofctl\_v1\_0 library * add firewall Ryu application * app\_manager: fix close dict handling bug * ryu-manager: use try-finally statement * nx\_match: add vlan and vlan\_pop * topology: support link discovery * topology: switch discovering module * event: Add sync flag and event src for request/reply * TLS: use a full spelling of a cli option * TLS: test cli options consistently in the same line * TLS: update an example output * ofconfig: use ElementTree iterator instead of getchildren * ryu.controller.controller.Datapath: keep handler list regardless of state * vsctl: fix timeout * tunnel\_port\_updater: g/c \_LOCK * packet lib: fix icmpv6.nd parser * doc: of\_config library * of\_config: sample test code to use ofconfig capable\_switch * of\_config: OF capable switch class to issue OFConfig request * of\_config: constants for of-config * of\_config/schema: add missing import * of\_config: import XML schema files for OF config * netconf: add constants for netconf * netconf: improve schema for netconf * netconf: import XML schema for netconf * netconf: import xml schema * MANIFEST.in: include XML schema files * ofp: send events to others before calling own handlers * wsgi: remove unused logging code * doc: fix bug in tls.rst * log-cleanup: honor --default-log-level in case of --verbose * log-cleanup: per RyuApp logger * log-cleanup: remove an unused logger instance * log-cleanup: remove an unused logger instance * ryu-manager: stop modifying CONF.app\_list * of1.3: fix error in group\_mod * Add request/reply event support to support communication between apps * ryu.log: change type of --use\_syslog option to Boolean * contrib ncclient: missing comma * contrib: import ncclient library (NETCONF clients) * of1.3: fix a comment typo * revert s/\_/-/ changes for ryu.conf * fix missing parameter in calling 'msg\_pack\_info' of OFPActionPushMpls/PopMpls * add missing 'field' parameter to \_\_init\_\_ function of OFPActionSetField * fix incorrect naming '\_\_serialize\_body' in OFPRoleRequest * fix OFPMatch decode error in 'parser' function of OFPFlowRemoved * add missing 'length' field of OFPPort when decoding * add missing 'match' parameter to \_\_init\_\_ function of OFPAggregateStatsRequest * fix error in OFP\_DESC\_PACK\_STR (change 'c' to 's') * remove port\_no argument of OFPPortDescStatsRequest.\_\_init\_\_ * fix OFPMultipartRequest.\_serialize\_stats\_body * test of1.2: fix typos from mid to min * g/c --monkey-patch option * test of1.2: add test code of OFPErrorExperimenterMsg * Ryu 1.7 * RyuApp: allows observers to specify state * lib/mac: fix raise ValueError * app\_manager: allow separated modules of Event and RyuApp * of1.2: fix OFPErrorExperimenterMsg * try to sync documentation with the reality * mechanical documentation update after option name changes * update an example after option name changes * change --foo\_bar options to --foo-bar * appease pep8 * test of1.2: add test code of max, min, and pattern. review of the test code * xflow: add sflow support * remove no longer used contrib/openstack * switch from openstack.common.cfg to oslo.config.cfg * import oslo-config * controller: fix that sender thread is never terminated * test: remove unnecessary variables * packet lib: fix icmpv6.nd\_s.parser() and support NDP option type * of1.3: fix error in port\_mod and get\_config\_reply logic * ryu/controller/dpset.py: duplicate import * of1.2: fix OFPGroupDescStats parser * doc: internal document on openstack cooperation * test: tuning integration test for OFPT\_FLOW\_REMOVED * of1.3: fix ACTION\_POP\_MPLS * stop requiring gflags * fix a typo in the help message of quantum\_controller\_addr * update a sample and documentation * adjust import order in ryu-manager and add a comment * use openstack.common.cfg instead of gflags * import cfg.py from oslo-incubator * controller: fix send\_q draining * of1.2: fix OFPQueueProp parser * fix breakage the commit 68f3259754fdbd7b5351c9739bf6f238c7ffb313 * controller/ofp\_handler: improve version negotiation * quantum\_adapter: exception when VM deletion * LICENCE: change end-of-line code CRLF to LF * tests: make run\_tests.py, test\_lib.py executable as it includes #! * doc: man pages for ryu-manager and ryu-client * doc: eliminate sphinx warnings * fix typos in comments * fix a fatal typo in network.py * fix a fatal typo in GRETunnel \_CONTEXTS * gre\_tunnel: adapt to the new world order after dispatcher removal * tunnel\_port\_updater: adapt to the new world order after dispatcher removal * controller/handler: allow set\_ev\_handler without dispatchers * app\_manager: add some assertions and LOG.info * app\_manager: print event flow for --verbose * app\_manager: print some info about event flows for --verbose * app\_manager: add an function to register an app instance explicitly * Add support live-migration * ryu/controller/controller: add a helper method, is\_reserved\_port() * ovs/bridge: more helper methods * ovs/vsctl: more commands * lib/ovs/db\_client: library for low-level ovsdb manipulation * app/client: add mac support * app/rest: add requirements to path component * app/rest: add API to register/update mac address for a given port * app/tunnel\_port\_updater: application that creates/deletes tunnel ports * ryu/controller/network.py: add helper functions for tunnel updater * app/gre\_tunnel: implement GRETunnel app * packet lib: rename icmp6 to icmpv6 * test: fix integration tests: reflects 978f3e5c * dpset: fix the new event mechnism breakage * dpset: improve debug message * packet lib: fix a bug in ipv6 * test: update integration tests * ryu/app/simple\_vlan: simple VLAN app for OVS * app: Add quantum adapter * bin/ryu-client: teach quantum iface rest api * ryu/app/client: teach quantum iface api * rest/quantum: quantum iface REST API * ryu/lib/quantum\_ifaces.py: track the relation of quantum iface-id * bin/ryu-client: support switch\_conf * bin/ryu-client: support gre tunnel client * ryu/app/client: support conf\_switch * ryu/app: REST API to set per-switch configuration * controller/switch\_conf: introduce a class to manage per-switch configuration * app/client: add tunnel client * app/rest\_tunnel: REST API for tunnel * controller/tunnel: introduce new class for tunneling * dpset: add port event support * controller/network: add event supports * controller/handler: allow set\_ev\_cls not to specify dispatchers * packet lib: add ipv6 ICMP support * packet lib: add ipv6 support * packet lib: add LLDP support * xflow: add netflow support * remove event dumper application * remove old dispatcher and friends * bin/ryu-manager: import ryu.flags for common options * app/client: add helper function to ignore NOT\_FOUND, 404 * ryu/app/client: factor out rest client code * app/rest\_nw\_id: add port type for reserved port and vport-gre * app/rest: add requirements to path component * replace dispatcher mechanism * lib/ovs/bridge: helper class to manipulate ovs bridge * lib/ovs/vsctl: python reimplementation of ovs-vsctl * lib/ovs: add constants for ovsdb Open\_vSwitch db * contrib: fix a comment typo * dpset: fix join race * packet lib: pep8 warning fix * test: remove some unnecessary bash dependencies * Ryu 1.6 * test: add mininet-test suite * test: Add "Decrement IP TTL" integration test * ofctl\_v1\_0: fix stats timeout handling * fix lack of comma in flagfile list * of1.3: Fix a typo in OFPPacketOut * setup: update installation infos * test: change the branch of openvswitch to 'of12' * ofp\_handler: receiving side of OFPHelloElem version negotiation * of1.3: improve OFPHello and OFPHelloElemVerionsBitmap * ofctl\_{rest, v1\_0}: update and clean up * ryu-manager: fix keyError * don't abuse \_\_dict\_\_ attribute * ofp\_handler: Improve hello version negotiation * of1.3: fix OFPMultipartReply parser * of1.3: support OFPHET\_VERSIONBITMAP * doc: setup TLS connection * of1.3: fix OFPT\_PACKET\_IN parser * Ryu 1.5 * set setup.py install\_requires properly * python/ovs/stream: Fix Stream.connect() retval for incomplete connection * Revert "contrib/ovs/stream.py: TypeError: bad operand type for unary -: 'NoneType'" * ryu/log: bugfix * ofctl\_v1\_0: update and clean up * enable OF1.3 support * of1.3: fix OFPMP\_FLOW * of1.3: support OFPMatch * Add workaround to switch\_features\_handler for OF1.3 * of1.3: fix OFPPacketQueue * of1.3: fix OFPSetAsyn * of1.3: fix OFPQueueProp * of1.3: fix OFPMeterFeaturesStatsRequest * of1.3: fix OFPMeterConfigStatsReply * of1.3: fix OFPPortStatsReply * of1.3: fix OFPMP\_AGGREGATE * of1.3: fix OFP\_DESC\_PACK\_STR * of1.3: fix OFP\_METER\_BAND\_DSCP\_REMARK\_PACK\_STR assert * of1.3: fix OFP\_TABLE\_MOD\_PACK\_STR assert * of1.3: fix OFP\_OXM\_EXPERIMENTER\_HEADER\_SIZE assert * contrib/ovs: TypeError: bad operand type for unary -: 'NoneType' * of1.2: fix some error constant typos * packet lib: add arp constants * add TLS support * of1.2: Fix MTVlanVid() parser and serializer * don't use select.POLL\* constants * ofctl\_v1\_0: update get\_flow\_stats() to dump actions * wsgi/routes: add regex pattern for each REST component * contrib/ovs/dirs: replace @variables@ which is replaced by configure * import ovs python binding library * prepare contrib directory which holds third party library * of1.2: Fix OFPActionExperimenter parser * packet lib: remove unnecessary ICMP debug message * Ryu 1.4 * ryu/app/ofctl\_rest: implements ofctl\_rest app * ryu/lib/ofctl\_v1\_0: introduce OF interface * test: add unittests for packet library * silence unhandled event message * test: add unittests for packet library * packet lib: fix udp header length * packet lib: fix ipv4 assertion of option field * tools/pip-requires: add routes which is used by wsgi.py module * packet lib: add unparsed data to Packet.protocols * doc: update packet library * packet lib: kill find\_protocol in Packet class * packet lib: set protocol\_name in each protocol * packet lib: make Packet class iterator * packet lib: fix icmp echo serialize * packet lib: add mpls * test: fix unittests for of parser * packet lib: add icmp.py * ofp\_handler: print msg.data in hex format, not raw string * utils: a helper function to convert byte array into hex string * of1.0: fix/add PortMod message * Removed leading '/' from data\_files * Ryu 1.3 * Fix zero padding * packet lib: fix vlan pcp bitshift * packet lib: ipv4 option data support * test: add more of1.2 integration tests * packet lib: tcp option support * doc: fix typo in openstack.rst * doc: rearrange top page * doc: use README as getting\_started * doc: rename getting\_started.rst -> parameters.rst * doc: rearrange openstack docs * doc: packet library * app/simple\_isolation: update handler registration * packet lib: fix ipv4 flags bitshift * simplify handler registration core * register OFP handlers via register\_instance * doc: integrate HACKING.rst into SubmittingPatches.rst * doc: rename SubmittingPatches to SubmittingPatches.rst * doc: convert SubmittingPatches into reST style * doc: update README.rst about migration from osrg.net * doc: set PYTHONPATH for ryu version constant * doc: write Ryu application * doc: use ryu version constant * doc: change Sphinx style to haiku * doc: fix the link in README.rst * Ryu 1.2 * remove OFPFlowRemoved and OFPPortStatus handlers in MAIN\_DISPATCHER * remove unnecessary OFPFlowRemoved and OFPBarrierReply handlers in CONFIG\_DISPATCHER * remove unnecessary OFPEchoReply handler in dispatchers * packet lib: fix ipv4 option field handling * packet lib: set \_MIN\_LEN class variable * packet lib: add tcp support * packet lib: convert ip to use the checksum helper function * packet lib: add udp data transmit and checksum support * packet lib: add packet\_utils.py * packet lib: add data serialize support to Packet class * packet lib: calculate the udp length * packet lib: calculate the ip total length * packet lib: serialize in reverse order * of1.2: fix OFPFlowRemoved parser * of1.2: fix ofp\_port\_stats pack format * test: fix pep8 1.3.3 warnings * fix pep8 1.3.3 warnings * test: use the latest version of pep8 * add packet library * controller: print backtrace when exception in addition to stacktrace * test: add stats and config tests to integrated test suite * of: Fix OFPEchoRequest serialize * of1.2: pretty OFPGetConfigReply parser * clean up ETH\_TYPE\_ constants * add ethernet type constants * test: fix SET\_NW\_TOS action in test\_add\_flow\_v10 * clean up IPPROTO\_ constants * add IPPROTO\_SCTP constant * rename ryu/ofproto/in.py to ryu/ofproto/inet.py * test: specify OF version in integrated test suite * Add SubmittingPatches doc * Ryu 1.1 * of1.2: handle unknown match field properly * test: simplify integrated OVS test suite * test: add more of1.2 unittests * of1.2: fix IPv6 match parsers * of1.2: make set\_metadata implementation consistent with the rest * of1.2: fix OFPExperimenter parser * of1.2: fix Instruction parser * of1.2: add OXM\_OF\_METADATA support * fix 475ca44ef4f87b00945ccd5be8ee4ab196c4e86f regression * test: add integrated OVS test suite * of1.2: fix OFPPortStatsRequest typo * of1.2: OFPGroupMod and OFPGroupFeaturesStats * simple\_switch: remove outside module dependence * cbench: specify OF1.0 * simple\_switch: specify OF1.0 * stop import ofproto\_v1\_0 as ofproto * nxm: remove import ofproto * of1.2: OFPMatch serialiser: fix ARP\_SPA, ARP\_TPA and IPV6\_FLABEL masking * simple\_switch: fix port\_status\_handler * of1.2: add OFPSF\_REPLY\_MORE constant * of1.2: remove unused mask in MTEthType * enable applications to specify OF versions * of1.2: add OFPQueuePropMinRate and OFPQueuePropMaxRate * nxm: fix nxm to OFPMatch conversion * of1.2: fix OFPGroupMod serialize * of1.2: OFPSetField serializer pads too much * of1.2: fix OFPPacketIn parser * of1.2: fix MTIPv6NdTarget * of1.2: fix OFPActionPopVlan parser * of1.2: fix OFPActionSetField padding * of1.2: fix vlan\_vid match * app/rest: fix value error exception * of1.2: change IPv6 address representation * of1.2: fix OFPActionSetField * of1.2: Correct pad calculation for OFPMatch * of1.2: fix OFPBucket parser and serialize methods * of1.2: fix OFAActionCopyTtlOut and OFPActionCopyTtlIn's parsers * of1.2: fix OFPActionSetField * of1.2: remove match argument in MT\* class serialize method * of1.2: add the common serialize method for MT\* classes * of1.2: make MT\* class make method take value and mask * of1.2: set value and mask in MT\* instance * of1.2: remove unused parser method in MT\* classes * of1.2: add common field\_parser for MT\* classes * of1.2: make pack\_str class variable * test: add more of1.2 unittests * of1.2: add missing struct ofp\_bucket definition * of1.2: implement FlowStats instruction parser * Ryu 1.0 * of1.2: add unittest workaround to OFPPortStatus parser * of1.2: fix bugs * add '--version' command line option * of1.2: add OFPG\_ constants * of1.3: Add OFPQ\_ALL * of1.2: Add OFPQ\_ALL * test: improve the framework * doc: add the supported OF versions to README.rst * of1.2: add OFPFlowStats support * of1.2: fix OFPPacketIn parser to set ethernet frame * of1.2: improve OFPMatch parser * nxm: fix NXM\_NX\_REG * of1.2: add OXM\_OF\_IPV6\_ND\_SLL and OXM\_OF\_IPV6\_ND\_TLL * of1.2: add OXM\_OF\_IPV6\_ND\_TARGET * of1.2: add OXM\_OF\_ICMPV6\_TYPE and OXM\_OF\_ICMPV6\_CODE * of1.2: add OXM\_OF\_IPV6\_FLABEL * of1.2: add OXM\_OF\_IPV6\_SRC and XM\_OF\_IPV6\_DST * don't call send\_delete\_all\_flows function in the core * add round\_up utility function * of1.2: Correct arguments to OFPMatch.parser() in OFPPacketIn * of1.2: support ofp\_instruction for OFPFlowMod * of1.2: add OXM\_OF\_ICMPV4\_TYPE and OXM\_OF\_ICMPV4\_CODE * of1.2: add OXM\_OF\_SCTP\_SRC and OXM\_OF\_SCTP\_DST * of1.2: add OXM\_OF\_UDP\_SRC and OXM\_OF\_UDP\_DST * of1.2: add OXM\_OF\_TCP\_SRC and OXM\_OF\_TCP\_DST * of1.2: add OXM\_OF\_IP\_SRC and OXM\_OF\_IP\_DST * of1.2: add OXM\_OF\_IP\_PROTO * of1.2: add OXM\_OF\_IP\_ECN * of1.2: add OXM\_OF\_IP\_DSCP * of1.2: remove FWW\_\* constants * of1.2: fix OFPFlowMod and OFPFlowRemoved * Add OFPBarrierRequest and OFPBarrierReply * Remove duplicated OFPMatch definition * of1.3: initial OF1.3 support * nxm: add NXM\_NX\_REG * fix test\_lib.py for SkipTest * nxm: add NXM\_NX\_IP\_FRAG * nxm: add NXM\_NX\_ND\_TARGET * nxm: add NXM\_NX\_IPV6\_SRC and NXM\_NX\_IPV6\_DST * nxm: add NXM\_NX\_IPV6\_LABEL * nxm: add NXM\_OF\_ARP\_SPA and NXM\_OF\_ARP\_TPA * nxm: fix MFField putw * of1.2: initial ofp\_match support * of1.2: reorder the arguments of OFPPacketOut * nxm: add NXM\_NX\_ICMPV6\_TYPE and NXM\_NX\_ICMPV6\_CODE support * add IPPROTO\_ constants * nxm: fix NXM\_OF\_ICMP\_TYPE and NXM\_OF\_ICMP\_CODE * nxm: fix nxm\_put() * Fix README.rst format * Move version string to ryu/\_\_init\_\_.py * Update setup.py * Update REAME.rst * of1.2: Add OXM\_OF\_ constants * of1.2: fix typo * of1.2: fix some typos * update the official site url * ofproto/nx\_match: various minor clean up * ofproto/nx\_match: simplify set\_dl\_{src, dst}\_mask() * of1.2: add MAX\_XID constant * update setup.py for PyPI * nxm: add NXM\_OF\_ICMP\_TYPE and NXM\_OF\_ICMP\_ICMP\_CODE support * nxm: add NXM\_OF\_IP\_SRC and NXM\_OF\_IP\_DST support * nxm: add NXM\_NX\_ARP\_\* support * nxm: add NXM\_OF\_TCP\_\* and NXM\_OF\_UDP\_\* support * nxm: add NXM\_OF\_ETH\_SRC\_W support * nxm: support arbitrary dl\_dst masks * nxm: add NXM\_OF\_IP\_PROTO support * nxm: add NXM\_NX\_IP\_TTL support * of1.2: cleanup and update * nxm: add NXM\_OF\_VLAN\_TCI support * kill unused function in utils.py * support commandline application initialization * Pass AppManager module name instead of class name * Make clear that ryu supports all the NX actions * Add Nicira Extension NXAST\_LEARN support * Add Nicira Extension NXT\_SET\_ASYNC\_CONFIG support * Add Nicira Extension NXT\_FLOW\_AGE support * Add Nicira Extension NXT\_PACKET\_IN support * Add Nicira Extension NXT\_SET\_PACKET\_IN\_FORMAT support * Add Nicira Extension NXT\_FLOW\_REMOVED support * rename NXMatch parse method to parser * update setup.py and setup.cfg for better packaging * doc: update the requirement in README * Replace wsapi * add Nicira Extension NXAST\_NOTE support * add Nicira Extension NXAST\_DEC\_TTL support * add Nicira Extension NXAST\_FIN\_TIMEOUT support * add Nicira Extension NXAST\_CONTROLLER support * Add Nicira Extension NXT\_SET\_CONTROLLER\_ID support * silence pep8 warning * fix NX\_ACTION\_HEADER pack string and size * don't close connection when getting OFPT\_ERROR\_MSG * rename OFPGetSwitchConfig to OFPGetConfigReply class * discard sample/test\_simple\_switch because of unittest fail * test: add NTT copyright to unittest files * app/simple\_switch: fix commit e5e4b844250d36788f9b1bf71cfd36a6e14d5315 regression * ryu/app: convert existing application to new style ryu application * base/app\_manager: introduce application context * add NXT\_ROLE\_REPLY support * Add Switch to Controller Nicira extension message support * Add Switch to Controller Vendor message support * test: add more unittests * Fix NXActionAutopath parser * test: add unittests for of1.2 parser * test: add more unittests for of1.0 parser * test: add more unittests for of parser * Fix OFPFlowRemoved \_\_str\_\_ method typo * Fix OFPVendorStats parser method * Fix OFPSwitchFeatures parser (of 1.2) * Fix the commit 458042d4032ad52dff93deb0f78d94cadb4f2d37 messup * Fix the commit eea434b8e45bc8ee91aa02096903a66af898ae35 messup * Fix OFPFlowStats parser * Add Nicira Extension NXAST\_POP\_QUEUE support * Add Nicira Extension NXAST\_SET\_QUEUE support * add Nicira Extension NXAST\_AUTOPATH support * add Nicira Extension NXAST\_EXIT support * Fix NXActionSetTunnel64 parser * Fix NXAactionOutputReg parser * rename NXTRequest to NiciraHeader * add NXT\_ROLE\_REQUEST support * Add NXT\_ROLE\_REQUEST/REPLY constants * ryu/controller/dpset.py: code simplification * lib/dpid: dpid formatter/parser * Kill parser\_stats\_body\_array method in OFPFlowStats class * fix OFPQueueGetConfigReply parser * fix OFPVendor parser * fix typo in ofproto\_v1\_0\_parser comment * fix StatsReply parser * Fix OFPQueuePropMinRate class * fix OFPPacketQueue class parser * ryu/app/wsapi: make json\_parse\_message\_body work * Pretty NXAcationBundleBase parser up * fix NXActionRegLoad parser * fix NXActionRegMove parser * fix NXActionMultipath parser * add Nicira Extension NXAST\_OUTPUT\_REG support * add Nicira Extension NXAST\_BUNDLE and NXAST\_BUNDLE\_LOAD support * add Nicira Extension NXAST\_REG\_LOAD support * add Nicira Extension NXAST\_REG\_MOVE support * Fix OFPStatsReply parser * Add NXAction parser support * Add OFPActionStripVlan class * lib/mac: improve helper functions * ofproto/ofproto\_v1\_0\_parser: PacketIn parser * ofproto\_v1\_0\_parser: fix OFPPacketOut serializer * remote COPYRIGHT file from MANIFEST.in * README: added the pointer to Gmane ML archive * add Nicira Extension NXAST\_MULTIPATH action * Added test framework, ported from Quantum * doc/source/step\_by\_step.rst: add item to setup quantum db * Fix OFP\_ACTION\_DL\_ADDR\_PACK\_STR * Fix OFPActionHeader class 'serialize' method * controller/controller: make send\_flow\_mod() allow default value for priority * app: use symbol instead of 32678 for default priority * ofproto/ofproto\_v1\_0\_parser: flowmod default parameter * ofproto/ofproto\_v1\_0\_parser: make FlowMod allow meaningful default parameter * controller, ofproto\_v1\_0: avoid format for argument * ofproto/ofproto\_v1\_0\_parser: serializer for NXActionResbumit * ofproto/ofproto\_v1\_0\_parser: serializer for nxt\_flow\_mod\_table\_id * ofproto/ofproto\_v1\_0\_parser: improve NXTRequest initializer * ofproto/ofproto\_v1\_0: more constants for nx * app/wsapi: make WSPathComponent inherit object * app/wsapi/WSPathArbitraryString: wrong indent * add missing super().\_\_init\_\_() * app/simple\_isolation: unbreak nx patch * fix find\_flagfile path handling bug * update docs on the license switch * Switch to Apache 2.0 license * Use the original file license * ryu 0.2 * ignore GreenletExit exception * Add NXActionSetTunnel and NXActionSetTunnel64 * Allow send\_flow\_mod() to send NXTFlowMod messages * Add match\_tuple() and flow\_format() methods to ClsRule * Add NXTFlowMod * NXM: Add MFIPDSCP and MFIPECN classes * NXM: Add MFEthType class * NXM: Add MFEthSrc class * NXM: Add MFEthDst class * NXM: Add MFTunId class * NXM: Add MFInPort class * Add base for serialising NXM matches * Add support for NXT\_SET\_FLOW\_FORMAT * Add Nicira vendor extensions * ryu/handler: class decorator should return class object * controller: print stack trace when datapath main loop goes wrong and log it * controller/network: fix key error * Avoid loop in OFPAction.parser() * Increment offset in OFPFlowStats.parser() * Use struct.unpack\_from() in OFPFlowStats.parser() * doc: update README.rst (OpenStack mainline inclusion status) * Correct typos in OFPFlowStatsRequestBase class * yield the CPU to other greenlets * avoid reading too much data from socket * limit the queue size (send\_q) * kill recv\_q * dispatcher: eliminate weakref.WeakValueDictionary * dispatcher: eliminate use of weakref for EventQueue event queue * controller: eliminate weakref of datapath.ev\_q.aux * dispatcher: use TrackInstances and kill some WeakValueDictionary * lib: mixin class to track all instances of a given class * controller: make Controller::serve more robust * ryu/controller/ofp\_event: use utils.load\_module * ryu/utils: make import\_module() reliable * controller/dispatcher: eliminate unregistering handlers * enable OF1.2 support * add initial OF1.2 support * doc: update using\_with\_openstack.rst to catch up openstack * add HACKING.rst: style guide * doc: update osrg/nova, quantum repository * setup.py: typo autor -> author * dpset: pep8 * ryu/controller/handler: pep8 * ofproto\_parser: pep8 * ofproto\_v1\_0\_parser: typo * ofproto/ofproto\_v1\_0\_parser: unbreak 0bff34ca87af74b7eb13d9c996fd869172a7f0a4 * doc: sample configuration files * doc: step-by-step example * app/simple\_isolation: various improvement * controller/{mac\_to\_port, network}: add more methods to track port status change * controller/datapath: add a helper function to delete flow entries * controller/dispatcher: eliminate the use of WeakSet * fix ofp\_event conversion messup * add cbench application * move to the main mode right after sending BARRIER * fix datapath disconnection cleanup * rest: add '/network' prefix to its path * remove unused members in Datapath class * client: pass http responce when an error occurs * controller: factor out ofp message event from event.py * pylint: various fixes for pylint * doc: how to invoke ryu-manager, its options and example * app: event dumper application * controller/dpset: Introduce datapath enter/leave event * dispatcher, handler: constantiate dispatcher name * controller: pass datapath to EventQueue for EventQueueCreate event * dispacher: introduce inheritable handler * controller/dispatcher: introduce events on event queue itself * dispatcher: pass name to EventQueue and track all instances * controller/dispatcher: allow handler that accepts any event type * controller/dispatcher: pylint * use 0 dl\_{src, dst} for OFPMatch * move \_pack\_into and \_str\_attr to ofproto\_parser.py * xid: improve xid handling * ofproto\_v1\_0: add a constant, MAX\_XID * ofproto/ofproto\_v1\_0\_parser: more parsers/serializers * ofproto\_v1\_0\_parser: allows 0 as dl\_{src, dst} for OFPMatch * lib/mac: add helper function/values * ofproto/ofproto\_v1\_0: typo, missing consts * move MsgBase class to ofproto\_parser.py from ofproto\_parser\_v1\_0.py * remove OF version dependence from MsgBase class * pylint: add a script to run pylint and pylintrc * pep8: utils.py * pep8: ryu/ofproto/ofproto\_v1\_0.py * ryu.conf: eliminate obsolete config * Use from gevent.queue import Queue * Fix to send OFPT\_HELLO with the highest OpenFlow protocol version * doc: how-l2-segregation-works: update images a bit * doc: fix typos * doc: use Network Operating System instead of Network OS for consistency * doc: fix typo * doc: clarify our goal for OpenStack * initial commit ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/HACKING.rst0000664000175000017500000000023400000000000014606 0ustar00zuulzuul00000000000000os-ken Style Commandments =============================================== Read the OpenStack Style Commandments https://docs.openstack.org/hacking/latest/ ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/LICENSE0000664000175000017500000002363700000000000014031 0ustar00zuulzuul00000000000000 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. ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/MANIFEST.in0000664000175000017500000000047700000000000014557 0ustar00zuulzuul00000000000000include LICENSE include MANIFEST.in include *.rst recursive-include os_ken *.xsd graft doc graft etc graft tools recursive-exclude doc/build * recursive-exclude os_ken/tests/packet_data_generator * recursive-exclude os_ken/tests/packet_data_generator2 * global-exclude *~ global-exclude *.pyc global-exclude .gitignore ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.3741212 os-ken-2.10.0/PKG-INFO0000664000175000017500000000260500000000000014111 0ustar00zuulzuul00000000000000Metadata-Version: 1.2 Name: os-ken Version: 2.10.0 Summary: A component-based software defined networking framework for OpenStack. Home-page: http://www.openstack.org/ Author: OpenStack Author-email: openstack-discuss@lists.openstack.org License: UNKNOWN Description: ====== os-ken ====== A component-based software defined networking framework in OpenStack. This is a fork of the Ryu library tailored for OpenStack Neutron. * License: Apache License, Version 2.0 * Documentation: https://docs.openstack.org/os-ken/latest/ * Source: https://opendev.org/openstack/os-ken/ * Bugs: https://storyboard.openstack.org/#!/project/openstack/os-ken * Release Notes: https://docs.openstack.org/releasenotes/os-ken Platform: UNKNOWN Classifier: Environment :: OpenStack Classifier: Intended Audience :: Information Technology Classifier: Intended Audience :: System Administrators Classifier: License :: OSI Approved :: Apache Software License Classifier: Operating System :: POSIX :: Linux Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 Classifier: Programming Language :: Python :: 3.10 Classifier: Programming Language :: Python :: 3.11 Requires-Python: >=3.8 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/README.rst0000664000175000017500000000066700000000000014511 0ustar00zuulzuul00000000000000====== os-ken ====== A component-based software defined networking framework in OpenStack. This is a fork of the Ryu library tailored for OpenStack Neutron. * License: Apache License, Version 2.0 * Documentation: https://docs.openstack.org/os-ken/latest/ * Source: https://opendev.org/openstack/os-ken/ * Bugs: https://storyboard.openstack.org/#!/project/openstack/os-ken * Release Notes: https://docs.openstack.org/releasenotes/os-ken ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.0461018 os-ken-2.10.0/doc/0000775000175000017500000000000000000000000013556 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/Makefile0000664000175000017500000001140600000000000015220 0ustar00zuulzuul00000000000000# Makefile for Sphinx documentation # export PYTHONPATH = $PYTHONPATH:.. # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build PAPER = BUILDDIR = build # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest help: @echo "Please use \`make ' where is one of" @echo " html to make standalone HTML files" @echo " dirhtml to make HTML files named index.html in directories" @echo " singlehtml to make a single large HTML file" @echo " pickle to make pickle files" @echo " json to make JSON files" @echo " htmlhelp to make HTML files and a HTML help project" @echo " qthelp to make HTML files and a qthelp project" @echo " devhelp to make HTML files and a Devhelp project" @echo " epub to make an epub" @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" @echo " latexpdf to make LaTeX files and run them through pdflatex" @echo " text to make text files" @echo " man to make manual pages" @echo " changes to make an overview of all changed/added/deprecated items" @echo " linkcheck to check all external links for integrity" @echo " doctest to run all doctests embedded in the documentation (if enabled)" clean: -rm -rf $(BUILDDIR)/* html: $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." dirhtml: $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." singlehtml: $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml @echo @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." pickle: $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle @echo @echo "Build finished; now you can process the pickle files." json: $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json @echo @echo "Build finished; now you can process the JSON files." htmlhelp: $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp @echo @echo "Build finished; now you can run HTML Help Workshop with the" \ ".hhp project file in $(BUILDDIR)/htmlhelp." qthelp: $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp @echo @echo "Build finished; now you can run "qcollectiongenerator" with the" \ ".qhcp project file in $(BUILDDIR)/qthelp, like this:" @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/os_ken.qhcp" @echo "To view the help file:" @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/os_ken.qhc" devhelp: $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp @echo @echo "Build finished." @echo "To view the help file:" @echo "# mkdir -p $$HOME/.local/share/devhelp/os_ken" @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/os_ken" @echo "# devhelp" epub: $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub @echo @echo "Build finished. The epub file is in $(BUILDDIR)/epub." latex: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." @echo "Run \`make' in that directory to run these through (pdf)latex" \ "(use \`make latexpdf' here to do that automatically)." latexpdf: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo "Running LaTeX files through pdflatex..." $(MAKE) -C $(BUILDDIR)/latex all-pdf @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." text: $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text @echo @echo "Build finished. The text files are in $(BUILDDIR)/text." man: $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man @echo @echo "Build finished. The manual pages are in $(BUILDDIR)/man." changes: $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes @echo @echo "The overview file is in $(BUILDDIR)/changes." linkcheck: $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck @echo @echo "Link check complete; look for any errors in the above output " \ "or in $(BUILDDIR)/linkcheck/output.txt." doctest: $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest @echo "Testing of doctests in the sources finished, look at the " \ "results in $(BUILDDIR)/doctest/output.txt." ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/requirements.txt0000664000175000017500000000014200000000000017037 0ustar00zuulzuul00000000000000sphinx>2.2.0 # BSD openstackdocstheme>=2.2.1 # Apache-2.0 # releasenotes reno>=3.1.0 # Apache-2.0 ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.0541024 os-ken-2.10.0/doc/source/0000775000175000017500000000000000000000000015056 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.0541024 os-ken-2.10.0/doc/source/_static/0000775000175000017500000000000000000000000016504 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/_static/.placeholder0000664000175000017500000000000000000000000020755 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.0541024 os-ken-2.10.0/doc/source/_templates/0000775000175000017500000000000000000000000017213 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/_templates/.placeholder0000664000175000017500000000000000000000000021464 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.0541024 os-ken-2.10.0/doc/source/admin/0000775000175000017500000000000000000000000016146 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/admin/index.rst0000664000175000017500000000010700000000000020005 0ustar00zuulzuul00000000000000==================== Administrators guide ==================== T.B.D. ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/api_ref.rst0000664000175000017500000000100100000000000017205 0ustar00zuulzuul00000000000000.. _api_ref: ******************************* OS-Ken API Reference ******************************* .. XXX list all members explicitly to workaround a sphinx bug .. XXX https://bitbucket.org/birkenfeld/sphinx/issue/1362 .. py:currentmodule:: os_ken.base.app_manager .. autoclass:: os_ken.base.app_manager.OSKenApp :members: OFP_VERSIONS,_CONTEXTS,_EVENTS,close,context_iteritems,reply_to_request,send_event,send_event_to_observers,send_request,start .. autoclass:: os_ken.controller.dpset.DPSet :members: ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.0541024 os-ken-2.10.0/doc/source/app/0000775000175000017500000000000000000000000015636 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/app/ofctl.rst0000664000175000017500000000126200000000000017500 0ustar00zuulzuul00000000000000**************** os_ken.app.ofctl **************** os_ken.app.ofctl provides a convenient way to use OpenFlow messages synchronously. OfctlService os_ken application is automatically loaded if your OS-Ken application imports ofctl.api module. Example:: import os_ken.app.ofctl.api OfctlService application internally uses OpenFlow barrier messages to ensure message boundaries. As OpenFlow messages are asynchronous and some of messages does not have any replies on success, barriers are necessary for correct error handling. api module ========== .. automodule:: os_ken.app.ofctl.api :members: exceptions ========== .. automodule:: os_ken.app.ofctl.exception :members: ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/app.rst0000664000175000017500000000042300000000000016367 0ustar00zuulzuul00000000000000**************************** Built-in OS-Ken applications **************************** OS-Ken has some built-in OS-Ken applications. Some of them are examples. Others provide some functionalities to other OS-Ken applications. .. toctree:: :maxdepth: 1 app/ofctl.rst ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/archive.rst0000664000175000017500000000047200000000000017234 0ustar00zuulzuul00000000000000================= Archived Contents ================= .. note:: Contents here are imported from the upstream Ryu documentation. They will be merged into the OS-Ken documentation gradually. .. toctree:: :maxdepth: 2 developing.rst configuration.rst tests.rst snort_integrate.rst app.rst ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/components.rst0000664000175000017500000000536700000000000020010 0ustar00zuulzuul00000000000000******************** Components of OS-Ken ******************** Executables =========== osken-manager ------------------ The main executable. Base components =============== os_ken.base.app_manager ----------------------- .. automodule:: os_ken.base.app_manager OpenFlow controller =================== os_ken.controller.controller ---------------------------- .. automodule:: os_ken.controller.controller os_ken.controller.dpset ----------------------- .. automodule:: os_ken.controller.dpset os_ken.controller.ofp_event --------------------------- .. automodule:: os_ken.controller.ofp_event os_ken.controller.ofp_handler ----------------------------- .. automodule:: os_ken.controller.ofp_handler OpenFlow wire protocol encoder and decoder ========================================== os_ken.ofproto.ofproto_v1_0 --------------------------- .. automodule:: os_ken.ofproto.ofproto_v1_0 os_ken.ofproto.ofproto_v1_0_parser ---------------------------------- .. automodule:: os_ken.ofproto.ofproto_v1_0_parser os_ken.ofproto.ofproto_v1_2 --------------------------- .. automodule:: os_ken.ofproto.ofproto_v1_2 os_ken.ofproto.ofproto_v1_2_parser ---------------------------------- .. automodule:: os_ken.ofproto.ofproto_v1_2_parser os_ken.ofproto.ofproto_v1_3 --------------------------- .. automodule:: os_ken.ofproto.ofproto_v1_3 os_ken.ofproto.ofproto_v1_3_parser ---------------------------------- .. automodule:: os_ken.ofproto.ofproto_v1_3_parser os_ken.ofproto.ofproto_v1_4 --------------------------- .. automodule:: os_ken.ofproto.ofproto_v1_4 os_ken.ofproto.ofproto_v1_4_parser ---------------------------------- .. automodule:: os_ken.ofproto.ofproto_v1_4_parser os_ken.ofproto.ofproto_v1_5 --------------------------- .. automodule:: os_ken.ofproto.ofproto_v1_5 os_ken.ofproto.ofproto_v1_5_parser ---------------------------------- .. automodule:: os_ken.ofproto.ofproto_v1_5_parser OS-Ken applications =================== os_ken.topology --------------- .. automodule:: os_ken.topology Libraries ========= os_ken.lib.packet ----------------- .. automodule:: os_ken.lib.packet os_ken.lib.ovs -------------- .. automodule:: os_ken.lib.ovs os_ken.lib.of_config -------------------- .. automodule:: os_ken.lib.of_config os_ken.lib.netconf ------------------ .. automodule:: os_ken.lib.netconf os_ken.lib.xflow ---------------- .. automodule:: os_ken.lib.xflow Third party libraries ===================== os_ken.contrib.ovs ------------------ Open vSwitch python binding. Used by os_ken.lib.ovs. os_ken.contrib.oslo.config -------------------------- Oslo configuration library. Used for osken-manager's command-line options and configuration files. os_ken.contrib.ncclient ----------------------- Python library for NETCONF client. Used by os_ken.lib.of_config. ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/conf.py0000664000175000017500000000532600000000000016363 0ustar00zuulzuul00000000000000# -*- coding: utf-8 -*- # 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. import os import sys sys.path.insert(0, os.path.abspath('../..')) # -- General configuration ---------------------------------------------------- # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = [ 'sphinx.ext.autodoc', 'openstackdocstheme', #'sphinx.ext.intersphinx', ] # autodoc generation is a bit aggressive and a nuisance when doing heavy # text edit cycles. # execute "export SPHINX_DEBUG=1" in your terminal to disable # The suffix of source filenames. source_suffix = '.rst' # The master toctree document. master_doc = 'index' # General information about the project. project = 'os-ken' copyright = '2018, OpenStack Developers' # openstackdocstheme options openstackdocs_repo_name = 'openstack/os-ken' openstackdocs_pdf_link = True openstackdocs_auto_name = False openstackdocs_bug_project = 'neutron' openstackdocs_bug_tag = '' # If true, '()' will be appended to :func: etc. cross-reference text. add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). add_module_names = True # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'native' # -- Options for HTML output -------------------------------------------------- # The theme to use for HTML and HTML Help pages. Major themes that come with # Sphinx are currently 'default' and 'sphinxdoc'. # html_theme_path = ["."] # html_theme = '_theme' # html_static_path = ['static'] html_theme = 'openstackdocs' # Output file base name for HTML help builder. htmlhelp_basename = '%sdoc' % project # -- Options for LaTeX output ------------------------------------------------- # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass # [howto/manual]). latex_documents = [ ('index', 'doc-%s.tex' % project, '%s Documentation' % project, 'OpenStack Developers', 'manual'), ] latex_use_xindy = False latex_elements = { 'extraclassoptions': 'openany,oneside', 'preamble': r'\setcounter{tocdepth}{2}', } ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.0541024 os-ken-2.10.0/doc/source/configuration/0000775000175000017500000000000000000000000017725 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/configuration/index.rst0000664000175000017500000000006200000000000021564 0ustar00zuulzuul00000000000000============= Configuration ============= T.B.D. ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/configuration.rst0000664000175000017500000000012500000000000020455 0ustar00zuulzuul00000000000000************* Configuration ************* .. toctree:: :maxdepth: 2 tls.rst ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.0541024 os-ken-2.10.0/doc/source/contributor/0000775000175000017500000000000000000000000017430 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/contributor/index.rst0000664000175000017500000000016600000000000021274 0ustar00zuulzuul00000000000000========================= Contributor Documentation ========================= .. include:: ../../../CONTRIBUTING.rst ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/developing.rst0000664000175000017500000000041000000000000017737 0ustar00zuulzuul00000000000000******************************* Writing Your OS-Ken Application ******************************* .. toctree:: :maxdepth: 2 writing_os_ken_app.rst components.rst os_ken_app_api.rst library.rst ofproto_ref.rst nicira_ext_ref.rst api_ref.rst ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/docutils.conf0000664000175000017500000000003600000000000017552 0ustar00zuulzuul00000000000000[parsers] smart_quotes: false ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/gui.png0000664000175000017500000006014000000000000016351 0ustar00zuulzuul00000000000000PNG  IHDR PLTEBA=8LKF@?:DC>A@<=<8?>:MLG651GFAkkk9848 *,,)wYXR%~_^WW4 dc[|nSjh_و)ߒ/+{{y?ی234RMMMonm-icttr4$"$t?J ѨI \aV2ou9<@T٘3P!y꾅DUSOo0I(Am¶bVKC6:[m%R*ꩦnp˾惸y<EL /V~4+o*t]Ȥ,<^fl/.NZ8ܮ׉rA0Yrx }X:r[?0ȍReKQ@3P8v!sKj?p/QLbƹV'أ`ԝ<`5!JޚFhKs<wz6J&VSi6 >_mǐKNXg;FFUcԚ9]+q} grNC~p΁A 7҈c F1QW8䮘P) YzsD2L7ؾ[TL-www ZWBȬ*'v7T=zՈ~3a؃o3O=}Iv(خeLe:dSӋS,?0 F4o /k/ШjhNT~%&:\϶zz LeSca&M欒Iy1㠷[ wMOOLOH"L 'I "Q>j*7 '޿~0&X][* T/yYc([i o̴Q~cr8KEn?}k}=)0^+#&2Ml&(xicN˹&WʭNUaG+qbo6S=뗙 Qäܫi`-(D)J@9=4Yt;  kh=CHIN^t _it$ OtM&3HIpɃKkg!,zRF[*܍H:6&yQyo$0qa ) bn%LT7sI+\:Nttfbd)zQ[*r}mPdvz'%t`ǛBpә^UVFy9 r--8luvz&UԆ|_bDyLMhQ'TrSru>ȦrzZz{Ws \˒W![žAGmܞ%VXDz{aUE~.wnvXAMmb\(ez4>z\fɝ{eJYT\աPVҧݻn40$RQ[ o_xv!N*#F"RiN-Hpu =u%oH;L+-zMC b2b{mgrslcW[) [ai>W-@dvwc8ro2-5vm_}-'BIwSQ$">z',afP{[]m*- 4hMd!wn1$ݖ9¯RH!h^/(1 8hb/$w~Cup ,WF>mp,}}˼IpT D gDlrmZeM'w:;BBj -ȕc)DQm͡M5CZoj8 ;u@<\N膹@qn/%+*2}Z 3[=\q?G:re- V嶊c-}?d;BJpI\x䇛048Ӎܬx0,*];3"wqV^V/2)sE^T),ܤH_!"7=|1C3'TXY "7@AD3͙HLSS>)m$ *Ft2U5Na+רLIPHg"AP^..Ƹ~38ggE^g( [,YB{3p;5rbgI ǞPީSo," %d#KN_Uy=ՋQc+!sz;ЯF$Ox(5(s綣@n j"FAp8j v8F:r;p(NncD3o+;&(WЃ {@%/9-\$($=Ń`NJaAP𤢧@ErQKb%Жb(=PC{*}y3&#uƵȭ)C~+WXo&ܚ(N  WMQ )!Һkcc'a'1MeP[C܆ma䢡EsX(Ä% ZXm7hs32k8̈́Wnj6[jB=-Wn2d2Ir&2i- wvgҕ[i6hQ5d{Z Mx"LD $ܸҋCݤxj9LXqOZS,YʝVJPR\|ϽwKY' .Mp&䎨%$DTN USO[>%4vA730НVZTKcXnw:Ana╻UP4jAr9-o9q P\~0erl/@ceQ|]:x_{^~9Պc=kQ-sS0co!RndXn&rWiͶ@SǾܷ sb"gX\7O]?qb~z Oޅ*U S1PK_-`[= T;k?ji̟Ӟp䶾#lXcʭW۵Kn sETk%[[Mfv 7`b 0F xq /*lO,AvY^'ϤZNŎ#xұdg,50ddZڍNe) (kK R"y4TFs`+e>ܕ]Qwa,hj<=kQmw̟n˝;喝,7V\jyAin(@ \In{fP$9? qV]*Kgk/94lxZWXZN-<+w2#dr3!#^k7|k]9ͩ7@:ȍvDzWn6Ҙ?E>YΊlN +ܮjw+*J\)0}o^9K8>OCpǞZzIF9B4i7&lefB M(VձgNN\Mn:/zn$-x}=ȗ`4fW?7tO2~>t#]9G0c-ZTKc\&%uHk8̈́oUP[=n܉Ix-28=nԯdv ژ~Pl '1}5c˻9MrG=kQ-s 4#=r Hn:)ד }&܀p7,73ؐ܄i$DU*V=Q=rŸ́; Jqow\S w?eP\hBÈ'7~˝JTP3!edT HNn Ä0=0r3̀r3̀r3̀r3̀r3v,(B7IWd߷k7}PB,F(x {%[^d&e+_s !7|27Hn!R"0"2E"1E"5Ō"3%"4"2s"̑B9BڦB[tR44BPr NFBښFBʚ>FBHn!I3!R@-D:h:!D O=dL`z +_jdeKA'V0?K-A"ӑgeP% ۪h\_2+۵l Y_5߯zV[ۯ;!A(7;o XlrO0*Vǩxl'1vc4f-]ƛɉrhnVYw`o]r͸m~*?dfB4z͐Co5ltg"2(J1rq+wUzpRbPgf_n;Ark{M0d)o\ &_d+^LUf07Gp74>'XmpNZT @x/ p-gXA|1 HzMhpCri{Kfck7Z~{tH5x+g-jyBcѽ bG*XSщ;n`fp{5z8t#gfg&ii/C|gq5-~/{OnHb[]p=:fFrc;Fߪ/1΄8gye*ZK߰OeB  d3C6' ~BYhyM܋UZ{3++5@ZTݚ&3߸ӡ^{G`=&9 jr;F,OZTto o\gd9;4)m"=s۶]˱ ΏHrюxeӸF^Z˺$cEw,%:<i o\k4Zr' \#cc-^8 œLRu­92 Y^$Kn:OSp0̹޸_dbj;η \X{!~(krs r&_S<1^=F+踉BųjS<;|Ó7xˡN]\ƻ+7- PC51^r?_nPnn(*s[r?xNrO(Kd)~vmXܱW=CAGRCPk}~Օ%55–nx7Z̉STbV{*rhEKke:˛/],޶)ŕ=X`b) *Ljr7 .nvjr^E(7^gP $JOf-_(7}/=zZ̗؀S-xsVgUW¥kNONKq\q}7}g:?^=.r͵C B'|6`%Z2l~Vگg6]3ֽLW˝[j>$͞o_K:aLN2Bt毐jؓ_f.h&o.}/l~X ^6, nh_-H!["H)["H)["H)["gƢ(!Jn(!Jn(!Jn(!}ŦXKn(!Jn(!Jn(!Jn(!Jn(!Jn(!Jn(!Jn(!Jn(!Jn(!Jn(!Jns,LaZ\\\].~c r  (HvJEUzwoIw"n P @7(E@q"n P @7(E@q"n P @7(E@q"n P @7(^Z]c6]]7DT)j3$f ;+N-C*׾3I_mHTVwhs\kOt%ROK q+uhAsq\+Y{U7eh$ӝb(tgFW;^شrflVZB*Y'!+ۖq+ qǫZ鉲6H*{s7:wƦ#:M>1~7Ȳ3/퉯,ز̺z8g;^[c։"i6le]ɘ:BO۱d?/;ecBQvYү.Ms#⎗涋|msn?w/ܶ&k}_mfH;^V˼LEpCg/Eܾ#xw;^8WCa#x_>}}DJoo_z|ǟ4X}C1h޽k7~!1[- qG2ɛ.ϟyѽ:vnWgε7DҺ/3eOwn4٢Mʤ]df^ᕙ'_ٻc&0,6o"UvPJ$M!QDB APFBC[ S&)UJhy/$p]cv܋ n'Q (ʧ+8Ar{Ȓ-qgRfч+S#qKnz'iheŇMK+XAS?FկO" LCU$`qk,&h$9L?_ʶFM4O ]:a}m*q;V{*7[[ݎy,R%NFNm͸gf|?(j1.0o܎{WnNYQhIh cq:: qjAh/"A]h\ n^[SC?;Wa=5,VeMcqt \ np7P7"kct0X%`q;p!057HfVEk np5s75s75s7x1 k>&B~gXD; Ң qX3?7xO 7j|7Bkٹc(»ܦ/f:5j݀ Q&jF%b & Lu^Ĉ̍"nG)ݕ?ȷ$6ib'mpiѮnVR!M)?}[c w-Ҵl"/elW/ٯVDM&/8F&=,ҽb&$Mlo $v 9xޱu72iq;(|ϗŠ('t]~1X̭ø)!G?y{2e%4Ȋ$5I,HK-xޱU72 u `!WhgI9|)$ضhI|̜u!T!iL ;S̱xݜENfꢖ"={Ba1N~D05ڄc?qڅvndflOxcǼP;|Ex`܍-b;xU/gWٯ^ 8fcwCs,./b R)*)R/b?1QnXlPcp0dZ^y?q7/7oۺ,(z{\1:qהyVgYo^q2q&AWgqRએWGLq̼`6ۺ) :+Ʈ7N*?Ǎ۰yyYb,[1NWzJdݕj71oøih¨Y҉=~cJw[;|Ǎc߁qקE`].߮y Ʋ.]-Yra=>npy߆qL$fIqw*qcVsӇc0DEl;7wwhnajxϗ^ߊ"8  1-(ZL {= 5b6$ ۬(ݸ)}eg"||{{9cR'Jpxp/w@?aq_Lg7*iѳnU܎BTT.ݰ32˄;>r&|nOi}7ĸt"P=֎p0s6Wh jδEC > b4~P4&7)'0Aș_dꆿ`6i(YhyKع2v''z9ʫ/2<8Ղq(kYV_ ɀ(勌!@mR$RHIpHҽl167¸m)%A&=$4,7q z17aܶ)(W/Y"<8paM/2Ī*n. i&i&Bӧϖw˧{OL2aeQI(Q(EϨ%E6IO%s !-yo3=NbUmIjX⦑,_9HswfQf[ء4-)$1߈ے jx{2e=`+.@,O`3=9yc(͙X ']c?L)a@sLNJڴ>=ٷG鍋X7KbĚOQzt:egYa~3OPݸBؿ4`xFg+,{=!hY~cÞCc{D ͚aܿ@m.J Z+8v ';I #{gJ#eDΤ*WE&Dd ]06 PIKM\55X*DąJ"iT!4NIM={{\9y|F<]I}iP2Gz%a6\ƶ~0=Gsr{ bC,eW? T)*Y?Om^ޞ5LOgs-G&Xfrlg )U!}[v ry55}`1^b2LFsQn$n~kB/t!q)fllo02س}Nf 1ЖmUrS,t'VD6qa<(0ƢɜC%a΅YёKFcSSrЅ {ͻs_:i1L0xrO-w|fUCv钣0}0(FF^ڽ? ;jU=dWݥaz''C<Ăr_n&45q_W(-yflϫ݆}1ݺ Mލ?ZU&K0c런;HU=de:rÕ}`9`LOGPc(ur{3c'|jn{xK[7'V2ҳ94/ ^KP𻅏(q1w[d,%[O܀r >=B?]OIV!xJz"`J~r25Ќ !yo)V+<r=l^o?/PTnBO=lv%9 v pbr-c˺WF HVN(]bB7s)m։OKIn2l!*';|џ5¡Ԫ !"۴>f"M,(p=(a E12c3z3ǵǕR|%n/qw{ln߈r5c0vy&5 8E*Lۅ'5a9#X8`f/glCѝ⑐/Ӎ Q mIqnZZ uoddJaݬkۨ]s*4x0nLg6`gҠf<2D5fVIub(vr1Bbkh68}J+ Ga(Ř.j1Mϕ譡fw+"7ɼz^׿t }8b.F%2B!`/}p2VWDDСL$љ!flX *K@PnV ^דNRF GsmFβӑ/=B!=3-S^֌,o%dl]FɔqŞ;: m,_G|"Y . rjJ2Lx[;RkR_;h:vE#"ʥrsk>AdU=70=ʍr_9~ymRdfEVaOHi>Kjn<´-^ g9UƖ ? ln; e# ]f Kl i꾱m^kG" ʭ-n+?Ɓf(Ea?vN#9H.3lR4 zӻLK,l5UV5[cݫjaD D2Wk?d>Oےm 90}VS}2u2V>@Pn x4告Zn1,xn! h!UܟL:>Qu_Sm9&2;7hpa^("w,a)Qh;P˽݊sVXPkϫn;h 0 ~_372;ܽ'Vܒ$1-GX;& f4Sg !d"PTM)@ͼܘEPnTkǽ.9چTs/YBnrX32%A9:ɚ8KAȼ-DZ[(ǚ2 럸@Hϐ !O}gn@:F<֌1!cRt.n3j"[h0U@ܺF)EՌ͔^?e9g"8Y\n{h Iv,.Qz!Pn( \舩 T-.n,."2AV e]8(-AڣWJ!5H (Q*CPw:gD chMLB%e0)@Z@Ry"3GGN .ޯ5<)p-6}D[+1D ʭήxzU 4(Pkoh<ч/s_ur᳀t9.jszWy?&grZy<|ë.|s~x*rr?8Jg7璳ɏ"$pKِ̯(6tJZ4֔.V["[.HFHC+J"Q$q0#v>z\unl;|_1n pMSO<5o{7rv˗t^y&CkyAƸU4 2?Vqw>z| %n0VҀޓw2͋'}-GG@v~:qs@C_[Qݑk9Rܱ<V`F{"2{yWU'AH778DuBqۦR0n9ExDD"Bx/@f190O=o*7A-)hB >ttLgƍ8M5xAZ:EMXA &HrEZh<`2jDN{| q$ya),cppse(h q$>s 4^N%4Ǜoʀ$M -s떮H[q]CRGDM,80MŴj~";Ԛ 7Aqwe{h qT-q(CUIܸ;8MܫA!nR;8 !n,/[L qS47IfKMJ'{"֜ԝDJqVI?N]Yƴ!n%XEHӎxՓ4MWܑʖNU~.~d!n%,/eUiqVqbqܿ7-p {O)CH%"0JI8"xwF7(CP炶_^822{07oHC`!nni<t֩UhjL9:UʆsIcMjPۆu5~PUȁΟu_ /|R3e+0`zwCFa_<L};:b4)*$=Aݔ!n{_M..vuC{ue=[(K~:%ʬZ^9a/:祰gFL}elC-Y;aBj(ڵ('g͚mUm=R8Uw|fhKdI6/:7a}x0L=쳨?j3["?y64 C--)hB >ttLg& qC(nXXTфU 57ϖx 5^"g ̖ӆt)̰U [8R RFp܅gn=ֺƋԩRun7 i u3k[*&ꀸ!w1-B$xFr? nw5A܀( B܀( J_q÷;TB3ˆ7>iCffxTH")#㙜6 %%І;~VtMTUe쪀ZNZ [NH%$SQUq4PBPlXAkZG׼>q+7}ېQɮm7/ì, ٻ{(0ç]`!(vQB "6Y- i,,!6JlmB,%X&En ;0 BH7<œyxg}iuR5^0q3`ߓj~`tii]|9ެ_yٗBw\+ uw.uܓf5a{a v:Nw{zzTF %nNwpt9efz֫^jj@<ȼԧh\oOjz{k73m_^.jFܡ,ƧMMJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJA -{@%7D QrC%7D QrC%7D QrC%7D QrC%7D QrCurArC%7D QrC%7D=[o Q?m4v톖jSR-[k%[TBRhKQ*MEŋH\"$of;ktwvM=LΞ=~9sf*!斐PHsKHd(%$2 in 4DB[B"C!-!斐PHsKHd(%$2 in E. CYE5~e$+kc>8fMrx;$H.hc~d&tg@psvs~߿{ ӧ}^DZQ~^8 5> lhF-cB.o N$ϓ5ŨaRL0kڼI蝟{zxVtyXXҼZq>ZCe /쵋vؘlGMo85Q z9qj%enJ̝r=&`u){/I?3g}*l l 7 :PɞD?UsO6+3 d\oݲpnUm^hS(zjB8J܄In_wUu=enͩufU jAFm蕍Oi`YsW\ NTvCf-:erw޿9X7AoE˾`jH\f1T2/+ڹpԝ9 #J]ZmFOʻR\7|F~2*9k`Y/(o!7ܶh)m_ L=D6Rq-bބAUa A|#s%IY9}24$bd# s4}0#gO`Şg;_wy ?ڹ5nɹRp:WVl G1Ӻ+-K _jvxK'o+oEH$W;ܐ+GjlT= md89QWyllT0g2*Ʋ!pqqơ3ᡓ-8dаR POl0ϛ׆';7d bF|'}ͬRa^VnAk9-mM[;Y-ߧꀾ?:d`TXCJa"PW^Y"TkV. |8Bnh=RX&WfSR0ϛ̍<\EnfCS b 1onp*FM{~iW:b#l`uFhKs+~3bEVE-Aи!_Vn$e6f^]xXNug RYB p[f')C,c6nrEy>6 !kQC[G_1Bz|} >}efYNMymCPas*NZX'Jv Idߖt4]#̻ DI6''17%IjPUqh$B)-1Hhi73)R 0ϛED]]mIa&.}AQ"l]OTCx.O|&@g$a ,21۴ 2&5bik᭔t5L4KT%_O]8f+)C,fS>vrW?07]=Ew|蓹})7& 傹PhL`3nJxa ),qC? gw{1i#}j\V9Q*깣/C&VjP\;o_$Hf uSq8ƫLe3R[ƪEIsI fS>6 6͛̍ڠCϯg>->}AQ"lQ捶e­\ɨ-- ]u7K,WˮY|mQmڅBT,Ea[Es63eqoiqqnzv1gnZQ=YB]N8X1jV !!z-܀\u2I[n&;)-7yZ!x Ҫu)^> dn.bZe#{sDsΝJӵXk1_Q}rc|XZ|1;o;wU'|0".s;=+"[jۨFL3BKoi9g Cx96\u:1{kzAg* sT[ xࡓ @{f9Qhl=9{Y&i7AZEu!~>A:)7e<ӬİVXK,`nWuaoSe+[?-f' 0m-вnnd-샙Џl(@6ԊKH[hxmŵ^T3/(BE#^PRz_C՗S_-inmJ5?k.M#B#v= ڢ)uTys+T4VrL^wY9sSo ^ݫ7gi׹+eaush, R au*v@B 3@CHAɼHDJ]%PSV}^DZ<:U}:W߇|jJnMzF- *"8 9jݼs ^uX{?g:CXj"!Q?;P!(N%S9sDْaH`0A/YTT5#[?ٛ'=b11iE- *"8 @q@D1̝A p60fc03GTЂ>`g0; ƈQ(%(Aآ)uVC(1* 07zX窯МRO{Γ=a[bJ -WXN]"9Pn0wsm k2 /d j& :NE-ŏ2PP"$͍mu(KP4z'Sa3WhN{jcY)5R8CXNn0w3x{gBF1 W :NEAt :D>TN;<-os %J̍^"x*u<"ZGE9HӶ4ɁN:s{|<|Ƃp:N#;AGPȇ QwQZCDV77z0˚Ss8ZUT?ss cI2w$@ =H=vNawmG#/ʠ#(JC1s1Q"u.f%a8^FWSX窯МROgGj(ie>sˌ%nX( )p-ޚHXY;rc:CXJtE |(fnAɕ.DM,Y\Kp(dWSX窯 TRjtsmI䪌(Bt2.CiLjչv/\|DTtPC SQ(%g(ABO0DAKxU<:Y ͑zR}ñ]3q@Hg9HӶf)K"S$ǤPBf9i0$T_'oNe47ո v~|/S9mrw̥v:F`H{ͩLgnn%e71Bb)QQ]DK7=ry#_hչ ]k|40/qQ.0|zfO`SU_KZQ,Lb,=Q$V؊=baO^؃[{F\b&Y̝` nc̍:ܿ>,=Q$g{b>\cnh 17%i%o=0w}jbT1I3 LbxJܳ DMڏ 4=!WEwf <ӗuuĠSxA@XO׋*iE~B [ZGCG#0@0bb =I!\$5f~&xyD pbO֯K2k{e:rI20MUu!ZJ~@;1D2CC2G$F@I> Hp%W,i0I澺7G|!N 5|q 'D X h9ƻ7'I24v!kUTP5 p9HE=o= D!\$u{CR,V/nĞuBX4\EܙH3:ܒV~rPi"}8Y'1&3Hp9HE=XbŲ {~6 67=pD '6e+G$f : ɓ MEHZJT"Oj%9d/3+dUbk" D[!\:sC jX$=/0 x-1k [ϩ󿼝1XOܿyAMy*:U͙;}LJ*wAMy+մ!p\{aL'=ħ ^" lMo.^pdzOӯ]}!i XrŲ k{+={t!fM2](D'JWazVmsoĬiTzisB!:QzȾ c><;pU!fMK_ щCF55I` !xh9e%?r$#m>: mG[!((.QQ])vbK_=]AwЄcmaSh>%ѳvjcF }x77.:3qPL$xLVI$,נFF{ ,#ep~U_;5FxԴ <{+;I> V?Q/%Km]4Qq|ԨOXo7% ʕ$[Ya ee$GaMc_  dةQ?{GIhQK"OThZ(JZ̝eGYF k}#|dcFߟ4nY}="D+3~aE1X cu62zT8 =6#߰/cpdvs|Ԩ`n<g;ND2Bref"1Vrn1%ś~hm62ztbOW ڗ182@F;9>ΚO¤ҶdD"Ж` c -.i]g_2ȎD3t1$h_Uh'N oO?q:4+;^Im9Z(KJnnBmnedGv372ܩ\Ugnvr|(g %re+hKkn~憹%I( 3eAYF:p!}0182GF;9>vjTtAmV{|]D2B@347YIWaB(#\SHΏD_"Gh'=N.}{!Z8:"yD23v0˘B`nIbn9dcg#.Q_ƃ}#|dcF]6k Cf' }n?}bRL2Bree"1ſ,+T2)4 -$-'8 jh\ {'ǻ֘8H_nY8Fc|/*-9n{w-PEQK K/6Uњ3w%K/DF1w-b%O4t Jn(!Jn(!Jn(!Jn(!Jn(!Jn䆨3~\%'IENDB`././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/index.rst0000664000175000017500000000114000000000000016713 0ustar00zuulzuul00000000000000.. os-ken documentation master file, created by sphinx-quickstart on Tue Jul 9 22:26:36 2013. You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. ====================================== Welcome to the documentation of os_ken ====================================== .. toctree:: :maxdepth: 2 readme library/index contributor/index configuration/index user/index admin/index reference/index archive .. only:: html .. rubric:: Indices and tables * :ref:`genindex` * :ref:`modindex` * :ref:`search` ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.0541024 os-ken-2.10.0/doc/source/library/0000775000175000017500000000000000000000000016522 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/library/index.rst0000664000175000017500000000011100000000000020354 0ustar00zuulzuul00000000000000======== Usage ======== To use os-ken in a project:: import os_ken ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/library.rst0000664000175000017500000000052700000000000017260 0ustar00zuulzuul00000000000000******* Library ******* OS-Ken provides some useful library for your network applications. .. toctree:: :maxdepth: 1 library_packet.rst library_packet_ref.rst library_pcap.rst library_of_config.rst library_bgp_speaker.rst library_bgp_speaker_ref.rst library_mrt.rst library_ovsdb_manager.rst library_ovsdb.rst ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/library_bgp_speaker.rst0000664000175000017500000000372700000000000021627 0ustar00zuulzuul00000000000000******************* BGP speaker library ******************* Introduction ============ OS-Ken BGP speaker library helps you to enable your code to speak BGP protocol. The library supports IPv4, IPv4 MPLS-labeled VPN, IPv6 MPLS-labeled VPN and L2VPN EVPN address families. Example ======= The following simple code creates a BGP instance with AS number 64512 and Router ID 10.0.0.1. It tries to establish a bgp session with a peer (its IP is 192.168.177.32 and the AS number is 64513). The instance advertizes some prefixes. .. code-block:: python import eventlet # BGPSpeaker needs sockets patched eventlet.monkey_patch() # initialize a log handler # this is not strictly necessary but useful if you get messages like: # No handlers could be found for logger "os_ken.lib.hub" import logging import sys log = logging.getLogger() log.addHandler(logging.StreamHandler(sys.stderr)) from os_ken.services.protocols.bgp.bgpspeaker import BGPSpeaker def dump_remote_best_path_change(event): print 'the best path changed:', event.remote_as, event.prefix,\ event.nexthop, event.is_withdraw def detect_peer_down(remote_ip, remote_as): print 'Peer down:', remote_ip, remote_as if __name__ == "__main__": speaker = BGPSpeaker(as_number=64512, router_id='10.0.0.1', best_path_change_handler=dump_remote_best_path_change, peer_down_handler=detect_peer_down) speaker.neighbor_add('192.168.177.32', 64513) # uncomment the below line if the speaker needs to talk with a bmp server. # speaker.bmp_server_add('192.168.177.2', 11019) count = 1 while True: eventlet.sleep(30) prefix = '10.20.' + str(count) + '.0/24' print "add a new prefix", prefix speaker.prefix_add(prefix) count += 1 if count == 4: speaker.shutdown() break ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/library_bgp_speaker_ref.rst0000664000175000017500000000106100000000000022450 0ustar00zuulzuul00000000000000********************************* BGP speaker library API Reference ********************************* BGPSpeaker class ================ .. autoclass:: os_ken.services.protocols.bgp.bgpspeaker.BGPSpeaker :members: .. autoclass:: os_ken.services.protocols.bgp.bgpspeaker.EventPrefix :members: .. autoclass:: os_ken.services.protocols.bgp.info_base.base.PrefixFilter :members: .. autoclass:: os_ken.services.protocols.bgp.info_base.base.ASPathFilter :members: .. autoclass:: os_ken.services.protocols.bgp.info_base.base.AttributeMap :members: ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/library_mrt.rst0000664000175000017500000000112500000000000020135 0ustar00zuulzuul00000000000000**************** MRT file library **************** Introduction ============ OS-Ken MRT file library helps you to read/write MRT (Multi-Threaded Routing Toolkit) Routing Information Export Format [`RFC6396`_]. .. _RFC6396: https://tools.ietf.org/html/rfc6396 Reading MRT file ================ For loading the routing information contained in MRT files, you can use mrtlib.Reader. .. autoclass:: os_ken.lib.mrtlib.Reader Writing MRT file ================ For dumping the routing information which your OSKenApp generated, you can use mrtlib.Writer. .. autoclass:: os_ken.lib.mrtlib.Writer ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/library_of_config.rst0000664000175000017500000000170300000000000021266 0ustar00zuulzuul00000000000000***************** OF-Config support ***************** OS-Ken has a library for OF-Config support. XML schema files for NETCONFIG and OFConfig =========================================== XML schema files for NETCONF and OFConfig are stolen from LINC whose licence is Apache 2.0. It supports only part of OFConfig so that its schema files are (intentionally) limited such that operation attributes are allowed only in several limited places. Once our library is tested with other OFConfig switches, the schema files should be updated to allow operation attribute in more places. References ========== * `NETCONF ietf `_, * `NETCONF ietf wiki `_, * `OF-Config spec `_, * `ncclient `_, * `ncclient repo `_, * `LINC git repo `_ ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/library_ovsdb.rst0000664000175000017500000000405000000000000020450 0ustar00zuulzuul00000000000000************* OVSDB library ************* Path: ``os_ken.lib.ovs`` Similar to the :doc:`library_ovsdb_manager`, this library enables your application to speak the OVSDB protocol (RFC7047_), but differ from the :doc:`library_ovsdb_manager`, this library will initiate connections from controller side as ovs-vsctl_ command does. Please make sure that your devices are listening on either the Unix domain socket or TCP/SSL port before calling the APIs of this library. .. code-block:: bash # Show current configuration $ ovs-vsctl get-manager # Set TCP listen address $ ovs-vsctl set-manager "ptcp:6640" See manpage of ovs-vsctl_ command for more details. .. _RFC7047: https://tools.ietf.org/html/rfc7047 .. _ovs-vsctl: http://openvswitch.org/support/dist-docs/ovs-vsctl.8.txt Basic Usage =========== 1. Instantiate :py:mod:`os_ken.lib.ovs.vsctl.VSCtl`. 2. Construct commands with :py:mod:`os_ken.lib.ovs.vsctl.VSCtlCommand`. The syntax is almost the same as ovs-vsctl_ command. 3. Execute commands via :py:mod:`os_ken.lib.ovs.vsctl.VSCtl.run_command`. Example ------- .. code-block:: python from os_ken.lib.ovs import vsctl OVSDB_ADDR = 'tcp:127.0.0.1:6640' ovs_vsctl = vsctl.VSCtl(OVSDB_ADDR) # Equivalent to # $ ovs-vsctl show command = vsctl.VSCtlCommand('show') ovs_vsctl.run_command([command]) print(command) # >>> VSCtlCommand(args=[],command='show',options=[],result='830d781f-c3c8-4b4f-837e-106e1b33d058\n ovs_version: "2.8.90"\n') # Equivalent to # $ ovs-vsctl list Port s1-eth1 command = vsctl.VSCtlCommand('list', ('Port', 's1-eth1')) ovs_vsctl.run_command([command]) print(command) # >>> VSCtlCommand(args=('Port', 's1-eth1'),command='list',options=[],result=[]) print(command.result[0].name) # >>> s1-eth1 API Reference ============= os_ken.lib.ovs.vsctl -------------------- .. automodule:: os_ken.lib.ovs.vsctl :members: os_ken.lib.ovs.bridge --------------------- .. automodule:: os_ken.lib.ovs.bridge :members: ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/library_ovsdb_manager.rst0000664000175000017500000000643400000000000022152 0ustar00zuulzuul00000000000000********************* OVSDB Manager library ********************* Path: ``os_ken.services.protocols.ovsdb`` Introduction ============ OS-Ken OVSDB Manager library allows your code to interact with devices speaking the OVSDB protocol. This enables your code to perform remote management of the devices and react to topology changes on them. Please note this library will spawn a server listening on the port 6640 (the IANA registered for OVSDB protocol), but does not initiate connections from controller side. Then, to make your devices connect to OS-Ken, you need to tell the controller IP address and port to your devices. .. code-block:: bash # Show current configuration $ ovs-vsctl get-manager # Set manager (controller) address $ ovs-vsctl set-manager "tcp:127.0.0.1:6640" # If you want to specify IPv6 address, wrap ip with brackets $ ovs-vsctl set-manager "tcp:[::1]:6640" Also this library identifies the devices by "system-id" which should be unique, persistent identifier among all devices connecting to a single controller. Please make sure "system-id" is configured before connecting. .. code-block:: bash # Show current configuration $ ovs-vsctl get Open_vSwitch . external_ids:system-id # Set system-id manually $ ovs-vsctl set Open_vSwitch . external_ids:system-id= Example ======= The following logs all new OVSDB connections in "handle_new_ovsdb_connection" and also provides the API "create_port" for creating a port on a bridge. .. code-block:: python import uuid from os_ken.base import app_manager from os_ken.controller.handler import set_ev_cls from os_ken.services.protocols.ovsdb import api as ovsdb from os_ken.services.protocols.ovsdb import event as ovsdb_event class MyApp(app_manager.OSKenApp): @set_ev_cls(ovsdb_event.EventNewOVSDBConnection) def handle_new_ovsdb_connection(self, ev): system_id = ev.system_id address = ev.client.address self.logger.info( 'New OVSDB connection from system-id=%s, address=%s', system_id, address) # Example: If device has bridge "s1", add port "s1-eth99" if ovsdb.bridge_exists(self, system_id, "s1"): self.create_port(system_id, "s1", "s1-eth99") def create_port(self, system_id, bridge_name, name): new_iface_uuid = uuid.uuid4() new_port_uuid = uuid.uuid4() bridge = ovsdb.row_by_name(self, system_id, bridge_name) def _create_port(tables, insert): iface = insert(tables['Interface'], new_iface_uuid) iface.name = name iface.type = 'internal' port = insert(tables['Port'], new_port_uuid) port.name = name port.interfaces = [iface] bridge.ports = bridge.ports + [port] return new_port_uuid, new_iface_uuid req = ovsdb_event.EventModifyRequest(system_id, _create_port) rep = self.send_request(req) if rep.status != 'success': self.logger.error('Error creating port %s on bridge %s: %s', name, bridge, rep.status) return None return rep.insert_uuids[new_port_uuid] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/library_packet.rst0000664000175000017500000000655700000000000020620 0ustar00zuulzuul00000000000000************** Packet library ************** Introduction ============ OS-Ken packet library helps you to parse and build various protocol packets. dpkt is the popular library for the same purpose, however it is not designed to handle protocols that are interleaved; vlan, mpls, gre, etc. So we implemented our own packet library. Network Addresses ================= Unless otherwise specified, MAC/IPv4/IPv6 addresses are specified using human readable strings for this library. For example, '08:60:6e:7f:74:e7', '192.0.2.1', 'fe80::a60:6eff:fe7f:74e7'. Parsing Packet ============== First, let's look at how we can use the library to parse the received packets in a handler for OFPPacketIn messages. .. code-block:: python from os_ken.lib.packet import packet @handler.set_ev_cls(ofp_event.EventOFPPacketIn, handler.MAIN_DISPATCHER) def packet_in_handler(self, ev): pkt = packet.Packet(array.array('B', ev.msg.data)) for p in pkt.protocols: print p You can create a Packet class instance with the received raw data. Then the packet library parses the data and creates protocol class instances included the data. The packet class 'protocols' has the protocol class instances. If a TCP packet is received, something like the following is printed:: If vlan is not used, you see something like:: You can access to a specific protocol class instance by using the packet class iterator. Let's try to check VLAN id if VLAN is used: .. code-block:: python from os_ken.lib.packet import packet @handler.set_ev_cls(ofp_event.EventOFPPacketIn, handler.MAIN_DISPATCHER) def packet_in_handler(self, ev): pkt = packet.Packet(array.array('B', ev.msg.data)) for p in pkt: print p.protocol_name, p if p.protocol_name == 'vlan': print 'vid = ', p.vid You see something like:: ethernet vlan vid = 10 ipv4 tcp Building Packet =============== You need to create protocol class instances that you want to send, add them to a packet class instance via add_protocol method, and then call serialize method. You have the raw data to send. The following example is building an arp packet. .. code-block:: python from os_ken.ofproto import ether from os_ken.lib.packet import ethernet, arp, packet e = ethernet.ethernet(dst='ff:ff:ff:ff:ff:ff', src='08:60:6e:7f:74:e7', ethertype=ether.ETH_TYPE_ARP) a = arp.arp(hwtype=1, proto=0x0800, hlen=6, plen=4, opcode=2, src_mac='08:60:6e:7f:74:e7', src_ip='192.0.2.1', dst_mac='00:00:00:00:00:00', dst_ip='192.0.2.2') p = packet.Packet() p.add_protocol(e) p.add_protocol(a) p.serialize() print repr(p.data) # the on-wire packet ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.0621028 os-ken-2.10.0/doc/source/library_packet_ref/0000775000175000017500000000000000000000000020705 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/library_packet_ref/packet_arp.rst0000664000175000017500000000010000000000000023537 0ustar00zuulzuul00000000000000*** ARP *** .. automodule:: os_ken.lib.packet.arp :members: ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/library_packet_ref/packet_base.rst0000664000175000017500000000016200000000000023677 0ustar00zuulzuul00000000000000***************** Packet Base Class ***************** .. automodule:: os_ken.lib.packet.packet_base :members: ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/library_packet_ref/packet_bfd.rst0000664000175000017500000000010000000000000023510 0ustar00zuulzuul00000000000000*** BFD *** .. automodule:: os_ken.lib.packet.bfd :members: ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/library_packet_ref/packet_bgp.rst0000664000175000017500000000010000000000000023525 0ustar00zuulzuul00000000000000*** BGP *** .. automodule:: os_ken.lib.packet.bgp :members: ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/library_packet_ref/packet_bmp.rst0000664000175000017500000000010000000000000023533 0ustar00zuulzuul00000000000000*** BMP *** .. automodule:: os_ken.lib.packet.bmp :members: ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/library_packet_ref/packet_bpdu.rst0000664000175000017500000000010400000000000023713 0ustar00zuulzuul00000000000000**** BPDU **** .. automodule:: os_ken.lib.packet.bpdu :members: ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/library_packet_ref/packet_cfm.rst0000664000175000017500000000010000000000000023522 0ustar00zuulzuul00000000000000*** CFM *** .. automodule:: os_ken.lib.packet.cfm :members: ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/library_packet_ref/packet_dhcp.rst0000664000175000017500000000010400000000000023677 0ustar00zuulzuul00000000000000**** DHCP **** .. automodule:: os_ken.lib.packet.dhcp :members: ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/library_packet_ref/packet_dhcp6.rst0000664000175000017500000000011000000000000023762 0ustar00zuulzuul00000000000000***** DHCP6 ***** .. automodule:: os_ken.lib.packet.dhcp6 :members: ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/library_packet_ref/packet_ethernet.rst0000664000175000017500000000012400000000000024601 0ustar00zuulzuul00000000000000******** Ethernet ******** .. automodule:: os_ken.lib.packet.ethernet :members: ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/library_packet_ref/packet_geneve.rst0000664000175000017500000000011400000000000024233 0ustar00zuulzuul00000000000000****** Geneve ****** .. automodule:: os_ken.lib.packet.geneve :members: ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/library_packet_ref/packet_gre.rst0000664000175000017500000000010000000000000023532 0ustar00zuulzuul00000000000000*** GRE *** .. automodule:: os_ken.lib.packet.gre :members: ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/library_packet_ref/packet_icmp.rst0000664000175000017500000000010400000000000023711 0ustar00zuulzuul00000000000000**** ICMP **** .. automodule:: os_ken.lib.packet.icmp :members: ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/library_packet_ref/packet_icmpv6.rst0000664000175000017500000000011400000000000024166 0ustar00zuulzuul00000000000000****** ICMPv6 ****** .. automodule:: os_ken.lib.packet.icmpv6 :members: ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/library_packet_ref/packet_igmp.rst0000664000175000017500000000010400000000000023715 0ustar00zuulzuul00000000000000**** IGMP **** .. automodule:: os_ken.lib.packet.igmp :members: ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/library_packet_ref/packet_ipv4.rst0000664000175000017500000000010400000000000023643 0ustar00zuulzuul00000000000000**** IPv4 **** .. automodule:: os_ken.lib.packet.ipv4 :members: ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/library_packet_ref/packet_ipv6.rst0000664000175000017500000000010400000000000023645 0ustar00zuulzuul00000000000000**** IPv6 **** .. automodule:: os_ken.lib.packet.ipv6 :members: ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/library_packet_ref/packet_llc.rst0000664000175000017500000000010000000000000023527 0ustar00zuulzuul00000000000000*** LLC *** .. automodule:: os_ken.lib.packet.llc :members: ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/library_packet_ref/packet_lldp.rst0000664000175000017500000000010400000000000023714 0ustar00zuulzuul00000000000000**** LLDP **** .. automodule:: os_ken.lib.packet.lldp :members: ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/library_packet_ref/packet_mpls.rst0000664000175000017500000000010400000000000023734 0ustar00zuulzuul00000000000000**** MPLS **** .. automodule:: os_ken.lib.packet.mpls :members: ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/library_packet_ref/packet_openflow.rst0000664000175000017500000000012400000000000024614 0ustar00zuulzuul00000000000000******** OpenFlow ******** .. automodule:: os_ken.lib.packet.openflow :members: ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/library_packet_ref/packet_ospf.rst0000664000175000017500000000010400000000000023730 0ustar00zuulzuul00000000000000**** OSPF **** .. automodule:: os_ken.lib.packet.ospf :members: ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/library_packet_ref/packet_pbb.rst0000664000175000017500000000010000000000000023520 0ustar00zuulzuul00000000000000*** PBB *** .. automodule:: os_ken.lib.packet.pbb :members: ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/library_packet_ref/packet_sctp.rst0000664000175000017500000000010400000000000023732 0ustar00zuulzuul00000000000000**** SCTP **** .. automodule:: os_ken.lib.packet.sctp :members: ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/library_packet_ref/packet_slow.rst0000664000175000017500000000010400000000000023745 0ustar00zuulzuul00000000000000**** Slow **** .. automodule:: os_ken.lib.packet.slow :members: ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/library_packet_ref/packet_tcp.rst0000664000175000017500000000010000000000000023543 0ustar00zuulzuul00000000000000*** TCP *** .. automodule:: os_ken.lib.packet.tcp :members: ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/library_packet_ref/packet_udp.rst0000664000175000017500000000010000000000000023545 0ustar00zuulzuul00000000000000*** UDP *** .. automodule:: os_ken.lib.packet.udp :members: ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/library_packet_ref/packet_vlan.rst0000664000175000017500000000010400000000000023721 0ustar00zuulzuul00000000000000**** VLAN **** .. automodule:: os_ken.lib.packet.vlan :members: ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/library_packet_ref/packet_vrrp.rst0000664000175000017500000000010400000000000023752 0ustar00zuulzuul00000000000000**** VRRP **** .. automodule:: os_ken.lib.packet.vrrp :members: ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/library_packet_ref/packet_vxlan.rst0000664000175000017500000000011000000000000024106 0ustar00zuulzuul00000000000000***** VXLAN ***** .. automodule:: os_ken.lib.packet.vxlan :members: ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/library_packet_ref/packet_zebra.rst0000664000175000017500000000011000000000000024061 0ustar00zuulzuul00000000000000***** Zebra ***** .. automodule:: os_ken.lib.packet.zebra :members: ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/library_packet_ref.rst0000664000175000017500000000073500000000000021444 0ustar00zuulzuul00000000000000**************************** Packet library API Reference **************************** Packet class ============ .. automodule:: os_ken.lib.packet.packet :members: Stream Parser class =================== .. automodule:: os_ken.lib.packet.stream_parser :members: List of the sub-classes: - :py:mod:`os_ken.lib.packet.bgp.StreamParser` Protocol Header classes ======================= .. toctree:: :glob: library_packet_ref/packet_base library_packet_ref/*././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/library_pcap.rst0000664000175000017500000000114100000000000020254 0ustar00zuulzuul00000000000000***************** PCAP file library ***************** Introduction ============ OS-Ken PCAP file library helps you to read/write PCAP file which file format are described in `The Wireshark Wiki`_. .. _The Wireshark Wiki: https://wiki.wireshark.org/Development/LibpcapFileFormat Reading PCAP file ================= For loading the packet data containing in PCAP files, you can use pcaplib.Reader. .. autoclass:: os_ken.lib.pcaplib.Reader Writing PCAP file ================= For dumping the packet data which your OSKenApp received, you can use pcaplib.Writer. .. autoclass:: os_ken.lib.pcaplib.Writer ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.0621028 os-ken-2.10.0/doc/source/man/0000775000175000017500000000000000000000000015631 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/man/osken.rst0000664000175000017500000000274400000000000017511 0ustar00zuulzuul00000000000000:orphan: os_ken manual page ================== Synopsis -------- **osken** [-h] [--config-dir DIR] [--config-file PATH] [--version] [subcommand] ... Description ----------- :program:`os_ken` is the executable for OS-Ken applications. os_ken loads a sub-module corresponding to the sub-command and run it. 'run' sub-command is an equivalent to osken-manager. OS-Ken is a component-based software defined networking framework. OS-Ken provides software components with well defined API that make it easy for developers to create new network management and control applications. OS-Ken supports various protocols for managing network devices, such as OpenFlow, Netconf, OF-config, etc. About OpenFlow, OS-Ken supports fully 1.0, 1.2, 1.3, 1.4 and Nicira Extensions. Options ------- subcommand [rpc-cli|run|of-config-cli] subcommand_args subcommand specific arguments -h, --help show this help message and exit --config-dir DIR Path to a config directory to pull \*.conf files from. This file set is sorted, so as to provide a predictable parse order if individual options are over-ridden. The set is parsed after the file(s) specified via previous --config-file, arguments hence over-ridden options in the directory take precedence. --config-file PATH Path to a config file to use. Multiple config files can be specified, with values in later files taking precedence. The default files used are: None --version show program's version number and exit ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/man/osken_manager.rst0000664000175000017500000001154200000000000021177 0ustar00zuulzuul00000000000000:orphan: osken-manager manual page ========================== Synopsis -------- **osken-manager** [-h] [--app-lists APP_LISTS] [--ca-certs CA_CERTS] [--config-dir DIR] [--config-file PATH] [--ctl-cert CTL_CERT] [--ctl-privkey CTL_PRIVKEY] [--default-log-level DEFAULT_LOG_LEVEL] [--explicit-drop] [--install-lldp-flow] [--log-config-file LOG_CONFIG_FILE] [--log-dir LOG_DIR] [--log-file LOG_FILE] [--log-file-mode LOG_FILE_MODE] [--neutron-admin-auth-url NEUTRON_ADMIN_AUTH_URL] [--neutron-admin-password NEUTRON_ADMIN_PASSWORD] [--neutron-admin-tenant-name NEUTRON_ADMIN_TENANT_NAME] [--neutron-admin-username NEUTRON_ADMIN_USERNAME] [--neutron-auth-strategy NEUTRON_AUTH_STRATEGY] [--neutron-controller-addr NEUTRON_CONTROLLER_ADDR] [--neutron-url NEUTRON_URL] [--neutron-url-timeout NEUTRON_URL_TIMEOUT] [--noexplicit-drop] [--noinstall-lldp-flow] [--noobserve-links] [--nouse-stderr] [--nouse-syslog] [--noverbose] [--observe-links] [--ofp-listen-host OFP_LISTEN_HOST] [--ofp-ssl-listen-port OFP_SSL_LISTEN_PORT] [--ofp-tcp-listen-port OFP_TCP_LISTEN_PORT] [--use-stderr] [--use-syslog] [--verbose] [--version] [--wsapi-host WSAPI_HOST] [--wsapi-port WSAPI_PORT] [--test-switch-dir TEST-SWITCH_DIR] [--test-switch-target TEST-SWITCH_TARGET] [--test-switch-tester TEST-SWITCH_TESTER] [app [app ...]] Description ----------- :program:`osken-manager` is the executable for OS-Ken applications. osken-manager loads OS-Ken applications and run it. OS-Ken is a component-based software defined networking framework. OS-Ken provides software components with well defined API that make it easy for developers to create new network management and control applications. OS-Ken supports various protocols for managing network devices, such as OpenFlow, Netconf, OF-config, etc. About OpenFlow, OS-Ken supports fully 1.0, 1.2, 1.3, 1.4 and Nicira Extensions. Options ------- app application module name to run -h, --help show this help message and exit --app-lists APP_LISTS application module name to run --ca-certs CA_CERTS CA certificates --config-dir DIR Path to a config directory to pull \*.conf files from. This file set is sorted, so as to provide a predictable parse order if individual options are over-ridden. The set is parsed after the file(s) specified via previous --config-file, arguments hence over-ridden options in the directory take precedence. --config-file PATH Path to a config file to use. Multiple config files can be specified, with values in later files taking precedence. The default files used are: None --ctl-cert CTL_CERT controller certificate --ctl-privkey CTL_PRIVKEY controller private key --default-log-level DEFAULT_LOG_LEVEL default log level --explicit-drop link discovery: explicitly drop lldp packet in --install-lldp-flow link discovery: explicitly install flow entry to send lldp packet to controller --log-config-file LOG_CONFIG_FILE Path to a logging config file to use --log-dir LOG_DIR log file directory --log-file LOG_FILE log file name --log-file-mode LOG_FILE_MODE default log file permission --neutron-admin-auth-url NEUTRON_ADMIN_AUTH_URL auth url for connecting to neutron in admin context --neutron-admin-password NEUTRON_ADMIN_PASSWORD password for connecting to neutron in admin context --neutron-admin-tenant-name NEUTRON_ADMIN_TENANT_NAME tenant name for connecting to neutron in admin context --neutron-admin-username NEUTRON_ADMIN_USERNAME username for connecting to neutron in admin context --neutron-auth-strategy NEUTRON_AUTH_STRATEGY auth strategy for connecting to neutron in admincontext --neutron-controller-addr NEUTRON_CONTROLLER_ADDR openflow method:address:port to set controller ofovs bridge --neutron-url NEUTRON_URL URL for connecting to neutron --neutron-url-timeout NEUTRON_URL_TIMEOUT timeout value for connecting to neutron in seconds --noexplicit-drop The inverse of --explicit-drop --noinstall-lldp-flow The inverse of --install-lldp-flow --noobserve-links The inverse of --observe-links --nouse-stderr The inverse of --use-stderr --nouse-syslog The inverse of --use-syslog --noverbose The inverse of --verbose --observe-links observe link discovery events. --ofp-listen-host OFP_LISTEN_HOST openflow listen host --ofp-ssl-listen-port OFP_SSL_LISTEN_PORT openflow ssl listen port --ofp-tcp-listen-port OFP_TCP_LISTEN_PORT openflow tcp listen port --use-stderr log to standard error --use-syslog output to syslog --verbose show debug output --version show program's version number and exit --wsapi-host WSAPI_HOST webapp listen host --wsapi-port WSAPI_PORT webapp listen port --test-switch-dir TEST-SWITCH_DIR test files directory --test-switch-target TEST-SWITCH_TARGET target sw dp-id --test-switch-tester TEST-SWITCH_TESTER tester sw dp-id ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/nicira_ext_ref.rst0000664000175000017500000000404000000000000020567 0ustar00zuulzuul00000000000000*************************** Nicira Extension Structures *************************** .. _nx_actions_structures: Nicira Extension Actions Structures =================================== The followings shows the supported NXAction classes only in OpenFlow1.0 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. py:currentmodule:: os_ken.ofproto.ofproto_v1_0_parser .. autoclass:: NXActionSetQueue .. autoclass:: NXActionDecTtl .. autoclass:: NXActionPushMpls .. autoclass:: NXActionPopMpls .. autoclass:: NXActionSetMplsTtl .. autoclass:: NXActionDecMplsTtl .. autoclass:: NXActionSetMplsLabel .. autoclass:: NXActionSetMplsTc The followings shows the supported NXAction classes in OpenFlow1.0 or later ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. py:currentmodule:: os_ken.ofproto.ofproto_v1_3_parser .. autoclass:: NXActionPopQueue .. autoclass:: NXActionRegLoad .. autoclass:: NXActionRegLoad2 .. autoclass:: NXActionNote .. autoclass:: NXActionSetTunnel .. autoclass:: NXActionSetTunnel64 .. autoclass:: NXActionRegMove .. autoclass:: NXActionResubmit .. autoclass:: NXActionResubmitTable .. autoclass:: NXActionOutputReg .. autoclass:: NXActionOutputReg2 .. autoclass:: NXActionLearn .. autoclass:: NXActionExit .. autoclass:: NXActionController .. autoclass:: NXActionController2 .. autoclass:: NXActionDecTtlCntIds .. autoclass:: NXActionStackPush .. autoclass:: NXActionStackPop .. autoclass:: NXActionSample .. autoclass:: NXActionSample2 .. autoclass:: NXActionFinTimeout .. autoclass:: NXActionConjunction .. autoclass:: NXActionMultipath .. autoclass:: NXActionBundle .. autoclass:: NXActionBundleLoad .. autoclass:: NXActionCT .. autoclass:: NXActionNAT .. autoclass:: NXActionOutputTrunc .. autoclass:: NXActionDecNshTtl .. autoclass:: NXFlowSpecMatch .. autoclass:: NXFlowSpecLoad .. autoclass:: NXFlowSpecOutput .. autofunction:: os_ken.ofproto.nicira_ext.ofs_nbits .. _nx_match_structures: Nicira Extended Match Structures ================================ .. automodule:: os_ken.ofproto.nicira_ext ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/ofproto_base.rst0000664000175000017500000000221400000000000020271 0ustar00zuulzuul00000000000000************************************************** OpenFlow version independent classes and functions ************************************************** .. py:currentmodule:: os_ken.ofproto.ofproto_parser Base class for OpenFlow messages -------------------------------- .. XXX .. the descrption of _TYPE is inlined from os_ken/lib/stringify.py. .. this is a work around for a sphinx bug. .. https://bitbucket.org/birkenfeld/sphinx/issue/741/autodoc-inherited-members-wont-work-for .. autoclass:: MsgBase :members: to_jsondict, from_jsondict .. attribute:: _TYPE _TYPE class attribute is used to annotate types of attributes. This type information is used to find an appropriate conversion for a JSON style dictionary. Currently the following types are implemented. ===== ========== Type Descrption ===== ========== ascii US-ASCII utf-8 UTF-8 ===== ========== Example:: _TYPE = { 'ascii': [ 'hw_addr', ], 'utf-8': [ 'name', ] } Functions --------- .. autofunction:: ofp_msg_from_jsondict ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/ofproto_ref.rst0000664000175000017500000000043500000000000020136 0ustar00zuulzuul00000000000000.. _ofproto_ref: ******************************* OpenFlow protocol API Reference ******************************* .. toctree:: :maxdepth: 3 ofproto_base.rst ofproto_v1_0_ref.rst ofproto_v1_2_ref.rst ofproto_v1_3_ref.rst ofproto_v1_4_ref.rst ofproto_v1_5_ref.rst ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/ofproto_v1_0_ref.rst0000664000175000017500000001556600000000000020776 0ustar00zuulzuul00000000000000************************************* OpenFlow v1.0 Messages and Structures ************************************* .. py:currentmodule:: os_ken.ofproto.ofproto_v1_0_parser Controller-to-Switch Messages ============================= Handshake --------- .. autoclass:: OFPFeaturesRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of10/1-5-features_request.packet.json .. autoclass:: OFPSwitchFeatures JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of10/1-6-ofp_switch_features.packet.json Switch Configuration -------------------- .. autoclass:: OFPSetConfig .. JSON Example: .. .. .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of10/1-7-ofp_set_config.packet.json .. autoclass:: OFPGetConfigRequest .. JSON Example: .. .. .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of10/1-8-ofp_get_config_request.packet.json .. autoclass:: OFPGetConfigReply .. JSON Example: .. .. .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of10/1-9-ofp_get_config_reply.packet.json Modify State Messages --------------------- .. autoclass:: OFPFlowMod JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of10/1-2-ofp_flow_mod.packet.json .. .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of10/1-3-ofp_flow_mod.packet.json .. autoclass:: OFPPortMod .. JSON Example: .. .. .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of10/1-22-ofp_port_mod.packet.json Queue Configuration Messages ---------------------------- .. autoclass:: OFPQueueGetConfigRequest .. JSON Example: .. .. .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of10/1-35-ofp_queue_get_config_request.packet.json .. autoclass:: OFPQueueGetConfigReply .. JSON Example: .. .. .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of10/1-36-ofp_queue_get_config_reply.packet.json Read State Messages ------------------- .. autoclass:: OFPDescStatsRequest .. JSON Example: .. .. .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of10/1-24-ofp_desc_stats_request.packet.json .. autoclass:: OFPDescStatsReply .. JSON Example: .. .. .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of10/1-0-ofp_desc_stats_reply.packet.json .. autoclass:: OFPFlowStatsRequest .. JSON Example: .. .. .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of10/1-11-ofp_flow_stats_request.packet.json .. autoclass:: OFPFlowStatsReply .. JSON Example: .. .. .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of10/1-12-ofp_flow_stats_reply.packet.json .. autoclass:: OFPAggregateStatsRequest .. JSON Example: .. .. .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of10/1-25-ofp_aggregate_stats_request.packet.json .. autoclass:: OFPAggregateStatsReply .. JSON Example: .. .. .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of10/1-26-ofp_aggregate_stats_reply.packet.json .. autoclass:: OFPTableStatsRequest .. JSON Example: .. .. .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of10/1-27-ofp_table_stats_request.packet.json .. autoclass:: OFPTableStatsReply .. XXX commented out because it's too long .. JSON Example: .. .. .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of10/1-28-ofp_table_stats_reply.packet.json .. autoclass:: OFPPortStatsRequest .. JSON Example: .. .. .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of10/1-29-ofp_port_stats_request.packet.json .. autoclass:: OFPPortStatsReply .. JSON Example: .. .. .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of10/1-30-ofp_port_stats_reply.packet.json .. autoclass:: OFPQueueStatsRequest .. JSON Example: .. .. .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of10/1-37-ofp_queue_stats_request.packet.json .. autoclass:: OFPQueueStatsReply .. JSON Example: .. .. .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of10/1-38-ofp_queue_stats_reply.packet.json .. autoclass:: OFPVendorStatsRequest .. autoclass:: OFPVendorStatsReply Send Packet Message ------------------- .. autoclass:: OFPPacketOut JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of10/1-1-ofp_packet_out.packet.json Barrier Message --------------- .. autoclass:: OFPBarrierRequest .. JSON Example: .. .. .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of10/1-17-ofp_barrier_request.packet.json .. autoclass:: OFPBarrierReply .. JSON Example: .. .. .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of10/1-18-ofp_barrier_reply.packet.json Asynchronous Messages ===================== Packet-In Message ----------------- .. autoclass:: OFPPacketIn JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of10/1-4-ofp_packet_in.packet.json Flow Removed Message -------------------- .. autoclass:: OFPFlowRemoved .. JSON Example: .. .. .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of10/1-40-ofp_flow_removed.packet.json Port Status Message ------------------- .. autoclass:: OFPPortStatus .. JSON Example: .. .. .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of10/1-39-ofp_port_status.packet.json Error Message ------------- .. autoclass:: OFPErrorMsg .. JSON Example: .. .. .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of10/1-15-ofp_error_msg.packet.json .. .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of10/1-41-ofp_error_msg_vendor.packet.json Symmetric Messages ================== Hello ----- .. autoclass:: OFPHello .. JSON Example: .. .. .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of10/1-10-ofp_hello.packet.json Echo Request ------------ .. autoclass:: OFPEchoRequest .. JSON Example: .. .. .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of10/1-13-ofp_echo_request.packet.json Echo Reply ---------- .. autoclass:: OFPEchoReply .. JSON Example: .. .. .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of10/1-14-ofp_echo_reply.packet.json Vendor ------------ .. autoclass:: OFPVendor .. JSON Example: .. .. .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of10/1-16-ofp_vendor.packet.json Port Structures =============== .. autoclass:: OFPPhyPort Flow Match Structure ==================== .. autoclass:: OFPMatch Action Structures ================= .. autoclass:: OFPActionHeader .. autoclass:: OFPAction .. autoclass:: OFPActionOutput .. autoclass:: OFPActionVlanVid .. autoclass:: OFPActionVlanPcp .. autoclass:: OFPActionStripVlan .. autoclass:: OFPActionDlAddr .. autoclass:: OFPActionSetDlSrc .. autoclass:: OFPActionSetDlDst .. autoclass:: OFPActionNwAddr .. autoclass:: OFPActionSetNwSrc .. autoclass:: OFPActionSetNwDst .. autoclass:: OFPActionSetNwTos .. autoclass:: OFPActionTpPort .. autoclass:: OFPActionSetTpSrc .. autoclass:: OFPActionSetTpDst .. autoclass:: OFPActionEnqueue .. autoclass:: OFPActionVendor ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/ofproto_v1_2_ref.rst0000664000175000017500000002022000000000000020757 0ustar00zuulzuul00000000000000************************************* OpenFlow v1.2 Messages and Structures ************************************* .. py:currentmodule:: os_ken.ofproto.ofproto_v1_2_parser Controller-to-Switch Messages ============================= Handshake --------- .. autoclass:: OFPFeaturesRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of12/3-5-ofp_features_request.packet.json .. autoclass:: OFPSwitchFeatures JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of12/3-6-ofp_features_reply.packet.json Switch Configuration -------------------- .. autoclass:: OFPSetConfig JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of12/3-7-ofp_set_config.packet.json .. autoclass:: OFPGetConfigRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of12/3-8-ofp_get_config_request.packet.json .. autoclass:: OFPGetConfigReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of12/3-9-ofp_get_config_reply.packet.json Flow Table Configuration ------------------------ .. autoclass:: OFPTableMod JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of12/3-23-ofp_table_mod.packet.json Modify State Messages --------------------- .. autoclass:: OFPFlowMod JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of12/3-2-ofp_flow_mod.packet.json .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of12/3-3-ofp_flow_mod.packet.json .. autoclass:: OFPGroupMod JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of12/3-21-ofp_group_mod.packet.json .. autoclass:: OFPPortMod JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of12/3-22-ofp_port_mod.packet.json Read State Messages ------------------- .. autoclass:: OFPDescStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of12/3-24-ofp_desc_stats_request.packet.json .. autoclass:: OFPDescStats JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of12/3-0-ofp_desc_stats_reply.packet.json .. autoclass:: OFPFlowStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of12/3-11-ofp_flow_stats_request.packet.json .. autoclass:: OFPFlowStats JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of12/3-12-ofp_flow_stats_reply.packet.json .. autoclass:: OFPAggregateStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of12/3-25-ofp_aggregate_stats_request.packet.json .. autoclass:: OFPAggregateStatsReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of12/3-26-ofp_aggregate_stats_reply.packet.json .. autoclass:: OFPTableStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of12/3-27-ofp_table_stats_request.packet.json .. autoclass:: OFPTableStats .. XXX commented out because it's too long .. JSON Example: .. .. .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of12/3-28-ofp_table_stats_reply.packet.json .. autoclass:: OFPPortStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of12/3-29-ofp_port_stats_request.packet.json .. autoclass:: OFPPortStats JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of12/3-30-ofp_port_stats_reply.packet.json .. autoclass:: OFPQueueStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of12/3-37-ofp_queue_stats_request.packet.json .. autoclass:: OFPQueueStats JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of12/3-38-ofp_queue_stats_reply.packet.json .. autoclass:: OFPGroupStatsRequest .. autoclass:: OFPGroupStats .. autoclass:: OFPGroupDescStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of12/3-33-ofp_group_desc_stats_request.packet.json .. autoclass:: OFPGroupDescStats JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of12/3-34-ofp_group_desc_stats_reply.packet.json .. autoclass:: OFPGroupFeaturesStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of12/3-31-ofp_group_features_stats_request.packet.json .. autoclass:: OFPGroupFeaturesStats JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of12/3-32-ofp_group_features_stats_reply.packet.json Queue Configuration Messages ---------------------------- .. autoclass:: OFPQueueGetConfigRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of12/3-35-ofp_queue_get_config_request.packet.json .. autoclass:: OFPQueueGetConfigReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of12/3-36-ofp_queue_get_config_reply.packet.json Packet-Out Message ------------------ .. autoclass:: OFPPacketOut JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of12/3-1-ofp_packet_out.packet.json Barrier Message --------------- .. autoclass:: OFPBarrierRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of12/3-17-ofp_barrier_request.packet.json .. autoclass:: OFPBarrierReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of12/3-18-ofp_barrier_reply.packet.json Role Request Message -------------------- .. autoclass:: OFPRoleRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of12/3-19-ofp_role_request.packet.json .. autoclass:: OFPRoleReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of12/3-20-ofp_role_reply.packet.json Asynchronous Messages ===================== Packet-In Message ----------------- .. autoclass:: OFPPacketIn JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of12/3-4-ofp_packet_in.packet.json Flow Removed Message -------------------- .. autoclass:: OFPFlowRemoved JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of12/3-40-ofp_flow_removed.packet.json Port Status Message ------------------- .. autoclass:: OFPPortStatus JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of12/3-39-ofp_port_status.packet.json Error Message ------------- .. autoclass:: OFPErrorMsg JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of12/3-15-ofp_error_msg.packet.json .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of12/3-41-ofp_error_msg_experimenter.packet.json Symmetric Messages ================== Hello ----- .. autoclass:: OFPHello JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of12/3-10-ofp_hello.packet.json Echo Request ------------ .. autoclass:: OFPEchoRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of12/3-13-ofp_echo_request.packet.json Echo Reply ---------- .. autoclass:: OFPEchoReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of12/3-14-ofp_echo_reply.packet.json Experimenter ------------ .. autoclass:: OFPExperimenter JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of12/3-16-ofp_experimenter.packet.json Port Structures =============== .. autoclass:: OFPPort Flow Match Structure ==================== .. autoclass:: OFPMatch Flow Instruction Structures =========================== .. autoclass:: OFPInstructionGotoTable .. autoclass:: OFPInstructionWriteMetadata .. autoclass:: OFPInstructionActions Action Structures ================= .. autoclass:: OFPActionOutput .. autoclass:: OFPActionGroup .. autoclass:: OFPActionSetQueue .. autoclass:: OFPActionSetMplsTtl .. autoclass:: OFPActionDecMplsTtl .. autoclass:: OFPActionSetNwTtl .. autoclass:: OFPActionDecNwTtl .. autoclass:: OFPActionCopyTtlOut .. autoclass:: OFPActionCopyTtlIn .. autoclass:: OFPActionPushVlan .. autoclass:: OFPActionPushMpls .. autoclass:: OFPActionPopVlan .. autoclass:: OFPActionPopMpls .. autoclass:: OFPActionSetField .. autoclass:: OFPActionExperimenter ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/ofproto_v1_3_ref.rst0000664000175000017500000002453600000000000020776 0ustar00zuulzuul00000000000000************************************* OpenFlow v1.3 Messages and Structures ************************************* .. py:currentmodule:: os_ken.ofproto.ofproto_v1_3_parser Controller-to-Switch Messages ============================= Handshake --------- .. autoclass:: OFPFeaturesRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-5-ofp_features_request.packet.json .. autoclass:: OFPSwitchFeatures JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-6-ofp_features_reply.packet.json Switch Configuration -------------------- .. autoclass:: OFPSetConfig JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-7-ofp_set_config.packet.json .. autoclass:: OFPGetConfigRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-8-ofp_get_config_request.packet.json .. autoclass:: OFPGetConfigReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-9-ofp_get_config_reply.packet.json Flow Table Configuration ------------------------ .. autoclass:: OFPTableMod JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-23-ofp_table_mod.packet.json Modify State Messages --------------------- .. autoclass:: OFPFlowMod JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-2-ofp_flow_mod.packet.json .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-3-ofp_flow_mod.packet.json .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-46-ofp_flow_mod.packet.json .. autoclass:: OFPGroupMod JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-21-ofp_group_mod.packet.json .. autoclass:: OFPPortMod JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-22-ofp_port_mod.packet.json .. autoclass:: OFPMeterMod JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-45-ofp_meter_mod.packet.json Multipart Messages ------------------ .. autoclass:: OFPDescStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-24-ofp_desc_request.packet.json .. autoclass:: OFPDescStatsReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-0-ofp_desc_reply.packet.json .. autoclass:: OFPFlowStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-11-ofp_flow_stats_request.packet.json .. autoclass:: OFPFlowStatsReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-12-ofp_flow_stats_reply.packet.json .. autoclass:: OFPAggregateStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-25-ofp_aggregate_stats_request.packet.json .. autoclass:: OFPAggregateStatsReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-26-ofp_aggregate_stats_reply.packet.json .. autoclass:: OFPTableStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-27-ofp_table_stats_request.packet.json .. autoclass:: OFPTableStatsReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-28-ofp_table_stats_reply.packet.json .. autoclass:: OFPPortStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-29-ofp_port_stats_request.packet.json .. autoclass:: OFPPortStatsReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-30-ofp_port_stats_reply.packet.json .. autoclass:: OFPPortDescStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-53-ofp_port_desc_request.packet.json .. autoclass:: OFPPortDescStatsReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-54-ofp_port_desc_reply.packet.json .. autoclass:: OFPQueueStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-37-ofp_queue_stats_request.packet.json .. autoclass:: OFPQueueStatsReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-38-ofp_queue_stats_reply.packet.json .. autoclass:: OFPGroupStatsRequest .. autoclass:: OFPGroupStatsReply .. autoclass:: OFPGroupDescStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-33-ofp_group_desc_request.packet.json .. autoclass:: OFPGroupDescStatsReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-34-ofp_group_desc_reply.packet.json .. autoclass:: OFPGroupFeaturesStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-31-ofp_group_features_request.packet.json .. autoclass:: OFPGroupFeaturesStatsReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-32-ofp_group_features_reply.packet.json .. autoclass:: OFPMeterStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-49-ofp_meter_stats_request.packet.json .. autoclass:: OFPMeterStatsReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-50-ofp_meter_stats_reply.packet.json .. autoclass:: OFPMeterConfigStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-47-ofp_meter_config_request.packet.json .. autoclass:: OFPMeterConfigStatsReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-48-ofp_meter_config_reply.packet.json .. autoclass:: OFPMeterFeaturesStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-51-ofp_meter_features_request.packet.json .. autoclass:: OFPMeterFeaturesStatsReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-52-ofp_meter_features_reply.packet.json .. autoclass:: OFPTableFeaturesStatsRequest .. autoclass:: OFPTableFeaturesStatsReply JSON Example: See an example in: ``os_ken/tests/unit/ofproto/json/of13/4-56-ofp_table_features_reply.packet.json`` Queue Configuration Messages ---------------------------- .. autoclass:: OFPQueueGetConfigRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-35-ofp_queue_get_config_request.packet.json .. autoclass:: OFPQueueGetConfigReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-36-ofp_queue_get_config_reply.packet.json Packet-Out Message ------------------ .. autoclass:: OFPPacketOut JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-1-ofp_packet_out.packet.json Barrier Message --------------- .. autoclass:: OFPBarrierRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-17-ofp_barrier_request.packet.json .. autoclass:: OFPBarrierReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-18-ofp_barrier_reply.packet.json Role Request Message -------------------- .. autoclass:: OFPRoleRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-19-ofp_role_request.packet.json .. autoclass:: OFPRoleReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-20-ofp_role_reply.packet.json Set Asynchronous Configuration Message -------------------------------------- .. autoclass:: OFPSetAsync JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-44-ofp_set_async.packet.json .. autoclass:: OFPGetAsyncRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-42-ofp_get_async_request.packet.json .. autoclass:: OFPGetAsyncReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-43-ofp_get_async_reply.packet.json Asynchronous Messages ===================== Packet-In Message ----------------- .. autoclass:: OFPPacketIn JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-4-ofp_packet_in.packet.json Flow Removed Message -------------------- .. autoclass:: OFPFlowRemoved JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-40-ofp_flow_removed.packet.json Port Status Message ------------------- .. autoclass:: OFPPortStatus JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-39-ofp_port_status.packet.json Error Message ------------- .. autoclass:: OFPErrorMsg JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-15-ofp_error_msg.packet.json Symmetric Messages ================== Hello ----- .. autoclass:: OFPHello JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-10-ofp_hello.packet.json .. autoclass:: OFPHelloElemVersionBitmap Echo Request ------------ .. autoclass:: OFPEchoRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-13-ofp_echo_request.packet.json Echo Reply ---------- .. autoclass:: OFPEchoReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-14-ofp_echo_reply.packet.json Experimenter ------------ .. autoclass:: OFPExperimenter JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of13/4-16-ofp_experimenter.packet.json Port Structures =============== .. autoclass:: OFPPort Flow Match Structure ==================== .. autoclass:: OFPMatch Flow Instruction Structures =========================== .. autoclass:: OFPInstructionGotoTable .. autoclass:: OFPInstructionWriteMetadata .. autoclass:: OFPInstructionActions .. autoclass:: OFPInstructionMeter Action Structures ================= .. autoclass:: OFPActionOutput .. autoclass:: OFPActionGroup .. autoclass:: OFPActionSetQueue .. autoclass:: OFPActionSetMplsTtl .. autoclass:: OFPActionDecMplsTtl .. autoclass:: OFPActionSetNwTtl .. autoclass:: OFPActionDecNwTtl .. autoclass:: OFPActionCopyTtlOut .. autoclass:: OFPActionCopyTtlIn .. autoclass:: OFPActionPushVlan .. autoclass:: OFPActionPushMpls .. autoclass:: OFPActionPopVlan .. autoclass:: OFPActionPopMpls .. autoclass:: OFPActionSetField .. autoclass:: OFPActionExperimenter ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/ofproto_v1_4_ref.rst0000664000175000017500000003141500000000000020771 0ustar00zuulzuul00000000000000************************************* OpenFlow v1.4 Messages and Structures ************************************* .. py:currentmodule:: os_ken.ofproto.ofproto_v1_4_parser Controller-to-Switch Messages ============================= Handshake --------- .. autoclass:: OFPFeaturesRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-5-ofp_features_request.packet.json .. autoclass:: OFPSwitchFeatures JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-6-ofp_features_reply.packet.json Switch Configuration -------------------- .. autoclass:: OFPSetConfig JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-7-ofp_set_config.packet.json .. autoclass:: OFPGetConfigRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-8-ofp_get_config_request.packet.json .. autoclass:: OFPGetConfigReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-9-ofp_get_config_reply.packet.json Modify State Messages --------------------- .. autoclass:: OFPTableMod JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-23-ofp_table_mod.packet.json .. autoclass:: OFPFlowMod JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-2-ofp_flow_mod.packet.json .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-3-ofp_flow_mod.packet.json .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-44-ofp_flow_mod.packet.json .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-58-ofp_flow_mod.packet.json .. autoclass:: OFPGroupMod JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-21-ofp_group_mod.packet.json .. autoclass:: OFPPortMod JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-22-ofp_port_mod.packet.json .. autoclass:: OFPMeterMod JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-43-ofp_meter_mod.packet.json Multipart Messages ------------------ .. autoclass:: OFPDescStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-24-ofp_desc_request.packet.json .. autoclass:: OFPDescStatsReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-0-ofp_desc_reply.packet.json .. autoclass:: OFPFlowStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-11-ofp_flow_stats_request.packet.json .. autoclass:: OFPFlowStatsReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-12-ofp_flow_stats_reply.packet.json .. autoclass:: OFPAggregateStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-25-ofp_aggregate_stats_request.packet.json .. autoclass:: OFPAggregateStatsReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-26-ofp_aggregate_stats_reply.packet.json .. autoclass:: OFPTableStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-27-ofp_table_stats_request.packet.json .. autoclass:: OFPTableStatsReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-28-ofp_table_stats_reply.packet.json .. autoclass:: OFPTableDescStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-61-ofp_table_desc_request.packet.json .. autoclass:: OFPTableDescStatsReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-62-ofp_table_desc_reply.packet.json .. autoclass:: OFPTableFeaturesStatsRequest JSON Example: See an example in: ``os_ken/tests/unit/ofproto/json/of14/5-53-ofp_table_features_request.packet.json`` .. autoclass:: OFPTableFeaturesStatsReply JSON Example: See an example in: ``os_ken/tests/unit/ofproto/json/of14/5-54-ofp_table_features_reply.packet.json`` .. autoclass:: OFPPortStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-29-ofp_port_stats_request.packet.json .. autoclass:: OFPPortStatsReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-30-ofp_port_stats_reply.packet.json .. autoclass:: OFPPortDescStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-51-ofp_port_desc_request.packet.json .. autoclass:: OFPPortDescStatsReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-52-ofp_port_desc_reply.packet.json .. autoclass:: OFPQueueStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-35-ofp_queue_stats_request.packet.json .. autoclass:: OFPQueueStatsReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-36-ofp_queue_stats_reply.packet.json .. autoclass:: OFPQueueDescStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-63-ofp_queue_desc_request.packet.json .. autoclass:: OFPQueueDescStatsReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-64-ofp_queue_desc_reply.packet.json .. autoclass:: OFPGroupStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-55-ofp_group_stats_request.packet.json .. autoclass:: OFPGroupStatsReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-56-ofp_group_stats_reply.packet.json .. autoclass:: OFPGroupDescStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-33-ofp_group_desc_request.packet.json .. autoclass:: OFPGroupDescStatsReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-34-ofp_group_desc_reply.packet.json .. autoclass:: OFPGroupFeaturesStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-31-ofp_group_features_request.packet.json .. autoclass:: OFPGroupFeaturesStatsReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-32-ofp_group_features_reply.packet.json .. autoclass:: OFPMeterStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-47-ofp_meter_stats_request.packet.json .. autoclass:: OFPMeterStatsReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-48-ofp_meter_stats_reply.packet.json .. autoclass:: OFPMeterConfigStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-45-ofp_meter_config_request.packet.json .. autoclass:: OFPMeterConfigStatsReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-46-ofp_meter_config_reply.packet.json .. autoclass:: OFPMeterFeaturesStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-49-ofp_meter_features_request.packet.json .. autoclass:: OFPMeterFeaturesStatsReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-50-ofp_meter_features_reply.packet.json .. autoclass:: OFPFlowMonitorRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-66-ofp_flow_monitor_request.packet.json .. autoclass:: OFPFlowMonitorReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-67-ofp_flow_monitor_reply.packet.json .. autoclass:: OFPExperimenterStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-59-ofp_experimenter_request.packet.json .. autoclass:: OFPExperimenterStatsReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-60-ofp_experimenter_reply.packet.json Packet-Out Message ------------------ .. autoclass:: OFPPacketOut JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-1-ofp_packet_out.packet.json Barrier Message --------------- .. autoclass:: OFPBarrierRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-17-ofp_barrier_request.packet.json .. autoclass:: OFPBarrierReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-18-ofp_barrier_reply.packet.json Role Request Message -------------------- .. autoclass:: OFPRoleRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-19-ofp_role_request.packet.json .. autoclass:: OFPRoleReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-20-ofp_role_reply.packet.json Bundle Messages --------------- .. autoclass:: OFPBundleCtrlMsg JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-69-ofp_bundle_ctrl_msg.packet.json .. autoclass:: OFPBundleAddMsg JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-70-ofp_bundle_add_msg.packet.json Set Asynchronous Configuration Message -------------------------------------- .. autoclass:: OFPSetAsync JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-42-ofp_set_async.packet.json .. autoclass:: OFPGetAsyncRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-40-ofp_get_async_request.packet.json .. autoclass:: OFPGetAsyncReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-41-ofp_get_async_reply.packet.json Asynchronous Messages ===================== Packet-In Message ----------------- .. autoclass:: OFPPacketIn JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-4-ofp_packet_in.packet.json .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-57-ofp_packet_in.packet.json Flow Removed Message -------------------- .. autoclass:: OFPFlowRemoved JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-38-ofp_flow_removed.packet.json Port Status Message ------------------- .. autoclass:: OFPPortStatus JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-37-ofp_port_status.packet.json Controller Role Status Message ------------------------------ .. autoclass:: OFPRoleStatus JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-65-ofp_role_status.packet.json Table Status Message -------------------- .. autoclass:: OFPTableStatus JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-68-ofp_table_status.packet.json Request Forward Message ----------------------- .. autoclass:: OFPRequestForward JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-71-ofp_requestforward.packet.json Symmetric Messages ================== Hello ----- .. autoclass:: OFPHello JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-10-ofp_hello.packet.json .. autoclass:: OFPHelloElemVersionBitmap Echo Request ------------ .. autoclass:: OFPEchoRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-13-ofp_echo_request.packet.json Echo Reply ---------- .. autoclass:: OFPEchoReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-14-ofp_echo_reply.packet.json Error Message ------------- .. autoclass:: OFPErrorMsg JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-15-ofp_error_msg.packet.json Experimenter ------------ .. autoclass:: OFPExperimenter JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of14/5-16-ofp_experimenter.packet.json Port Structures =============== .. autoclass:: OFPPort Flow Match Structure ==================== .. autoclass:: OFPMatch Flow Instruction Structures =========================== .. autoclass:: OFPInstructionGotoTable .. autoclass:: OFPInstructionWriteMetadata .. autoclass:: OFPInstructionActions .. autoclass:: OFPInstructionMeter Action Structures ================= .. autoclass:: OFPActionOutput .. autoclass:: OFPActionCopyTtlOut .. autoclass:: OFPActionCopyTtlIn .. autoclass:: OFPActionSetMplsTtl .. autoclass:: OFPActionDecMplsTtl .. autoclass:: OFPActionPushVlan .. autoclass:: OFPActionPopVlan .. autoclass:: OFPActionPushMpls .. autoclass:: OFPActionPopMpls .. autoclass:: OFPActionSetQueue .. autoclass:: OFPActionGroup .. autoclass:: OFPActionSetNwTtl .. autoclass:: OFPActionDecNwTtl .. autoclass:: OFPActionSetField .. autoclass:: OFPActionPushPbb .. autoclass:: OFPActionPopPbb .. autoclass:: OFPActionExperimenter ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/ofproto_v1_5_ref.rst0000664000175000017500000003520100000000000020767 0ustar00zuulzuul00000000000000************************************* OpenFlow v1.5 Messages and Structures ************************************* .. py:currentmodule:: os_ken.ofproto.ofproto_v1_5_parser Controller-to-Switch Messages ============================= Handshake --------- .. autoclass:: OFPFeaturesRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-features_request.packet.json .. autoclass:: OFPSwitchFeatures JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-features_reply.packet.json Switch Configuration -------------------- .. autoclass:: OFPSetConfig JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-set_config.packet.json .. autoclass:: OFPGetConfigRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-get_config_request.packet.json .. autoclass:: OFPGetConfigReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-get_config_reply.packet.json Modify State Messages --------------------- .. autoclass:: OFPTableMod JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-table_mod.packet.json .. autoclass:: OFPFlowMod JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-flow_mod.packet.json .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-flow_mod_conjunction.packet.json .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-flow_mod_match_conj.packet.json .. autoclass:: OFPGroupMod JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-group_mod.packet.json .. autoclass:: OFPPortMod JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-port_mod.packet.json .. autoclass:: OFPMeterMod JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-meter_mod.packet.json Multipart Messages ------------------ .. autoclass:: OFPDescStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-desc_request.packet.json .. autoclass:: OFPDescStatsReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-desc_reply.packet.json .. autoclass:: OFPFlowDescStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-flow_desc_request.packet.json .. autoclass:: OFPFlowDescStatsReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-flow_desc_reply.packet.json .. autoclass:: OFPFlowStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-flow_stats_request.packet.json .. autoclass:: OFPFlowStatsReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-flow_stats_reply.packet.json .. autoclass:: OFPAggregateStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-aggregate_stats_request.packet.json .. autoclass:: OFPAggregateStatsReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-aggregate_stats_reply.packet.json .. autoclass:: OFPPortStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-port_stats_request.packet.json .. autoclass:: OFPPortStatsReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-port_stats_reply.packet.json .. autoclass:: OFPPortDescStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-port_desc_request.packet.json .. autoclass:: OFPPortDescStatsReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-port_desc_reply.packet.json .. autoclass:: OFPQueueStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-queue_stats_request.packet.json .. autoclass:: OFPQueueStatsReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-queue_stats_reply.packet.json .. autoclass:: OFPQueueDescStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-queue_desc_request.packet.json .. autoclass:: OFPQueueDescStatsReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-queue_desc_reply.packet.json .. autoclass:: OFPGroupStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-group_stats_request.packet.json .. autoclass:: OFPGroupStatsReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-group_stats_reply.packet.json .. autoclass:: OFPGroupDescStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-group_desc_request.packet.json .. autoclass:: OFPGroupDescStatsReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-group_desc_reply.packet.json .. autoclass:: OFPGroupFeaturesStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-group_features_request.packet.json .. autoclass:: OFPGroupFeaturesStatsReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-group_features_reply.packet.json .. autoclass:: OFPMeterStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-meter_stats_request.packet.json .. autoclass:: OFPMeterStatsReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-meter_stats_reply.packet.json .. autoclass:: OFPMeterDescStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-meter_desc_request.packet.json .. autoclass:: OFPMeterDescStatsReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-meter_desc_reply.packet.json .. autoclass:: OFPMeterFeaturesStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-meter_features_request.packet.json .. autoclass:: OFPMeterFeaturesStatsReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-meter_features_reply.packet.json .. autoclass:: OFPControllerStatusStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-controller_status_request.packet.json .. autoclass:: OFPControllerStatusStatsReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-controller_status_reply.packet.json .. autoclass:: OFPTableStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-table_stats_request.packet.json .. autoclass:: OFPTableStatsReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-table_stats_reply.packet.json .. autoclass:: OFPTableDescStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-table_desc_request.packet.json .. autoclass:: OFPTableDescStatsReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-table_desc_reply.packet.json .. autoclass:: OFPTableFeaturesStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-table_features_request.packet.json .. autoclass:: OFPTableFeaturesStatsReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-table_features_reply.packet.json .. autoclass:: OFPFlowMonitorRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-flow_monitor_request.packet.json .. autoclass:: OFPFlowMonitorReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-flow_monitor_reply.packet.json .. autoclass:: OFPBundleFeaturesStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-bundle_features_request.packet.json .. autoclass:: OFPBundleFeaturesStatsReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-bundle_features_reply.packet.json .. autoclass:: OFPExperimenterStatsRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-experimenter_request.packet.json .. autoclass:: OFPExperimenterStatsReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-experimenter_reply.packet.json Packet-Out Message ------------------ .. autoclass:: OFPPacketOut JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-packet_out.packet.json Barrier Message --------------- .. autoclass:: OFPBarrierRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-barrier_request.packet.json .. autoclass:: OFPBarrierReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-barrier_reply.packet.json Role Request Message -------------------- .. autoclass:: OFPRoleRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-role_request.packet.json .. autoclass:: OFPRoleReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-role_reply.packet.json Bundle Messages --------------- .. autoclass:: OFPBundleCtrlMsg JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-bundle_ctrl.packet.json .. autoclass:: OFPBundleAddMsg JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-bundle_add.packet.json Set Asynchronous Configuration Message -------------------------------------- .. autoclass:: OFPSetAsync JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-set_async.packet.json .. autoclass:: OFPGetAsyncRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-get_async_request.packet.json .. autoclass:: OFPGetAsyncReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-get_async_reply.packet.json Asynchronous Messages ===================== Packet-In Message ----------------- .. autoclass:: OFPPacketIn JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-packet_in.packet.json Flow Removed Message -------------------- .. autoclass:: OFPFlowRemoved JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-flow_removed.packet.json Port Status Message ------------------- .. autoclass:: OFPPortStatus JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-port_status.packet.json Controller Role Status Message ------------------------------ .. autoclass:: OFPRoleStatus JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-role_status.packet.json Table Status Message -------------------- .. autoclass:: OFPTableStatus JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-table_status.packet.json Request Forward Message ----------------------- .. autoclass:: OFPRequestForward JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-requestforward.packet.json Controller Status Message ------------------------- .. autoclass:: OFPControllerStatus JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-controller_status.packet.json Symmetric Messages ================== Hello ----- .. autoclass:: OFPHello JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-hello.packet.json .. autoclass:: OFPHelloElemVersionBitmap Echo Request ------------ .. autoclass:: OFPEchoRequest JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-echo_request.packet.json Echo Reply ---------- .. autoclass:: OFPEchoReply JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-echo_reply.packet.json Error Message ------------- .. autoclass:: OFPErrorMsg JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-error_msg.packet.json Experimenter ------------ .. autoclass:: OFPExperimenter JSON Example: .. literalinclude:: ../../os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-error_msg_experimenter.packet.json Port Structures =============== .. autoclass:: OFPPort Flow Match Structure ==================== .. autoclass:: OFPMatch Flow Stats Structures ===================== .. autoclass:: OFPStats Flow Instruction Structures =========================== .. autoclass:: OFPInstructionGotoTable .. autoclass:: OFPInstructionWriteMetadata .. autoclass:: OFPInstructionActions .. autoclass:: OFPInstructionStatTrigger Action Structures ================= .. autoclass:: OFPActionOutput .. autoclass:: OFPActionCopyTtlOut .. autoclass:: OFPActionCopyTtlIn .. autoclass:: OFPActionSetMplsTtl .. autoclass:: OFPActionDecMplsTtl .. autoclass:: OFPActionPushVlan .. autoclass:: OFPActionPopVlan .. autoclass:: OFPActionPushMpls .. autoclass:: OFPActionPopMpls .. autoclass:: OFPActionSetQueue .. autoclass:: OFPActionGroup .. autoclass:: OFPActionSetNwTtl .. autoclass:: OFPActionDecNwTtl .. autoclass:: OFPActionSetField .. autoclass:: OFPActionPushPbb .. autoclass:: OFPActionPopPbb .. autoclass:: OFPActionCopyField .. autoclass:: OFPActionMeter .. autoclass:: OFPActionExperimenter Controller Status Structure =========================== .. autoclass:: OFPControllerStatusStats ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/os_ken_app_api.rst0000664000175000017500000001400100000000000020553 0ustar00zuulzuul00000000000000********************** OS-Ken application API ********************** OS-Ken application programming model ==================================== Threads, events, and event queues --------------------------------- OS-Ken applications are single-threaded entities which implement various functionalities in OS-Ken. Events are messages between them. OS-Ken applications send asynchronous events to each other. Besides that, there are some OS-Ken-internal event sources which are not OS-Ken applications. One of the examples of such event sources is the OpenFlow controller. While an event can currently contain arbitrary python objects, it's discouraged to pass complex objects (eg. unpickleable objects) between OS-Ken applications. Each OS-Ken application has a receive queue for events. The queue is FIFO and preserves the order of events. Each OS-Ken application has a thread for event processing. The thread keeps draining the receive queue by dequeueing an event and calling the appropritate event handler for the event type. Because the event handler is called in the context of the event processing thread, it should be careful when blocking. While an event handler is blocked, no further events for the OS-Ken application will be processed. There are kinds of events which are used to implement synchronous inter-application calls between OS-Ken applications. While such requests use the same machinery as ordinary events, their replies are put on a queue dedicated to the transaction to avoid deadlock. While threads and queues are currently implemented with eventlet/greenlet, a direct use of them in a OS-Ken application is strongly discouraged. Contexts -------- Contexts are ordinary python objects shared among OS-Ken applications. The use of contexts is discouraged for new code. Create a OS-Ken application =========================== A OS-Ken application is a python module which defines a subclass of os_ken.base.app_manager.OSKenApp. If two or more such classes are defined in a module, the first one (by name order) will be picked by app_manager. An OS-Ken application is singleton: only a single instance of a given OS-Ken application is supported. Observe events ============== A OS-Ken application can register itself to listen for specific events using os_ken.controller.handler.set_ev_cls decorator. Generate events =============== A OS-Ken application can raise events by calling appropriate os_ken.base.app_manager.OSKenApp's methods like send_event or send_event_to_observers. Event classes ============= An event class describes a OS-Ken event generated in the system. By convention, event class names are prefixed by "Event". Events are generated either by the core part of OS-Ken or OS-Ken applications. A OS-Ken application can register its interest for a specific type of event by providing a handler method using the os_ken.controller.handler.set_ev_cls decorator. OpenFlow event classes ---------------------- os_ken.controller.ofp_event module exports event classes which describe receptions of OpenFlow messages from connected switches. By convention, they are named as os_ken.controller.ofp_event.EventOFPxxxx where xxxx is the name of the corresponding OpenFlow message. For example, EventOFPPacketIn for the packet-in message. The OpenFlow controller part of OS-Ken automatically decodes OpenFlow messages received from switches and send these events to OS-Ken applications which expressed an interest using os_ken.controller.handler.set_ev_cls. OpenFlow event classes are subclasses of the following class. .. autoclass:: os_ken.controller.ofp_event.EventOFPMsgBase See :ref:`ofproto_ref` for more info about OpenFlow messages. os_ken.base.app_manager.OSKenApp ================================ See :ref:`api_ref`. os_ken.controller.handler.set_ev_cls ==================================== .. autofunction:: os_ken.controller.handler.set_ev_cls os_ken.controller.controller.Datapath ===================================== .. autoclass:: os_ken.controller.controller.Datapath os_ken.controller.event.EventBase ================================= .. autoclass:: os_ken.controller.event.EventBase os_ken.controller.event.EventRequestBase ======================================== .. autoclass:: os_ken.controller.event.EventRequestBase os_ken.controller.event.EventReplyBase ====================================== .. autoclass:: os_ken.controller.event.EventReplyBase os_ken.controller.ofp_event.EventOFPStateChange =============================================== .. autoclass:: os_ken.controller.ofp_event.EventOFPStateChange os_ken.controller.ofp_event.EventOFPPortStateChange =================================================== .. autoclass:: os_ken.controller.ofp_event.EventOFPPortStateChange os_ken.controller.dpset.EventDP =============================== .. autoclass:: os_ken.controller.dpset.EventDP os_ken.controller.dpset.EventPortAdd ==================================== .. autoclass:: os_ken.controller.dpset.EventPortAdd os_ken.controller.dpset.EventPortDelete ======================================= .. autoclass:: os_ken.controller.dpset.EventPortDelete os_ken.controller.dpset.EventPortModify ======================================= .. autoclass:: os_ken.controller.dpset.EventPortModify os_ken.controller.network.EventNetworkPort ========================================== .. autoclass:: os_ken.controller.network.EventNetworkPort os_ken.controller.network.EventNetworkDel ========================================= .. autoclass:: os_ken.controller.network.EventNetworkDel os_ken.controller.network.EventMacAddress ========================================= .. autoclass:: os_ken.controller.network.EventMacAddress os_ken.controller.tunnels.EventTunnelKeyAdd =========================================== .. autoclass:: os_ken.controller.tunnels.EventTunnelKeyAdd os_ken.controller.tunnels.EventTunnelKeyDel =========================================== .. autoclass:: os_ken.controller.tunnels.EventTunnelKeyDel os_ken.controller.tunnels.EventTunnelPort ========================================= .. autoclass:: os_ken.controller.tunnels.EventTunnelPort ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/parameters.rst0000664000175000017500000000475100000000000017762 0ustar00zuulzuul00000000000000:orphan: .. _getting_started: *************** Getting Started *************** Overview/What's OS-Ken the Network Operating System =================================================== OS-Ken is an open-sourced Network Operating System which is licensed under Apache v2.0. It supports openflow protocol. If you are not familiar with Software Defined Network(SDN) and OpenFlow/openflow controller, please refer to `openflow org `_ . The mailing list is available at `OpenStack-dev ML `_ Installing OS-Ken Network Operating System ========================================== Extract source code and just type:: % python ./setup.py install Then, run osken-manager. It listens to ip address 0.0.0.0 and port 6633 by default. Then have your openflow switch (hardware or openvswitch OVS) to connect to osken-manager. For OVS case, you can done it by % ovs-vsctl set-controller tcp:[:] At the moment, osken-manager supports only tcp method. invoking application and Configuration ====================================== It can be configured by passing configuration file like:: osken-manager [generic/application specific options...] The generic available is as follows:: --app-lists: application module name to run; repeat this option to specify a list of values --help: show help The options for openflow controller:: --ofp-listen-host: openflow listen host (default: '') --ofp-tcp-listen-port: openflow tcp listen port (default: '6633') (an integer) The options for log:: --default-log-level: default log level (an integer) --log-dir: log file directory --log-file: log file name --log-file-mode: default log file permission (default: '0644') --[no]use-stderr: log to standard error (default: 'true') --use-syslog: output to syslog (default: 'False') --[no]verbose: show debug output (default: 'false') The option for oslo.config.cfg:: --config-file: Path to a config file to use. Multiple config files can be specified, with values in later files taking precedence. (default: []) --config-dir: Path to a config directory to pull *.conf files from. This file set is sorted, so as to provide a predictable parse order if individual options are over-ridden. The set is parsed after the file(s), if any, specified via --config-file, hence over-ridden options in the directory take precedence. ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.0621028 os-ken-2.10.0/doc/source/quantumclient/0000775000175000017500000000000000000000000017747 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/quantumclient/__init__.py0000664000175000017500000000000000000000000022046 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/quantumclient/client.py0000664000175000017500000000002600000000000021575 0ustar00zuulzuul00000000000000""" dummy module. """ ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.0621028 os-ken-2.10.0/doc/source/quantumclient/common/0000775000175000017500000000000000000000000021237 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/quantumclient/common/__init__.py0000664000175000017500000000000000000000000023336 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/quantumclient/common/exceptions.py0000664000175000017500000000007700000000000023776 0ustar00zuulzuul00000000000000""" dummy module. """ class QuantumClientException: pass ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.0621028 os-ken-2.10.0/doc/source/quantumclient/v2_0/0000775000175000017500000000000000000000000020515 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/quantumclient/v2_0/__init__.py0000664000175000017500000000000000000000000022614 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/quantumclient/v2_0/client.py0000664000175000017500000000002600000000000022343 0ustar00zuulzuul00000000000000""" dummy module. """ ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/readme.rst0000664000175000017500000000070000000000000017042 0ustar00zuulzuul00000000000000======== Overview ======== A component-based software defined networking framework in OpenStack. os-ken is a fork of the Ryu library tailored for OpenStack Neutron. * License: Apache License, Version 2.0 * Documentation: https://docs.openstack.org/os-ken/latest/ * Source: https://opendev.org/openstack/os-ken/ * Bugs: https://storyboard.openstack.org/#!/project/openstack/os-ken * Release Notes: https://docs.openstack.org/releasenotes/os-ken/ ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.0621028 os-ken-2.10.0/doc/source/reference/0000775000175000017500000000000000000000000017014 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/reference/index.rst0000664000175000017500000000005100000000000020651 0ustar00zuulzuul00000000000000========== References ========== T.B.D. ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/snort_integrate.rst0000664000175000017500000001165500000000000021027 0ustar00zuulzuul00000000000000****************** Snort Intergration ****************** This document describes how to integrate OS-Ken with Snort. Overview ======== There are two options can send alert to OS-Ken controller. The Option 1 is easier if you just want to demonstrate or test. Since Snort need very large computation power for analyzing packets you can choose Option 2 to separate them. **[Option 1] OS-Ken and Snort are on the same machine** :: +------------------------+ | unixsock | | OS-Ken == snort | +----eth0-----eth1-------+ | | +-------+ +----------+ +-------+ | HostA |---| OFSwitch |---| HostB | +-------+ +----------+ +-------+ The above depicts OS-Ken and Snort architecture. OS-Ken receives Snort alert packet via **Unix Domain Socket** . To monitor packets between HostA and HostB, installing a flow that mirrors packets to Snort. **[Option 2] OS-Ken and Snort are on the different machines** :: +---------------+ | Snort eth0--| | Sniffer | | +-----eth1------+ | | | +-------+ +----------+ +-----------+ | HostA |---| OFSwitch |---| LAN (*CP) | +-------+ +----------+ +-----------+ | | +----------+ +-------------+ | HostB | | OS-Ken | +----------+ +-------------+ **\*CP: Control Plane** The above depicts OS-Ken and Snort architecture. OS-Ken receives Snort alert packet via **Network Socket** . To monitor packets between HostA and HostB, installing a flow that mirrors packets to Snort. Installation Snort ================== Snort is an open source network intrusion prevention and detectionsystem developed by Sourcefire. If you are not familiar with installing/setting up Snort, please referto snort setup guides. http://www.snort.org/documents Configure Snort =============== The configuration example is below: - Add a snort rules file into ``/etc/snort/rules`` named ``Myrules.rules`` :: alert icmp any any -> any any (msg:"Pinging...";sid:1000004;) alert tcp any any -> any 80 (msg:"Port 80 is accessing"; sid:1000003;) - Add the custom rules in ``/etc/snort/snort.conf`` :: include $RULE_PATH/Myrules.rules Configure NIC as a promiscuous mode. :: $ sudo ifconfig eth1 promisc Usage ===== **[Option 1]** 1. Modify the ``simple_switch_snort.py``: :: socket_config = {'unixsock': True} # True: Unix Domain Socket Server [Option1] # False: Network Socket Server [Option2] 2. Run OS-Ken with sample application: :: $ sudo osken-manager os_ken/app/simple_switch_snort.py The incoming packets will all mirror to **port 3** which should be connect to Snort network interface. You can modify the mirror port by assign a new value in the ``self.snort_port = 3`` of ``simple_switch_snort.py`` 3. Run Snort: :: $ sudo -i $ snort -i eth1 -A unsock -l /tmp -c /etc/snort/snort.conf 4. Send an ICMP packet from HostA (192.168.8.40) to HostB (192.168.8.50): :: $ ping 192.168.8.50 5. You can see the result under next section. **[Option 2]** 1. Modify the ``simple_switch_snort.py``: :: socket_config = {'unixsock': False} # True: Unix Domain Socket Server [Option1] # False: Network Socket Server [Option2] 2. Run OS-Ken with sample application (On the Controller): :: $ osken-manager os_ken/app/simple_switch_snort.py 3. Run Snort (On the Snort machine): :: $ sudo -i $ snort -i eth1 -A unsock -l /tmp -c /etc/snort/snort.conf 4. Run ``pigrelay.py`` (On the Snort machine): :: $ sudo python pigrelay.py This program listening snort alert messages from unix domain socket and sending it to OS-Ken using network socket. You can clone the source code from this repo. https://github.com/John-Lin/pigrelay 5. Send an ICMP packet from HostA (192.168.8.40) to HostB (192.168.8.50): :: $ ping 192.168.8.50 6. You can see the alert message below: :: alertmsg: Pinging... icmp(code=0,csum=19725,data=echo(data=array('B', [97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 97, 98, 99, 100, 101, 102, 103, 104, 105]),id=1,seq=78),type=8) ipv4(csum=42562,dst='192.168.8.50',flags=0,header_length=5,identification=724,offset=0,option=None,proto=1,src='192.168.8.40',tos=0,total_length=60,ttl=128,version=4) ethernet(dst='00:23:54:5a:05:14',ethertype=2048,src='00:23:54:6c:1d:17') alertmsg: Pinging... icmp(code=0,csum=21773,data=echo(data=array('B', [97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 97, 98, 99, 100, 101, 102, 103, 104, 105]),id=1,seq=78),type=0) ipv4(csum=52095,dst='192.168.8.40',flags=0,header_length=5,identification=7575,offset=0,option=None,proto=1,src='192.168.8.50',tos=0,total_length=60,ttl=64,version=4) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/test-of-config-with-linc.rst0000664000175000017500000001231200000000000022327 0ustar00zuulzuul00000000000000=================================== Testing OF-config support with LINC =================================== This page describes how to setup LINC and test OS-Ken OF-config with it. The procedure is as follows. Although all the procedure is written for reader's convenience, please refer to LINC document for latest informations of LINC. https://github.com/FlowForwarding/LINC-Switch The test procedure * install Erlang environment * build LINC * configure LINC switch * setup for LINC * run LINC switch * run OS-Ken test_of_config app For getting/installing OS-Ken itself, please refer to http://osrg.github.io/os_ken/ Install Erlang environment ========================== Since LINC is written in Erlang, you need to install Erlang execution environment. Required version is R15B+. The easiest way is to use binary package from https://www.erlang-solutions.com/downloads/download-erlang-otp The distribution may also provide Erlang package. build LINC ========== install necessary packages for build ------------------------------------ install necessary build tools ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ On Ubuntu:: # apt-get install git-core bridge-utils libpcap0.8 libpcap-dev libcap2-bin uml-utilities On RedHat/CentOS:: # yum install git sudo bridge-utils libpcap libpcap-devel libcap tunctl Note that on RedHat/CentOS 5.x you need a newer version of libpcap:: # yum erase libpcap libpcap-devel # yum install flex byacc # wget http://www.tcpdump.org/release/libpcap-1.2.1.tar.gz # tar xzf libpcap-1.2.1.tar.gz # cd libpcap-1.2.1 # ./configure # make && make install get LINC repo and built ^^^^^^^^^^^^^^^^^^^^^^^ Clone LINC repo:: % git clone git://github.com/FlowForwarding/LINC-Switch.git Then compile everything:: % cd LINC-Switch % make .. NOTE:: At the time of this writing, test_of_config fails due to a bug of LINC. You can try this test with LINC which is built by the following methods. :: % cd LINC-Switch % make % cd deps/of_config % git reset --hard f772af4b765984381ad024ca8e5b5b8c54362638 % cd ../.. % make offline Setup LINC ========== edit LINC switch configuration file. ``rel/linc/releases/0.1/sys.config`` Here is the sample sys.config for test_of_config.py to run. :: [{linc, [{of_config,enabled}, {capable_switch_ports, [{port,1,[{interface,"linc-port"}]}, {port,2,[{interface,"linc-port2"}]}, {port,3,[{interface,"linc-port3"}]}, {port,4,[{interface,"linc-port4"}]}]}, {capable_switch_queues, [ {queue,991,[{min_rate,10},{max_rate,120}]}, {queue,992,[{min_rate,10},{max_rate,130}]}, {queue,993,[{min_rate,200},{max_rate,300}]}, {queue,994,[{min_rate,400},{max_rate,900}]} ]}, {logical_switches, [{switch,0, [{backend,linc_us4}, {controllers,[{"Switch0-Default-Controller","127.0.0.1",6633,tcp}]}, {controllers_listener,{"127.0.0.1",9998,tcp}}, {queues_status,enabled}, {ports,[{port,1,{queues,[]}},{port,2,{queues,[991,992]}}]}]} , {switch,7, [{backend,linc_us3}, {controllers,[{"Switch7-Controller","127.0.0.1",6633,tcp}]}, {controllers_listener,disabled}, {queues_status,enabled}, {ports,[{port,4,{queues,[]}},{port,3,{queues,[993,994]}}]}]} ]}]}, {enetconf, [{capabilities, [{base,{1,0}}, {base,{1,1}}, {startup,{1,0}}, {'writable-running',{1,0}}]}, {callback_module,linc_ofconfig}, {sshd_ip,{127,0,0,1}}, {sshd_port,1830}, {sshd_user_passwords,[{"linc","linc"}]}]}, {lager, [{handlers, [{lager_console_backend,debug}, {lager_file_backend, [{"log/error.log",error,10485760,"$D0",5}, {"log/console.log",info,10485760,"$D0",5}]}]}]}, {sasl, [{sasl_error_logger,{file,"log/sasl-error.log"}}, {errlog_type,error}, {error_logger_mf_dir,"log/sasl"}, {error_logger_mf_maxbytes,10485760}, {error_logger_mf_maxfiles,5}]}, {sync,[{excluded_modules,[procket]}]}]. setup for LINC ============== As the above sys.config requires some network interface, create them:: # ip link add linc-port type veth peer name linc-port-peer # ip link set linc-port up # ip link add linc-port2 type veth peer name linc-port-peer2 # ip link set linc-port2 up # ip link add linc-port3 type veth peer name linc-port-peer3 # ip link set linc-port3 up # ip link add linc-port4 type veth peer name linc-port-peer4 # ip link set linc-port4 up After stopping LINC, those created interfaces can be deleted:: # ip link delete linc-port # ip link delete linc-port2 # ip link delete linc-port3 # ip link delete linc-port4 Starting LINC OpenFlow switch ============================= Then run LINC:: # rel/linc/bin/linc console ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/test-vrrp.rst0000664000175000017500000001510600000000000017561 0ustar00zuulzuul00000000000000=================== Testing VRRP Module =================== This page describes how to test OS-Ken VRRP service Running integrated tests ======================== Some testing scripts are available. * os_ken/tests/integrated/test_vrrp_linux_multi.py * os_ken/tests/integrated/test_vrrp_multi.py Each files include how to run in the comment. Please refer to it. Running multiple OS-Ken VRRP in network namespace ================================================= The following command lines set up necessary bridges and interfaces. And then run OSKen-VRRP:: # ip netns add gateway1 # ip netns add gateway2 # ip link add dev vrrp-br0 type bridge # ip link add dev vrrp-br1 type bridge # ip link add veth0 type veth peer name veth0-br0 # ip link add veth1 type veth peer name veth1-br0 # ip link add veth2 type veth peer name veth2-br0 # ip link add veth3 type veth peer name veth3-br1 # ip link add veth4 type veth peer name veth4-br1 # ip link add veth5 type veth peer name veth5-br1 # ip link set dev veth0-br0 master vrrp-br0 # ip link set dev veth1-br0 master vrrp-br0 # ip link set dev veth2-br0 master vrrp-br0 # ip link set dev veth3-br0 master vrrp-br1 # ip link set dev veth4-br0 master vrrp-br1 # ip link set dev veth5-br0 master vrrp-br1 # ip link set vrrp-br0 up # ip link set vrrp-br1 up # ip link set veth0 up # ip link set veth0-br0 up # ip link set veth1-br0 up # ip link set veth2-br0 up # ip link set veth3-br1 up # ip link set veth4-br1 up # ip link set veth5 up # ip link set veth5-br1 up # ip link set veth1 netns gateway1 # ip link set veth2 netns gateway2 # ip link set veth3 netns gateway1 # ip link set veth4 netns gateway2 # ip netns exec gateway1 ip link set veth1 up # ip netns exec gateway2 ip link set veth2 up # ip netns exec gateway1 ip link set veth3 up # ip netns exec gateway2 ip link set veth4 up # ip netns exec gateway1 .os_ken-vrrp veth1 '10.0.0.2' 254 # ip netns exec gateway2 .os_ken-vrrp veth2 '10.0.0.3' 100 .. admonition:: Caveats Please make sure that all interfaces and bridges are UP. Don't forget interfaces in netns gateway1/gateway2. :: ^ veth5 | V veth5-br1 ----------------------- |Linux Brirge vrrp-br1| ----------------------- veth3-br1^ ^ veth4-br1 | | veth3V V veth4 ------------- ------------- |netns | |netns | |gateway1 | |gateway2 | |os_ken-vrrp| |os_ken-vrrp| ------------- ---------- veth1^ ^ veth2 | | veth1-br0V V veth2-br0 ----------------------- |Linux Brirge vrrp-br0| ----------------------- ^ veth0-br0 | V veth0 Here's the helper executable, os_ken-vrrp:: #!/usr/bin/env python3 # # Copyright (C) 2013 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013 Isaku Yamahata # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. from os_ken.lib import hub hub.patch() # TODO: # Right now, we have our own patched copy of ovs python bindings # Once our modification is upstreamed and widely deployed, # use it # # NOTE: this modifies sys.path and thus affects the following imports. # eg. oslo.config.cfg. import os_ken.contrib from oslo.config import cfg import logging import netaddr import sys import time from os_ken import log log.early_init_log(logging.DEBUG) from os_ken import flags from os_ken import version from os_ken.base import app_manager from os_ken.controller import controller from os_ken.lib import mac as lib_mac from os_ken.lib.packet import vrrp from os_ken.services.protocols.vrrp import api as vrrp_api from os_ken.services.protocols.vrrp import event as vrrp_event CONF = cfg.CONF _VRID = 7 _IP_ADDRESS = '10.0.0.1' _PRIORITY = 100 class VRRPTestRouter(app_manager.OSKenApp): def __init__(self, *args, **kwargs): super(VRRPTestRouter, self).__init__(*args, **kwargs) print args self.logger.debug('vrrp_config %s', args) self._ifname = args[0] self._primary_ip_address = args[1] self._priority = int(args[2]) def start(self): print 'start' hub.spawn(self._main) def _main(self): print self interface = vrrp_event.VRRPInterfaceNetworkDevice( lib_mac.DONTCARE, self._primary_ip_address, None, self._ifname) self.logger.debug('%s', interface) ip_addresses = [_IP_ADDRESS] config = vrrp_event.VRRPConfig( version=vrrp.VRRP_VERSION_V3, vrid=_VRID, priority=self._priority, ip_addresses=ip_addresses) self.logger.debug('%s', config) rep = vrrp_api.vrrp_config(self, interface, config) self.logger.debug('%s', rep) def main(): vrrp_config = sys.argv[-3:] sys.argv = sys.argv[:-3] CONF(project='os_ken', version='os_ken-vrrp %s' % version) log.init_log() # always enable ofp for now. app_lists = ['os_ken.services.protocols.vrrp.manager', 'os_ken.services.protocols.vrrp.dumper', 'os_ken.services.protocols.vrrp.sample_manager'] app_mgr = app_manager.AppManager.get_instance() app_mgr.load_apps(app_lists) contexts = app_mgr.create_contexts() app_mgr.instantiate_apps(**contexts) vrrp_router = app_mgr.instantiate(VRRPTestRouter, *vrrp_config, **contexts) vrrp_router.start() while True: time.sleep(999999) app_mgr.close() if __name__ == "__main__": main() ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/tests.rst0000664000175000017500000000012200000000000016745 0ustar00zuulzuul00000000000000***** Tests ***** .. toctree:: test-vrrp.rst test-of-config-with-linc.rst ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/tls.rst0000664000175000017500000000516500000000000016421 0ustar00zuulzuul00000000000000******************** Setup TLS Connection ******************** If you want to use secure channel to connect OpenFlow switches, you need to use TLS connection. This document describes how to setup OS-Ken to connect to the Open vSwitch over TLS. Configuring a Public Key Infrastructure ======================================== If you don't have a PKI, the ovs-pki script included with Open vSwitch can help you. This section is based on the INSTALL.SSL in the Open vSwitch source code. NOTE: How to install Open vSwitch isn't described in this document. Please refer to the Open vSwitch documents. Create a PKI by using ovs-pki script:: % ovs-pki init (Default directory is /usr/local/var/lib/openvswitch/pki) The pki directory consists of controllerca and switchca subdirectories. Each directory contains CA files. Create a controller private key and certificate:: % ovs-pki req+sign ctl controller ctl-privkey.pem and ctl-cert.pem are generated in the current directory. Create a switch private key and certificate:: % ovs-pki req+sign sc switch sc-privkey.pem and sc-cert.pem are generated in the current directory. Testing TLS Connection ====================== Configuring ovs-vswitchd to use CA files using the ovs-vsctl "set-ssl" command, e.g.:: % ovs-vsctl set-ssl /etc/openvswitch/sc-privkey.pem \ /etc/openvswitch/sc-cert.pem \ /usr/local/var/lib/openvswitch/pki/controllerca/cacert.pem % ovs-vsctl add-br br0 % ovs-vsctl set-controller br0 ssl:127.0.0.1:6633 Substitute the correct file names, if they differ from the ones used above. You should use absolute file names. Run OS-Ken with CA files:: % osken-manager --ctl-privkey ctl-privkey.pem \ --ctl-cert ctl-cert.pem \ --ca-certs /usr/local/var/lib/openvswitch/pki/switchca/cacert.pem \ --verbose You can see something like:: loading app os_ken.controller.ofp_handler instantiating app os_ken.controller.ofp_handler BRICK ofp_event CONSUMES EventOFPSwitchFeatures CONSUMES EventOFPErrorMsg CONSUMES EventOFPHello CONSUMES EventOFPEchoRequest connected socket: a ddress:('127.0.0.1', 61302) hello ev move onto config mode switch features ev version: 0x1 msg_type 0x6 xid 0xb0bb34e5 port OFPPhyPort(port _no=65534, hw_addr='\x16\xdc\xa2\xe2}K', name='br0\x00\x00\x00\x00\x00\x00\x00\x 00\x00\x00\x00\x00\x00', config=0, state=0, curr=0, advertised=0, supported=0, p eer=0) move onto main mode ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.0621028 os-ken-2.10.0/doc/source/user/0000775000175000017500000000000000000000000016034 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/user/index.rst0000664000175000017500000000005400000000000017674 0ustar00zuulzuul00000000000000=========== Users guide =========== T.B.D. ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/doc/source/writing_os_ken_app.rst0000664000175000017500000001045400000000000021475 0ustar00zuulzuul00000000000000********************* The First Application ********************* Whetting Your Appetite ====================== If you want to manage the network gears (switches, routers, etc) at your way, you need to write your OS-Ken application. Your application tells OS-Ken how you want to manage the gears. Then OS-Ken configures the gears by using OpenFlow protocol, etc. Writing OS-Ken application is easy. It's just Python scripts. Start Writing ============= We show a OS-Ken application that make OpenFlow switches work as a dumb layer 2 switch. Open a text editor creating a new file with the following content: .. code-block:: python from os_ken.base import app_manager class L2Switch(app_manager.OSKenApp): def __init__(self, *args, **kwargs): super(L2Switch, self).__init__(*args, **kwargs) OS-Ken application is just a Python script so you can save the file with any name, extensions, and any place you want. Let's name the file 'l2.py' at your home directory. This application does nothing useful yet, however it's a complete OS-Ken application. In fact, you can run this OS-Ken application:: % osken-manager ~/l2.py loading app /Users/fujita/l2.py instantiating app /Users/fujita/l2.py All you have to do is defining needs a new subclass of OSKenApp to run your Python script as a OS-Ken application. Next let's add the functionality of sending a received packet to all the ports. .. code-block:: python from os_ken.base import app_manager from os_ken.controller import ofp_event from os_ken.controller.handler import MAIN_DISPATCHER from os_ken.controller.handler import set_ev_cls from os_ken.ofproto import ofproto_v1_0 class L2Switch(app_manager.OSKenApp): OFP_VERSIONS = [ofproto_v1_0.OFP_VERSION] def __init__(self, *args, **kwargs): super(L2Switch, self).__init__(*args, **kwargs) @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER) def packet_in_handler(self, ev): msg = ev.msg dp = msg.datapath ofp = dp.ofproto ofp_parser = dp.ofproto_parser actions = [ofp_parser.OFPActionOutput(ofp.OFPP_FLOOD)] out = ofp_parser.OFPPacketOut( datapath=dp, buffer_id=msg.buffer_id, in_port=msg.in_port, actions=actions) dp.send_msg(out) A new method 'packet_in_handler' is added to L2Switch class. This is called when OS-Ken receives an OpenFlow packet_in message. The trick is 'set_ev_cls' decorator. This decorator tells OS-Ken when the decorated function should be called. The first argument of the decorator indicates an event that makes function called. As you expect easily, every time OS-Ken gets a packet_in message, this function is called. The second argument indicates the state of the switch. Probably, you want to ignore packet_in messages before the negotiation between OS-Ken and the switch finishes. Using 'MAIN_DISPATCHER' as the second argument means this function is called only after the negotiation completes. Next let's look at the first half of the 'packet_in_handler' function. * ev.msg is an object that represents a packet_in data structure. * msg.dp is an object that represents a datapath (switch). * dp.ofproto and dp.ofproto_parser are objects that represent the OpenFlow protocol that OS-Ken and the switch negotiated. Ready for the second half. * OFPActionOutput class is used with a packet_out message to specify a switch port that you want to send the packet out of. This application need a switch to send out of all the ports so OFPP_FLOOD constant is used. * OFPPacketOut class is used to build a packet_out message. * If you call Datapath class's send_msg method with a OpenFlow message class object, OS-Ken builds and send the on-wire data format to the switch. Here, you finished implementing your first OS-Ken application. You are ready to run this OS-Ken application that does something useful. A dumb l2 switch is too dumb? You want to implement a learning l2 switch? Move to `the next step `_. You can learn from the existing OS-Ken applications at `os_ken/app `_ directory and `integrated tests `_ directory. ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.0261006 os-ken-2.10.0/etc/0000775000175000017500000000000000000000000013564 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.0621028 os-ken-2.10.0/etc/os_ken/0000775000175000017500000000000000000000000015042 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/etc/os_ken/os_ken.conf0000664000175000017500000000022000000000000017161 0ustar00zuulzuul00000000000000# Sample configuration file [DEFAULT] #wsapi_host= #wsapi_port= #ofp_listen_host= #ofp_tcp_listen_port= ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.0621028 os-ken-2.10.0/os_ken/0000775000175000017500000000000000000000000014267 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/__init__.py0000664000175000017500000000122600000000000016401 0ustar00zuulzuul00000000000000# -*- coding: utf-8 -*- # 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. import pbr.version __version__ = pbr.version.VersionInfo( 'os-ken').version_string() ././@PaxHeader0000000000000000000000000000003300000000000011451 xustar000000000000000027 mtime=1724334546.066103 os-ken-2.10.0/os_ken/app/0000775000175000017500000000000000000000000015047 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/app/__init__.py0000664000175000017500000000000000000000000017146 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003300000000000011451 xustar000000000000000027 mtime=1724334546.066103 os-ken-2.10.0/os_ken/app/ofctl/0000775000175000017500000000000000000000000016156 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/app/ofctl/__init__.py0000664000175000017500000000124600000000000020272 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2014 YAMAMOTO Takashi # # 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. ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/app/ofctl/api.py0000664000175000017500000000573300000000000017311 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2014 YAMAMOTO Takashi # # 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. # client for os_ken.app.ofctl.service from os_ken.base import app_manager from . import event def get_datapath(app, dpid=None): """ Get datapath object by dpid. :param app: Client OSKenApp instance :param dpid: Datapath ID (int type) or None to get all datapath objects Returns a object of datapath, a list of datapath objects when no dpid given or None when error. Raises an exception if any of the given values is invalid. Example:: # ...(snip)... import os_ken.app.ofctl.api as ofctl_api class MyApp(app_manager.OSKenApp): def _my_handler(self, ev): # Get all datapath objects result = ofctl_api.get_datapath(self) # Get the datapath object which has the given dpid result = ofctl_api.get_datapath(self, dpid=1) """ return app.send_request(event.GetDatapathRequest(dpid=dpid))() def send_msg(app, msg, reply_cls=None, reply_multi=False): """ Send an OpenFlow message and wait for reply messages. :param app: Client OSKenApp instance :param msg: An OpenFlow controller-to-switch message to send :param reply_cls: OpenFlow message class for expected replies. None means no replies are expected. The default is None. :param reply_multi: True if multipart replies are expected. The default is False. If no replies, returns None. If reply_multi=False, returns OpenFlow switch-to-controller message. If reply_multi=True, returns a list of OpenFlow switch-to-controller messages. Raise an exception on error. Example:: # ...(snip)... import os_ken.app.ofctl.api as ofctl_api class MyApp(app_manager.OSKenApp): def _my_handler(self, ev): # ...(snip)... msg = parser.OFPPortDescStatsRequest(datapath=datapath) result = ofctl_api.send_msg( self, msg, reply_cls=parser.OFPPortDescStatsReply, reply_multi=True) """ return app.send_request(event.SendMsgRequest(msg=msg, reply_cls=reply_cls, reply_multi=reply_multi))() app_manager.require_app('os_ken.app.ofctl.service', api_style=True) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/app/ofctl/event.py0000664000175000017500000000320500000000000017651 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2014 YAMAMOTO Takashi # # 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. import numbers from os_ken.controller import event # base classes class _RequestBase(event.EventRequestBase): def __init__(self): self.dst = 'ofctl_service' class _ReplyBase(event.EventReplyBase): pass # get datapath class GetDatapathRequest(_RequestBase): def __init__(self, dpid=None): assert dpid is None or isinstance(dpid, numbers.Integral) super(GetDatapathRequest, self).__init__() self.dpid = dpid # send msg class SendMsgRequest(_RequestBase): def __init__(self, msg, reply_cls=None, reply_multi=False): super(SendMsgRequest, self).__init__() self.msg = msg self.reply_cls = reply_cls self.reply_multi = reply_multi # generic reply class Reply(_ReplyBase): def __init__(self, result=None, exception=None): self.result = result self.exception = exception def __call__(self): if self.exception: raise self.exception return self.result ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/app/ofctl/exception.py0000664000175000017500000000251000000000000020524 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2014 YAMAMOTO Takashi # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. from os_ken import exception # base classes class _ExceptionBase(exception.OSKenException): def __init__(self, result): self.result = result super(_ExceptionBase, self).__init__(result=result) class UnexpectedMultiReply(_ExceptionBase): """Two or more replies are received for reply_muiti=False request.""" message = 'Unexpected Multi replies %(result)s' class OFError(_ExceptionBase): """OFPErrorMsg is received.""" message = 'OpenFlow errors %(result)s' class InvalidDatapath(_ExceptionBase): """Datapath is invalid. This can happen when the bridge disconnects. """ message = 'Datapath Invalid %(result)s' ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/app/ofctl/service.py0000664000175000017500000002062200000000000020172 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2014 YAMAMOTO Takashi # # 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. # ofctl service import numbers from os_ken.base import app_manager from os_ken.controller import ofp_event from os_ken.controller.handler import CONFIG_DISPATCHER, MAIN_DISPATCHER,\ DEAD_DISPATCHER from os_ken.controller.handler import set_ev_cls from . import event from . import exception class _SwitchInfo(object): def __init__(self, datapath): self.datapath = datapath self.xids = {} self.barriers = {} self.results = {} class OfctlService(app_manager.OSKenApp): def __init__(self, *args, **kwargs): super(OfctlService, self).__init__(*args, **kwargs) self.name = 'ofctl_service' self._switches = {} self._observing_events = {} def _observe_msg(self, msg_cls): assert msg_cls is not None ev_cls = ofp_event.ofp_msg_to_ev_cls(msg_cls) self._observing_events.setdefault(ev_cls, 0) if self._observing_events[ev_cls] == 0: self.logger.debug('ofctl: start observing %s', ev_cls) self.register_handler(ev_cls, self._handle_reply) self.observe_event(ev_cls) self._observing_events[ev_cls] += 1 def _unobserve_msg(self, msg_cls): assert msg_cls is not None ev_cls = ofp_event.ofp_msg_to_ev_cls(msg_cls) assert self._observing_events[ev_cls] > 0 self._observing_events[ev_cls] -= 1 if self._observing_events[ev_cls] == 0: self.unregister_handler(ev_cls, self._handle_reply) self.unobserve_event(ev_cls) self.logger.debug('ofctl: stop observing %s', ev_cls) def _cancel(self, info, barrier_xid, exception): xid = info.barriers.pop(barrier_xid) req = info.xids.pop(xid) msg = req.msg datapath = msg.datapath parser = datapath.ofproto_parser is_barrier = isinstance(msg, parser.OFPBarrierRequest) info.results.pop(xid) if not is_barrier and req.reply_cls is not None: self._unobserve_msg(req.reply_cls) self.logger.error('failed to send message <%s>', req.msg) self.reply_to_request(req, event.Reply(exception=exception)) @staticmethod def _is_error(msg): return (ofp_event.ofp_msg_to_ev_cls(type(msg)) == ofp_event.EventOFPErrorMsg) @set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER) def _switch_features_handler(self, ev): datapath = ev.msg.datapath id = datapath.id assert isinstance(id, numbers.Integral) old_info = self._switches.get(id, None) new_info = _SwitchInfo(datapath=datapath) self.logger.debug('add dpid %s datapath %s new_info %s old_info %s', id, datapath, new_info, old_info) self._switches[id] = new_info if old_info: old_info.datapath.close() for xid in list(old_info.barriers): self._cancel( old_info, xid, exception.InvalidDatapath(result=id)) @set_ev_cls(ofp_event.EventOFPStateChange, DEAD_DISPATCHER) def _handle_dead(self, ev): datapath = ev.datapath id = datapath.id self.logger.debug('del dpid %s datapath %s', id, datapath) if id is None: return try: info = self._switches[id] except KeyError: return if info.datapath is datapath: self.logger.debug('forget info %s', info) self._switches.pop(id) for xid in list(info.barriers): self._cancel(info, xid, exception.InvalidDatapath(result=id)) @set_ev_cls(event.GetDatapathRequest, MAIN_DISPATCHER) def _handle_get_datapath(self, req): result = None if req.dpid is None: result = [v.datapath for v in self._switches.values()] else: if req.dpid in self._switches: result = self._switches[req.dpid].datapath self.reply_to_request(req, event.Reply(result=result)) @set_ev_cls(event.SendMsgRequest, MAIN_DISPATCHER) def _handle_send_msg(self, req): msg = req.msg datapath = msg.datapath parser = datapath.ofproto_parser is_barrier = isinstance(msg, parser.OFPBarrierRequest) try: si = self._switches[datapath.id] except KeyError: self.logger.error('unknown dpid %s' % (datapath.id,)) rep = event.Reply(exception=exception. InvalidDatapath(result=datapath.id)) self.reply_to_request(req, rep) return def _store_xid(xid, barrier_xid): assert xid not in si.results assert xid not in si.xids assert barrier_xid not in si.barriers si.results[xid] = [] si.xids[xid] = req si.barriers[barrier_xid] = xid if is_barrier: barrier = msg datapath.set_xid(barrier) _store_xid(barrier.xid, barrier.xid) else: if req.reply_cls is not None: self._observe_msg(req.reply_cls) datapath.set_xid(msg) barrier = datapath.ofproto_parser.OFPBarrierRequest(datapath) datapath.set_xid(barrier) _store_xid(msg.xid, barrier.xid) if not datapath.send_msg(msg): return self._cancel( si, barrier.xid, exception.InvalidDatapath(result=datapath.id)) if not datapath.send_msg(barrier): return self._cancel( si, barrier.xid, exception.InvalidDatapath(result=datapath.id)) @set_ev_cls(ofp_event.EventOFPBarrierReply, MAIN_DISPATCHER) def _handle_barrier(self, ev): msg = ev.msg datapath = msg.datapath parser = datapath.ofproto_parser try: si = self._switches[datapath.id] except KeyError: self.logger.error('unknown dpid %s', datapath.id) return try: xid = si.barriers.pop(msg.xid) except KeyError: self.logger.error('unknown barrier xid %s', msg.xid) return result = si.results.pop(xid) req = si.xids.pop(xid) is_barrier = isinstance(req.msg, parser.OFPBarrierRequest) if req.reply_cls is not None and not is_barrier: self._unobserve_msg(req.reply_cls) if is_barrier and req.reply_cls == parser.OFPBarrierReply: rep = event.Reply(result=ev.msg) elif any(self._is_error(r) for r in result): rep = event.Reply(exception=exception.OFError(result=result)) elif req.reply_multi: rep = event.Reply(result=result) elif len(result) == 0: rep = event.Reply() elif len(result) == 1: rep = event.Reply(result=result[0]) else: rep = event.Reply(exception=exception. UnexpectedMultiReply(result=result)) self.reply_to_request(req, rep) @set_ev_cls(ofp_event.EventOFPErrorMsg, MAIN_DISPATCHER) def _handle_reply(self, ev): msg = ev.msg datapath = msg.datapath try: si = self._switches[datapath.id] except KeyError: self.logger.error('unknown dpid %s', datapath.id) return try: req = si.xids[msg.xid] except KeyError: self.logger.error('unknown error xid %s', msg.xid) return if ((not isinstance(ev, ofp_event.EventOFPErrorMsg)) and (req.reply_cls is None or not isinstance(ev.msg, req.reply_cls))): self.logger.error('unexpected reply %s for xid %s', ev, msg.xid) return try: si.results[msg.xid].append(ev.msg) except KeyError: self.logger.error('unknown error xid %s', msg.xid) ././@PaxHeader0000000000000000000000000000003300000000000011451 xustar000000000000000027 mtime=1724334546.066103 os-ken-2.10.0/os_ken/base/0000775000175000017500000000000000000000000015201 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/base/__init__.py0000664000175000017500000000000000000000000017300 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/base/app_manager.py0000664000175000017500000004446300000000000020040 0ustar00zuulzuul00000000000000# Copyright (C) 2011-2014 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2011 Isaku Yamahata # # 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. """ The central management of OSKen applications. - Load OSKen applications - Provide `contexts` to OSKen applications - Route messages among OSKen applications """ import inspect import itertools import logging import sys import os import gc from os_ken import cfg from os_ken import utils from os_ken.controller.handler import register_instance, get_dependent_services from os_ken.controller.controller import Datapath from os_ken.controller import event from os_ken.controller.event import EventRequestBase, EventReplyBase from os_ken.lib import hub from os_ken.ofproto import ofproto_protocol LOG = logging.getLogger('os_ken.base.app_manager') SERVICE_BRICKS = {} def lookup_service_brick(name): return SERVICE_BRICKS.get(name) def _lookup_service_brick_by_ev_cls(ev_cls): return _lookup_service_brick_by_mod_name(ev_cls.__module__) def _lookup_service_brick_by_mod_name(mod_name): return lookup_service_brick(mod_name.split('.')[-1]) def register_app(app): assert isinstance(app, OSKenApp) assert app.name not in SERVICE_BRICKS SERVICE_BRICKS[app.name] = app register_instance(app) def unregister_app(app): SERVICE_BRICKS.pop(app.name) def require_app(app_name, api_style=False): """ Request the application to be automatically loaded. If this is used for "api" style modules, which is imported by a client application, set api_style=True. If this is used for client application module, set api_style=False. """ iterable = (inspect.getmodule(frame[0]) for frame in inspect.stack()) modules = [module for module in iterable if module is not None] if api_style: m = modules[2] # skip a frame for "api" module else: m = modules[1] m._REQUIRED_APP = getattr(m, '_REQUIRED_APP', []) m._REQUIRED_APP.append(app_name) LOG.debug('require_app: %s is required by %s', app_name, m.__name__) class OSKenApp(object): """ The base class for OSKen applications. OSKenApp subclasses are instantiated after osken-manager loaded all requested OSKen application modules. __init__ should call OSKenApp.__init__ with the same arguments. It's illegal to send any events in __init__. The instance attribute 'name' is the name of the class used for message routing among OSKen applications. (Cf. send_event) It's set to __class__.__name__ by OSKenApp.__init__. It's discouraged for subclasses to override this. """ _CONTEXTS = {} """ A dictionary to specify contexts which this OSKen application wants to use. Its key is a name of context and its value is an ordinary class which implements the context. The class is instantiated by app_manager and the instance is shared among OSKenApp subclasses which has _CONTEXTS member with the same key. A OSKenApp subclass can obtain a reference to the instance via its __init__'s kwargs as the following. Example:: _CONTEXTS = { 'network': network.Network } def __init__(self, *args, *kwargs): self.network = kwargs['network'] """ _EVENTS = [] """ A list of event classes which this OSKenApp subclass would generate. This should be specified if and only if event classes are defined in a different python module from the OSKenApp subclass is. """ OFP_VERSIONS = None """ A list of supported OpenFlow versions for this OSKenApp. The default is all versions supported by the framework. Examples:: OFP_VERSIONS = [ofproto_v1_0.OFP_VERSION, ofproto_v1_2.OFP_VERSION] If multiple OSKen applications are loaded in the system, the intersection of their OFP_VERSIONS is used. """ @classmethod def context_iteritems(cls): """ Return iterator over the (key, contxt class) of application context """ return iter(cls._CONTEXTS.items()) def __init__(self, *_args, **_kwargs): super(OSKenApp, self).__init__() self.name = self.__class__.__name__ self.event_handlers = {} # ev_cls -> handlers:list self.observers = {} # ev_cls -> observer-name -> states:set self.threads = [] self.main_thread = None self.events = hub.Queue(128) self._events_sem = hub.BoundedSemaphore(self.events.maxsize) if hasattr(self.__class__, 'LOGGER_NAME'): self.logger = logging.getLogger(self.__class__.LOGGER_NAME) else: self.logger = logging.getLogger(self.name) self.CONF = cfg.CONF # prevent accidental creation of instances of this class outside OSKenApp class _EventThreadStop(event.EventBase): pass self._event_stop = _EventThreadStop() self.is_active = True def start(self): """ Hook that is called after startup initialization is done. """ self.threads.append(hub.spawn(self._event_loop)) def stop(self): if self.main_thread: hub.kill(self.main_thread) self.is_active = False self._send_event(self._event_stop, None) hub.joinall(self.threads) def set_main_thread(self, thread): """ Set self.main_thread so that stop() can terminate it. Only AppManager.instantiate_apps should call this function. """ self.main_thread = thread def register_handler(self, ev_cls, handler): assert callable(handler) self.event_handlers.setdefault(ev_cls, []) self.event_handlers[ev_cls].append(handler) def unregister_handler(self, ev_cls, handler): assert callable(handler) self.event_handlers[ev_cls].remove(handler) if not self.event_handlers[ev_cls]: del self.event_handlers[ev_cls] def register_observer(self, ev_cls, name, states=None): states = states or set() ev_cls_observers = self.observers.setdefault(ev_cls, {}) ev_cls_observers.setdefault(name, set()).update(states) def unregister_observer(self, ev_cls, name): observers = self.observers.get(ev_cls, {}) observers.pop(name) def unregister_observer_all_event(self, name): for observers in self.observers.values(): observers.pop(name, None) def observe_event(self, ev_cls, states=None): brick = _lookup_service_brick_by_ev_cls(ev_cls) if brick is not None: brick.register_observer(ev_cls, self.name, states) def unobserve_event(self, ev_cls): brick = _lookup_service_brick_by_ev_cls(ev_cls) if brick is not None: brick.unregister_observer(ev_cls, self.name) def get_handlers(self, ev, state=None): """Returns a list of handlers for the specific event. :param ev: The event to handle. :param state: The current state. ("dispatcher") If None is given, returns all handlers for the event. Otherwise, returns only handlers that are interested in the specified state. The default is None. """ ev_cls = ev.__class__ handlers = self.event_handlers.get(ev_cls, []) if state is None: return handlers def test(h): if not hasattr(h, 'callers') or ev_cls not in h.callers: # dynamically registered handlers does not have # h.callers element for the event. return True states = h.callers[ev_cls].dispatchers if not states: # empty states means all states return True return state in states return filter(test, handlers) def get_observers(self, ev, state): observers = [] for k, v in self.observers.get(ev.__class__, {}).items(): if not state or not v or state in v: observers.append(k) return observers def send_request(self, req): """ Make a synchronous request. Set req.sync to True, send it to a OSKen application specified by req.dst, and block until receiving a reply. Returns the received reply. The argument should be an instance of EventRequestBase. """ assert isinstance(req, EventRequestBase) req.sync = True req.reply_q = hub.Queue() self.send_event(req.dst, req) # going to sleep for the reply return req.reply_q.get() def _event_loop(self): while self.is_active or not self.events.empty(): ev, state = self.events.get() self._events_sem.release() if ev == self._event_stop: continue handlers = self.get_handlers(ev, state) for handler in handlers: try: handler(ev) except hub.TaskExit: # Normal exit. # Propagate upwards, so we leave the event loop. raise except: LOG.exception('%s: Exception occurred during handler processing. ' 'Backtrace from offending handler ' '[%s] servicing event [%s] follows.', self.name, handler.__name__, ev.__class__.__name__) def _send_event(self, ev, state): self._events_sem.acquire() self.events.put((ev, state)) def send_event(self, name, ev, state=None): """ Send the specified event to the OSKenApp instance specified by name. """ if name in SERVICE_BRICKS: if isinstance(ev, EventRequestBase): ev.src = self.name LOG.debug("EVENT %s->%s %s", self.name, name, ev.__class__.__name__) SERVICE_BRICKS[name]._send_event(ev, state) else: LOG.debug("EVENT LOST %s->%s %s", self.name, name, ev.__class__.__name__) def send_event_to_observers(self, ev, state=None): """ Send the specified event to all observers of this OSKenApp. """ for observer in self.get_observers(ev, state): self.send_event(observer, ev, state) def reply_to_request(self, req, rep): """ Send a reply for a synchronous request sent by send_request. The first argument should be an instance of EventRequestBase. The second argument should be an instance of EventReplyBase. """ assert isinstance(req, EventRequestBase) assert isinstance(rep, EventReplyBase) rep.dst = req.src if req.sync: req.reply_q.put(rep) else: self.send_event(rep.dst, rep) def close(self): """ teardown method. The method name, close, is chosen for python context manager """ pass class AppManager(object): # singleton _instance = None @staticmethod def run_apps(app_lists): """Run a set of OSKen applications A convenient method to load and instantiate apps. This blocks until all relevant apps stop. """ app_mgr = AppManager.get_instance() app_mgr.load_apps(app_lists) contexts = app_mgr.create_contexts() services = app_mgr.instantiate_apps(**contexts) try: hub.joinall(services) finally: app_mgr.close() for t in services: t.kill() hub.joinall(services) gc.collect() @staticmethod def get_instance(): if not AppManager._instance: AppManager._instance = AppManager() return AppManager._instance def __init__(self): self.applications_cls = {} self.applications = {} self.contexts_cls = {} self.contexts = {} self.close_sem = hub.Semaphore() def load_app(self, name): mod = utils.import_module(name) clses = inspect.getmembers(mod, lambda cls: (inspect.isclass(cls) and issubclass(cls, OSKenApp) and mod.__name__ == cls.__module__)) if clses: return clses[0][1] return None def load_apps(self, app_lists): app_lists = [app for app in itertools.chain.from_iterable(app.split(',') for app in app_lists)] while len(app_lists) > 0: app_cls_name = app_lists.pop(0) context_modules = [x.__module__ for x in self.contexts_cls.values()] if app_cls_name in context_modules: continue LOG.info('loading app %s', app_cls_name) cls = self.load_app(app_cls_name) if cls is None: continue self.applications_cls[app_cls_name] = cls services = [] for key, context_cls in cls.context_iteritems(): v = self.contexts_cls.setdefault(key, context_cls) assert v == context_cls context_modules.append(context_cls.__module__) if issubclass(context_cls, OSKenApp): services.extend(get_dependent_services(context_cls)) # we can't load an app that will be initiataed for # contexts. for i in get_dependent_services(cls): if i not in context_modules: services.append(i) if services: app_lists.extend([s for s in set(services) if s not in app_lists]) def create_contexts(self): for key, cls in self.contexts_cls.items(): if issubclass(cls, OSKenApp): # hack for dpset context = self._instantiate(None, cls) else: context = cls() LOG.info('creating context %s', key) assert key not in self.contexts self.contexts[key] = context return self.contexts def _update_bricks(self): for i in SERVICE_BRICKS.values(): for _k, m in inspect.getmembers(i, inspect.ismethod): if not hasattr(m, 'callers'): continue for ev_cls, c in m.callers.items(): if not c.ev_source: continue brick = _lookup_service_brick_by_mod_name(c.ev_source) if brick: brick.register_observer(ev_cls, i.name, c.dispatchers) # allow OSKenApp and Event class are in different module for brick in SERVICE_BRICKS.values(): if ev_cls in brick._EVENTS: brick.register_observer(ev_cls, i.name, c.dispatchers) @staticmethod def _report_brick(name, app): LOG.debug("BRICK %s", name) for ev_cls, list_ in app.observers.items(): LOG.debug(" PROVIDES %s TO %s", ev_cls.__name__, list_) for ev_cls in app.event_handlers.keys(): LOG.debug(" CONSUMES %s", ev_cls.__name__) @staticmethod def report_bricks(): for brick, i in SERVICE_BRICKS.items(): AppManager._report_brick(brick, i) def _instantiate(self, app_name, cls, *args, **kwargs): # for now, only single instance of a given module # Do we need to support multiple instances? # Yes, maybe for slicing. LOG.info('instantiating app %s of %s', app_name, cls.__name__) if hasattr(cls, 'OFP_VERSIONS') and cls.OFP_VERSIONS is not None: ofproto_protocol.set_app_supported_versions(cls.OFP_VERSIONS) if app_name is not None: assert app_name not in self.applications app = cls(*args, **kwargs) register_app(app) assert app.name not in self.applications self.applications[app.name] = app return app def instantiate(self, cls, *args, **kwargs): app = self._instantiate(None, cls, *args, **kwargs) self._update_bricks() self._report_brick(app.name, app) return app def instantiate_apps(self, *args, **kwargs): for app_name, cls in self.applications_cls.items(): self._instantiate(app_name, cls, *args, **kwargs) self._update_bricks() self.report_bricks() threads = [] for app in self.applications.values(): t = app.start() if t is not None: app.set_main_thread(t) threads.append(t) return threads @staticmethod def _close(app): close_method = getattr(app, 'close', None) if callable(close_method): close_method() def uninstantiate(self, name): app = self.applications.pop(name) unregister_app(app) for app_ in SERVICE_BRICKS.values(): app_.unregister_observer_all_event(name) app.stop() self._close(app) events = app.events if not events.empty(): app.logger.debug('%s events remains %d', app.name, events.qsize()) def close(self): def close_all(close_dict): for app in close_dict.values(): self._close(app) close_dict.clear() # This semaphore prevents parallel execution of this function, # as run_apps's finally clause starts another close() call. with self.close_sem: for app_name in list(self.applications.keys()): self.uninstantiate(app_name) assert not self.applications close_all(self.contexts) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/cfg.py0000664000175000017500000000342700000000000015406 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2014 YAMAMOTO Takashi # # 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. import oslo_config.cfg # there are 3 ways to access the configuration. # # a. os_ken.cfg.CONF (used to register cli options) # b. OSKenApp.CONF (preferred way for os_ken applications) # c. oslo_config.cfg.CONF # # Currently a. and b. shares a single ConfigOpts instance. # We intentionally avoid using c. for our options as a python program # which embeds os_ken applications (eg. neutron agent) might want to put # its own set of cli options into it, which can conflict with ours. # (Currently there seems no conflict for the neutron agent. But who knows?) # At some point later we might want to unshare a. and b. as well, in order # to allow app-specific options. CONF = oslo_config.cfg.ConfigOpts() # re-export for convenience from oslo_config.cfg import ConfigOpts from oslo_config.cfg import Opt from oslo_config.cfg import BoolOpt from oslo_config.cfg import IntOpt from oslo_config.cfg import ListOpt from oslo_config.cfg import MultiStrOpt from oslo_config.cfg import StrOpt from oslo_config.cfg import FloatOpt from oslo_config.cfg import RequiredOptError from oslo_config.cfg import ConfigFilesNotFoundError ././@PaxHeader0000000000000000000000000000003300000000000011451 xustar000000000000000027 mtime=1724334546.066103 os-ken-2.10.0/os_ken/cmd/0000775000175000017500000000000000000000000015032 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/cmd/__init__.py0000664000175000017500000000000000000000000017131 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/cmd/manager.py0000775000175000017500000000665400000000000017034 0ustar00zuulzuul00000000000000#!/usr/bin/env python3 # # Copyright (C) 2011, 2012 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2011 Isaku Yamahata # # 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. import os import sys from os_ken.lib import hub hub.patch(thread=False) from os_ken import cfg import logging from os_ken import log log.early_init_log(logging.DEBUG) from os_ken import flags from os_ken import __version__ as version from os_ken.base.app_manager import AppManager from os_ken.controller import controller from os_ken.topology import switches CONF = cfg.CONF CONF.register_cli_opts([ cfg.ListOpt('app-lists', default=[], help='application module name to run'), cfg.MultiStrOpt('app', positional=True, default=[], help='application module name to run'), cfg.StrOpt('pid-file', default=None, help='pid file name'), cfg.BoolOpt('enable-debugger', default=False, help='don\'t overwrite Python standard threading library' '(use only for debugging)'), cfg.StrOpt('user-flags', default=None, help='Additional flags file for user applications'), ]) def _parse_user_flags(): """ Parses user-flags file and loads it to register user defined options. """ try: idx = list(sys.argv).index('--user-flags') user_flags_file = sys.argv[idx + 1] except (ValueError, IndexError): user_flags_file = '' if user_flags_file and os.path.isfile(user_flags_file): from os_ken.utils import _import_module_file _import_module_file(user_flags_file) def main(args=None, prog=None): _parse_user_flags() try: CONF(args=args, prog=prog, project='os_ken', version='osken-manager %s' % version, default_config_files=['/usr/local/etc/os_ken/os_ken.conf']) except cfg.ConfigFilesNotFoundError: CONF(args=args, prog=prog, project='os_ken', version='osken-manager %s' % version) log.init_log() logger = logging.getLogger(__name__) if CONF.enable_debugger: msg = 'debugging is available (--enable-debugger option is turned on)' logger.info(msg) else: hub.patch(thread=True) if CONF.pid_file: with open(CONF.pid_file, 'w') as pid_file: pid_file.write(str(os.getpid())) app_lists = CONF.app_lists + CONF.app # keep old behavior, run ofp if no application is specified. if not app_lists: app_lists = ['os_ken.controller.ofp_handler'] app_mgr = AppManager.get_instance() app_mgr.load_apps(app_lists) contexts = app_mgr.create_contexts() services = [] services.extend(app_mgr.instantiate_apps(**contexts)) try: hub.joinall(services) except KeyboardInterrupt: logger.debug("Keyboard Interrupt received. " "Closing OSKen application manager...") finally: app_mgr.close() if __name__ == "__main__": main() ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/cmd/of_config_cli.py0000775000175000017500000003632100000000000020174 0ustar00zuulzuul00000000000000#!/usr/bin/env python3 # # Copyright (C) 2013 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013 YAMAMOTO Takashi # # 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 simple command line OF-CONFIG client # # a usage example: # % PYTHONPATH=. ./bin/of_config_cli \ # --peers=sw1=localhost:1830:username:password # (Cmd) raw_get sw1 import cmd import sys import lxml.etree as ET from ncclient.operations.rpc import RPCError from os_ken import cfg from os_ken.lib import of_config from os_ken.lib.of_config import capable_switch import os_ken.lib.of_config.classes as ofc CONF = cfg.CONF CONF.register_cli_opts([ cfg.ListOpt('peers', default=[], help='list of peers') ]) class Peer(capable_switch.OFCapableSwitch): def __init__(self, name, host, port, username, password): self._name = name super(Peer, self).__init__( host=host, port=port, username=username, password=password, unknown_host_cb=lambda host, fingeprint: True) peers = {} def add_peer(name, host, port, username, password): peers[name] = Peer(name, host, port, username, password) def et_tostring_pp(tree): # pretty_print is an lxml feature, not available in ElementTree try: return ET.tostring(tree, pretty_print=True) except TypeError: return ET.tostring(tree) def validate(tree): schema = ET.XMLSchema(file=of_config.OF_CONFIG_1_1_1_XSD) if not schema(tree): print(schema.error_log) class Cmd(cmd.Cmd): def __init__(self, *args, **kwargs): self._in_onecmd = False cmd.Cmd.__init__(self, *args, **kwargs) def _request(self, line, f): args = line.split() try: peer = args[0] except: print("argument error") return try: p = peers[peer] except KeyError: print("unknown peer %s" % peer) return try: f(p, args[1:]) except RPCError as e: print("RPC Error %s" % e) except EOFError: print("disconnected") def _complete_peer(self, text, line, _begidx, _endidx): if len((line + 'x').split()) >= 3: return [] return [name for name in peers if name.startswith(text)] def do_list_cap(self, line): """list_cap """ def f(p, args): for i in p.netconf.server_capabilities: print(i) self._request(line, f) def do_raw_get(self, line): """raw_get """ def f(p, args): result = p.raw_get() tree = ET.fromstring(result) validate(tree) print(et_tostring_pp(tree)) self._request(line, f) def do_raw_get_config(self, line): """raw_get_config """ def f(p, args): try: source = args[0] except: print("argument error") return result = p.raw_get_config(source) tree = ET.fromstring(result) validate(tree) print(et_tostring_pp(tree)) self._request(line, f) def do_get(self, line): """get eg. get sw1 """ def f(p, args): print(p.get()) self._request(line, f) def do_commit(self, line): """commit eg. commit sw1 """ def f(p, args): print(p.commit()) self._request(line, f) def do_discard(self, line): """discard eg. discard sw1 """ def f(p, args): print(p.discard_changes()) self._request(line, f) def do_get_config(self, line): """get_config eg. get_config sw1 startup """ def f(p, args): try: source = args[0] except: print("argument error") return print(p.get_config(source)) self._request(line, f) def do_delete_config(self, line): """delete_config eg. delete_config sw1 startup """ def f(p, args): try: source = args[0] except: print("argument error") return print(p.delete_config(source)) self._request(line, f) def do_copy_config(self, line): """copy_config eg. copy_config sw1 running startup """ def f(p, args): try: source, target = args except: print("argument error") return print(p.copy_config(source, target)) self._request(line, f) def do_list_port(self, line): """list_port """ def f(p, args): o = p.get() for p in o.resources.port: print('%s %s %s' % (p.resource_id, p.name, p.number)) self._request(line, f) _port_settings = [ 'admin-state', 'no-forward', 'no-packet-in', 'no-receive', ] def do_get_port_config(self, line): """get_config_port eg. get_port_config sw1 running LogicalSwitch7-Port2 """ def f(p, args): try: source, port = args except: print("argument error") return o = p.get_config(source) for p in o.resources.port: if p.resource_id != port: continue print(p.resource_id) conf = p.configuration for k in self._port_settings: try: v = getattr(conf, k) except AttributeError: continue print('%s %s' % (k, v)) self._request(line, f) def do_set_port_config(self, line): """set_port_config eg. set_port_config sw1 running LogicalSwitch7-Port2 admin-state down eg. set_port_config sw1 running LogicalSwitch7-Port2 no-forward false """ def f(p, args): try: target, port, key, value = args except: print("argument error") print(args) return # get switch id o = p.get() capable_switch_id = o.id try: capable_switch = ofc.OFCapableSwitchType( id=capable_switch_id, resources=ofc.OFCapableSwitchResourcesType( port=[ ofc.OFPortType( resource_id=port, configuration=ofc.OFPortConfigurationType( **{key: value})) ] ) ) except TypeError: print("argument error") return try: p.edit_config(target, capable_switch) except Exception as e: print(e) self._request(line, f) def do_list_queue(self, line): """list_queue """ def f(p, args): o = p.get() if o.resources.queue: for q in o.resources.queue: print('%s %s' % (q.resource_id, q.port)) self._request(line, f) _queue_settings = [ 'max-rate', 'min-rate', 'experimenter', ] def do_get_queue_config(self, line): """get_queue_port eg. get_queue_config sw1 running LogicalSwitch7-Port1-Queue922 """ def f(p, args): try: source, queue = args except: print("argument error") return o = p.get_config(source) for q in o.resources.queue: if q.resource_id != queue: continue print(q.resource_id) conf = q.properties for k in self._queue_settings: try: v = getattr(conf, k) except AttributeError: continue print('%s %s' % (k, v)) self._request(line, f) def do_set_queue_config(self, line): """set_queue_config eg. set_queue_config sw1 running LogicalSwitch7-Port1-Queue922 \ max-rate 100 """ def f(p, args): try: target, queue, key, value = args except: print("argument error") print(args) return # get switch id o = p.get() capable_switch_id = o.id try: capable_switch = ofc.OFCapableSwitchType( id=capable_switch_id, resources=ofc.OFCapableSwitchResourcesType( queue=[ ofc.OFQueueType( resource_id=queue, properties=ofc.OFQueuePropertiesType( **{key: value})), ] ) ) except TypeError: print("argument error") return try: p.edit_config(target, capable_switch) except Exception as e: print(e) self._request(line, f) def do_add_queue(self, line): """add_queue eg. add_queue sw1 running LogicalSwitch7 NameOfNewQueue """ def f(p, args): try: target, lsw, queue = args except: print("argument error") print(args) return # get switch id o = p.get() capable_switch_id = o.id try: capable_switch = ofc.OFCapableSwitchType( id=capable_switch_id, resources=ofc.OFCapableSwitchResourcesType( queue=[ ofc.OFQueueType(resource_id=queue) ] ), logical_switches=ofc.OFCapableSwitchLogicalSwitchesType( switch=[ofc.OFLogicalSwitchType( id=lsw, resources=ofc.OFLogicalSwitchResourcesType( queue=[queue]) )] ) ) except TypeError: print("argument error") return try: p.edit_config(target, capable_switch) except Exception as e: print(e) self._request(line, f) def do_list_logical_switch(self, line): """list_logical_switch """ def f(p, args): o = p.get() for s in o.logical_switches.switch: print('%s %s' % (s.id, s.datapath_id)) self._request(line, f) def do_show_logical_switch(self, line): """show_logical_switch """ def f(p, args): try: (lsw,) = args except: print("argument error") return o = p.get() for s in o.logical_switches.switch: if s.id != lsw: continue print(s.id) print('datapath-id %s' % s.datapath_id) if s.resources.queue: print('queues:') for q in s.resources.queue: print('\t %s' % q) if s.resources.port: print('ports:') for p in s.resources.port: print('\t %s' % p) self._request(line, f) _lsw_settings = [ 'lost-connection-behavior', ] def do_get_logical_switch_config(self, line): """get_logical_switch_config """ def f(p, args): try: source, lsw = args except: print("argument error") return o = p.get_config(source) for l in o.logical_switches.switch: if l.id != lsw: continue print(l.id) for k in self._lsw_settings: try: v = getattr(l, k) except AttributeError: continue print('%s %s' % (k, v)) self._request(line, f) def do_set_logical_switch_config(self, line): """set_logical_switch_config eg. set_logical_switch_config sw1 running LogicalSwitch7 \ lost-connection-behavior failStandaloneMode """ def f(p, args): try: target, lsw, key, value = args except: print("argument error") return # get switch id o = p.get_config(target) capable_switch_id = o.id try: capable_switch = ofc.OFCapableSwitchType( id=capable_switch_id, logical_switches=ofc.OFCapableSwitchLogicalSwitchesType( switch=[ofc.OFLogicalSwitchType( id=lsw, **{key: value} )] ) ) except TypeError: print("argument error") return try: p.edit_config(target, capable_switch) except Exception as e: print(e) self._request(line, f) completedefault = _complete_peer def complete_EOF(self, _text, _line, _begidx, _endidx): return [] def do_EOF(self, _line): sys.exit(0) def onecmd(self, string): self._in_onecmd = True try: return cmd.Cmd.onecmd(self, string) finally: self._in_onecmd = False def main(args=None, prog=None): CONF(args=args, prog=prog, project='of-config-cli', version='of-config-cli') for p_str in CONF.peers: name, addr = p_str.split('=') host, port, username, password = addr.rsplit(':', 3) add_peer(name, host, port, username, password) Cmd().cmdloop() if __name__ == "__main__": main() ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/cmd/ofa_neutron_agent.py0000775000175000017500000000246100000000000021107 0ustar00zuulzuul00000000000000#!/usr/bin/env python3 # Copyright (C) 2014 VA Linux Systems Japan K.K. # All Rights Reserved. # # 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. # # @author: Fumihiko Kakuma, VA Linux Systems Japan K.K. # @author: YAMAMOTO Takashi, VA Linux Systems Japan K.K. # NOTE: This module is used by Neutron "ofagent" agent for # IceHouse release. Juno and later releases do not use this. # TODO: Remove this module when IceHouse is EOL'ed. from os_ken.lib import hub hub.patch() from os_ken import cfg from neutron.common import config as logging_config from os_ken.base.app_manager import AppManager def main(): cfg.CONF(project='os_ken') logging_config.setup_logging(cfg.CONF) AppManager.run_apps(['neutron.plugins.ofagent.agent.ofa_neutron_agent']) if __name__ == "__main__": main() ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/cmd/osken_base.py0000664000175000017500000000466000000000000017523 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2014 YAMAMOTO Takashi # # 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. import argparse import os.path import sys from os_ken import cfg from os_ken import utils from os_ken import version subcommands = { 'run': 'os_ken.cmd.manager', 'of-config-cli': 'os_ken.cmd.of_config_cli', 'rpc-cli': 'os_ken.cmd.rpc_cli', } class RemainderOpt(cfg.MultiStrOpt): def _get_argparse_kwargs(self, group, **kwargs): kwargs = cfg.MultiStrOpt._get_argparse_kwargs(self, group, **kwargs) kwargs['nargs'] = argparse.REMAINDER return kwargs base_conf = cfg.ConfigOpts() base_conf.register_cli_opt(cfg.StrOpt('subcommand', positional=True, required=True, help='[%s]' % '|'.join( list(subcommands.keys())))) base_conf.register_cli_opt(RemainderOpt('subcommand_args', default=[], positional=True, help='subcommand specific arguments')) class SubCommand(object): def __init__(self, name, entry): self.name = name self.entry = entry def run(self, args): prog = '%s %s' % (os.path.basename(sys.argv[0]), self.name,) self.entry(args=args, prog=prog) def main(): try: base_conf(project='os_ken', version='os_ken %s' % version) except cfg.RequiredOptError as e: base_conf.print_help() raise SystemExit(1) subcmd_name = base_conf.subcommand try: subcmd_mod_name = subcommands[subcmd_name] except KeyError: base_conf.print_help() raise SystemExit('Unknown subcommand %s' % subcmd_name) subcmd_mod = utils.import_module(subcmd_mod_name) subcmd = SubCommand(name=subcmd_name, entry=subcmd_mod.main) subcmd.run(base_conf.subcommand_args) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/cmd/rpc_cli.py0000775000175000017500000001662600000000000017035 0ustar00zuulzuul00000000000000#!/usr/bin/env python3 # # Copyright (C) 2013 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013 YAMAMOTO Takashi # # 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 simple command line msgpack-rpc client # # a usage example: # % PYTHONPATH=. ./bin/rpc-cli \ # --peers=echo-server=localhost:9999,hoge=localhost:9998 # (Cmd) request echo-server echo ["hoge"] # RESULT hoge # (Cmd) request echo-server notify ["notify-method", ["param1","param2"]] # RESULT notify-method # (Cmd) # NOTIFICATION from echo-server ['notify-method', ['param1', 'param2']] # (Cmd) import ast import cmd import signal import socket import sys import termios from os_ken import cfg from os_ken.lib import rpc CONF = cfg.CONF CONF.register_cli_opts([ cfg.ListOpt('peers', default=[], help='List of peers, separated by commas. ' '(e.g., "hoge=localhost:9998,fuga=localhost:9999")'), cfg.StrOpt('command', short='c', default=None, help='Command to be executed as single command. ' 'The default is None and opens interactive console.'), ]) class Peer(object): def __init__(self, name, addr): self._name = name self._addr = addr self.socket = None self.client = None try: self.connect() except ConnectionError as e: print('Exception when connecting to peer "%s": %s' % (name, e)) raise e def connect(self): self.socket = socket.create_connection(self._addr) self.client = rpc.Client(self.socket, notification_callback=self.notification) def try_to_connect(self, verbose=False): if self.client: return try: self.connect() assert self.client except Exception as e: if verbose: print("connection failure %s" % e) raise EOFError def notification(self, n): print("NOTIFICATION from %s %s" % (self._name, n)) def call(self, method, params): return self._do(lambda: self.client.call(method, params)) def send_notification(self, method, params): self._do(lambda: self.client.send_notification(method, params)) def _do(self, f): def g(): try: return f() except EOFError: self.client = None raise self.try_to_connect(verbose=True) try: return g() except EOFError: print("disconnected. trying to connect...") self.try_to_connect(verbose=True) print("connected. retrying the request...") return g() def close(self): self.socket.close() peers = {} def add_peer(name, host, port): try: peer = Peer(name, (host, port)) except ConnectionError: return peers[name] = peer def close_peers(): for peer in peers.values(): peer.socket.close() class Cmd(cmd.Cmd): def __init__(self, *args, **kwargs): self._in_onecmd = False self._notification_check_interval = 1 # worth to be configurable? self._saved_termios = None cmd.Cmd.__init__(self, *args, **kwargs) def _request(self, line, f): args = line.split(None, 2) try: peer = args[0] method = args[1] params = ast.literal_eval(args[2]) except (IndexError, ValueError) as e: print("argument error: %s" % e) return try: p = peers[peer] except KeyError: print("unknown peer %s" % peer) return try: f(p, method, params) except rpc.RPCError as e: print("RPC ERROR %s" % e) except EOFError: print("disconnected") def _complete_peer(self, text, line, _begidx, _endidx): if len((line + 'x').split()) >= 3: return [] return [name for name in peers if name.startswith(text)] def do_request(self, line): """request send a msgpack-rpc request and print a response. is a python code snippet, it should be eval'ed to a list. """ def f(p, method, params): result = p.call(method, params) print("RESULT %s" % result) self._request(line, f) def do_notify(self, line): """notify send a msgpack-rpc notification. is a python code snippet, it should be eval'ed to a list. """ def f(p, method, params): p.send_notification(method, params) self._request(line, f) def complete_request(self, text, line, begidx, endidx): return self._complete_peer(text, line, begidx, endidx) def complete_notify(self, text, line, begidx, endidx): return self._complete_peer(text, line, begidx, endidx) def do_EOF(self, _line=None): close_peers() sys.exit(0) def emptyline(self): self._peek_notification() def postcmd(self, _stop, _line): self._peek_notification() def _peek_notification(self): for k, p in peers.items(): if p.client: try: p.client.peek_notification() except EOFError: p.client = None print("disconnected %s" % k) @staticmethod def _save_termios(): return termios.tcgetattr(sys.stdin.fileno()) @staticmethod def _restore_termios(t): termios.tcsetattr(sys.stdin.fileno(), termios.TCSADRAIN, t) def preloop(self): self._saved_termios = self._save_termios() signal.signal(signal.SIGALRM, self._timeout) signal.alarm(1) def postloop(self): close_peers() def onecmd(self, string): self._in_onecmd = True try: return cmd.Cmd.onecmd(self, string) finally: self._in_onecmd = False def _timeout(self, _sig, _frame): if not self._in_onecmd: # restore terminal settings. (cooked/raw, ...) # required for pypy at least. # this doesn't seem to be needed for cpython readline # module but i'm not sure if it's by spec or luck. o = self._save_termios() self._restore_termios(self._saved_termios) self._peek_notification() self._restore_termios(o) signal.alarm(self._notification_check_interval) def main(args=None, prog=None): CONF(args=args, prog=prog, project='rpc-cli', version='rpc-cli') for p_str in CONF.peers: name, addr = p_str.split('=') host, port = addr.rsplit(':', 1) add_peer(name, host, port) if CONF.command: command = Cmd() command.onecmd(CONF.command) command.do_EOF() Cmd().cmdloop() if __name__ == "__main__": main() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.0701032 os-ken-2.10.0/os_ken/contrib/0000775000175000017500000000000000000000000015727 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/contrib/__init__.py0000664000175000017500000000107300000000000020041 0ustar00zuulzuul00000000000000import sys _orig_sys_path = None def update_module_path(): # Adjust module loading path for third party libraries import os global _orig_sys_path _orig_sys_path = sys.path[:] for path in __path__: if path in sys.path: sys.path.remove(path) path = os.path.abspath(path) if path in sys.path: sys.path.remove(path) sys.path.insert(0, path) # prioritize our own copy than system's def restore_module_path(): global _orig_sys_path sys.path = _orig_sys_path _orig_sys_path = None ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.0701032 os-ken-2.10.0/os_ken/controller/0000775000175000017500000000000000000000000016452 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/controller/__init__.py0000664000175000017500000000000000000000000020551 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/controller/conf_switch.py0000664000175000017500000000571600000000000021343 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2012 Isaku Yamahata # # 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. import logging from os_ken.controller import event from os_ken.lib.dpid import dpid_to_str from os_ken.base import app_manager LOG = logging.getLogger(__name__) class EventConfSwitchDelDPID(event.EventBase): def __init__(self, dpid): super(EventConfSwitchDelDPID, self).__init__() self.dpid = dpid def __str__(self): return 'EventConfSwitchDelDPID<%s>' % dpid_to_str(self.dpid) class EventConfSwitchSet(event.EventBase): def __init__(self, dpid, key, value): super(EventConfSwitchSet, self).__init__() self.dpid = dpid self.key = key self.value = value def __str__(self): return 'EventConfSwitchSet<%s, %s, %s>' % ( dpid_to_str(self.dpid), self.key, self.value) class EventConfSwitchDel(event.EventBase): def __init__(self, dpid, key): super(EventConfSwitchDel, self).__init__() self.dpid = dpid self.key = key def __str__(self): return 'EventConfSwitchDel<%s, %s>' % (dpid_to_str(self.dpid), self.key) class ConfSwitchSet(app_manager.OSKenApp): def __init__(self): super(ConfSwitchSet, self).__init__() self.name = 'conf_switch' self.confs = {} def dpids(self): return list(self.confs.keys()) def del_dpid(self, dpid): del self.confs[dpid] self.send_event_to_observers(EventConfSwitchDelDPID(dpid)) def keys(self, dpid): return list(self.confs[dpid].keys()) def set_key(self, dpid, key, value): conf = self.confs.setdefault(dpid, {}) conf[key] = value self.send_event_to_observers(EventConfSwitchSet(dpid, key, value)) def get_key(self, dpid, key): return self.confs[dpid][key] def del_key(self, dpid, key): del self.confs[dpid][key] self.send_event_to_observers(EventConfSwitchDel(dpid, key)) # methods for TunnelUpdater def __contains__(self, item): """(dpid, key) in """ (dpid, key) = item return dpid in self.confs and key in self.confs[dpid] def find_dpid(self, key, value): for dpid, conf in self.confs.items(): if key in conf: if conf[key] == value: return dpid return None ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/controller/controller.py0000664000175000017500000005316200000000000021216 0ustar00zuulzuul00000000000000# Copyright (C) 2011, 2012 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2011, 2012 Isaku Yamahata # # 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. """ The main component of OpenFlow controller. - Handle connections from switches - Generate and route events to appropriate entities like OSKen applications """ import contextlib import logging import random from socket import IPPROTO_TCP from socket import TCP_NODELAY from socket import SHUT_WR from socket import timeout as SocketTimeout import ssl from os_ken import cfg from os_ken.lib import hub from os_ken.lib.hub import StreamServer import os_ken.base.app_manager from os_ken.ofproto import ofproto_common from os_ken.ofproto import ofproto_parser from os_ken.ofproto import ofproto_protocol from os_ken.ofproto import ofproto_v1_0 from os_ken.ofproto import nx_match from os_ken.controller import ofp_event from os_ken.controller.handler import HANDSHAKE_DISPATCHER, DEAD_DISPATCHER from os_ken.lib.dpid import dpid_to_str from os_ken.lib import ip LOG = logging.getLogger('os_ken.controller.controller') DEFAULT_OFP_HOST = '0.0.0.0' DEFAULT_OFP_SW_CON_INTERVAL = 1 CONF = cfg.CONF CONF.register_cli_opts([ cfg.StrOpt('ofp-listen-host', default=DEFAULT_OFP_HOST, help='openflow listen host (default %s)' % DEFAULT_OFP_HOST), cfg.IntOpt('ofp-tcp-listen-port', default=None, help='openflow tcp listen port ' '(default: %d)' % ofproto_common.OFP_TCP_PORT), cfg.IntOpt('ofp-ssl-listen-port', default=None, help='openflow ssl listen port ' '(default: %d)' % ofproto_common.OFP_SSL_PORT), cfg.StrOpt('ctl-privkey', default=None, help='controller private key'), cfg.StrOpt('ctl-cert', default=None, help='controller certificate'), cfg.StrOpt('ca-certs', default=None, help='CA certificates'), cfg.StrOpt('ciphers', default=None, help='list of ciphers to enable'), cfg.ListOpt('ofp-switch-address-list', item_type=str, default=[], help='list of IP address and port pairs (default empty). ' 'e.g., "127.0.0.1:6653,[::1]:6653"'), cfg.IntOpt('ofp-switch-connect-interval', default=DEFAULT_OFP_SW_CON_INTERVAL, help='interval in seconds to connect to switches ' '(default %d)' % DEFAULT_OFP_SW_CON_INTERVAL), ]) CONF.register_opts([ cfg.FloatOpt('socket-timeout', default=5.0, help='Time, in seconds, to await completion of socket operations.'), cfg.FloatOpt('echo-request-interval', default=15.0, help='Time, in seconds, between sending echo requests to a datapath.'), cfg.IntOpt('maximum-unreplied-echo-requests', default=0, min=0, help='Maximum number of unreplied echo requests before datapath is disconnected.') ]) def _split_addr(addr): """ Splits a str of IP address and port pair into (host, port). Example:: >>> _split_addr('127.0.0.1:6653') ('127.0.0.1', 6653) >>> _split_addr('[::1]:6653') ('::1', 6653) Raises ValueError if invalid format. :param addr: A pair of IP address and port. :return: IP address and port """ e = ValueError('Invalid IP address and port pair: "%s"' % addr) pair = addr.rsplit(':', 1) if len(pair) != 2: raise e addr, port = pair if addr.startswith('[') and addr.endswith(']'): addr = addr.lstrip('[').rstrip(']') if not ip.valid_ipv6(addr): raise e elif not ip.valid_ipv4(addr): raise e return addr, int(port, 0) class OpenFlowController(object): def __init__(self): super(OpenFlowController, self).__init__() if not CONF.ofp_tcp_listen_port and not CONF.ofp_ssl_listen_port: self.ofp_tcp_listen_port = ofproto_common.OFP_TCP_PORT self.ofp_ssl_listen_port = ofproto_common.OFP_SSL_PORT # For the backward compatibility, we spawn a server loop # listening on the old OpenFlow listen port 6633. hub.spawn(self.server_loop, ofproto_common.OFP_TCP_PORT_OLD, ofproto_common.OFP_SSL_PORT_OLD) else: self.ofp_tcp_listen_port = CONF.ofp_tcp_listen_port self.ofp_ssl_listen_port = CONF.ofp_ssl_listen_port # Example: # self._clients = { # ('127.0.0.1', 6653): , # } self._clients = {} # entry point def __call__(self): # LOG.debug('call') for address in CONF.ofp_switch_address_list: addr = tuple(_split_addr(address)) self.spawn_client_loop(addr) self.server_loop(self.ofp_tcp_listen_port, self.ofp_ssl_listen_port) def spawn_client_loop(self, addr, interval=None): interval = interval or CONF.ofp_switch_connect_interval client = hub.StreamClient(addr) hub.spawn(client.connect_loop, datapath_connection_factory, interval) self._clients[addr] = client def stop_client_loop(self, addr): client = self._clients.get(addr, None) if client is not None: client.stop() def server_loop(self, ofp_tcp_listen_port, ofp_ssl_listen_port): if CONF.ctl_privkey is not None and CONF.ctl_cert is not None: p = 'PROTOCOL_TLS' ssl_args = {'ssl_ctx': ssl.SSLContext(getattr(ssl, p))} # Restrict non-safe versions ssl_args['ssl_ctx'].options |= ssl.OP_NO_SSLv3 | ssl.OP_NO_SSLv2 if CONF.ciphers is not None: ssl_args['ciphers'] = CONF.ciphers if CONF.ca_certs is not None: server = StreamServer((CONF.ofp_listen_host, ofp_ssl_listen_port), datapath_connection_factory, keyfile=CONF.ctl_privkey, certfile=CONF.ctl_cert, cert_reqs=ssl.CERT_REQUIRED, ca_certs=CONF.ca_certs, **ssl_args) else: server = StreamServer((CONF.ofp_listen_host, ofp_ssl_listen_port), datapath_connection_factory, keyfile=CONF.ctl_privkey, certfile=CONF.ctl_cert, **ssl_args) else: server = StreamServer((CONF.ofp_listen_host, ofp_tcp_listen_port), datapath_connection_factory) # LOG.debug('loop') server.serve_forever() def _deactivate(method): def deactivate(self): try: method(self) finally: try: self.socket.close() except IOError: pass return deactivate class Datapath(ofproto_protocol.ProtocolDesc): """ A class to describe an OpenFlow switch connected to this controller. An instance has the following attributes. .. tabularcolumns:: |l|L| ==================================== ====================================== Attribute Description ==================================== ====================================== id 64-bit OpenFlow Datapath ID. Only available for os_ken.controller.handler.MAIN_DISPATCHER phase. ofproto A module which exports OpenFlow definitions, mainly constants appeared in the specification, for the negotiated OpenFlow version. For example, os_ken.ofproto.ofproto_v1_0 for OpenFlow 1.0. ofproto_parser A module which exports OpenFlow wire message encoder and decoder for the negotiated OpenFlow version. For example, os_ken.ofproto.ofproto_v1_0_parser for OpenFlow 1.0. ofproto_parser.OFPxxxx(datapath,...) A callable to prepare an OpenFlow message for the given switch. It can be sent with Datapath.send_msg later. xxxx is a name of the message. For example OFPFlowMod for flow-mod message. Arguemnts depend on the message. set_xid(self, msg) Generate an OpenFlow XID and put it in msg.xid. send_msg(self, msg) Queue an OpenFlow message to send to the corresponding switch. If msg.xid is None, set_xid is automatically called on the message before queueing. send_packet_out deprecated send_flow_mod deprecated send_flow_del deprecated send_delete_all_flows deprecated send_barrier Queue an OpenFlow barrier message to send to the switch. send_nxt_set_flow_format deprecated is_reserved_port deprecated ==================================== ====================================== """ def __init__(self, socket, address): super(Datapath, self).__init__() self.socket = socket self.socket.setsockopt(IPPROTO_TCP, TCP_NODELAY, 1) self.socket.settimeout(CONF.socket_timeout) self.address = address self.is_active = True # The limit is arbitrary. We need to limit queue size to # prevent it from eating memory up. self.send_q = hub.Queue(16) self._send_q_sem = hub.BoundedSemaphore(self.send_q.maxsize) self.echo_request_interval = CONF.echo_request_interval self.max_unreplied_echo_requests = CONF.maximum_unreplied_echo_requests self.unreplied_echo_requests = [] self.xid = random.randint(0, self.ofproto.MAX_XID) self.id = None # datapath_id is unknown yet self._ports = None self.flow_format = ofproto_v1_0.NXFF_OPENFLOW10 self.ofp_brick = os_ken.base.app_manager.lookup_service_brick('ofp_event') self.state = None # for pylint self.set_state(HANDSHAKE_DISPATCHER) def _close_write(self): # Note: Close only further sends in order to wait for the switch to # disconnect this connection. try: self.socket.shutdown(SHUT_WR) except (EOFError, IOError): pass def close(self): self.set_state(DEAD_DISPATCHER) self._close_write() def set_state(self, state): if self.state == state: return self.state = state ev = ofp_event.EventOFPStateChange(self) ev.state = state if self.ofp_brick is not None: self.ofp_brick.send_event_to_observers(ev, state) # Low level socket handling layer @_deactivate def _recv_loop(self): buf = bytearray() count = 0 min_read_len = remaining_read_len = ofproto_common.OFP_HEADER_SIZE while self.state != DEAD_DISPATCHER: try: read_len = min_read_len if remaining_read_len > min_read_len: read_len = remaining_read_len ret = self.socket.recv(read_len) except SocketTimeout: continue except ssl.SSLError: # eventlet throws SSLError (which is a subclass of IOError) # on SSL socket read timeout; re-try the loop in this case. continue except (EOFError, IOError): break if not ret: break buf += ret buf_len = len(buf) while buf_len >= min_read_len: (version, msg_type, msg_len, xid) = ofproto_parser.header(buf) if msg_len < min_read_len: # Someone isn't playing nicely; log it, and try something sane. LOG.debug("Message with invalid length %s received from switch at address %s", msg_len, self.address) msg_len = min_read_len if buf_len < msg_len: remaining_read_len = (msg_len - buf_len) break msg = ofproto_parser.msg( self, version, msg_type, msg_len, xid, buf[:msg_len]) # LOG.debug('queue msg %s cls %s', msg, msg.__class__) if msg: ev = ofp_event.ofp_msg_to_ev(msg) if self.ofp_brick is not None: self.ofp_brick.send_event_to_observers(ev, self.state) def dispatchers(x): return x.callers[ev.__class__].dispatchers handlers = [handler for handler in self.ofp_brick.get_handlers(ev) if self.state in dispatchers(handler)] for handler in handlers: handler(ev) buf = buf[msg_len:] buf_len = len(buf) remaining_read_len = min_read_len # We need to schedule other greenlets. Otherwise, os_ken # can't accept new switches or handle the existing # switches. The limit is arbitrary. We need the better # approach in the future. count += 1 if count > 2048: count = 0 hub.sleep(0) def _send_loop(self): try: while self.state != DEAD_DISPATCHER: buf, close_socket = self.send_q.get() self._send_q_sem.release() self.socket.sendall(buf) if close_socket: break except SocketTimeout: LOG.debug("Socket timed out while sending data to switch at address %s", self.address) except IOError as ioe: # Convert ioe.errno to a string, just in case it was somehow set to None. errno = "%s" % ioe.errno LOG.debug("Socket error while sending data to switch at address %s: [%s] %s", self.address, errno, ioe.strerror) finally: q = self.send_q # First, clear self.send_q to prevent new references. self.send_q = None # Now, drain the send_q, releasing the associated semaphore for each entry. # This should release all threads waiting to acquire the semaphore. try: while q.get(block=False): self._send_q_sem.release() except hub.QueueEmpty: pass # Finally, disallow further sends. self._close_write() def send(self, buf, close_socket=False): msg_enqueued = False self._send_q_sem.acquire() if self.send_q: self.send_q.put((buf, close_socket)) msg_enqueued = True else: self._send_q_sem.release() if not msg_enqueued: LOG.debug('Datapath in process of terminating; send() to %s discarded.', self.address) return msg_enqueued def set_xid(self, msg): self.xid += 1 self.xid &= self.ofproto.MAX_XID msg.set_xid(self.xid) return self.xid def send_msg(self, msg, close_socket=False): assert isinstance(msg, self.ofproto_parser.MsgBase) if msg.xid is None: self.set_xid(msg) msg.serialize() # LOG.debug('send_msg %s', msg) return self.send(msg.buf, close_socket=close_socket) def _echo_request_loop(self): if not self.max_unreplied_echo_requests: return while (self.send_q and (len(self.unreplied_echo_requests) <= self.max_unreplied_echo_requests)): echo_req = self.ofproto_parser.OFPEchoRequest(self) self.unreplied_echo_requests.append(self.set_xid(echo_req)) self.send_msg(echo_req) hub.sleep(self.echo_request_interval) self.close() def acknowledge_echo_reply(self, xid): try: self.unreplied_echo_requests.remove(xid) except ValueError: pass def serve(self): send_thr = hub.spawn(self._send_loop) # send hello message immediately hello = self.ofproto_parser.OFPHello(self) self.send_msg(hello) echo_thr = hub.spawn(self._echo_request_loop) try: self._recv_loop() finally: hub.kill(send_thr) hub.kill(echo_thr) hub.joinall([send_thr, echo_thr]) self.is_active = False # # Utility methods for convenience # def send_packet_out(self, buffer_id=0xffffffff, in_port=None, actions=None, data=None): if in_port is None: in_port = self.ofproto.OFPP_NONE packet_out = self.ofproto_parser.OFPPacketOut( self, buffer_id, in_port, actions, data) self.send_msg(packet_out) def send_flow_mod(self, rule, cookie, command, idle_timeout, hard_timeout, priority=None, buffer_id=0xffffffff, out_port=None, flags=0, actions=None): if priority is None: priority = self.ofproto.OFP_DEFAULT_PRIORITY if out_port is None: out_port = self.ofproto.OFPP_NONE flow_format = rule.flow_format() assert (flow_format == ofproto_v1_0.NXFF_OPENFLOW10 or flow_format == ofproto_v1_0.NXFF_NXM) if self.flow_format < flow_format: self.send_nxt_set_flow_format(flow_format) if flow_format == ofproto_v1_0.NXFF_OPENFLOW10: match_tuple = rule.match_tuple() match = self.ofproto_parser.OFPMatch(*match_tuple) flow_mod = self.ofproto_parser.OFPFlowMod( self, match, cookie, command, idle_timeout, hard_timeout, priority, buffer_id, out_port, flags, actions) else: flow_mod = self.ofproto_parser.NXTFlowMod( self, cookie, command, idle_timeout, hard_timeout, priority, buffer_id, out_port, flags, rule, actions) self.send_msg(flow_mod) def send_flow_del(self, rule, cookie, out_port=None): self.send_flow_mod(rule=rule, cookie=cookie, command=self.ofproto.OFPFC_DELETE, idle_timeout=0, hard_timeout=0, priority=0, out_port=out_port) def send_delete_all_flows(self): rule = nx_match.ClsRule() self.send_flow_mod( rule=rule, cookie=0, command=self.ofproto.OFPFC_DELETE, idle_timeout=0, hard_timeout=0, priority=0, buffer_id=0, out_port=self.ofproto.OFPP_NONE, flags=0, actions=None) def send_barrier(self): barrier_request = self.ofproto_parser.OFPBarrierRequest(self) return self.send_msg(barrier_request) def send_nxt_set_flow_format(self, flow_format): assert (flow_format == ofproto_v1_0.NXFF_OPENFLOW10 or flow_format == ofproto_v1_0.NXFF_NXM) if self.flow_format == flow_format: # Nothing to do return self.flow_format = flow_format set_format = self.ofproto_parser.NXTSetFlowFormat(self, flow_format) # FIXME: If NXT_SET_FLOW_FORMAT or NXFF_NXM is not supported by # the switch then an error message will be received. It may be # handled by setting self.flow_format to # ofproto_v1_0.NXFF_OPENFLOW10 but currently isn't. self.send_msg(set_format) self.send_barrier() def is_reserved_port(self, port_no): return port_no > self.ofproto.OFPP_MAX def datapath_connection_factory(socket, address): LOG.debug('connected socket:%s address:%s', socket, address) with contextlib.closing(Datapath(socket, address)) as datapath: try: datapath.serve() except: # Something went wrong. # Especially malicious switch can send malformed packet, # the parser raise exception. # Can we do anything more graceful? if datapath.id is None: dpid_str = "%s" % datapath.id else: dpid_str = dpid_to_str(datapath.id) LOG.error("Error in the datapath %s from %s", dpid_str, address) raise ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/controller/dpset.py0000664000175000017500000003030600000000000020145 0ustar00zuulzuul00000000000000# Copyright (C) 2012, 2013 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2012 Isaku Yamahata # # 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. """ Manage switches. Planned to be replaced by os_ken/topology. """ import logging import warnings from os_ken.base import app_manager from os_ken.controller import event from os_ken.controller import handler from os_ken.controller import ofp_event from os_ken.controller.handler import set_ev_cls import os_ken.exception as os_ken_exc from os_ken.lib.dpid import dpid_to_str LOG = logging.getLogger('os_ken.controller.dpset') DPSET_EV_DISPATCHER = "dpset" class EventDPBase(event.EventBase): def __init__(self, dp): super(EventDPBase, self).__init__() self.dp = dp class EventDP(EventDPBase): """ An event class to notify connect/disconnect of a switch. For OpenFlow switches, one can get the same notification by observing os_ken.controller.ofp_event.EventOFPStateChange. An instance has at least the following attributes. ========= ================================================================= Attribute Description ========= ================================================================= dp A os_ken.controller.controller.Datapath instance of the switch enter True when the switch connected to our controller. False for disconnect. ports A list of port instances. ========= ================================================================= """ def __init__(self, dp, enter_leave): # enter_leave # True: dp entered # False: dp leaving super(EventDP, self).__init__(dp) self.enter = enter_leave self.ports = [] # port list when enter or leave class EventDPReconnected(EventDPBase): def __init__(self, dp): super(EventDPReconnected, self).__init__(dp) # port list, which should not change across reconnects self.ports = [] class EventPortBase(EventDPBase): def __init__(self, dp, port): super(EventPortBase, self).__init__(dp) self.port = port class EventPortAdd(EventPortBase): """ An event class for switch port status "ADD" notification. This event is generated when a new port is added to a switch. For OpenFlow switches, one can get the same notification by observing os_ken.controller.ofp_event.EventOFPPortStatus. An instance has at least the following attributes. ========= ================================================================= Attribute Description ========= ================================================================= dp A os_ken.controller.controller.Datapath instance of the switch port port number ========= ================================================================= """ def __init__(self, dp, port): super(EventPortAdd, self).__init__(dp, port) class EventPortDelete(EventPortBase): """ An event class for switch port status "DELETE" notification. This event is generated when a port is removed from a switch. For OpenFlow switches, one can get the same notification by observing os_ken.controller.ofp_event.EventOFPPortStatus. An instance has at least the following attributes. ========= ================================================================= Attribute Description ========= ================================================================= dp A os_ken.controller.controller.Datapath instance of the switch port port number ========= ================================================================= """ def __init__(self, dp, port): super(EventPortDelete, self).__init__(dp, port) class EventPortModify(EventPortBase): """ An event class for switch port status "MODIFY" notification. This event is generated when some attribute of a port is changed. For OpenFlow switches, one can get the same notification by observing os_ken.controller.ofp_event.EventOFPPortStatus. An instance has at least the following attributes. ========= ==================================================================== Attribute Description ========= ==================================================================== dp A os_ken.controller.controller.Datapath instance of the switch port port number ========= ==================================================================== """ def __init__(self, dp, new_port): super(EventPortModify, self).__init__(dp, new_port) class PortState(dict): def __init__(self): super(PortState, self).__init__() def add(self, port_no, port): self[port_no] = port def remove(self, port_no): del self[port_no] def modify(self, port_no, port): self[port_no] = port # this depends on controller::Datapath and dispatchers in handler class DPSet(app_manager.OSKenApp): """ DPSet application manages a set of switches (datapaths) connected to this controller. Usage Example:: # ...(snip)... from os_ken.controller import dpset class MyApp(app_manager.OSKenApp): _CONTEXTS = { 'dpset': dpset.DPSet, } def __init__(self, *args, **kwargs): super(MyApp, self).__init__(*args, **kwargs) # Stores DPSet instance to call its API in this app self.dpset = kwargs['dpset'] def _my_handler(self): # Get the datapath object which has the given dpid dpid = 1 dp = self.dpset.get(dpid) if dp is None: self.logger.info('No such datapath: dpid=%d', dpid) """ def __init__(self, *args, **kwargs): super(DPSet, self).__init__(*args, **kwargs) self.name = 'dpset' self.dps = {} # datapath_id => class Datapath self.port_state = {} # datapath_id => ports def _register(self, dp): LOG.debug('DPSET: register datapath %s', dp) assert dp.id is not None # while dpid should be unique, we need to handle duplicates here # because it's entirely possible for a switch to reconnect us # before we notice the drop of the previous connection. # in that case, # - forget the older connection as it likely will disappear soon # - do not send EventDP leave/enter events # - keep the PortState for the dpid send_dp_reconnected = False if dp.id in self.dps: self.logger.warning('DPSET: Multiple connections from %s', dpid_to_str(dp.id)) self.logger.debug('DPSET: Forgetting datapath %s', self.dps[dp.id]) (self.dps[dp.id]).close() self.logger.debug('DPSET: New datapath %s', dp) send_dp_reconnected = True self.dps[dp.id] = dp if dp.id not in self.port_state: self.port_state[dp.id] = PortState() ev = EventDP(dp, True) with warnings.catch_warnings(): warnings.simplefilter('ignore') for port in dp.ports.values(): self._port_added(dp, port) ev.ports.append(port) self.send_event_to_observers(ev) if send_dp_reconnected: ev = EventDPReconnected(dp) ev.ports = self.port_state.get(dp.id, {}).values() self.send_event_to_observers(ev) def _unregister(self, dp): # see the comment in _register(). if dp not in self.dps.values(): return LOG.debug('DPSET: unregister datapath %s', dp) assert self.dps[dp.id] == dp # Now datapath is already dead, so port status change event doesn't # interfere us. ev = EventDP(dp, False) for port in list(self.port_state.get(dp.id, {}).values()): self._port_deleted(dp, port) ev.ports.append(port) self.send_event_to_observers(ev) del self.dps[dp.id] del self.port_state[dp.id] def get(self, dp_id): """ This method returns the os_ken.controller.controller.Datapath instance for the given Datapath ID. """ return self.dps.get(dp_id) def get_all(self): """ This method returns a list of tuples which represents instances for switches connected to this controller. The tuple consists of a Datapath ID and an instance of os_ken.controller.controller.Datapath. A return value looks like the following:: [ (dpid_A, Datapath_A), (dpid_B, Datapath_B), ... ] """ return list(self.dps.items()) def _port_added(self, datapath, port): self.port_state[datapath.id].add(port.port_no, port) def _port_deleted(self, datapath, port): self.port_state[datapath.id].remove(port.port_no) @set_ev_cls(ofp_event.EventOFPStateChange, [handler.MAIN_DISPATCHER, handler.DEAD_DISPATCHER]) def dispatcher_change(self, ev): datapath = ev.datapath assert datapath is not None if ev.state == handler.MAIN_DISPATCHER: self._register(datapath) elif ev.state == handler.DEAD_DISPATCHER: self._unregister(datapath) @set_ev_cls(ofp_event.EventOFPSwitchFeatures, handler.CONFIG_DISPATCHER) def switch_features_handler(self, ev): msg = ev.msg datapath = msg.datapath # ofp_handler.py does the following so we could remove... if datapath.ofproto.OFP_VERSION < 0x04: datapath.ports = msg.ports @set_ev_cls(ofp_event.EventOFPPortStatus, handler.MAIN_DISPATCHER) def port_status_handler(self, ev): msg = ev.msg reason = msg.reason datapath = msg.datapath port = msg.desc ofproto = datapath.ofproto if reason == ofproto.OFPPR_ADD: LOG.debug('DPSET: A port was added.' + '(datapath id = %s, port number = %s)', dpid_to_str(datapath.id), port.port_no) self._port_added(datapath, port) self.send_event_to_observers(EventPortAdd(datapath, port)) elif reason == ofproto.OFPPR_DELETE: LOG.debug('DPSET: A port was deleted.' + '(datapath id = %s, port number = %s)', dpid_to_str(datapath.id), port.port_no) self._port_deleted(datapath, port) self.send_event_to_observers(EventPortDelete(datapath, port)) else: assert reason == ofproto.OFPPR_MODIFY LOG.debug('DPSET: A port was modified.' + '(datapath id = %s, port number = %s)', dpid_to_str(datapath.id), port.port_no) self.port_state[datapath.id].modify(port.port_no, port) self.send_event_to_observers(EventPortModify(datapath, port)) def get_port(self, dpid, port_no): """ This method returns the os_ken.controller.dpset.PortState instance for the given Datapath ID and the port number. Raises os_ken_exc.PortNotFound if no such a datapath connected to this controller or no such a port exists. """ try: return self.port_state[dpid][port_no] except KeyError: raise os_ken_exc.PortNotFound(dpid=dpid, port=port_no, network_id=None) def get_ports(self, dpid): """ This method returns a list of os_ken.controller.dpset.PortState instances for the given Datapath ID. Raises KeyError if no such a datapath connected to this controller. """ return list(self.port_state[dpid].values()) handler.register_service('os_ken.controller.dpset') ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/controller/event.py0000664000175000017500000000266200000000000020153 0ustar00zuulzuul00000000000000# Copyright (C) 2011 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2011 Isaku Yamahata # # 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 EventBase(object): """ The base of all event classes. A OSKen application can define its own event type by creating a subclass. """ def __init__(self): super(EventBase, self).__init__() class EventRequestBase(EventBase): """ The base class for synchronous request for OSKenApp.send_request. """ def __init__(self): super(EventRequestBase, self).__init__() self.dst = None # app.name of provide the event. self.src = None self.sync = False self.reply_q = None class EventReplyBase(EventBase): """ The base class for synchronous request reply for OSKenApp.send_reply. """ def __init__(self, dst): super(EventReplyBase, self).__init__() self.dst = dst ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/controller/handler.py0000664000175000017500000001307500000000000020447 0ustar00zuulzuul00000000000000# Copyright (C) 2011-2014 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2011, 2012 Isaku Yamahata # # 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. import inspect import logging import sys LOG = logging.getLogger('os_ken.controller.handler') # just represent OF datapath state. datapath specific so should be moved. HANDSHAKE_DISPATCHER = "handshake" CONFIG_DISPATCHER = "config" MAIN_DISPATCHER = "main" DEAD_DISPATCHER = "dead" class _Caller(object): """Describe how to handle an event class. """ def __init__(self, dispatchers, ev_source): """Initialize _Caller. :param dispatchers: A list of states or a state, in which this is in effect. None and [] mean all states. :param ev_source: The module which generates the event. ev_cls.__module__ for set_ev_cls. None for set_ev_handler. """ self.dispatchers = dispatchers self.ev_source = ev_source # should be named something like 'observe_event' def set_ev_cls(ev_cls, dispatchers=None): """ A decorator for OSKen application to declare an event handler. Decorated method will become an event handler. ev_cls is an event class whose instances this OSKenApp wants to receive. dispatchers argument specifies one of the following negotiation phases (or a list of them) for which events should be generated for this handler. Note that, in case an event changes the phase, the phase before the change is used to check the interest. .. tabularcolumns:: |l|L| ============================================== =============================== Negotiation phase Description ============================================== =============================== os_ken.controller.handler.HANDSHAKE_DISPATCHER Sending and waiting for hello message os_ken.controller.handler.CONFIG_DISPATCHER Version negotiated and sent features-request message os_ken.controller.handler.MAIN_DISPATCHER Switch-features message received and sent set-config message os_ken.controller.handler.DEAD_DISPATCHER Disconnect from the peer. Or disconnecting due to some unrecoverable errors. ============================================== =============================== """ def _set_ev_cls_dec(handler): if 'callers' not in dir(handler): handler.callers = {} for e in _listify(ev_cls): handler.callers[e] = _Caller(_listify(dispatchers), e.__module__) return handler return _set_ev_cls_dec def set_ev_handler(ev_cls, dispatchers=None): def _set_ev_cls_dec(handler): if 'callers' not in dir(handler): handler.callers = {} for e in _listify(ev_cls): handler.callers[e] = _Caller(_listify(dispatchers), None) return handler return _set_ev_cls_dec def _has_caller(meth): return hasattr(meth, 'callers') def _listify(may_list): if may_list is None: may_list = [] if not isinstance(may_list, list): may_list = [may_list] return may_list def register_instance(i): for _k, m in inspect.getmembers(i, inspect.ismethod): # LOG.debug('instance %s k %s m %s', i, _k, m) if _has_caller(m): for ev_cls, c in m.callers.items(): i.register_handler(ev_cls, m) def _is_method(f): return inspect.isfunction(f) or inspect.ismethod(f) def get_dependent_services(cls): services = [] for _k, m in inspect.getmembers(cls, _is_method): if _has_caller(m): for ev_cls, c in m.callers.items(): service = getattr(sys.modules[ev_cls.__module__], '_SERVICE_NAME', None) if service: # avoid cls that registers the own events (like # ofp_handler) if cls.__module__ != service: services.append(service) m = sys.modules[cls.__module__] services.extend(getattr(m, '_REQUIRED_APP', [])) services = list(set(services)) return services def register_service(service): """ Register the os_ken application specified by 'service' as a provider of events defined in the calling module. If an application being loaded consumes events (in the sense of set_ev_cls) provided by the 'service' application, the latter application will be automatically loaded. This mechanism is used to e.g. automatically start ofp_handler if there are applications consuming OFP events. """ frame = inspect.currentframe() if frame is not None: m_name = frame.f_back.f_globals['__name__'] m = sys.modules[m_name] m._SERVICE_NAME = service ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/controller/mac_to_network.py0000664000175000017500000000366700000000000022053 0ustar00zuulzuul00000000000000# Copyright (C) 2011 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2011 Isaku Yamahata # # 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. import logging from os_ken.exception import MacAddressDuplicated from os_ken.lib.mac import haddr_to_str LOG = logging.getLogger('os_ken.controller.mac_to_network') class MacToNetwork(object): def __init__(self, nw): super(MacToNetwork, self).__init__() self.mac_to_net = {} self.dpid = {} self.nw = nw def get_network(self, mac, default=None): return self.mac_to_net.get(mac, default) def add_mac(self, mac, nw_id, nw_id_external=None): _nw_id = self.mac_to_net.get(mac) if _nw_id == nw_id: return # allow changing from nw_id_external to known nw id if _nw_id is None or _nw_id == nw_id_external: self.mac_to_net[mac] = nw_id LOG.debug('overwrite nw_id: mac %s nw old %s new %s', haddr_to_str(mac), _nw_id, nw_id) return if nw_id == nw_id_external: # this can happens when the packet traverses # VM-> tap-> ovs-> ext-port-> wire-> ext-port-> ovs-> tap-> VM return LOG.warning('duplicated nw_id: mac %s nw old %s new %s', haddr_to_str(mac), _nw_id, nw_id) raise MacAddressDuplicated(mac=mac) def del_mac(self, mac): del self.mac_to_net[mac] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/controller/mac_to_port.py0000664000175000017500000000356400000000000021342 0ustar00zuulzuul00000000000000# Copyright (C) 2011 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2011 Isaku Yamahata # # 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. import logging from os_ken.lib.mac import haddr_to_str LOG = logging.getLogger('os_ken.controller.mac_to_port') class MacToPortTable(object): """MAC addr <-> (dpid, port name)""" def __init__(self): super(MacToPortTable, self).__init__() self.mac_to_port = {} def dpid_add(self, dpid): LOG.debug('dpid_add: 0x%016x', dpid) self.mac_to_port.setdefault(dpid, {}) def port_add(self, dpid, port, mac): """ :returns: old port if learned. (this may be = port) None otherwise """ old_port = self.mac_to_port[dpid].get(mac, None) self.mac_to_port[dpid][mac] = port if old_port is not None and old_port != port: LOG.debug('port_add: 0x%016x 0x%04x %s', dpid, port, haddr_to_str(mac)) return old_port def port_get(self, dpid, mac): # LOG.debug('dpid 0x%016x mac %s', dpid, haddr_to_str(mac)) return self.mac_to_port[dpid].get(mac) def mac_list(self, dpid, port): return [mac for (mac, port_) in self.mac_to_port.get(dpid, {}).items() if port_ == port] def mac_del(self, dpid, mac): del self.mac_to_port[dpid][mac] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/controller/network.py0000664000175000017500000004600000000000000020515 0ustar00zuulzuul00000000000000# Copyright (C) 2011 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2011 Isaku Yamahata # # 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. import collections from os_ken.base import app_manager import os_ken.exception as os_ken_exc from os_ken.controller import event from os_ken.exception import NetworkNotFound, NetworkAlreadyExist from os_ken.exception import PortAlreadyExist, PortNotFound, PortUnknown NW_ID_UNKNOWN = '__NW_ID_UNKNOWN__' class MacAddressAlreadyExist(os_ken_exc.OSKenException): message = 'port (%(dpid)s, %(port)s) has already mac %(mac_address)s' class EventNetworkDel(event.EventBase): """ An event class for network deletion. This event is generated when a network is deleted by the REST API. An instance has at least the following attributes. ========== =================================================================== Attribute Description ========== =================================================================== network_id Network ID ========== =================================================================== """ def __init__(self, network_id): super(EventNetworkDel, self).__init__() self.network_id = network_id class EventNetworkPort(event.EventBase): """ An event class for notification of port arrival and deperture. This event is generated when a port is introduced to or removed from a network by the REST API. An instance has at least the following attributes. ========== ================================================================ Attribute Description ========== ================================================================ network_id Network ID dpid OpenFlow Datapath ID of the switch to which the port belongs. port_no OpenFlow port number of the port add_del True for adding a port. False for removing a port. ========== ================================================================ """ def __init__(self, network_id, dpid, port_no, add_del): super(EventNetworkPort, self).__init__() self.network_id = network_id self.dpid = dpid self.port_no = port_no self.add_del = add_del class EventMacAddress(event.EventBase): """ An event class for end-point MAC address registration. This event is generated when a end-point MAC address is updated by the REST API. An instance has at least the following attributes. =========== =============================================================== Attribute Description =========== =============================================================== network_id Network ID dpid OpenFlow Datapath ID of the switch to which the port belongs. port_no OpenFlow port number of the port mac_address The old MAC address of the port if add_del is False. Otherwise the new MAC address. add_del False if this event is a result of a port removal. Otherwise True. =========== =============================================================== """ def __init__(self, dpid, port_no, network_id, mac_address, add_del): super(EventMacAddress, self).__init__() assert network_id is not None assert mac_address is not None self.dpid = dpid self.port_no = port_no self.network_id = network_id self.mac_address = mac_address self.add_del = add_del class Networks(dict): "network_id -> set of (dpid, port_no)" def __init__(self, f): super(Networks, self).__init__() self.send_event = f def list_networks(self): return list(self.keys()) def has_network(self, network_id): return network_id in self def update_network(self, network_id): self.setdefault(network_id, set()) def create_network(self, network_id): if network_id in self: raise NetworkAlreadyExist(network_id=network_id) self[network_id] = set() def remove_network(self, network_id): try: ports = self[network_id] except KeyError: raise NetworkNotFound(network_id=network_id) while ports: (dpid, port_no) = ports.pop() self._remove_event(network_id, dpid, port_no) if self.pop(network_id, None) is not None: self.send_event(EventNetworkDel(network_id)) def list_ports(self, network_id): try: # use list() to keep compatibility for output # set() isn't json serializable return list(self[network_id]) except KeyError: raise NetworkNotFound(network_id=network_id) def add_raw(self, network_id, dpid, port_no): self[network_id].add((dpid, port_no)) def add_event(self, network_id, dpid, port_no): self.send_event( EventNetworkPort(network_id, dpid, port_no, True)) # def add(self, network_id, dpid, port_no): # self.add_raw(network_id, dpid, port_no) # self.add_event(network_id, dpid, port_no) def _remove_event(self, network_id, dpid, port_no): self.send_event(EventNetworkPort(network_id, dpid, port_no, False)) def remove_raw(self, network_id, dpid, port_no): ports = self[network_id] if (dpid, port_no) in ports: ports.remove((dpid, port_no)) self._remove_event(network_id, dpid, port_no) def remove(self, network_id, dpid, port_no): try: self.remove_raw(network_id, dpid, port_no) except KeyError: raise NetworkNotFound(network_id=network_id) except ValueError: raise PortNotFound(network_id=network_id, dpid=dpid, port=port_no) def has_port(self, network_id, dpid, port): return (dpid, port) in self[network_id] def get_dpids(self, network_id): try: ports = self[network_id] except KeyError: return set() # python 2.6 doesn't support set comprehension # port = (dpid, port_no) return set([port[0] for port in ports]) class Port(object): def __init__(self, port_no, network_id, mac_address=None): super(Port, self).__init__() self.port_no = port_no self.network_id = network_id self.mac_address = mac_address class DPIDs(dict): """dpid -> port_no -> Port(port_no, network_id, mac_address)""" def __init__(self, f, nw_id_unknown): super(DPIDs, self).__init__() self.send_event = f self.nw_id_unknown = nw_id_unknown def setdefault_dpid(self, dpid): return self.setdefault(dpid, {}) def _setdefault_network(self, dpid, port_no, default_network_id): dp = self.setdefault_dpid(dpid) return dp.setdefault(port_no, Port(port_no=port_no, network_id=default_network_id)) def setdefault_network(self, dpid, port_no): self._setdefault_network(dpid, port_no, self.nw_id_unknown) def update_port(self, dpid, port_no, network_id): port = self._setdefault_network(dpid, port_no, network_id) port.network_id = network_id def remove_port(self, dpid, port_no): try: # self.dpids[dpid][port_no] can be already deleted by # port_deleted() port = self[dpid].pop(port_no, None) if port and port.network_id and port.mac_address: self.send_event(EventMacAddress(dpid, port_no, port.network_id, port.mac_address, False)) except KeyError: raise PortNotFound(dpid=dpid, port=port_no, network_id=None) def get_ports(self, dpid, network_id=None, mac_address=None): if network_id is None: return list(self.get(dpid, {}).values()) if mac_address is None: return [p for p in self.get(dpid, {}).values() if p.network_id == network_id] # live-migration: There can be two ports that have same mac address. return [p for p in self.get(dpid, {}).values() if p.network_id == network_id and p.mac_address == mac_address] def get_port(self, dpid, port_no): try: return self[dpid][port_no] except KeyError: raise PortNotFound(dpid=dpid, port=port_no, network_id=None) def get_network(self, dpid, port_no): try: return self[dpid][port_no].network_id except KeyError: raise PortUnknown(dpid=dpid, port=port_no) def get_networks(self, dpid): return set(self[dpid].values()) def get_network_safe(self, dpid, port_no): port = self.get(dpid, {}).get(port_no) if port is None: return self.nw_id_unknown return port.network_id def get_mac(self, dpid, port_no): port = self.get_port(dpid, port_no) return port.mac_address def _set_mac(self, network_id, dpid, port_no, port, mac_address): if not (port.network_id is None or port.network_id == network_id or port.network_id == self.nw_id_unknown): raise PortNotFound(network_id=network_id, dpid=dpid, port=port_no) port.network_id = network_id port.mac_address = mac_address if port.network_id and port.mac_address: self.send_event(EventMacAddress( dpid, port_no, port.network_id, port.mac_address, True)) def set_mac(self, network_id, dpid, port_no, mac_address): port = self.get_port(dpid, port_no) if port.mac_address is not None: raise MacAddressAlreadyExist(dpid=dpid, port=port_no, mac_address=mac_address) self._set_mac(network_id, dpid, port_no, port, mac_address) def update_mac(self, network_id, dpid, port_no, mac_address): port = self.get_port(dpid, port_no) if port.mac_address is None: self._set_mac(network_id, dpid, port_no, port, mac_address) return # For now, we don't allow changing mac address. if port.mac_address != mac_address: raise MacAddressAlreadyExist(dpid=dpid, port=port_no, mac_address=port.mac_address) MacPort = collections.namedtuple('MacPort', ('dpid', 'port_no')) class MacToPort(collections.defaultdict): """mac_address -> set of MacPort(dpid, port_no)""" def __init__(self): super(MacToPort, self).__init__(set) def add_port(self, dpid, port_no, mac_address): self[mac_address].add(MacPort(dpid, port_no)) def remove_port(self, dpid, port_no, mac_address): ports = self[mac_address] ports.discard(MacPort(dpid, port_no)) if not ports: del self[mac_address] def get_ports(self, mac_address): return self[mac_address] class MacAddresses(dict): """network_id -> mac_address -> set of (dpid, port_no)""" def add_port(self, network_id, dpid, port_no, mac_address): mac2port = self.setdefault(network_id, MacToPort()) mac2port.add_port(dpid, port_no, mac_address) def remove_port(self, network_id, dpid, port_no, mac_address): mac2port = self.get(network_id) if mac2port is None: return mac2port.remove_port(dpid, port_no, mac_address) if not mac2port: del self[network_id] def get_ports(self, network_id, mac_address): mac2port = self.get(network_id) if not mac2port: return set() return mac2port.get_ports(mac_address) class Network(app_manager.OSKenApp): def __init__(self, nw_id_unknown=NW_ID_UNKNOWN): super(Network, self).__init__() self.name = 'network' self.nw_id_unknown = nw_id_unknown self.networks = Networks(self.send_event_to_observers) self.dpids = DPIDs(self.send_event_to_observers, nw_id_unknown) self.mac_addresses = MacAddresses() def _check_nw_id_unknown(self, network_id): if network_id == self.nw_id_unknown: raise NetworkAlreadyExist(network_id=network_id) def list_networks(self): return self.networks.list_networks() def update_network(self, network_id): self._check_nw_id_unknown(network_id) self.networks.update_network(network_id) def create_network(self, network_id): self._check_nw_id_unknown(network_id) self.networks.create_network(network_id) def remove_network(self, network_id): self.networks.remove_network(network_id) def list_ports(self, network_id): return self.networks.list_ports(network_id) def list_ports_noraise(self, network_id): try: return self.list_ports(network_id) except NetworkNotFound: return [] def _update_port(self, network_id, dpid, port, port_may_exist): def _known_nw_id(nw_id): return nw_id is not None and nw_id != self.nw_id_unknown queue_add_event = False self._check_nw_id_unknown(network_id) try: old_network_id = self.dpids.get_network_safe(dpid, port) if (self.networks.has_port(network_id, dpid, port) or _known_nw_id(old_network_id)): if not port_may_exist: raise PortAlreadyExist(network_id=network_id, dpid=dpid, port=port) if old_network_id != network_id: queue_add_event = True self.networks.add_raw(network_id, dpid, port) if _known_nw_id(old_network_id): self.networks.remove_raw(old_network_id, dpid, port) except KeyError: raise NetworkNotFound(network_id=network_id) self.dpids.update_port(dpid, port, network_id) if queue_add_event: self.networks.add_event(network_id, dpid, port) def create_port(self, network_id, dpid, port): self._update_port(network_id, dpid, port, False) def update_port(self, network_id, dpid, port): self._update_port(network_id, dpid, port, True) def _get_old_mac(self, network_id, dpid, port_no): try: port = self.dpids.get_port(dpid, port_no) except PortNotFound: pass else: if port.network_id == network_id: return port.mac_address return None def remove_port(self, network_id, dpid, port_no): # generate event first, then do the real task old_mac_address = self._get_old_mac(network_id, dpid, port_no) self.dpids.remove_port(dpid, port_no) try: self.networks.remove(network_id, dpid, port_no) except NetworkNotFound: # port deletion can be called after network deletion # due to Openstack auto deletion port.(dhcp/router port) pass if old_mac_address is not None: self.mac_addresses.remove_port(network_id, dpid, port_no, old_mac_address) # # methods for gre tunnel # def get_dpids(self, network_id): return self.networks.get_dpids(network_id) def has_network(self, network_id): return self.networks.has_network(network_id) def get_networks(self, dpid): return self.dpids.get_networks(dpid) def create_mac(self, network_id, dpid, port_no, mac_address): self.mac_addresses.add_port(network_id, dpid, port_no, mac_address) self.dpids.set_mac(network_id, dpid, port_no, mac_address) def update_mac(self, network_id, dpid, port_no, mac_address): old_mac_address = self._get_old_mac(network_id, dpid, port_no) self.dpids.update_mac(network_id, dpid, port_no, mac_address) if old_mac_address is not None: self.mac_addresses.remove_port(network_id, dpid, port_no, old_mac_address) self.mac_addresses.add_port(network_id, dpid, port_no, mac_address) def get_mac(self, dpid, port_no): return self.dpids.get_mac(dpid, port_no) def list_mac(self, dpid, port_no): mac_address = self.dpids.get_mac(dpid, port_no) if mac_address is None: return [] return [mac_address] def get_ports(self, dpid, network_id=None, mac_address=None): return self.dpids.get_ports(dpid, network_id, mac_address) def get_port(self, dpid, port_no): return self.dpids.get_port(dpid, port_no) def get_ports_with_mac(self, network_id, mac_address): return self.mac_addresses.get_ports(network_id, mac_address) # # methods for simple_isolation # def same_network(self, dpid, nw_id, out_port, allow_nw_id_external=None): assert nw_id != self.nw_id_unknown out_nw = self.dpids.get_network_safe(dpid, out_port) if nw_id == out_nw: return True if (allow_nw_id_external is not None and (allow_nw_id_external == nw_id or allow_nw_id_external == out_nw)): # allow external network -> known network id return True self.logger.debug('blocked dpid %s nw_id %s out_port %d out_nw %s' 'external %s', dpid, nw_id, out_port, out_nw, allow_nw_id_external) return False def get_network(self, dpid, port): return self.dpids.get_network(dpid, port) def add_datapath(self, ofp_switch_features): datapath = ofp_switch_features.datapath dpid = ofp_switch_features.datapath_id ports = ofp_switch_features.ports self.dpids.setdefault_dpid(dpid) for port_no in ports: self.port_added(datapath, port_no) def port_added(self, datapath, port_no): if port_no == 0 or port_no >= datapath.ofproto.OFPP_MAX: # skip fake output ports return self.dpids.setdefault_network(datapath.id, port_no) def port_deleted(self, dpid, port_no): self.dpids.remove_port(dpid, port_no) def filter_ports(self, dpid, in_port, nw_id, allow_nw_id_external=None): assert nw_id != self.nw_id_unknown ret = [] for port in self.get_ports(dpid): nw_id_ = port.network_id if port.port_no == in_port: continue if nw_id_ == nw_id: ret.append(port.port_no) elif (allow_nw_id_external is not None and nw_id_ == allow_nw_id_external): ret.append(port.port_no) return ret ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/controller/ofp_api.py0000664000175000017500000000453200000000000020445 0ustar00zuulzuul00000000000000# Copyright (C) 2017 Nippon Telegraph and Telephone 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. """ OpenFlow related APIs of os_ken.controller module. """ import netaddr from os_ken.base import app_manager from os_ken.lib import hub from os_ken.lib import ip from . import ofp_event _TMP_ADDRESSES = {} def register_switch_address(addr, interval=None): """ Registers a new address to initiate connection to switch. Registers a new IP address and port pair of switch to let os_ken.controller.controller.OpenFlowController to try to initiate connection to switch. :param addr: A tuple of (host, port) pair of switch. :param interval: Interval in seconds to try to connect to switch """ assert len(addr) == 2 assert ip.valid_ipv4(addr[0]) or ip.valid_ipv6(addr[0]) ofp_handler = app_manager.lookup_service_brick(ofp_event.NAME) _TMP_ADDRESSES[addr] = interval def _retry_loop(): # Delays registration if ofp_handler is not started yet while True: if ofp_handler is not None and ofp_handler.controller is not None: for a, i in _TMP_ADDRESSES.items(): ofp_handler.controller.spawn_client_loop(a, i) hub.sleep(1) break hub.sleep(1) hub.spawn(_retry_loop) def unregister_switch_address(addr): """ Unregister the given switch address. Unregisters the given switch address to let os_ken.controller.controller.OpenFlowController stop trying to initiate connection to switch. :param addr: A tuple of (host, port) pair of switch. """ ofp_handler = app_manager.lookup_service_brick(ofp_event.NAME) # Do nothing if ofp_handler is not started yet if ofp_handler is None or ofp_handler.controller is None: return ofp_handler.controller.stop_client_loop(addr) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/controller/ofp_event.py0000664000175000017500000001126600000000000021017 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2011 Isaku Yamahata # # 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. """ OpenFlow event definitions. """ import inspect import time from os_ken.controller import handler from os_ken import ofproto from . import event NAME = 'ofp_event' class EventOFPMsgBase(event.EventBase): """ The base class of OpenFlow event class. OpenFlow event classes have at least the following attributes. .. tabularcolumns:: |l|L| ============ ============================================================== Attribute Description ============ ============================================================== msg An object which describes the corresponding OpenFlow message. msg.datapath A os_ken.controller.controller.Datapath instance which describes an OpenFlow switch from which we received this OpenFlow message. timestamp Timestamp when Datapath instance generated this event. ============ ============================================================== The msg object has some more additional members whose values are extracted from the original OpenFlow message. """ def __init__(self, msg): self.timestamp = time.time() super(EventOFPMsgBase, self).__init__() self.msg = msg # # Create ofp_event type corresponding to OFP Msg # _OFP_MSG_EVENTS = {} def _ofp_msg_name_to_ev_name(msg_name): return 'Event' + msg_name def ofp_msg_to_ev(msg): return ofp_msg_to_ev_cls(msg.__class__)(msg) def ofp_msg_to_ev_cls(msg_cls): name = _ofp_msg_name_to_ev_name(msg_cls.__name__) return _OFP_MSG_EVENTS[name] def _create_ofp_msg_ev_class(msg_cls): name = _ofp_msg_name_to_ev_name(msg_cls.__name__) # print 'creating ofp_event %s' % name if name in _OFP_MSG_EVENTS: return cls = type(name, (EventOFPMsgBase,), dict(__init__=lambda self, msg: super(self.__class__, self).__init__(msg))) globals()[name] = cls _OFP_MSG_EVENTS[name] = cls def _create_ofp_msg_ev_from_module(ofp_parser): # print mod for _k, cls in inspect.getmembers(ofp_parser, inspect.isclass): if not hasattr(cls, 'cls_msg_type'): continue _create_ofp_msg_ev_class(cls) for ofp_mods in ofproto.get_ofp_modules().values(): ofp_parser = ofp_mods[1] # print 'loading module %s' % ofp_parser _create_ofp_msg_ev_from_module(ofp_parser) class EventOFPStateChange(event.EventBase): """ An event class for negotiation phase change notification. An instance of this class is sent to observer after changing the negotiation phase. An instance has at least the following attributes. ========= ================================================================= Attribute Description ========= ================================================================= datapath os_ken.controller.controller.Datapath instance of the switch ========= ================================================================= """ def __init__(self, dp): super(EventOFPStateChange, self).__init__() self.datapath = dp class EventOFPPortStateChange(event.EventBase): """ An event class to notify the port state changes of Dtatapath instance. This event performs like EventOFPPortStatus, but OSKen will send this event after updating ``ports`` dict of Datapath instances. An instance has at least the following attributes. ========= ================================================================= Attribute Description ========= ================================================================= datapath os_ken.controller.controller.Datapath instance of the switch reason one of OFPPR_* port_no Port number which state was changed ========= ================================================================= """ def __init__(self, dp, reason, port_no): super(EventOFPPortStateChange, self).__init__() self.datapath = dp self.reason = reason self.port_no = port_no handler.register_service('os_ken.controller.ofp_handler') ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/controller/ofp_handler.py0000664000175000017500000003252300000000000021312 0ustar00zuulzuul00000000000000# Copyright (C) 2011, 2012 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2011, 2012 Isaku Yamahata # # 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. """ Basic OpenFlow handling including negotiation. """ import itertools import logging import warnings import os_ken.base.app_manager from os_ken.lib import hub from os_ken import utils from os_ken.controller import ofp_event from os_ken.controller.controller import OpenFlowController from os_ken.controller.handler import set_ev_handler from os_ken.controller.handler import HANDSHAKE_DISPATCHER, CONFIG_DISPATCHER,\ MAIN_DISPATCHER from os_ken.ofproto import ofproto_parser # The state transition: HANDSHAKE -> CONFIG -> MAIN # # HANDSHAKE: if it receives HELLO message with the valid OFP version, # sends Features Request message, and moves to CONFIG. # # CONFIG: it receives Features Reply message and moves to MAIN # # MAIN: it does nothing. Applications are expected to register their # own handlers. # # Note that at any state, when we receive Echo Request message, send # back Echo Reply message. class OFPHandler(os_ken.base.app_manager.OSKenApp): def __init__(self, *args, **kwargs): super(OFPHandler, self).__init__(*args, **kwargs) self.name = ofp_event.NAME self.controller = None def start(self): super(OFPHandler, self).start() self.controller = OpenFlowController() return hub.spawn(self.controller) def _hello_failed(self, datapath, error_desc): self.logger.error('%s on datapath %s', error_desc, datapath.address) error_msg = datapath.ofproto_parser.OFPErrorMsg( datapath=datapath, type_=datapath.ofproto.OFPET_HELLO_FAILED, code=datapath.ofproto.OFPHFC_INCOMPATIBLE, data=error_desc) datapath.send_msg(error_msg, close_socket=True) @set_ev_handler(ofp_event.EventOFPHello, HANDSHAKE_DISPATCHER) def hello_handler(self, ev): self.logger.debug('hello ev %s', ev) msg = ev.msg datapath = msg.datapath # check if received version is supported. # pre 1.0 is not supported elements = getattr(msg, 'elements', None) if elements: switch_versions = set() for version in itertools.chain.from_iterable( element.versions for element in elements): switch_versions.add(version) usable_versions = switch_versions & set( datapath.supported_ofp_version) # We didn't send our supported versions for interoperability as # most switches would not understand elements at the moment. # So the switch would think that the negotiated version would # be max(negotiated_versions), but actual usable version is # max(usable_versions). negotiated_versions = set( version for version in switch_versions if version <= max(datapath.supported_ofp_version)) if negotiated_versions and not usable_versions: # e.g. # versions of OF 1.0 and 1.1 from switch # max of OF 1.2 from OSKen and supported_ofp_version = (1.2, ) # negotiated version = 1.1 # usable version = None error_desc = ( 'no compatible version found: ' 'switch versions %s controller version 0x%x, ' 'the negotiated version is 0x%x, ' 'but no usable version found. ' 'If possible, set the switch to use one of OF version %s' % (switch_versions, max(datapath.supported_ofp_version), max(negotiated_versions), sorted(datapath.supported_ofp_version))) self._hello_failed(datapath, error_desc) return if (negotiated_versions and usable_versions and max(negotiated_versions) != max(usable_versions)): # e.g. # versions of OF 1.0 and 1.1 from switch # max of OF 1.2 from OSKen and supported_ofp_version = (1.0, 1.2) # negotiated version = 1.1 # usable version = 1.0 # # TODO: In order to get the version 1.0, OSKen need to send # supported verions. error_desc = ( 'no compatible version found: ' 'switch versions 0x%x controller version 0x%x, ' 'the negotiated version is %s but found usable %s. ' 'If possible, ' 'set the switch to use one of OF version %s' % ( max(switch_versions), max(datapath.supported_ofp_version), sorted(negotiated_versions), sorted(usable_versions), sorted(usable_versions))) self._hello_failed(datapath, error_desc) return else: usable_versions = set(version for version in datapath.supported_ofp_version if version <= msg.version) if (usable_versions and max(usable_versions) != min(msg.version, datapath.ofproto.OFP_VERSION)): # The version of min(msg.version, datapath.ofproto.OFP_VERSION) # should be used according to the spec. But we can't. # So log it and use max(usable_versions) with the hope that # the switch is able to understand lower version. # e.g. # OF 1.1 from switch # OF 1.2 from OSKen and supported_ofp_version = (1.0, 1.2) # In this case, 1.1 should be used according to the spec, # but 1.1 can't be used. # # OF1.3.1 6.3.1 # Upon receipt of this message, the recipient must # calculate the OpenFlow protocol version to be used. If # both the Hello message sent and the Hello message # received contained a OFPHET_VERSIONBITMAP hello element, # and if those bitmaps have some common bits set, the # negotiated version must be the highest version set in # both bitmaps. Otherwise, the negotiated version must be # the smaller of the version number that was sent and the # one that was received in the version fields. If the # negotiated version is supported by the recipient, then # the connection proceeds. Otherwise, the recipient must # reply with an OFPT_ERROR message with a type field of # OFPET_HELLO_FAILED, a code field of OFPHFC_INCOMPATIBLE, # and optionally an ASCII string explaining the situation # in data, and then terminate the connection. version = max(usable_versions) error_desc = ( 'no compatible version found: ' 'switch 0x%x controller 0x%x, but found usable 0x%x. ' 'If possible, set the switch to use OF version 0x%x' % ( msg.version, datapath.ofproto.OFP_VERSION, version, version)) self._hello_failed(datapath, error_desc) return if not usable_versions: error_desc = ( 'unsupported version 0x%x. ' 'If possible, set the switch to use one of the versions %s' % ( msg.version, sorted(datapath.supported_ofp_version))) self._hello_failed(datapath, error_desc) return datapath.set_version(max(usable_versions)) # Move on to config state self.logger.debug('move onto config mode') datapath.set_state(CONFIG_DISPATCHER) # Finally, send feature request features_request = datapath.ofproto_parser.OFPFeaturesRequest(datapath) datapath.send_msg(features_request) @set_ev_handler(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER) def switch_features_handler(self, ev): msg = ev.msg datapath = msg.datapath self.logger.debug('switch features ev %s', msg) datapath.id = msg.datapath_id # hacky workaround, will be removed. OF1.3 doesn't have # ports. An application should not depend on them. But there # might be such bad applications so keep this workaround for # while. if datapath.ofproto.OFP_VERSION < 0x04: datapath.ports = msg.ports else: datapath.ports = {} if datapath.ofproto.OFP_VERSION < 0x04: self.logger.debug('move onto main mode') ev.msg.datapath.set_state(MAIN_DISPATCHER) else: port_desc = datapath.ofproto_parser.OFPPortDescStatsRequest( datapath, 0) datapath.send_msg(port_desc) @set_ev_handler(ofp_event.EventOFPPortDescStatsReply, CONFIG_DISPATCHER) def multipart_reply_handler(self, ev): msg = ev.msg datapath = msg.datapath with warnings.catch_warnings(): warnings.simplefilter('ignore') for port in msg.body: datapath.ports[port.port_no] = port if msg.flags & datapath.ofproto.OFPMPF_REPLY_MORE: return self.logger.debug('move onto main mode') ev.msg.datapath.set_state(MAIN_DISPATCHER) @set_ev_handler(ofp_event.EventOFPEchoRequest, [HANDSHAKE_DISPATCHER, CONFIG_DISPATCHER, MAIN_DISPATCHER]) def echo_request_handler(self, ev): msg = ev.msg datapath = msg.datapath echo_reply = datapath.ofproto_parser.OFPEchoReply(datapath) echo_reply.xid = msg.xid echo_reply.data = msg.data datapath.send_msg(echo_reply) @set_ev_handler(ofp_event.EventOFPEchoReply, [HANDSHAKE_DISPATCHER, CONFIG_DISPATCHER, MAIN_DISPATCHER]) def echo_reply_handler(self, ev): msg = ev.msg datapath = msg.datapath datapath.acknowledge_echo_reply(msg.xid) @set_ev_handler(ofp_event.EventOFPPortStatus, MAIN_DISPATCHER) def port_status_handler(self, ev): msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto if msg.reason in [ofproto.OFPPR_ADD, ofproto.OFPPR_MODIFY]: datapath.ports[msg.desc.port_no] = msg.desc elif msg.reason == ofproto.OFPPR_DELETE: datapath.ports.pop(msg.desc.port_no, None) else: return self.send_event_to_observers( ofp_event.EventOFPPortStateChange( datapath, msg.reason, msg.desc.port_no), datapath.state) @set_ev_handler(ofp_event.EventOFPErrorMsg, [HANDSHAKE_DISPATCHER, CONFIG_DISPATCHER, MAIN_DISPATCHER]) def error_msg_handler(self, ev): msg = ev.msg ofp = msg.datapath.ofproto self.logger.debug( "EventOFPErrorMsg received.\n" "version=%s, msg_type=%s, msg_len=%s, xid=%s\n" " `-- msg_type: %s", hex(msg.version), hex(msg.msg_type), hex(msg.msg_len), hex(msg.xid), ofp.ofp_msg_type_to_str(msg.msg_type)) if msg.type == ofp.OFPET_EXPERIMENTER: self.logger.debug( "OFPErrorExperimenterMsg(type=%s, exp_type=%s," " experimenter=%s, data=b'%s')", hex(msg.type), hex(msg.exp_type), hex(msg.experimenter), utils.binary_str(msg.data)) else: self.logger.debug( "OFPErrorMsg(type=%s, code=%s, data=b'%s')\n" " |-- type: %s\n" " |-- code: %s", hex(msg.type), hex(msg.code), utils.binary_str(msg.data), ofp.ofp_error_type_to_str(msg.type), ofp.ofp_error_code_to_str(msg.type, msg.code)) if msg.type == ofp.OFPET_HELLO_FAILED: self.logger.debug( " `-- data: %s", msg.data.decode('ascii')) elif len(msg.data) >= ofp.OFP_HEADER_SIZE: (version, msg_type, msg_len, xid) = ofproto_parser.header(msg.data) self.logger.debug( " `-- data: version=%s, msg_type=%s, msg_len=%s, xid=%s\n" " `-- msg_type: %s", hex(version), hex(msg_type), hex(msg_len), hex(xid), ofp.ofp_msg_type_to_str(msg_type)) else: self.logger.warning( "The data field sent from the switch is too short: " "len(msg.data) < OFP_HEADER_SIZE\n" "The OpenFlow Spec says that the data field should contain " "at least 64 bytes of the failed request.\n" "Please check the settings or implementation of your switch.") ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/controller/tunnels.py0000664000175000017500000002103700000000000020517 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2012 Isaku Yamahata # # 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. import collections import logging import os_ken.exception as os_ken_exc from os_ken.base import app_manager from os_ken.controller import event class RemoteDPIDAlreadyExist(os_ken_exc.OSKenException): message = ('port (%(dpid)s, %(port)s) has already ' 'remote dpid %(remote_dpid)s') class TunnelKeyAlreadyExist(os_ken_exc.OSKenException): message = 'tunnel key %(tunnel_key)s already exists' class TunnelKeyNotFound(os_ken_exc.OSKenException): message = 'no tunnel key for network %(network_id)s' class EventTunnelKeyBase(event.EventBase): def __init__(self, network_id, tunnel_key): super(EventTunnelKeyBase, self).__init__() self.network_id = network_id self.tunnel_key = tunnel_key class EventTunnelKeyAdd(EventTunnelKeyBase): """ An event class for tunnel key registration. This event is generated when a tunnel key is registered or updated by the REST API. An instance has at least the following attributes. =========== =============================================================== Attribute Description =========== =============================================================== network_id Network ID tunnel_key Tunnel Key =========== =============================================================== """ def __init__(self, network_id, tunnel_key): super(EventTunnelKeyAdd, self).__init__(network_id, tunnel_key) class EventTunnelKeyDel(EventTunnelKeyBase): """ An event class for tunnel key registration. This event is generated when a tunnel key is removed by the REST API. An instance has at least the following attributes. =========== =============================================================== Attribute Description =========== =============================================================== network_id Network ID tunnel_key Tunnel Key =========== =============================================================== """ def __init__(self, network_id, tunnel_key): super(EventTunnelKeyDel, self).__init__(network_id, tunnel_key) class EventTunnelPort(event.EventBase): """ An event class for tunnel port registration. This event is generated when a tunnel port is added or removed by the REST API. An instance has at least the following attributes. =========== =============================================================== Attribute Description =========== =============================================================== dpid OpenFlow Datapath ID port_no OpenFlow port number remote_dpid OpenFlow port number of the tunnel peer add_del True for adding a tunnel. False for removal. =========== =============================================================== """ def __init__(self, dpid, port_no, remote_dpid, add_del): super(EventTunnelPort, self).__init__() self.dpid = dpid self.port_no = port_no self.remote_dpid = remote_dpid self.add_del = add_del class TunnelKeys(dict): """network id(uuid) <-> tunnel key(32bit unsigned int)""" def __init__(self, f): super(TunnelKeys, self).__init__() self.send_event = f def get_key(self, network_id): try: return self[network_id] except KeyError: raise TunnelKeyNotFound(network_id=network_id) def _set_key(self, network_id, tunnel_key): self[network_id] = tunnel_key self.send_event(EventTunnelKeyAdd(network_id, tunnel_key)) def register_key(self, network_id, tunnel_key): if network_id in self: raise os_ken_exc.NetworkAlreadyExist(network_id=network_id) if tunnel_key in self.values(): raise TunnelKeyAlreadyExist(tunnel_key=tunnel_key) self._set_key(network_id, tunnel_key) def update_key(self, network_id, tunnel_key): if network_id not in self and tunnel_key in self.values(): raise TunnelKeyAlreadyExist(key=tunnel_key) key = self.get(network_id) if key is None: self._set_key(network_id, tunnel_key) return if key != tunnel_key: raise os_ken_exc.NetworkAlreadyExist(network_id=network_id) def delete_key(self, network_id): try: tunnel_key = self[network_id] self.send_event(EventTunnelKeyDel(network_id, tunnel_key)) del self[network_id] except KeyError: raise os_ken_exc.NetworkNotFound(network_id=network_id) class DPIDs(object): """dpid -> port_no -> remote_dpid""" def __init__(self, f): super(DPIDs, self).__init__() self.dpids = collections.defaultdict(dict) self.send_event = f def list_ports(self, dpid): return self.dpids[dpid] def _add_remote_dpid(self, dpid, port_no, remote_dpid): self.dpids[dpid][port_no] = remote_dpid self.send_event(EventTunnelPort(dpid, port_no, remote_dpid, True)) def add_remote_dpid(self, dpid, port_no, remote_dpid): if port_no in self.dpids[dpid]: raise os_ken_exc.PortAlreadyExist(dpid=dpid, port=port_no, network_id=None) self._add_remote_dpid(dpid, port_no, remote_dpid) def update_remote_dpid(self, dpid, port_no, remote_dpid): remote_dpid_ = self.dpids[dpid].get(port_no) if remote_dpid_ is None: self._add_remote_dpid(dpid, port_no, remote_dpid) elif remote_dpid_ != remote_dpid: raise os_ken_exc.RemoteDPIDAlreadyExist(dpid=dpid, port=port_no, remote_dpid=remote_dpid) def get_remote_dpid(self, dpid, port_no): try: return self.dpids[dpid][port_no] except KeyError: raise os_ken_exc.PortNotFound(dpid=dpid, port=port_no) def delete_port(self, dpid, port_no): try: remote_dpid = self.dpids[dpid][port_no] self.send_event(EventTunnelPort(dpid, port_no, remote_dpid, False)) del self.dpids[dpid][port_no] except KeyError: raise os_ken_exc.PortNotFound(dpid=dpid, port=port_no) def get_port(self, dpid, remote_dpid): try: dp = self.dpids[dpid] except KeyError: raise os_ken_exc.PortNotFound(dpid=dpid, port=None, network_id=None) res = [port_no for (port_no, remote_dpid_) in dp.items() if remote_dpid_ == remote_dpid] assert len(res) <= 1 if len(res) == 0: raise os_ken_exc.PortNotFound(dpid=dpid, port=None, network_id=None) return res[0] class Tunnels(app_manager.OSKenApp): def __init__(self): super(Tunnels, self).__init__() self.name = 'tunnels' self.tunnel_keys = TunnelKeys(self.send_event_to_observers) self.dpids = DPIDs(self.send_event_to_observers) def get_key(self, network_id): return self.tunnel_keys.get_key(network_id) def register_key(self, network_id, tunnel_key): self.tunnel_keys.register_key(network_id, tunnel_key) def update_key(self, network_id, tunnel_key): self.tunnel_keys.update_key(network_id, tunnel_key) def delete_key(self, network_id): self.tunnel_keys.delete_key(network_id) def list_ports(self, dpid): return self.dpids.list_ports(dpid).keys() def register_port(self, dpid, port_no, remote_dpid): self.dpids.add_remote_dpid(dpid, port_no, remote_dpid) def update_port(self, dpid, port_no, remote_dpid): self.dpids.update_remote_dpid(dpid, port_no, remote_dpid) def get_remote_dpid(self, dpid, port_no): return self.dpids.get_remote_dpid(dpid, port_no) def delete_port(self, dpid, port_no): self.dpids.delete_port(dpid, port_no) # # methods for gre tunnel # def get_port(self, dpid, remote_dpid): return self.dpids.get_port(dpid, remote_dpid) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/exception.py0000664000175000017500000000447200000000000016646 0ustar00zuulzuul00000000000000# Copyright (C) 2011 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2011 Isaku Yamahata # # 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 OSKenException(Exception): message = 'An unknown exception' def __init__(self, msg=None, **kwargs): self.kwargs = kwargs if msg is None: msg = self.message try: msg = msg % kwargs except Exception: msg = self.message super(OSKenException, self).__init__(msg) class OFPUnknownVersion(OSKenException): message = 'unknown version %(version)x' class OFPMalformedMessage(OSKenException): message = 'malformed message' class OFPTruncatedMessage(OSKenException): message = 'truncated message: %(orig_ex)s' def __init__(self, ofpmsg, residue, original_exception, msg=None, **kwargs): self.ofpmsg = ofpmsg self.residue = residue self.original_exception = original_exception kwargs['orig_ex'] = str(original_exception) super(OFPTruncatedMessage, self).__init__(msg, **kwargs) class OFPInvalidActionString(OSKenException): message = 'unable to parse: %(action_str)s' class NetworkNotFound(OSKenException): message = 'no such network id %(network_id)s' class NetworkAlreadyExist(OSKenException): message = 'network id %(network_id)s already exists' class PortNotFound(OSKenException): message = 'no such port (%(dpid)s, %(port)s) in network %(network_id)s' class PortAlreadyExist(OSKenException): message = 'port (%(dpid)s, %(port)s) in network %(network_id)s ' \ 'already exists' class PortUnknown(OSKenException): message = 'unknown network id for port (%(dpid)s %(port)s)' class MacAddressDuplicated(OSKenException): message = 'MAC address %(mac)s is duplicated' ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/flags.py0000664000175000017500000001144400000000000015741 0ustar00zuulzuul00000000000000# Copyright (C) 2011 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2011 Isaku Yamahata # # 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. """ global flags """ from packaging import version from os_ken import cfg CONF = cfg.CONF CONF.register_cli_opts([ # tests/switch/tester cfg.StrOpt('target', default='0000000000000001', help='target sw dp-id'), cfg.StrOpt('tester', default='0000000000000002', help='tester sw dp-id'), cfg.IntOpt('target_recv_port', default=1, help='target sw receiving port ' '(default: 1)'), cfg.IntOpt('target_send_port_1', default=2, help='target sw sending port 1 ' '(default: 2)'), cfg.IntOpt('target_send_port_2', default=3, help='target sw sending port 2 ' '(default: 3)'), cfg.IntOpt('tester_send_port', default=1, help='tester sw sending port ' '(default: 1)'), cfg.IntOpt('tester_recv_port_1', default=2, help='tester sw receiving port 1 ' '(default: 2)'), cfg.IntOpt('tester_recv_port_2', default=3, help='tester sw receiving port 2 ' '(default: 3)'), cfg.StrOpt('dir', default='os_ken/tests/switch/of13', help='test files directory'), cfg.StrOpt('target-version', default='openflow13', help='target sw OFP version ' '[openflow10|openflow13|openflow14] ' '(default: openflow13)'), cfg.StrOpt('tester-version', default='openflow13', help='tester sw OFP version ' '[openflow10|openflow13|openflow14] ' '(default: openflow13)'), cfg.IntOpt('interval', default=0, help='interval time in seconds of each test ' '(default: 0)'), ], group='test-switch') DEFAULT_RPC_PORT = 50002 DEFAULT_RPC_HOST = '0.0.0.0' CONF.register_cli_opts([ cfg.IntOpt('rpc-port', default=DEFAULT_RPC_PORT, help='Port for RPC server (default: %s)' % DEFAULT_RPC_PORT), cfg.StrOpt('rpc-host', default=DEFAULT_RPC_HOST, help='IP for RPC server (default: %s)' % DEFAULT_RPC_HOST), cfg.StrOpt('config-file', default=None, help='The config file formatted in Python source file. ' 'Please refer to "bgp_sample_conf.py" for details.') ], group='bgp-app') DEFAULT_ZSERV_HOST = '/var/run/quagga/zserv.api' DEFAULT_ZSERV_PORT = 2600 DEFAULT_ZSERV_VERSION = 2 # Version of Ubuntu 16.04 LTS packaged Quagga DEFAULT_ZSERV_CLIENT_ROUTE_TYPE = 'BGP' DEFAULT_ZSERV_INTERVAL = 10 DEFAULT_ZSERV_DATABASE = 'sqlite:///zebra.db' DEFAULT_ZSERV_ROUTER_ID = '1.1.1.1' # For the backward compatibility with Quagga, the default FRRouting version # should be None. DEFAULT_ZSERV_FRR_VERSION = '0.0' CONF.register_cli_opts([ cfg.StrOpt( 'server-host', default=DEFAULT_ZSERV_HOST, help='Path to Unix Socket or IP address of Zebra server ' '(default: %s)' % DEFAULT_ZSERV_HOST), cfg.IntOpt( 'server-port', default=DEFAULT_ZSERV_PORT, help='Port number of Zebra server ' '(default: %s)' % DEFAULT_ZSERV_PORT), cfg.IntOpt( 'server-version', default=DEFAULT_ZSERV_VERSION, help='Zebra protocol version of Zebra server ' '(default: %s)' % DEFAULT_ZSERV_VERSION), cfg.StrOpt( 'client-route-type', default=DEFAULT_ZSERV_CLIENT_ROUTE_TYPE, help='Zebra route type advertised by Zebra client service. ' '(default: %s)' % DEFAULT_ZSERV_CLIENT_ROUTE_TYPE), cfg.IntOpt( 'retry-interval', default=DEFAULT_ZSERV_INTERVAL, help='Retry interval connecting to Zebra server ' '(default: %s)' % DEFAULT_ZSERV_INTERVAL), cfg.StrOpt( 'db-url', default=DEFAULT_ZSERV_DATABASE, help='URL to database used by Zebra protocol service ' '(default: %s)' % DEFAULT_ZSERV_DATABASE), cfg.StrOpt( 'router-id', default=DEFAULT_ZSERV_ROUTER_ID, help='Initial Router ID used by Zebra protocol service ' '(default: %s)' % DEFAULT_ZSERV_ROUTER_ID), cfg.Opt( 'frr-version', version.Version, default=DEFAULT_ZSERV_FRR_VERSION, help='FRRouting version when integrated with FRRouting (e.g., 3.0)'), ], group='zapi') ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/hooks.py0000664000175000017500000000472300000000000015772 0ustar00zuulzuul00000000000000# vim: tabstop=4 shiftwidth=4 softtabstop=4 # Copyright 2013 Hewlett-Packard Development Company, L.P. # All Rights Reserved. # # 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. import os import sys from setuptools.command import easy_install from os_ken import version # Global variables in this module doesn't work as we expect # because, during the setup procedure, this module seems to be # copied (as a file) and can be loaded multiple times. # We save them into __main__ module instead. def _main_module(): return sys.modules['__main__'] def save_orig(): """Save original easy_install.get_script_args. This is necessary because pbr's setup_hook is sometimes called before ours.""" _main_module()._orig_get_script_args = easy_install.get_script_args def setup_hook(config): """Filter config parsed from a setup.cfg to inject our defaults.""" metadata = config['metadata'] if sys.platform == 'win32': requires = metadata.get('requires_dist', '').split('\n') metadata['requires_dist'] = "\n".join(requires) config['metadata'] = metadata metadata['version'] = str(version) # pbr's setup_hook replaces easy_install.get_script_args with # their own version, override_get_script_args, prefering simpler # scripts which are not aware of multi-version. # prevent that by doing the opposite. it's a horrible hack # but we are in patching wars already... from pbr import packaging def my_get_script_args(*args, **kwargs): return _main_module()._orig_get_script_args(*args, **kwargs) packaging.override_get_script_args = my_get_script_args easy_install.get_script_args = my_get_script_args # another hack to allow setup from tarball. orig_get_version = packaging.get_version def my_get_version(package_name, pre_version=None): if package_name == 'os_ken': return str(version) return orig_get_version(package_name, pre_version) packaging.get_version = my_get_version ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.0781038 os-ken-2.10.0/os_ken/lib/0000775000175000017500000000000000000000000015035 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/__init__.py0000664000175000017500000000000000000000000017134 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/addrconv.py0000664000175000017500000000364600000000000017220 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013 YAMAMOTO Takashi # # 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. import netaddr class AddressConverter(object): def __init__(self, addr, strat, fallback=None, **kwargs): self._addr = addr self._strat = strat self._fallback = fallback self._addr_kwargs = kwargs def text_to_bin(self, text): try: return self._addr(text, **self._addr_kwargs).packed except Exception as e: if self._fallback is None: raise e # text_to_bin is expected to return binary string under # normal circumstances. See ofproto.oxx_fields._from_user. ip = self._fallback(text, **self._addr_kwargs) return ip.ip.packed, ip.netmask.packed def bin_to_text(self, bin): return str(self._addr(self._strat.packed_to_int(bin), **self._addr_kwargs)) ipv4 = AddressConverter(netaddr.IPAddress, netaddr.strategy.ipv4, fallback=netaddr.IPNetwork, version=4) ipv6 = AddressConverter(netaddr.IPAddress, netaddr.strategy.ipv6, fallback=netaddr.IPNetwork, version=6) class mac_mydialect(netaddr.mac_unix): word_fmt = '%.2x' mac = AddressConverter(netaddr.EUI, netaddr.strategy.eui48, version=48, dialect=mac_mydialect) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/alert.py0000664000175000017500000000673400000000000016530 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone 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. import struct from struct import calcsize class SfTimeval32(object): _PACK_STR = '!II' _SIZE = 8 def __init__(self, tv_sec, tv_usec): self.tv_sec = tv_sec self.tv_usec = tv_usec @classmethod def parser(cls, buf, offset): (tv_sec, tv_usec) = struct.unpack_from( cls._PACK_STR, buf, offset) msg = cls(tv_sec, tv_usec) return msg class Event(object): _PACK_STR = '!IIIIIII' _SIZE = 36 def __init__(self, sig_generator, sig_id, sig_rev, classification, priority, event_id, event_reference, ref_time): self.sig_generator = sig_generator self.sig_id = sig_id self.sig_rev = sig_rev self.classification = classification self.priority = priority self.event_id = event_id self.event_reference = event_reference self.ref_time = ref_time @classmethod def parser(cls, buf, offset): (sig_generator, sig_id, sig_rev, classification, priority, event_id, event_reference) = struct.unpack_from( cls._PACK_STR, buf, offset) offset += calcsize(cls._PACK_STR) ref_time = SfTimeval32.parser(buf, offset) msg = cls(sig_generator, sig_id, sig_rev, classification, priority, event_id, event_reference, ref_time) return msg class PcapPktHdr32(object): _PACK_STR = '!II' _SIZE = 16 def __init__(self, ts, caplen, len_): self.ts = ts self.caplen = caplen self.len = len_ @classmethod def parser(cls, buf, offset): ts = SfTimeval32.parser(buf, offset) offset += SfTimeval32._SIZE (caplen, len_) = struct.unpack_from( cls._PACK_STR, buf, offset) msg = cls(ts, caplen, len_) return msg class AlertPkt(object): _ALERTMSG_PACK_STR = '!256s' _ALERTPKT_PART_PACK_STR = '!IIIII65535s' _ALERTPKT_SIZE = 65863 def __init__(self, alertmsg, pkth, dlthdr, nethdr, transhdr, data, val, pkt, event): self.alertmsg = alertmsg self.pkth = pkth self.dlthdr = dlthdr self.nethdr = nethdr self.transhdr = transhdr self.data = data self.val = val self.pkt = pkt self.event = event @classmethod def parser(cls, buf): alertmsg = struct.unpack_from(cls._ALERTMSG_PACK_STR, buf) offset = calcsize(cls._ALERTMSG_PACK_STR) pkth = PcapPktHdr32.parser(buf, offset) offset += PcapPktHdr32._SIZE (dlthdr, nethdr, transhdr, data, val, pkt) = \ struct.unpack_from(cls._ALERTPKT_PART_PACK_STR, buf, offset) offset += calcsize(cls._ALERTPKT_PART_PACK_STR) event = Event.parser(buf, offset) msg = cls(alertmsg, pkth, dlthdr, nethdr, transhdr, data, val, pkt, event) return msg ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/bfdlib.py0000664000175000017500000010550200000000000016634 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Xinguard, Inc. # Copyright (C) 2013 Nippon Telegraph and Telephone 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 Bidirectional Forwarding Detection for IPv4 (Single Hop) This module provides a simple way to let OSKen act like a daemon for running IPv4 single hop BFD (RFC5881). Please note that: * Demand mode and echo function are not yet supported. * Mechanism on negotiating L2/L3 addresses for an established session is not yet implemented. * The interoperability of authentication support is not tested. * Configuring a BFD session with too small interval may lead to full of event queue and congestion of Openflow channels. For deploying a low-latency configuration or with a large number of BFD sessions, use standalone BFD daemon instead. """ import logging import time import random from os_ken.base import app_manager from os_ken.controller import event from os_ken.controller import ofp_event from os_ken.controller.handler import CONFIG_DISPATCHER, MAIN_DISPATCHER from os_ken.controller.handler import set_ev_cls from os_ken.exception import OSKenException from os_ken.ofproto.ether import ETH_TYPE_IP, ETH_TYPE_ARP from os_ken.ofproto import ofproto_v1_3 from os_ken.ofproto import inet from os_ken.lib import hub from os_ken.lib.packet import packet from os_ken.lib.packet import ethernet from os_ken.lib.packet import ipv4 from os_ken.lib.packet import udp from os_ken.lib.packet import bfd from os_ken.lib.packet import arp from os_ken.lib.packet.arp import ARP_REQUEST, ARP_REPLY LOG = logging.getLogger(__name__) UINT16_MAX = (1 << 16) - 1 UINT32_MAX = (1 << 32) - 1 # RFC5881 Section 8 BFD_CONTROL_UDP_PORT = 3784 BFD_ECHO_UDP_PORT = 3785 class BFDSession(object): """BFD Session class. An instance maintains a BFD session. """ def __init__(self, app, my_discr, dpid, ofport, src_mac, src_ip, src_port, dst_mac="FF:FF:FF:FF:FF:FF", dst_ip="255.255.255.255", detect_mult=3, desired_min_tx_interval=1000000, required_min_rx_interval=1000000, auth_type=0, auth_keys=None): """ Initialize a BFD session. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ========================= ============================================ Argument Description ========================= ============================================ app The instance of BFDLib. my_discr My Discriminator. dpid Datapath ID of the BFD interface. ofport Openflow port number of the BFD interface. src_mac Source MAC address of the BFD interface. src_ip Source IPv4 address of the BFD interface. dst_mac (Optional) Destination MAC address of the BFD interface. dst_ip (Optional) Destination IPv4 address of the BFD interface. detect_mult (Optional) Detection time multiplier. desired_min_tx_interval (Optional) Desired Min TX Interval. (in microseconds) required_min_rx_interval (Optional) Required Min RX Interval. (in microseconds) auth_type (Optional) Authentication type. auth_keys (Optional) A dictionary of authentication key chain which key is an integer of *Auth Key ID* and value is a string of *Password* or *Auth Key*. ========================= ============================================ Example:: sess = BFDSession(app=self.bfdlib, my_discr=1, dpid=1, ofport=1, src_mac="01:23:45:67:89:AB", src_ip="192.168.1.1", dst_mac="12:34:56:78:9A:BC", dst_ip="192.168.1.2", detect_mult=3, desired_min_tx_interval=1000000, required_min_rx_interval=1000000, auth_type=bfd.BFD_AUTH_KEYED_SHA1, auth_keys={1: "secret key 1", 2: "secret key 2"}) """ auth_keys = auth_keys if auth_keys else {} assert not (auth_type and len(auth_keys) == 0) # OSKenApp reference to BFDLib self.app = app # RFC5880 Section 6.8.1. # BFD Internal Variables self._session_state = bfd.BFD_STATE_DOWN self._remote_session_state = bfd.BFD_STATE_DOWN self._local_discr = my_discr self._remote_discr = 0 self._local_diag = 0 self._desired_min_tx_interval = 1000000 self._required_min_rx_interval = required_min_rx_interval self._remote_min_rx_interval = -1 # TODO: Demand mode is not yet supported. self._demand_mode = 0 self._remote_demand_mode = 0 self._detect_mult = detect_mult self._auth_type = auth_type self._auth_keys = auth_keys if self._auth_type in [bfd.BFD_AUTH_KEYED_MD5, bfd.BFD_AUTH_METICULOUS_KEYED_MD5, bfd.BFD_AUTH_KEYED_SHA1, bfd.BFD_AUTH_METICULOUS_KEYED_SHA1]: self._rcv_auth_seq = 0 self._xmit_auth_seq = random.randint(0, UINT32_MAX) self._auth_seq_known = 0 # BFD Runtime Variables self._cfg_desired_min_tx_interval = desired_min_tx_interval self._cfg_required_min_echo_rx_interval = 0 self._active_role = True self._detect_time = 0 self._xmit_period = None self._update_xmit_period() self._is_polling = True self._pending_final = False # _enable_send indicates the switch of the periodic transmission of # BFD Control packets. self._enable_send = True self._lock = None # L2/L3/L4 Header fields self.src_mac = src_mac self.dst_mac = dst_mac self.src_ip = src_ip self.dst_ip = dst_ip self.ipv4_id = random.randint(0, UINT16_MAX) self.src_port = src_port self.dst_port = BFD_CONTROL_UDP_PORT if dst_mac == "FF:FF:FF:FF:FF:FF" or dst_ip == "255.255.255.255": self._remote_addr_config = False else: self._remote_addr_config = True # Switch and port associated to this BFD session. self.dpid = dpid self.datapath = None self.ofport = ofport # Spawn a periodic transmission loop for BFD Control packets. hub.spawn(self._send_loop) LOG.info("[BFD][%s][INIT] BFD Session initialized.", hex(self._local_discr)) @property def my_discr(self): """ Returns My Discriminator of the BFD session. """ return self._local_discr @property def your_discr(self): """ Returns Your Discriminator of the BFD session. """ return self._remote_discr def set_remote_addr(self, dst_mac, dst_ip): """ Configure remote ethernet and IP addresses. """ self.dst_mac = dst_mac self.dst_ip = dst_ip if not (dst_mac == "FF:FF:FF:FF:FF:FF" or dst_ip == "255.255.255.255"): self._remote_addr_config = True LOG.info("[BFD][%s][REMOTE] Remote address configured: %s, %s.", hex(self._local_discr), self.dst_ip, self.dst_mac) def recv(self, bfd_pkt): """ BFD packet receiver. """ LOG.debug("[BFD][%s][RECV] BFD Control received: %s", hex(self._local_discr), bytes(bfd_pkt)) self._remote_discr = bfd_pkt.my_discr self._remote_state = bfd_pkt.state self._remote_demand_mode = bfd_pkt.flags & bfd.BFD_FLAG_DEMAND if self._remote_min_rx_interval != bfd_pkt.required_min_rx_interval: self._remote_min_rx_interval = bfd_pkt.required_min_rx_interval # Update transmit interval (RFC5880 Section 6.8.2.) self._update_xmit_period() # TODO: Echo function (RFC5880 Page 35) if bfd_pkt.flags & bfd.BFD_FLAG_FINAL and self._is_polling: self._is_polling = False # Check and update the session state (RFC5880 Page 35) if self._session_state == bfd.BFD_STATE_ADMIN_DOWN: return if bfd_pkt.state == bfd.BFD_STATE_ADMIN_DOWN: if self._session_state != bfd.BFD_STATE_DOWN: self._set_state(bfd.BFD_STATE_DOWN, bfd.BFD_DIAG_NEIG_SIG_SESS_DOWN) else: if self._session_state == bfd.BFD_STATE_DOWN: if bfd_pkt.state == bfd.BFD_STATE_DOWN: self._set_state(bfd.BFD_STATE_INIT) elif bfd_pkt.state == bfd.BFD_STATE_INIT: self._set_state(bfd.BFD_STATE_UP) elif self._session_state == bfd.BFD_STATE_INIT: if bfd_pkt.state in [bfd.BFD_STATE_INIT, bfd.BFD_STATE_UP]: self._set_state(bfd.BFD_STATE_UP) else: if bfd_pkt.state == bfd.BFD_STATE_DOWN: self._set_state(bfd.BFD_STATE_DOWN, bfd.BFD_DIAG_NEIG_SIG_SESS_DOWN) # TODO: Demand mode support. if self._remote_demand_mode and \ self._session_state == bfd.BFD_STATE_UP and \ self._remote_session_state == bfd.BFD_STATE_UP: self._enable_send = False if not self._remote_demand_mode or \ self._session_state != bfd.BFD_STATE_UP or \ self._remote_session_state != bfd.BFD_STATE_UP: if not self._enable_send: self._enable_send = True hub.spawn(self._send_loop) # Update the detection time (RFC5880 Section 6.8.4.) if self._detect_time == 0: self._detect_time = bfd_pkt.desired_min_tx_interval * \ bfd_pkt.detect_mult / 1000000.0 # Start the timeout loop. hub.spawn(self._recv_timeout_loop) if bfd_pkt.flags & bfd.BFD_FLAG_POLL: self._pending_final = True self._detect_time = bfd_pkt.desired_min_tx_interval * \ bfd_pkt.detect_mult / 1000000.0 # Update the remote authentication sequence number. if self._auth_type in [bfd.BFD_AUTH_KEYED_MD5, bfd.BFD_AUTH_METICULOUS_KEYED_MD5, bfd.BFD_AUTH_KEYED_SHA1, bfd.BFD_AUTH_METICULOUS_KEYED_SHA1]: self._rcv_auth_seq = bfd_pkt.auth_cls.seq self._auth_seq_known = 1 # Set the lock. if self._lock is not None: self._lock.set() def _set_state(self, new_state, diag=None): """ Set the state of the BFD session. """ old_state = self._session_state LOG.info("[BFD][%s][STATE] State changed from %s to %s.", hex(self._local_discr), bfd.BFD_STATE_NAME[old_state], bfd.BFD_STATE_NAME[new_state]) self._session_state = new_state if new_state == bfd.BFD_STATE_DOWN: if diag is not None: self._local_diag = diag self._desired_min_tx_interval = 1000000 self._is_polling = True self._update_xmit_period() elif new_state == bfd.BFD_STATE_UP: self._desired_min_tx_interval = self._cfg_desired_min_tx_interval self._is_polling = True self._update_xmit_period() self.app.send_event_to_observers( EventBFDSessionStateChanged(self, old_state, new_state)) def _recv_timeout_loop(self): """ A loop to check timeout of receiving remote BFD packet. """ while self._detect_time: last_wait = time.time() self._lock = hub.Event() self._lock.wait(timeout=self._detect_time) if self._lock.is_set(): # Authentication variable check (RFC5880 Section 6.8.1.) if getattr(self, "_auth_seq_known", 0): if last_wait > time.time() + 2 * self._detect_time: self._auth_seq_known = 0 else: # Check Detection Time expiration (RFC5880 section 6.8.4.) LOG.info("[BFD][%s][RECV] BFD Session timed out.", hex(self._local_discr)) if self._session_state not in [bfd.BFD_STATE_DOWN, bfd.BFD_STATE_ADMIN_DOWN]: self._set_state(bfd.BFD_STATE_DOWN, bfd.BFD_DIAG_CTRL_DETECT_TIME_EXPIRED) # Authentication variable check (RFC5880 Section 6.8.1.) if getattr(self, "_auth_seq_known", 0): self._auth_seq_known = 0 def _update_xmit_period(self): """ Update transmission period of the BFD session. """ # RFC5880 Section 6.8.7. if self._desired_min_tx_interval > self._remote_min_rx_interval: xmit_period = self._desired_min_tx_interval else: xmit_period = self._remote_min_rx_interval # This updates the transmission period of BFD Control packets. # (RFC5880 Section 6.8.2 & 6.8.3.) if self._detect_mult == 1: xmit_period *= random.randint(75, 90) / 100.0 else: xmit_period *= random.randint(75, 100) / 100.0 self._xmit_period = xmit_period / 1000000.0 LOG.info("[BFD][%s][XMIT] Transmission period changed to %f", hex(self._local_discr), self._xmit_period) def _send_loop(self): """ A loop to proceed periodic BFD packet transmission. """ while self._enable_send: hub.sleep(self._xmit_period) # Send BFD packet. (RFC5880 Section 6.8.7.) if self._remote_discr == 0 and not self._active_role: continue if self._remote_min_rx_interval == 0: continue if self._remote_demand_mode and \ self._session_state == bfd.BFD_STATE_UP and \ self._remote_session_state == bfd.BFD_STATE_UP and \ not self._is_polling: continue self._send() def _send(self): """ BFD packet sender. """ # If the switch was not connected to controller, exit. if self.datapath is None: return # BFD Flags Setup flags = 0 if self._pending_final: flags |= bfd.BFD_FLAG_FINAL self._pending_final = False self._is_polling = False if self._is_polling: flags |= bfd.BFD_FLAG_POLL # Authentication Section auth_cls = None if self._auth_type: auth_key_id = list(self._auth_keys.keys())[ random.randint(0, len(list(self._auth_keys.keys())) - 1)] auth_key = self._auth_keys[auth_key_id] if self._auth_type == bfd.BFD_AUTH_SIMPLE_PASS: auth_cls = bfd.SimplePassword(auth_key_id=auth_key_id, password=auth_key) if self._auth_type in [bfd.BFD_AUTH_KEYED_MD5, bfd.BFD_AUTH_METICULOUS_KEYED_MD5, bfd.BFD_AUTH_KEYED_SHA1, bfd.BFD_AUTH_METICULOUS_KEYED_SHA1]: if self._auth_type in [bfd.BFD_AUTH_KEYED_MD5, bfd.BFD_AUTH_KEYED_SHA1]: if random.randint(0, 1): self._xmit_auth_seq = \ (self._xmit_auth_seq + 1) & UINT32_MAX else: self._xmit_auth_seq = \ (self._xmit_auth_seq + 1) & UINT32_MAX auth_cls = bfd.bfd._auth_parsers[self._auth_type]( auth_key_id=auth_key_id, seq=self._xmit_auth_seq, auth_key=auth_key) if auth_cls is not None: flags |= bfd.BFD_FLAG_AUTH_PRESENT if self._demand_mode and \ self._session_state == bfd.BFD_STATE_UP and \ self._remote_session_state == bfd.BFD_STATE_UP: flags |= bfd.BFD_FLAG_DEMAND diag = self._local_diag state = self._session_state detect_mult = self._detect_mult my_discr = self._local_discr your_discr = self._remote_discr desired_min_tx_interval = self._desired_min_tx_interval required_min_rx_interval = self._required_min_rx_interval required_min_echo_rx_interval = self._cfg_required_min_echo_rx_interval # Prepare for Ethernet/IP/UDP header fields src_mac = self.src_mac dst_mac = self.dst_mac src_ip = self.src_ip dst_ip = self.dst_ip self.ipv4_id = (self.ipv4_id + 1) & UINT16_MAX ipv4_id = self.ipv4_id src_port = self.src_port dst_port = self.dst_port # Construct BFD Control packet data = BFDPacket.bfd_packet( src_mac=src_mac, dst_mac=dst_mac, src_ip=src_ip, dst_ip=dst_ip, ipv4_id=ipv4_id, src_port=src_port, dst_port=dst_port, diag=diag, state=state, flags=flags, detect_mult=detect_mult, my_discr=my_discr, your_discr=your_discr, desired_min_tx_interval=desired_min_tx_interval, required_min_rx_interval=required_min_rx_interval, required_min_echo_rx_interval=required_min_echo_rx_interval, auth_cls=auth_cls) # Prepare for a datapath datapath = self.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser actions = [parser.OFPActionOutput(self.ofport)] out = parser.OFPPacketOut(datapath=datapath, buffer_id=ofproto.OFP_NO_BUFFER, in_port=ofproto.OFPP_CONTROLLER, actions=actions, data=data) datapath.send_msg(out) LOG.debug("[BFD][%s][SEND] BFD Control sent.", hex(self._local_discr)) class BFDPacket(object): """ BFDPacket class for parsing raw BFD packet, and generating BFD packet with Ethernet, IPv4, and UDP headers. """ class BFDUnknownFormat(OSKenException): message = '%(msg)s' @staticmethod def bfd_packet(src_mac, dst_mac, src_ip, dst_ip, ipv4_id, src_port, dst_port, diag=0, state=0, flags=0, detect_mult=0, my_discr=0, your_discr=0, desired_min_tx_interval=0, required_min_rx_interval=0, required_min_echo_rx_interval=0, auth_cls=None): """ Generate BFD packet with Ethernet/IPv4/UDP encapsulated. """ # Generate ethernet header first. pkt = packet.Packet() eth_pkt = ethernet.ethernet(dst_mac, src_mac, ETH_TYPE_IP) pkt.add_protocol(eth_pkt) # IPv4 encapsulation # set ToS to 192 (Network control/CS6) # set TTL to 255 (RFC5881 Section 5.) ipv4_pkt = ipv4.ipv4(proto=inet.IPPROTO_UDP, src=src_ip, dst=dst_ip, tos=192, identification=ipv4_id, ttl=255) pkt.add_protocol(ipv4_pkt) # UDP encapsulation udp_pkt = udp.udp(src_port=src_port, dst_port=dst_port) pkt.add_protocol(udp_pkt) # BFD payload bfd_pkt = bfd.bfd( ver=1, diag=diag, state=state, flags=flags, detect_mult=detect_mult, my_discr=my_discr, your_discr=your_discr, desired_min_tx_interval=desired_min_tx_interval, required_min_rx_interval=required_min_rx_interval, required_min_echo_rx_interval=required_min_echo_rx_interval, auth_cls=auth_cls) pkt.add_protocol(bfd_pkt) pkt.serialize() return pkt.data @staticmethod def bfd_parse(data): """ Parse raw packet and return BFD class from packet library. """ pkt = packet.Packet(data) i = iter(pkt) eth_pkt = next(i) assert isinstance(eth_pkt, ethernet.ethernet) ipv4_pkt = next(i) assert isinstance(ipv4_pkt, ipv4.ipv4) udp_pkt = next(i) assert isinstance(udp_pkt, udp.udp) udp_payload = next(i) return bfd.bfd.parser(udp_payload)[0] class ARPPacket(object): """ ARPPacket class for parsing raw ARP packet, and generating ARP packet with Ethernet header. """ class ARPUnknownFormat(OSKenException): message = '%(msg)s' @staticmethod def arp_packet(opcode, src_mac, src_ip, dst_mac, dst_ip): """ Generate ARP packet with ethernet encapsulated. """ # Generate ethernet header first. pkt = packet.Packet() eth_pkt = ethernet.ethernet(dst_mac, src_mac, ETH_TYPE_ARP) pkt.add_protocol(eth_pkt) # Use IPv4 ARP wrapper from packet library directly. arp_pkt = arp.arp_ip(opcode, src_mac, src_ip, dst_mac, dst_ip) pkt.add_protocol(arp_pkt) pkt.serialize() return pkt.data @staticmethod def arp_parse(data): """ Parse ARP packet, return ARP class from packet library. """ # Iteratize pkt pkt = packet.Packet(data) i = iter(pkt) eth_pkt = next(i) # Ensure it's an ethernet frame. assert isinstance(eth_pkt, ethernet.ethernet) arp_pkt = next(i) if not isinstance(arp_pkt, arp.arp): raise ARPPacket.ARPUnknownFormat() if arp_pkt.opcode not in (ARP_REQUEST, ARP_REPLY): raise ARPPacket.ARPUnknownFormat( msg='unsupported opcode %d' % arp_pkt.opcode) if arp_pkt.proto != ETH_TYPE_IP: raise ARPPacket.ARPUnknownFormat( msg='unsupported arp ethtype 0x%04x' % arp_pkt.proto) return arp_pkt class EventBFDSessionStateChanged(event.EventBase): """ An event class that notifies the state change of a BFD session. """ def __init__(self, session, old_state, new_state): super(EventBFDSessionStateChanged, self).__init__() self.session = session self.old_state = old_state self.new_state = new_state class BFDLib(app_manager.OSKenApp): """ BFD daemon library. Add this library as a context in your app and use ``add_bfd_session`` function to establish a BFD session. Example:: from os_ken.base import app_manager from os_ken.controller.handler import set_ev_cls from os_ken.ofproto import ofproto_v1_3 from os_ken.lib import bfdlib from os_ken.lib.packet import bfd class Foo(app_manager.OSKenApp): OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION] _CONTEXTS = { 'bfdlib': bfdlib.BFDLib } def __init__(self, *args, **kwargs): super(Foo, self).__init__(*args, **kwargs) self.bfdlib = kwargs['bfdlib'] self.my_discr = \ self.bfdlib.add_bfd_session(dpid=1, ofport=1, src_mac="00:23:45:67:89:AB", src_ip="192.168.1.1") @set_ev_cls(bfdlib.EventBFDSessionStateChanged) def bfd_state_handler(self, ev): if ev.session.my_discr != self.my_discr: return if ev.new_state == bfd.BFD_STATE_DOWN: print "BFD Session=%d is DOWN!" % ev.session.my_discr elif ev.new_state == bfd.BFD_STATE_UP: print "BFD Session=%d is UP!" % ev.session.my_discr """ OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION] _EVENTS = [EventBFDSessionStateChanged] def __init__(self, *args, **kwargs): super(BFDLib, self).__init__(*args, **kwargs) # BFD Session Dictionary # key: My Discriminator # value: BFDSession object self.session = {} def close(self): pass @set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER) def switch_features_handler(self, ev): datapath = ev.msg.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser # Update datapath object in BFD sessions for s in self.session.values(): if s.dpid == datapath.id: s.datapath = datapath # Install default flows for capturing ARP & BFD packets. match = parser.OFPMatch(eth_type=ETH_TYPE_ARP) actions = [parser.OFPActionOutput(ofproto.OFPP_CONTROLLER, ofproto.OFPCML_NO_BUFFER)] self.add_flow(datapath, 0xFFFF, match, actions) match = parser.OFPMatch(eth_type=ETH_TYPE_IP, ip_proto=inet.IPPROTO_UDP, udp_dst=3784) actions = [parser.OFPActionOutput(ofproto.OFPP_CONTROLLER, ofproto.OFPCML_NO_BUFFER)] self.add_flow(datapath, 0xFFFF, match, actions) def add_flow(self, datapath, priority, match, actions): ofproto = datapath.ofproto parser = datapath.ofproto_parser inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions)] mod = parser.OFPFlowMod(datapath=datapath, priority=priority, match=match, instructions=inst) datapath.send_msg(mod) # Packet-In Handler, only for BFD packets. @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER) def _packet_in_handler(self, ev): msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser in_port = msg.match['in_port'] pkt = packet.Packet(msg.data) # If there's someone asked for an IP address associated # with a BFD session, generate an ARP reply for it. if arp.arp in pkt: arp_pkt = ARPPacket.arp_parse(msg.data) if arp_pkt.opcode == ARP_REQUEST: for s in self.session.values(): if s.dpid == datapath.id and \ s.ofport == in_port and \ s.src_ip == arp_pkt.dst_ip: ans = ARPPacket.arp_packet( ARP_REPLY, s.src_mac, s.src_ip, arp_pkt.src_mac, arp_pkt.src_ip) actions = [parser.OFPActionOutput(in_port)] out = parser.OFPPacketOut( datapath=datapath, buffer_id=ofproto.OFP_NO_BUFFER, in_port=ofproto.OFPP_CONTROLLER, actions=actions, data=ans) datapath.send_msg(out) return return # Check whether it's BFD packet or not. if ipv4.ipv4 not in pkt or udp.udp not in pkt: return udp_hdr = pkt.get_protocols(udp.udp)[0] if udp_hdr.dst_port != BFD_CONTROL_UDP_PORT: return # Parse BFD packet here. self.recv_bfd_pkt(datapath, in_port, msg.data) def add_bfd_session(self, dpid, ofport, src_mac, src_ip, dst_mac="FF:FF:FF:FF:FF:FF", dst_ip="255.255.255.255", auth_type=0, auth_keys=None): """ Establish a new BFD session and return My Discriminator of new session. Configure the BFD session with the following arguments. ================ ====================================================== Argument Description ================ ====================================================== dpid Datapath ID of the BFD interface. ofport Openflow port number of the BFD interface. src_mac Source MAC address of the BFD interface. src_ip Source IPv4 address of the BFD interface. dst_mac (Optional) Destination MAC address of the BFD interface. dst_ip (Optional) Destination IPv4 address of the BFD interface. auth_type (Optional) Authentication type. auth_keys (Optional) A dictionary of authentication key chain which key is an integer of *Auth Key ID* and value is a string of *Password* or *Auth Key*. ================ ====================================================== Example:: add_bfd_session(dpid=1, ofport=1, src_mac="01:23:45:67:89:AB", src_ip="192.168.1.1", dst_mac="12:34:56:78:9A:BC", dst_ip="192.168.1.2", auth_type=bfd.BFD_AUTH_KEYED_SHA1, auth_keys={1: "secret key 1", 2: "secret key 2"}) """ auth_keys = auth_keys if auth_keys else {} # Generate a unique discriminator while True: # Generate My Discriminator my_discr = random.randint(1, UINT32_MAX) # Generate an UDP destination port according to RFC5881 Section 4. src_port = random.randint(49152, 65535) # Ensure generated discriminator and UDP port are unique. if my_discr in self.session: continue unique_flag = True for s in self.session.values(): if s.your_discr == my_discr or s.src_port == src_port: unique_flag = False break if unique_flag: break sess = BFDSession(app=self, my_discr=my_discr, dpid=dpid, ofport=ofport, src_mac=src_mac, src_ip=src_ip, src_port=src_port, dst_mac=dst_mac, dst_ip=dst_ip, auth_type=auth_type, auth_keys=auth_keys) self.session[my_discr] = sess return my_discr def recv_bfd_pkt(self, datapath, in_port, data): pkt = packet.Packet(data) eth = pkt.get_protocols(ethernet.ethernet)[0] if eth.ethertype != ETH_TYPE_IP: return ip_pkt = pkt.get_protocols(ipv4.ipv4)[0] # Discard it if TTL != 255 for single hop bfd. (RFC5881 Section 5.) if ip_pkt.ttl != 255: return # Parse BFD packet here. bfd_pkt = BFDPacket.bfd_parse(data) if not isinstance(bfd_pkt, bfd.bfd): return # BFD sanity checks # RFC 5880 Section 6.8.6. if bfd_pkt.ver != 1: return if bfd_pkt.flags & bfd.BFD_FLAG_AUTH_PRESENT: if bfd_pkt.length < 26: return else: if bfd_pkt.length < 24: return if bfd_pkt.detect_mult == 0: return if bfd_pkt.flags & bfd.BFD_FLAG_MULTIPOINT: return if bfd_pkt.my_discr == 0: return if bfd_pkt.your_discr != 0 and bfd_pkt.your_discr not in self.session: return if bfd_pkt.your_discr == 0 and \ bfd_pkt.state not in [bfd.BFD_STATE_ADMIN_DOWN, bfd.BFD_STATE_DOWN]: return sess_my_discr = None if bfd_pkt.your_discr == 0: # Select session (Page 34) for s in self.session.values(): if s.dpid == datapath.id and s.ofport == in_port: sess_my_discr = s.my_discr break # BFD Session not found. if sess_my_discr is None: return else: sess_my_discr = bfd_pkt.your_discr sess = self.session[sess_my_discr] if bfd_pkt.flags & bfd.BFD_FLAG_AUTH_PRESENT and sess._auth_type == 0: return if bfd_pkt.flags & bfd.BFD_FLAG_AUTH_PRESENT == 0 and \ sess._auth_type != 0: return # Authenticate the session (Section 6.7.) if bfd_pkt.flags & bfd.BFD_FLAG_AUTH_PRESENT: if sess._auth_type == 0: return if bfd_pkt.auth_cls.auth_type != sess._auth_type: return # Check authentication sequence number to defend replay attack. if sess._auth_type in [bfd.BFD_AUTH_KEYED_MD5, bfd.BFD_AUTH_METICULOUS_KEYED_MD5, bfd.BFD_AUTH_KEYED_SHA1, bfd.BFD_AUTH_METICULOUS_KEYED_SHA1]: if sess._auth_seq_known: if bfd_pkt.auth_cls.seq < sess._rcv_auth_seq: return if sess._auth_type in [bfd.BFD_AUTH_METICULOUS_KEYED_MD5, bfd.BFD_AUTH_METICULOUS_KEYED_SHA1]: if bfd_pkt.auth_cls.seq <= sess._rcv_auth_seq: return if bfd_pkt.auth_cls.seq > sess._rcv_auth_seq \ + 3 * sess._detect_mult: return if not bfd_pkt.authenticate(sess._auth_keys): LOG.debug("[BFD][%s][AUTH] BFD Control authentication failed.", hex(sess._local_discr)) return # Sanity check passed, proceed. if sess is not None: # Check whether L2/L3 addresses were configured or not. # TODO: L2/L3 addresses negotiation for an established session. if not sess._remote_addr_config: sess.set_remote_addr(eth.src, ip_pkt.src) # Proceed to session update. sess.recv(bfd_pkt) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/dpid.py0000664000175000017500000000200600000000000016325 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2012 Isaku Yamahata # # 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. # Internal representation of datapath id is quad int # string representation is in hex without '0x' _DPID_LEN = 16 _DPID_FMT = '%0{0}x'.format(_DPID_LEN) DPID_PATTERN = r'[0-9a-f]{%d}' % _DPID_LEN def dpid_to_str(dpid): return _DPID_FMT % dpid def str_to_dpid(dpid_str): assert len(dpid_str) == _DPID_LEN return int(dpid_str, 16) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/hub.py0000664000175000017500000002062400000000000016171 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013 YAMAMOTO Takashi # # 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. import logging import os from os_ken.lib import ip # We don't bother to use cfg.py because monkey patch needs to be # called very early. Instead, we use an environment variable to # select the type of hub. HUB_TYPE = os.getenv('OSKEN_HUB_TYPE', 'eventlet') LOG = logging.getLogger('os_ken.lib.hub') if HUB_TYPE == 'eventlet': import eventlet # HACK: # sleep() is the workaround for the following issue. # https://github.com/eventlet/eventlet/issues/401 eventlet.sleep() import eventlet.event import eventlet.queue import eventlet.semaphore import eventlet.timeout import eventlet.wsgi from eventlet import websocket import greenlet import ssl import socket import traceback import sys getcurrent = eventlet.getcurrent sleep = eventlet.sleep listen = eventlet.listen connect = eventlet.connect def patch(thread=True): eventlet.monkey_patch(thread=thread) if thread: # Monkey patch the original current_thread to use the up-to-date _active # global variable. See https://bugs.launchpad.net/bugs/1863021 and # https://github.com/eventlet/eventlet/issues/592 import __original_module_threading as orig_threading # noqa import threading # noqa orig_threading.current_thread.__globals__['_active'] = threading._active def spawn(*args, **kwargs): raise_error = kwargs.pop('raise_error', False) def _launch(func, *args, **kwargs): # Mimic gevent's default raise_error=False behaviour # by not propagating an exception to the joiner. try: return func(*args, **kwargs) except TaskExit: pass except BaseException as e: if raise_error: raise e # Log uncaught exception. # Note: this is an intentional divergence from gevent # behaviour; gevent silently ignores such exceptions. LOG.error('hub: uncaught exception: %s', traceback.format_exc()) return eventlet.spawn(_launch, *args, **kwargs) def spawn_after(seconds, *args, **kwargs): raise_error = kwargs.pop('raise_error', False) def _launch(func, *args, **kwargs): # Mimic gevent's default raise_error=False behaviour # by not propagating an exception to the joiner. try: return func(*args, **kwargs) except TaskExit: pass except BaseException as e: if raise_error: raise e # Log uncaught exception. # Note: this is an intentional divergence from gevent # behaviour; gevent silently ignores such exceptions. LOG.error('hub: uncaught exception: %s', traceback.format_exc()) return eventlet.spawn_after(seconds, _launch, *args, **kwargs) def kill(thread): thread.kill() def joinall(threads): for t in threads: # This try-except is necessary when killing an inactive # greenthread. try: t.wait() except TaskExit: pass Queue = eventlet.queue.LightQueue QueueEmpty = eventlet.queue.Empty Semaphore = eventlet.semaphore.Semaphore BoundedSemaphore = eventlet.semaphore.BoundedSemaphore TaskExit = greenlet.GreenletExit class StreamServer(object): def __init__(self, listen_info, handle=None, backlog=None, spawn='default', **ssl_args): assert backlog is None assert spawn == 'default' if ip.valid_ipv6(listen_info[0]): self.server = eventlet.listen(listen_info, family=socket.AF_INET6) elif os.path.isdir(os.path.dirname(listen_info[0])): # Case for Unix domain socket self.server = eventlet.listen(listen_info[0], family=socket.AF_UNIX) else: self.server = eventlet.listen(listen_info) if ssl_args: ssl_args.setdefault('server_side', True) if 'ssl_ctx' in ssl_args: ctx = ssl_args.pop('ssl_ctx') ctx.load_cert_chain(ssl_args.pop('certfile'), ssl_args.pop('keyfile')) if 'cert_reqs' in ssl_args: ctx.verify_mode = ssl_args.pop('cert_reqs') if 'ca_certs' in ssl_args: ctx.load_verify_locations(ssl_args.pop('ca_certs')) def wrap_and_handle_ctx(sock, addr): handle(ctx.wrap_socket(sock, **ssl_args), addr) self.handle = wrap_and_handle_ctx else: def wrap_and_handle_ssl(sock, addr): handle(ssl.wrap_socket(sock, **ssl_args), addr) self.handle = wrap_and_handle_ssl else: self.handle = handle def serve_forever(self): while True: sock, addr = self.server.accept() spawn(self.handle, sock, addr) class StreamClient(object): def __init__(self, addr, timeout=None, **ssl_args): assert ip.valid_ipv4(addr[0]) or ip.valid_ipv6(addr[0]) self.addr = addr self.timeout = timeout self.ssl_args = ssl_args self._is_active = True def connect(self): try: if self.timeout is not None: client = socket.create_connection(self.addr, timeout=self.timeout) else: client = socket.create_connection(self.addr) except socket.error: return None if self.ssl_args: client = ssl.wrap_socket(client, **self.ssl_args) return client def connect_loop(self, handle, interval): while self._is_active: sock = self.connect() if sock: handle(sock, self.addr) sleep(interval) def stop(self): self._is_active = False class LoggingWrapper(object): def write(self, message): LOG.info(message.rstrip('\n')) class WSGIServer(StreamServer): def serve_forever(self): self.logger = LoggingWrapper() eventlet.wsgi.server(self.server, self.handle, self.logger) WebSocketWSGI = websocket.WebSocketWSGI Timeout = eventlet.timeout.Timeout class Event(object): def __init__(self): self._ev = eventlet.event.Event() self._cond = False def _wait(self, timeout=None): while not self._cond: self._ev.wait() def _broadcast(self): self._ev.send() # Since eventlet Event doesn't allow multiple send() operations # on an event, re-create the underlying event. # Note: _ev.reset() is obsolete. self._ev = eventlet.event.Event() def is_set(self): return self._cond def set(self): self._cond = True self._broadcast() def clear(self): self._cond = False def wait(self, timeout=None): if timeout is None: self._wait() else: try: with Timeout(timeout): self._wait() except Timeout: pass return self._cond ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/igmplib.py0000664000175000017500000007571300000000000017047 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone 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. import logging import struct from os_ken.base import app_manager from os_ken.controller import event from os_ken.controller import ofp_event from os_ken.controller.handler import DEAD_DISPATCHER from os_ken.controller.handler import MAIN_DISPATCHER from os_ken.controller.handler import set_ev_cls from os_ken.ofproto import ether from os_ken.ofproto import inet from os_ken.ofproto import ofproto_v1_0 from os_ken.ofproto import ofproto_v1_2 from os_ken.ofproto import ofproto_v1_3 from os_ken.lib import addrconv from os_ken.lib import hub from os_ken.lib.dpid import dpid_to_str from os_ken.lib.packet import packet from os_ken.lib.packet import ethernet from os_ken.lib.packet import ipv4 from os_ken.lib.packet import igmp class EventPacketIn(event.EventBase): """a PacketIn event class using except IGMP.""" def __init__(self, msg): """initialization.""" super(EventPacketIn, self).__init__() self.msg = msg MG_GROUP_ADDED = 1 MG_MEMBER_CHANGED = 2 MG_GROUP_REMOVED = 3 class EventMulticastGroupStateChanged(event.EventBase): """a event class that notifies the changes of the statuses of the multicast groups.""" def __init__(self, reason, address, src, dsts): """ ========= ===================================================== Attribute Description ========= ===================================================== reason why the event occurs. use one of MG_*. address a multicast group address. src a port number in which a querier exists. dsts a list of port numbers in which the members exist. ========= ===================================================== """ super(EventMulticastGroupStateChanged, self).__init__() self.reason = reason self.address = address self.src = src self.dsts = dsts class IgmpLib(app_manager.OSKenApp): """IGMP snooping library.""" # ------------------------------------------------------------------- # PUBLIC METHODS # ------------------------------------------------------------------- def __init__(self): """initialization.""" super(IgmpLib, self).__init__() self.name = 'igmplib' self._querier = IgmpQuerier() self._snooper = IgmpSnooper(self.send_event_to_observers) def set_querier_mode(self, dpid, server_port): """set a datapath id and server port number to the instance of IgmpQuerier. ============ ================================================== Attribute Description ============ ================================================== dpid the datapath id that will operate as a querier. server_port the port number linked to the multicasting server. ============ ================================================== """ self._querier.set_querier_mode(dpid, server_port) # ------------------------------------------------------------------- # PUBLIC METHODS ( EVENT HANDLERS ) # ------------------------------------------------------------------- @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER) def packet_in_handler(self, evt): """PacketIn event handler. when the received packet was IGMP, proceed it. otherwise, send a event.""" msg = evt.msg dpid = msg.datapath.id req_pkt = packet.Packet(msg.data) req_igmp = req_pkt.get_protocol(igmp.igmp) if req_igmp: if self._querier.dpid == dpid: self._querier.packet_in_handler(req_igmp, msg) else: self._snooper.packet_in_handler(req_pkt, req_igmp, msg) else: self.send_event_to_observers(EventPacketIn(msg)) @set_ev_cls(ofp_event.EventOFPStateChange, [MAIN_DISPATCHER, DEAD_DISPATCHER]) def state_change_handler(self, evt): """StateChange event handler.""" datapath = evt.datapath assert datapath is not None if datapath.id == self._querier.dpid: if evt.state == MAIN_DISPATCHER: self._querier.start_loop(datapath) elif evt.state == DEAD_DISPATCHER: self._querier.stop_loop() class IgmpBase(object): """IGMP abstract class library.""" # ------------------------------------------------------------------- # PUBLIC METHODS # ------------------------------------------------------------------- def __init__(self): self._set_flow_func = { ofproto_v1_0.OFP_VERSION: self._set_flow_entry_v1_0, ofproto_v1_2.OFP_VERSION: self._set_flow_entry_v1_2, ofproto_v1_3.OFP_VERSION: self._set_flow_entry_v1_2, } self._del_flow_func = { ofproto_v1_0.OFP_VERSION: self._del_flow_entry_v1_0, ofproto_v1_2.OFP_VERSION: self._del_flow_entry_v1_2, ofproto_v1_3.OFP_VERSION: self._del_flow_entry_v1_2, } # ------------------------------------------------------------------- # PROTECTED METHODS ( RELATED TO OPEN FLOW PROTOCOL ) # ------------------------------------------------------------------- def _set_flow_entry_v1_0(self, datapath, actions, in_port, dst, src=None): ofproto = datapath.ofproto parser = datapath.ofproto_parser match = parser.OFPMatch( dl_type=ether.ETH_TYPE_IP, in_port=in_port, nw_src=self._ipv4_text_to_int(src), nw_dst=self._ipv4_text_to_int(dst)) mod = parser.OFPFlowMod( datapath=datapath, match=match, cookie=0, command=ofproto.OFPFC_ADD, actions=actions) datapath.send_msg(mod) def _set_flow_entry_v1_2(self, datapath, actions, in_port, dst, src=None): ofproto = datapath.ofproto parser = datapath.ofproto_parser match = parser.OFPMatch( eth_type=ether.ETH_TYPE_IP, in_port=in_port, ipv4_dst=dst) if src is not None: match.append_field(ofproto.OXM_OF_IPV4_SRC, src) inst = [parser.OFPInstructionActions( ofproto.OFPIT_APPLY_ACTIONS, actions)] mod = parser.OFPFlowMod( datapath=datapath, command=ofproto.OFPFC_ADD, priority=65535, match=match, instructions=inst) datapath.send_msg(mod) def _set_flow_entry(self, datapath, actions, in_port, dst, src=None): """set a flow entry.""" set_flow = self._set_flow_func.get(datapath.ofproto.OFP_VERSION) assert set_flow set_flow(datapath, actions, in_port, dst, src) def _del_flow_entry_v1_0(self, datapath, in_port, dst, src=None): ofproto = datapath.ofproto parser = datapath.ofproto_parser match = parser.OFPMatch( dl_type=ether.ETH_TYPE_IP, in_port=in_port, nw_src=self._ipv4_text_to_int(src), nw_dst=self._ipv4_text_to_int(dst)) mod = parser.OFPFlowMod( datapath=datapath, match=match, cookie=0, command=ofproto.OFPFC_DELETE) datapath.send_msg(mod) def _del_flow_entry_v1_2(self, datapath, in_port, dst, src=None): ofproto = datapath.ofproto parser = datapath.ofproto_parser match = parser.OFPMatch( eth_type=ether.ETH_TYPE_IP, in_port=in_port, ipv4_dst=dst) if src is not None: match.append_field(ofproto.OXM_OF_IPV4_SRC, src) mod = parser.OFPFlowMod( datapath=datapath, command=ofproto.OFPFC_DELETE, out_port=ofproto.OFPP_ANY, out_group=ofproto.OFPG_ANY, match=match) datapath.send_msg(mod) def _del_flow_entry(self, datapath, in_port, dst, src=None): """remove a flow entry.""" del_flow = self._del_flow_func.get(datapath.ofproto.OFP_VERSION) assert del_flow del_flow(datapath, in_port, dst, src) def _do_packet_out(self, datapath, data, in_port, actions): """send a packet.""" ofproto = datapath.ofproto parser = datapath.ofproto_parser out = parser.OFPPacketOut( datapath=datapath, buffer_id=ofproto.OFP_NO_BUFFER, data=data, in_port=in_port, actions=actions) datapath.send_msg(out) # ------------------------------------------------------------------- # PROTECTED METHODS ( OTHERS ) # ------------------------------------------------------------------- def _ipv4_text_to_int(self, ip_text): """convert ip v4 string to integer.""" if ip_text is None: return None assert isinstance(ip_text, str) return struct.unpack('!I', addrconv.ipv4.text_to_bin(ip_text))[0] class IgmpQuerier(IgmpBase): """IGMP querier emulation class library. this querier is a simplified implementation, and is not based on RFC, for example as following points: - ignore some constant values - does not send a specific QUERY in response to LEAVE - and so on """ # ------------------------------------------------------------------- # PUBLIC METHODS # ------------------------------------------------------------------- def __init__(self): """initialization.""" super(IgmpQuerier, self).__init__() self.name = "IgmpQuerier" self.logger = logging.getLogger(self.name) self.dpid = None self.server_port = None self._datapath = None self._querier_thread = None # the structure of self._macst # # +-------+------------------+ # | group | port: True/False | # | +------------------+ # | |... | # +-------+------------------+ # | ... | # +--------------------------+ # # group multicast address. # port a port number which connect to the group member. # the value indicates that whether a flow entry # was registered. self._mcast = {} self._set_logger() def set_querier_mode(self, dpid, server_port): """set the datapath to work as a querier. note that you can set up only the one querier. when you called this method several times, only the last one becomes effective.""" self.dpid = dpid self.server_port = server_port if self._querier_thread: hub.kill(self._querier_thread) self._querier_thread = None def packet_in_handler(self, req_igmp, msg): """the process when the querier received IGMP.""" ofproto = msg.datapath.ofproto if ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION: in_port = msg.in_port else: in_port = msg.match['in_port'] if (igmp.IGMP_TYPE_REPORT_V1 == req_igmp.msgtype or igmp.IGMP_TYPE_REPORT_V2 == req_igmp.msgtype): self._do_report(req_igmp, in_port, msg) elif igmp.IGMP_TYPE_LEAVE == req_igmp.msgtype: self._do_leave(req_igmp, in_port, msg) def start_loop(self, datapath): """start QUERY thread.""" self._datapath = datapath self._querier_thread = hub.spawn(self._send_query) self.logger.info("started a querier.") def stop_loop(self): """stop QUERY thread.""" hub.kill(self._querier_thread) self._querier_thread = None self._datapath = None self.logger.info("stopped a querier.") # ------------------------------------------------------------------- # PRIVATE METHODS ( RELATED TO IGMP ) # ------------------------------------------------------------------- def _send_query(self): """ send a QUERY message periodically.""" timeout = 60 ofproto = self._datapath.ofproto parser = self._datapath.ofproto_parser if ofproto_v1_0.OFP_VERSION == ofproto.OFP_VERSION: send_port = ofproto.OFPP_NONE else: send_port = ofproto.OFPP_ANY # create a general query. res_igmp = igmp.igmp( msgtype=igmp.IGMP_TYPE_QUERY, maxresp=igmp.QUERY_RESPONSE_INTERVAL * 10, csum=0, address='0.0.0.0') res_ipv4 = ipv4.ipv4( total_length=len(ipv4.ipv4()) + len(res_igmp), proto=inet.IPPROTO_IGMP, ttl=1, src='0.0.0.0', dst=igmp.MULTICAST_IP_ALL_HOST) res_ether = ethernet.ethernet( dst=igmp.MULTICAST_MAC_ALL_HOST, src=self._datapath.ports[ofproto.OFPP_LOCAL].hw_addr, ethertype=ether.ETH_TYPE_IP) res_pkt = packet.Packet() res_pkt.add_protocol(res_ether) res_pkt.add_protocol(res_ipv4) res_pkt.add_protocol(res_igmp) res_pkt.serialize() flood = [parser.OFPActionOutput(ofproto.OFPP_FLOOD)] while True: # reset reply status. for status in self._mcast.values(): for port in status.keys(): status[port] = False # send a general query to the host that sent this message. self._do_packet_out( self._datapath, res_pkt.data, send_port, flood) hub.sleep(igmp.QUERY_RESPONSE_INTERVAL) # QUERY timeout expired. del_groups = [] for group, status in self._mcast.items(): del_ports = [] actions = [] for port in status.keys(): if not status[port]: del_ports.append(port) else: actions.append(parser.OFPActionOutput(port)) if len(actions) and len(del_ports): self._set_flow_entry( self._datapath, actions, self.server_port, group) if not len(actions): self._del_flow_entry( self._datapath, self.server_port, group) del_groups.append(group) if len(del_ports): for port in del_ports: self._del_flow_entry(self._datapath, port, group) for port in del_ports: del status[port] for group in del_groups: del self._mcast[group] rest_time = timeout - igmp.QUERY_RESPONSE_INTERVAL hub.sleep(rest_time) def _do_report(self, report, in_port, msg): """the process when the querier received a REPORT message.""" datapath = msg.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser if ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION: size = 65535 else: size = ofproto.OFPCML_MAX update = False self._mcast.setdefault(report.address, {}) if in_port not in self._mcast[report.address]: update = True self._mcast[report.address][in_port] = True if update: actions = [] for port in self._mcast[report.address]: actions.append(parser.OFPActionOutput(port)) self._set_flow_entry( datapath, actions, self.server_port, report.address) self._set_flow_entry( datapath, [parser.OFPActionOutput(ofproto.OFPP_CONTROLLER, size)], in_port, report.address) def _do_leave(self, leave, in_port, msg): """the process when the querier received a LEAVE message.""" datapath = msg.datapath parser = datapath.ofproto_parser self._mcast.setdefault(leave.address, {}) if in_port in self._mcast[leave.address]: self._del_flow_entry( datapath, in_port, leave.address) del self._mcast[leave.address][in_port] actions = [] for port in self._mcast[leave.address]: actions.append(parser.OFPActionOutput(port)) if len(actions): self._set_flow_entry( datapath, actions, self.server_port, leave.address) else: self._del_flow_entry( datapath, self.server_port, leave.address) # ------------------------------------------------------------------- # PRIVATE METHODS ( OTHERS ) # ------------------------------------------------------------------- def _set_logger(self): """change log format.""" self.logger.propagate = False hdl = logging.StreamHandler() fmt_str = '[querier][%(levelname)s] %(message)s' hdl.setFormatter(logging.Formatter(fmt_str)) self.logger.addHandler(hdl) class IgmpSnooper(IgmpBase): """IGMP snooping class library.""" # ------------------------------------------------------------------- # PUBLIC METHODS # ------------------------------------------------------------------- def __init__(self, send_event): """initialization.""" super(IgmpSnooper, self).__init__() self.name = "IgmpSnooper" self.logger = logging.getLogger(self.name) self._send_event = send_event # the structure of self._to_querier # # +------+--------------+ # | dpid | 'port': port | # | +--------------+ # | | 'ip': ip | # | +--------------+ # | | 'mac': mac | # +------+--------------+ # | ... | # +---------------------+ # # dpid datapath id. # port a port number which connect to the querier. # ip IP address of the querier. # mac MAC address of the querier. self._to_querier = {} # the structure of self._to_hosts # # +------+-------+---------------------------------+ # | dpid | group | 'replied': True/False | # | | +---------------------------------+ # | | | 'leave': leave | # | | +-----------+--------+------------+ # | | | 'ports' | portno | 'out': out | # | | | | +------------+ # | | | | | 'in': in | # | | | +--------+------------+ # | | | | ... | # | +-------+-----------+---------------------+ # | | ... | # +------+-----------------------------------------+ # | ... | # +------------------------------------------------+ # # dpid datapath id. # group multicast address. # replied the value indicates whether a REPORT message was # replied. # leave a LEAVE message. # portno a port number which has joined to the multicast # group. # out the value indicates whether a flow entry for the # packet outputted to the port was registered. # in the value indicates whether a flow entry for the # packet inputted from the port was registered. self._to_hosts = {} self._set_logger() def packet_in_handler(self, req_pkt, req_igmp, msg): """the process when the snooper received IGMP.""" dpid = msg.datapath.id ofproto = msg.datapath.ofproto if ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION: in_port = msg.in_port else: in_port = msg.match['in_port'] log = "SW=%s PORT=%d IGMP received. " % ( dpid_to_str(dpid), in_port) self.logger.debug(str(req_igmp)) if igmp.IGMP_TYPE_QUERY == req_igmp.msgtype: self.logger.info(log + "[QUERY]") (req_ipv4, ) = req_pkt.get_protocols(ipv4.ipv4) (req_eth, ) = req_pkt.get_protocols(ethernet.ethernet) self._do_query(req_igmp, req_ipv4, req_eth, in_port, msg) elif (igmp.IGMP_TYPE_REPORT_V1 == req_igmp.msgtype or igmp.IGMP_TYPE_REPORT_V2 == req_igmp.msgtype): self.logger.info(log + "[REPORT]") self._do_report(req_igmp, in_port, msg) elif igmp.IGMP_TYPE_LEAVE == req_igmp.msgtype: self.logger.info(log + "[LEAVE]") self._do_leave(req_igmp, in_port, msg) elif igmp.IGMP_TYPE_REPORT_V3 == req_igmp.msgtype: self.logger.info(log + "V3 is not supported yet.") self._do_flood(in_port, msg) else: self.logger.info(log + "[unknown type:%d]", req_igmp.msgtype) self._do_flood(in_port, msg) # ------------------------------------------------------------------- # PRIVATE METHODS ( RELATED TO IGMP ) # ------------------------------------------------------------------- def _do_query(self, query, iph, eth, in_port, msg): """the process when the snooper received a QUERY message.""" datapath = msg.datapath dpid = datapath.id ofproto = datapath.ofproto parser = datapath.ofproto_parser # learn the querier. self._to_querier[dpid] = { 'port': in_port, 'ip': iph.src, 'mac': eth.src } # set the timeout time. timeout = igmp.QUERY_RESPONSE_INTERVAL if query.maxresp: timeout = query.maxresp / 10 self._to_hosts.setdefault(dpid, {}) if query.address == '0.0.0.0': # general query. reset all reply status. for group in self._to_hosts[dpid].values(): group['replied'] = False group['leave'] = None else: # specific query. reset the reply status of the specific # group. group = self._to_hosts[dpid].get(query.address) if group: group['replied'] = False group['leave'] = None actions = [parser.OFPActionOutput(ofproto.OFPP_FLOOD)] self._do_packet_out( datapath, msg.data, in_port, actions) # wait for REPORT messages. hub.spawn(self._do_timeout_for_query, timeout, datapath) def _do_report(self, report, in_port, msg): """the process when the snooper received a REPORT message.""" datapath = msg.datapath dpid = datapath.id ofproto = datapath.ofproto parser = datapath.ofproto_parser if ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION: size = 65535 else: size = ofproto.OFPCML_MAX # check whether the querier port has been specified. outport = None value = self._to_querier.get(dpid) if value: outport = value['port'] # send a event when the multicast group address is new. self._to_hosts.setdefault(dpid, {}) if not self._to_hosts[dpid].get(report.address): self._send_event( EventMulticastGroupStateChanged( MG_GROUP_ADDED, report.address, outport, [])) self._to_hosts[dpid].setdefault( report.address, {'replied': False, 'leave': None, 'ports': {}}) # set a flow entry from a host to the controller when # a host sent a REPORT message. if not self._to_hosts[dpid][report.address]['ports'].get( in_port): self._to_hosts[dpid][report.address]['ports'][ in_port] = {'out': False, 'in': False} self._set_flow_entry( datapath, [parser.OFPActionOutput(ofproto.OFPP_CONTROLLER, size)], in_port, report.address) if not self._to_hosts[dpid][report.address]['ports'][ in_port]['out']: self._to_hosts[dpid][report.address]['ports'][ in_port]['out'] = True if not outport: self.logger.info("no querier exists.") return # set a flow entry from a multicast server to hosts. if not self._to_hosts[dpid][report.address]['ports'][ in_port]['in']: actions = [] ports = [] for port in self._to_hosts[dpid][report.address]['ports']: actions.append(parser.OFPActionOutput(port)) ports.append(port) self._send_event( EventMulticastGroupStateChanged( MG_MEMBER_CHANGED, report.address, outport, ports)) self._set_flow_entry( datapath, actions, outport, report.address) self._to_hosts[dpid][report.address]['ports'][ in_port]['in'] = True # send a REPORT message to the querier if this message arrived # first after a QUERY message was sent. if not self._to_hosts[dpid][report.address]['replied']: actions = [parser.OFPActionOutput(outport, size)] self._do_packet_out(datapath, msg.data, in_port, actions) self._to_hosts[dpid][report.address]['replied'] = True def _do_leave(self, leave, in_port, msg): """the process when the snooper received a LEAVE message.""" datapath = msg.datapath dpid = datapath.id ofproto = datapath.ofproto parser = datapath.ofproto_parser # check whether the querier port has been specified. if not self._to_querier.get(dpid): self.logger.info("no querier exists.") return # save this LEAVE message and reset the condition of the port # that received this message. self._to_hosts.setdefault(dpid, {}) self._to_hosts[dpid].setdefault( leave.address, {'replied': False, 'leave': None, 'ports': {}}) self._to_hosts[dpid][leave.address]['leave'] = msg self._to_hosts[dpid][leave.address]['ports'][in_port] = { 'out': False, 'in': False} # create a specific query. timeout = igmp.LAST_MEMBER_QUERY_INTERVAL res_igmp = igmp.igmp( msgtype=igmp.IGMP_TYPE_QUERY, maxresp=timeout * 10, csum=0, address=leave.address) res_ipv4 = ipv4.ipv4( total_length=len(ipv4.ipv4()) + len(res_igmp), proto=inet.IPPROTO_IGMP, ttl=1, src=self._to_querier[dpid]['ip'], dst=igmp.MULTICAST_IP_ALL_HOST) res_ether = ethernet.ethernet( dst=igmp.MULTICAST_MAC_ALL_HOST, src=self._to_querier[dpid]['mac'], ethertype=ether.ETH_TYPE_IP) res_pkt = packet.Packet() res_pkt.add_protocol(res_ether) res_pkt.add_protocol(res_ipv4) res_pkt.add_protocol(res_igmp) res_pkt.serialize() # send a specific query to the host that sent this message. actions = [parser.OFPActionOutput(ofproto.OFPP_IN_PORT)] self._do_packet_out(datapath, res_pkt.data, in_port, actions) # wait for REPORT messages. hub.spawn(self._do_timeout_for_leave, timeout, datapath, leave.address, in_port) def _do_flood(self, in_port, msg): """the process when the snooper received a message of the outside for processing. """ datapath = msg.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser actions = [parser.OFPActionOutput(ofproto.OFPP_FLOOD)] self._do_packet_out(datapath, msg.data, in_port, actions) def _do_timeout_for_query(self, timeout, datapath): """the process when the QUERY from the querier timeout expired.""" dpid = datapath.id hub.sleep(timeout) outport = self._to_querier[dpid]['port'] remove_dsts = [] for dst in self._to_hosts[dpid]: if not self._to_hosts[dpid][dst]['replied']: # if no REPORT message sent from any members of # the group, remove flow entries about the group and # send a LEAVE message if exists. self._remove_multicast_group(datapath, outport, dst) remove_dsts.append(dst) for dst in remove_dsts: del self._to_hosts[dpid][dst] def _do_timeout_for_leave(self, timeout, datapath, dst, in_port): """the process when the QUERY from the switch timeout expired.""" parser = datapath.ofproto_parser dpid = datapath.id hub.sleep(timeout) outport = self._to_querier[dpid]['port'] if self._to_hosts[dpid][dst]['ports'][in_port]['out']: return del self._to_hosts[dpid][dst]['ports'][in_port] self._del_flow_entry(datapath, in_port, dst) actions = [] ports = [] for port in self._to_hosts[dpid][dst]['ports']: actions.append(parser.OFPActionOutput(port)) ports.append(port) if len(actions): self._send_event( EventMulticastGroupStateChanged( MG_MEMBER_CHANGED, dst, outport, ports)) self._set_flow_entry( datapath, actions, outport, dst) self._to_hosts[dpid][dst]['leave'] = None else: self._remove_multicast_group(datapath, outport, dst) del self._to_hosts[dpid][dst] def _remove_multicast_group(self, datapath, outport, dst): """remove flow entries about the group and send a LEAVE message if exists.""" ofproto = datapath.ofproto parser = datapath.ofproto_parser dpid = datapath.id self._send_event( EventMulticastGroupStateChanged( MG_GROUP_REMOVED, dst, outport, [])) self._del_flow_entry(datapath, outport, dst) for port in self._to_hosts[dpid][dst]['ports']: self._del_flow_entry(datapath, port, dst) leave = self._to_hosts[dpid][dst]['leave'] if leave: if ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION: in_port = leave.in_port else: in_port = leave.match['in_port'] actions = [parser.OFPActionOutput(outport)] self._do_packet_out( datapath, leave.data, in_port, actions) # ------------------------------------------------------------------- # PRIVATE METHODS ( OTHERS ) # ------------------------------------------------------------------- def _set_logger(self): """change log format.""" self.logger.propagate = False hdl = logging.StreamHandler() fmt_str = '[snoop][%(levelname)s] %(message)s' hdl.setFormatter(logging.Formatter(fmt_str)) self.logger.addHandler(hdl) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/ip.py0000664000175000017500000001111700000000000016020 0ustar00zuulzuul00000000000000# Copyright (C) 2015 Nippon Telegraph and Telephone 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. import numbers import struct import netaddr from os_ken.lib import addrconv from os_ken.lib import type_desc def _valid_ip(strategy, bits, addr, flags=0): addr = addr.split('/') if len(addr) == 1: return strategy(addr[0], flags) elif len(addr) == 2: return strategy(addr[0], flags) and 0 <= int(addr[1]) <= bits else: return False def valid_ipv4(addr, flags=0): """ Wrapper function of "netaddr.valid_ipv4()". The function extends "netaddr.valid_ipv4()" to enable to validate IPv4 network address in "xxx.xxx.xxx.xxx/xx" format. :param addr: IP address to be validated. :param flags: See the "netaddr.valid_ipv4()" docs for details. :return: True is valid. False otherwise. """ return _valid_ip(netaddr.valid_ipv4, 32, addr, flags) def valid_ipv6(addr, flags=0): """ Wrapper function of "netaddr.valid_ipv6()". The function extends "netaddr.valid_ipv6()" to enable to validate IPv4 network address in "xxxx:xxxx:xxxx::/xx" format. :param addr: IP address to be validated. :param flags: See the "netaddr.valid_ipv6()" docs for details. :return: True is valid. False otherwise. """ return _valid_ip(netaddr.valid_ipv6, 128, addr, flags) def ipv4_to_bin(ip): """ Converts human readable IPv4 string to binary representation. :param str ip: IPv4 address string :return: binary representation of IPv4 address """ return addrconv.ipv4.text_to_bin(ip) def ipv4_to_int(ip): """ Converts human readable IPv4 string to int type representation. :param str ip: IPv4 address string w.x.y.z :returns: unsigned int of form w << 24 | x << 16 | y << 8 | z """ return struct.unpack("!I", addrconv.ipv4.text_to_bin(ip))[0] def ipv4_to_str(ip): """ Converts binary or int type representation to human readable IPv4 string. :param ip: binary or int type representation of IPv4 address :return: IPv4 address string """ if isinstance(ip, numbers.Integral): return addrconv.ipv4.bin_to_text(struct.pack("!I", ip)) else: return addrconv.ipv4.bin_to_text(ip) def ipv6_to_bin(ip): """ Converts human readable IPv6 string to binary representation. :param str ip: IPv6 address string :return: binary representation of IPv6 address """ return addrconv.ipv6.text_to_bin(ip) def ipv6_to_int(ip): """ Converts human readable IPv6 string to int type representation. :param str ip: IPv6 address string :returns: int type representation of IPv6 address """ return type_desc.Int16.to_user(addrconv.ipv6.text_to_bin(ip)) def ipv6_to_str(ip): """ Converts binary or int type representation to human readable IPv6 string. :param ip: binary or int type representation of IPv6 address :return: IPv6 address string """ if isinstance(ip, numbers.Integral): return addrconv.ipv6.bin_to_text(type_desc.Int16.from_user(ip)) else: return addrconv.ipv6.bin_to_text(ip) def text_to_bin(ip): """ Converts human readable IPv4 or IPv6 string to binary representation. :param str ip: IPv4 or IPv6 address string :return: binary representation of IPv4 or IPv6 address """ if ':' not in ip: return ipv4_to_bin(ip) else: return ipv6_to_bin(ip) def text_to_int(ip): """ Converts human readable IPv4 or IPv6 string to int type representation. :param str ip: IPv4 or IPv6 address string :return: int type representation of IPv4 or IPv6 address """ if ':' not in ip: return ipv4_to_int(ip) else: return ipv6_to_int(ip) def bin_to_text(ip): """ Converts binary representation to human readable IPv4 or IPv6 string. :param ip: binary representation of IPv4 or IPv6 address :return: IPv4 or IPv6 address string """ if len(ip) == 4: return ipv4_to_str(ip) elif len(ip) == 16: return ipv6_to_str(ip) else: raise struct.error('Invalid ip address length: %s' % len(ip)) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/lacplib.py0000664000175000017500000003220600000000000017020 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone 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. import logging from os_ken.base import app_manager from os_ken.controller import event from os_ken.controller import ofp_event from os_ken.controller.handler import MAIN_DISPATCHER from os_ken.controller.handler import set_ev_cls from os_ken.ofproto import ether from os_ken.ofproto import ofproto_v1_0 from os_ken.ofproto import ofproto_v1_2 from os_ken.ofproto import ofproto_v1_3 from os_ken.lib import addrconv from os_ken.lib.dpid import dpid_to_str from os_ken.lib.packet import packet from os_ken.lib.packet import ethernet from os_ken.lib.packet import slow class EventPacketIn(event.EventBase): """a PacketIn event class using except LACP.""" def __init__(self, msg): """initialization.""" super(EventPacketIn, self).__init__() self.msg = msg class EventSlaveStateChanged(event.EventBase): """a event class that notifies the changes of the statuses of the slave i/fs.""" def __init__(self, datapath, port, enabled): """initialization.""" super(EventSlaveStateChanged, self).__init__() self.datapath = datapath self.port = port self.enabled = enabled class LacpLib(app_manager.OSKenApp): """LACP exchange library. this works only in a PASSIVE mode.""" # ------------------------------------------------------------------- # PUBLIC METHODS # ------------------------------------------------------------------- def __init__(self): """initialization.""" super(LacpLib, self).__init__() self.name = 'lacplib' self._bonds = [] self._add_flow = { ofproto_v1_0.OFP_VERSION: self._add_flow_v1_0, ofproto_v1_2.OFP_VERSION: self._add_flow_v1_2, ofproto_v1_3.OFP_VERSION: self._add_flow_v1_2, } self._set_logger() def add(self, dpid, ports): """add a setting of a bonding i/f. 'add' method takes the corresponding args in this order. ========= ===================================================== Attribute Description ========= ===================================================== dpid datapath id. ports a list of integer values that means the ports face with the slave i/fs. ========= ===================================================== if you want to use multi LAG, call 'add' method more than once. """ assert isinstance(ports, list) assert len(ports) >= 2 ifs = {} for port in ports: ifs[port] = {'enabled': False, 'timeout': 0} bond = {dpid: ifs} self._bonds.append(bond) # ------------------------------------------------------------------- # PUBLIC METHODS ( EVENT HANDLERS ) # ------------------------------------------------------------------- @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER) def packet_in_handler(self, evt): """PacketIn event handler. when the received packet was LACP, proceed it. otherwise, send a event.""" req_pkt = packet.Packet(evt.msg.data) if slow.lacp in req_pkt: (req_lacp, ) = req_pkt.get_protocols(slow.lacp) (req_eth, ) = req_pkt.get_protocols(ethernet.ethernet) self._do_lacp(req_lacp, req_eth.src, evt.msg) else: self.send_event_to_observers(EventPacketIn(evt.msg)) @set_ev_cls(ofp_event.EventOFPFlowRemoved, MAIN_DISPATCHER) def flow_removed_handler(self, evt): """FlowRemoved event handler. when the removed flow entry was for LACP, set the status of the slave i/f to disabled, and send a event.""" msg = evt.msg datapath = msg.datapath ofproto = datapath.ofproto dpid = datapath.id match = msg.match if ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION: port = match.in_port dl_type = match.dl_type else: port = match['in_port'] dl_type = match['eth_type'] if ether.ETH_TYPE_SLOW != dl_type: return self.logger.info( "SW=%s PORT=%d LACP exchange timeout has occurred.", dpid_to_str(dpid), port) self._set_slave_enabled(dpid, port, False) self._set_slave_timeout(dpid, port, 0) self.send_event_to_observers( EventSlaveStateChanged(datapath, port, False)) # ------------------------------------------------------------------- # PRIVATE METHODS ( RELATED TO LACP ) # ------------------------------------------------------------------- def _do_lacp(self, req_lacp, src, msg): """packet-in process when the received packet is LACP.""" datapath = msg.datapath dpid = datapath.id ofproto = datapath.ofproto parser = datapath.ofproto_parser if ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION: port = msg.in_port else: port = msg.match['in_port'] self.logger.info("SW=%s PORT=%d LACP received.", dpid_to_str(dpid), port) self.logger.debug(str(req_lacp)) # when LACP arrived at disabled port, update the status of # the slave i/f to enabled, and send a event. if not self._get_slave_enabled(dpid, port): self.logger.info( "SW=%s PORT=%d the slave i/f has just been up.", dpid_to_str(dpid), port) self._set_slave_enabled(dpid, port, True) self.send_event_to_observers( EventSlaveStateChanged(datapath, port, True)) # set the idle_timeout time using the actor state of the # received packet. if req_lacp.LACP_STATE_SHORT_TIMEOUT == \ req_lacp.actor_state_timeout: idle_timeout = req_lacp.SHORT_TIMEOUT_TIME else: idle_timeout = req_lacp.LONG_TIMEOUT_TIME # when the timeout time has changed, update the timeout time of # the slave i/f and re-enter a flow entry for the packet from # the slave i/f with idle_timeout. if idle_timeout != self._get_slave_timeout(dpid, port): self.logger.info( "SW=%s PORT=%d the timeout time has changed.", dpid_to_str(dpid), port) self._set_slave_timeout(dpid, port, idle_timeout) func = self._add_flow.get(ofproto.OFP_VERSION) assert func func(src, port, idle_timeout, datapath) # create a response packet. res_pkt = self._create_response(datapath, port, req_lacp) # packet-out the response packet. out_port = ofproto.OFPP_IN_PORT actions = [parser.OFPActionOutput(out_port)] out = datapath.ofproto_parser.OFPPacketOut( datapath=datapath, buffer_id=ofproto.OFP_NO_BUFFER, data=res_pkt.data, in_port=port, actions=actions) datapath.send_msg(out) def _create_response(self, datapath, port, req): """create a packet including LACP.""" src = datapath.ports[port].hw_addr res_ether = ethernet.ethernet( slow.SLOW_PROTOCOL_MULTICAST, src, ether.ETH_TYPE_SLOW) res_lacp = self._create_lacp(datapath, port, req) res_pkt = packet.Packet() res_pkt.add_protocol(res_ether) res_pkt.add_protocol(res_lacp) res_pkt.serialize() return res_pkt def _create_lacp(self, datapath, port, req): """create a LACP packet.""" actor_system = datapath.ports[datapath.ofproto.OFPP_LOCAL].hw_addr res = slow.lacp( actor_system_priority=0xffff, actor_system=actor_system, actor_key=req.actor_key, actor_port_priority=0xff, actor_port=port, actor_state_activity=req.LACP_STATE_PASSIVE, actor_state_timeout=req.actor_state_timeout, actor_state_aggregation=req.actor_state_aggregation, actor_state_synchronization=req.actor_state_synchronization, actor_state_collecting=req.actor_state_collecting, actor_state_distributing=req.actor_state_distributing, actor_state_defaulted=req.LACP_STATE_OPERATIONAL_PARTNER, actor_state_expired=req.LACP_STATE_NOT_EXPIRED, partner_system_priority=req.actor_system_priority, partner_system=req.actor_system, partner_key=req.actor_key, partner_port_priority=req.actor_port_priority, partner_port=req.actor_port, partner_state_activity=req.actor_state_activity, partner_state_timeout=req.actor_state_timeout, partner_state_aggregation=req.actor_state_aggregation, partner_state_synchronization=req.actor_state_synchronization, partner_state_collecting=req.actor_state_collecting, partner_state_distributing=req.actor_state_distributing, partner_state_defaulted=req.actor_state_defaulted, partner_state_expired=req.actor_state_expired, collector_max_delay=0) self.logger.info("SW=%s PORT=%d LACP sent.", dpid_to_str(datapath.id), port) self.logger.debug(str(res)) return res def _get_slave_enabled(self, dpid, port): """get whether a slave i/f at some port of some datapath is enable or not.""" slave = self._get_slave(dpid, port) if slave: return slave['enabled'] else: return False def _set_slave_enabled(self, dpid, port, enabled): """set whether a slave i/f at some port of some datapath is enable or not.""" slave = self._get_slave(dpid, port) if slave: slave['enabled'] = enabled def _get_slave_timeout(self, dpid, port): """get the timeout time at some port of some datapath.""" slave = self._get_slave(dpid, port) if slave: return slave['timeout'] else: return 0 def _set_slave_timeout(self, dpid, port, timeout): """set the timeout time at some port of some datapath.""" slave = self._get_slave(dpid, port) if slave: slave['timeout'] = timeout def _get_slave(self, dpid, port): """get slave i/f at some port of some datapath.""" result = None for bond in self._bonds: if dpid in bond: if port in bond[dpid]: result = bond[dpid][port] break return result # ------------------------------------------------------------------- # PRIVATE METHODS ( RELATED TO OPEN FLOW PROTOCOL ) # ------------------------------------------------------------------- def _add_flow_v1_0(self, src, port, timeout, datapath): """enter a flow entry for the packet from the slave i/f with idle_timeout. for OpenFlow ver1.0.""" ofproto = datapath.ofproto parser = datapath.ofproto_parser match = parser.OFPMatch( in_port=port, dl_src=addrconv.mac.text_to_bin(src), dl_type=ether.ETH_TYPE_SLOW) actions = [parser.OFPActionOutput( ofproto.OFPP_CONTROLLER, 65535)] mod = parser.OFPFlowMod( datapath=datapath, match=match, cookie=0, command=ofproto.OFPFC_ADD, idle_timeout=timeout, priority=65535, flags=ofproto.OFPFF_SEND_FLOW_REM, actions=actions) datapath.send_msg(mod) def _add_flow_v1_2(self, src, port, timeout, datapath): """enter a flow entry for the packet from the slave i/f with idle_timeout. for OpenFlow ver1.2 and ver1.3.""" ofproto = datapath.ofproto parser = datapath.ofproto_parser match = parser.OFPMatch( in_port=port, eth_src=src, eth_type=ether.ETH_TYPE_SLOW) actions = [parser.OFPActionOutput( ofproto.OFPP_CONTROLLER, ofproto.OFPCML_MAX)] inst = [parser.OFPInstructionActions( ofproto.OFPIT_APPLY_ACTIONS, actions)] mod = parser.OFPFlowMod( datapath=datapath, command=ofproto.OFPFC_ADD, idle_timeout=timeout, priority=65535, flags=ofproto.OFPFF_SEND_FLOW_REM, match=match, instructions=inst) datapath.send_msg(mod) # ------------------------------------------------------------------- # PRIVATE METHODS ( OTHERS ) # ------------------------------------------------------------------- def _set_logger(self): """change log format.""" self.logger.propagate = False hdl = logging.StreamHandler() fmt_str = '[LACP][%(levelname)s] %(message)s' hdl.setFormatter(logging.Formatter(fmt_str)) self.logger.addHandler(hdl) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/mac.py0000664000175000017500000000347500000000000016160 0ustar00zuulzuul00000000000000# Copyright (C) 2011 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2011 Isaku Yamahata # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. from os_ken.lib import addrconv import struct # string representation HADDR_PATTERN = r'([0-9a-f]{2}:){5}[0-9a-f]{2}' DONTCARE = b'\x00' * 6 BROADCAST = b'\xff' * 6 DONTCARE_STR = '00:00:00:00:00:00' BROADCAST_STR = 'ff:ff:ff:ff:ff:ff' MULTICAST = 'fe:ff:ff:ff:ff:ff' UNICAST = '01:00:00:00:00:00' def is_multicast(addr): return bool(int(addr[0]) & 0x01) def haddr_to_str(addr): """Format mac address in internal representation into human readable form""" if addr is None: return 'None' try: return addrconv.mac.bin_to_text(addr) except: raise AssertionError def haddr_to_int(addr): """Convert mac address string in human readable format into integer value""" try: return int(addr.replace(':', ''), 16) except: raise ValueError def haddr_to_bin(string): """Parse mac address string in human readable format into internal representation""" try: return addrconv.mac.text_to_bin(string) except: raise ValueError def haddr_bitand(addr, mask): return b''.join(struct.Struct(">B").pack(int(a) & int(m)) for (a, m) in zip(addr, mask)) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/mrtlib.py0000664000175000017500000013543700000000000016715 0ustar00zuulzuul00000000000000# Copyright (C) 2016 Nippon Telegraph and Telephone 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. """ Library for reading/writing MRT (Multi-Threaded Routing Toolkit) Routing Information Export Format [RFC6396]. """ import abc import logging import struct import time from os_ken.lib import addrconv from os_ken.lib import ip from os_ken.lib import stringify from os_ken.lib import type_desc from os_ken.lib.packet import bgp from os_ken.lib.packet import ospf LOG = logging.getLogger(__name__) class MrtRecord(stringify.StringifyMixin, type_desc.TypeDisp, metaclass=abc.ABCMeta): """ MRT record. """ _HEADER_FMT = '!IHHI' # the same as MRT Common Header HEADER_SIZE = struct.calcsize(_HEADER_FMT) MESSAGE_CLS = None # parser class for message field # MRT Types TYPE_OSPFv2 = 11 TYPE_TABLE_DUMP = 12 TYPE_TABLE_DUMP_V2 = 13 TYPE_BGP4MP = 16 TYPE_BGP4MP_ET = 17 TYPE_ISIS = 32 TYPE_ISIS_ET = 33 TYPE_OSPFv3 = 48 TYPE_OSPFv3_ET = 49 # List of MRT type using Extended Timestamp MRT Header _EXT_TS_TYPES = [TYPE_BGP4MP_ET, TYPE_ISIS_ET, TYPE_OSPFv3_ET] def __init__(self, message, timestamp=None, type_=None, subtype=None, length=None): assert issubclass(message.__class__, MrtMessage) self.message = message self.timestamp = timestamp if type_ is None: type_ = self._rev_lookup_type(self.__class__) self.type = type_ if subtype is None: subtype = self.MESSAGE_CLS._rev_lookup_type(message.__class__) self.subtype = subtype self.length = length @classmethod def parse_common_header(cls, buf): header_fields = struct.unpack_from( cls._HEADER_FMT, buf) return list(header_fields), buf[cls.HEADER_SIZE:] @classmethod def parse_extended_header(cls, buf): # If extended header field exist, override this in subclass. return [], buf @classmethod def parse_pre(cls, buf): buf = bytes(buf) # for convenience header_fields, _ = cls.parse_common_header(buf) # timestamp = header_fields[0] type_ = header_fields[1] # subtype = header_fields[2] length = header_fields[3] if type_ in cls._EXT_TS_TYPES: header_cls = ExtendedTimestampMrtRecord else: header_cls = MrtCommonRecord required_len = header_cls.HEADER_SIZE + length return required_len @classmethod def parse(cls, buf): buf = bytes(buf) # for convenience header_fields, rest = cls.parse_common_header(buf) # timestamp = header_fields[0] type_ = header_fields[1] subtype = header_fields[2] length = header_fields[3] sub_cls = MrtRecord._lookup_type(type_) extended_headers, rest = sub_cls.parse_extended_header(rest) header_fields.extend(extended_headers) msg_cls = sub_cls.MESSAGE_CLS._lookup_type(subtype) message_bin = rest[:length] message = msg_cls.parse(message_bin) return sub_cls(message, *header_fields), rest[length:] @abc.abstractmethod def serialize_header(self): pass def serialize(self): if self.timestamp is None: self.timestamp = int(time.time()) buf = self.message.serialize() self.length = len(buf) # fixup return self.serialize_header() + buf class MrtCommonRecord(MrtRecord): """ MRT record using MRT Common Header. """ # 0 1 2 3 # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Timestamp | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Type | Subtype | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Length | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Message... (variable) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ _HEADER_FMT = '!IHHI' HEADER_SIZE = struct.calcsize(_HEADER_FMT) def serialize_header(self): return struct.pack(self._HEADER_FMT, self.timestamp, self.type, self.subtype, self.length) class ExtendedTimestampMrtRecord(MrtRecord): """ MRT record using Extended Timestamp MRT Header. """ # 0 1 2 3 # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Timestamp | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Type | Subtype | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Length | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Microsecond Timestamp | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Message... (variable) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ _HEADER_FMT = '!IHHII' HEADER_SIZE = struct.calcsize(_HEADER_FMT) _EXT_HEADER_FMT = '!I' EXT_HEADER_SIZE = struct.calcsize(_EXT_HEADER_FMT) def __init__(self, message, timestamp=None, type_=None, subtype=None, ms_timestamp=None, length=None): super(ExtendedTimestampMrtRecord, self).__init__( message, timestamp, type_, subtype, length) self.ms_timestamp = ms_timestamp @classmethod def parse_extended_header(cls, buf): (ms_timestamp,) = struct.unpack_from(cls._EXT_HEADER_FMT, buf) return [ms_timestamp], buf[cls.EXT_HEADER_SIZE:] def serialize_header(self): return struct.pack(self._HEADER_FMT, self.timestamp, self.type, self.subtype, self.length, self.ms_timestamp) class MrtMessage(stringify.StringifyMixin, type_desc.TypeDisp, metaclass=abc.ABCMeta): """ MRT Message in record. """ @classmethod @abc.abstractmethod def parse(cls, buf): pass @abc.abstractmethod def serialize(self): pass class UnknownMrtMessage(MrtMessage): """ MRT Message for the UNKNOWN Type. """ def __init__(self, buf): self.buf = buf @classmethod def parse(cls, buf): return cls(buf) def serialize(self): return self.buf # Registers self to unknown(default) type UnknownMrtMessage._UNKNOWN_TYPE = UnknownMrtMessage @MrtRecord.register_unknown_type() class UnknownMrtRecord(MrtCommonRecord): """ MRT record for the UNKNOWN Type. """ MESSAGE_CLS = UnknownMrtMessage class Ospf2MrtMessage(MrtMessage): """ MRT Message for the OSPFv2 Type. """ # 0 1 2 3 # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Remote IP Address | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Local IP Address | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | OSPF Message Contents (variable) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ _HEADER_FMT = '!4s4s' HEADER_SIZE = struct.calcsize(_HEADER_FMT) _TYPE = { 'ascii': [ 'remote_ip', 'local_ip', ], } def __init__(self, remote_ip, local_ip, ospf_message): self.remote_ip = remote_ip self.local_ip = local_ip assert isinstance(ospf_message, ospf.OSPFMessage) self.ospf_message = ospf_message @classmethod def parse(cls, buf): (remote_ip, local_ip) = struct.unpack_from(cls._HEADER_FMT, buf) remote_ip = addrconv.ipv4.bin_to_text(remote_ip) local_ip = addrconv.ipv4.bin_to_text(local_ip) ospf_message, _, _ = ospf.OSPFMessage.parser(buf[cls.HEADER_SIZE:]) return cls(remote_ip, local_ip, ospf_message) def serialize(self): return (addrconv.ipv4.text_to_bin(self.remote_ip) + addrconv.ipv4.text_to_bin(self.local_ip) + self.ospf_message.serialize()) @MrtRecord.register_type(MrtRecord.TYPE_OSPFv2) class Ospf2MrtRecord(MrtCommonRecord): """ MRT Record for the OSPFv2 Type. """ MESSAGE_CLS = Ospf2MrtMessage def __init__(self, message, timestamp=None, type_=None, subtype=0, length=None): super(Ospf2MrtRecord, self).__init__( message=message, timestamp=timestamp, type_=type_, subtype=subtype, length=length) # Registers self to unknown(default) type Ospf2MrtMessage._UNKNOWN_TYPE = Ospf2MrtMessage class TableDumpMrtMessage(MrtMessage, metaclass=abc.ABCMeta): """ MRT Message for the TABLE_DUMP Type. """ # 0 1 2 3 # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | View Number | Sequence Number | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Prefix (variable) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Prefix Length | Status | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Originated Time | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Peer IP Address (variable) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Peer AS | Attribute Length | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | BGP Attribute... (variable) # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ _HEADER_FMT = '' # should be defined in subclass HEADER_SIZE = 0 _TYPE = { 'ascii': [ 'prefix', 'peer_ip', ], } def __init__(self, view_num, seq_num, prefix, prefix_len, status, originated_time, peer_ip, peer_as, bgp_attributes, attr_len=None): self.view_num = view_num self.seq_num = seq_num self.prefix = prefix self.prefix_len = prefix_len # Status in the TABLE_DUMP Type SHOULD be set to 1 assert status == 1 self.status = status self.originated_time = originated_time self.peer_ip = peer_ip self.peer_as = peer_as self.attr_len = attr_len assert isinstance(bgp_attributes, (list, tuple)) for attr in bgp_attributes: assert isinstance(attr, bgp._PathAttribute) self.bgp_attributes = bgp_attributes @classmethod def parse(cls, buf): (view_num, seq_num, prefix, prefix_len, status, originated_time, peer_ip, peer_as, attr_len) = struct.unpack_from(cls._HEADER_FMT, buf) prefix = ip.bin_to_text(prefix) peer_ip = ip.bin_to_text(peer_ip) bgp_attr_bin = buf[cls.HEADER_SIZE:cls.HEADER_SIZE + attr_len] bgp_attributes = [] while bgp_attr_bin: attr, bgp_attr_bin = bgp._PathAttribute.parser(bgp_attr_bin) bgp_attributes.append(attr) return cls(view_num, seq_num, prefix, prefix_len, status, originated_time, peer_ip, peer_as, bgp_attributes, attr_len) def serialize(self): bgp_attrs_bin = bytearray() for attr in self.bgp_attributes: bgp_attrs_bin += attr.serialize() self.attr_len = len(bgp_attrs_bin) # fixup prefix = ip.text_to_bin(self.prefix) peer_ip = ip.text_to_bin(self.peer_ip) return struct.pack(self._HEADER_FMT, self.view_num, self.seq_num, prefix, self.prefix_len, self.status, self.originated_time, peer_ip, self.peer_as, self.attr_len) + bgp_attrs_bin @MrtRecord.register_type(MrtRecord.TYPE_TABLE_DUMP) class TableDumpMrtRecord(MrtCommonRecord): """ MRT Record for the TABLE_DUMP Type. """ MESSAGE_CLS = TableDumpMrtMessage # MRT Subtype SUBTYPE_AFI_IPv4 = 1 SUBTYPE_AFI_IPv6 = 2 @TableDumpMrtMessage.register_type(TableDumpMrtRecord.SUBTYPE_AFI_IPv4) class TableDumpAfiIPv4MrtMessage(TableDumpMrtMessage): """ MRT Message for the TABLE_DUMP Type and the AFI_IPv4 subtype. """ _HEADER_FMT = '!HH4sBBI4sHH' HEADER_SIZE = struct.calcsize(_HEADER_FMT) @TableDumpMrtMessage.register_type(TableDumpMrtRecord.SUBTYPE_AFI_IPv6) class TableDumpAfiIPv6MrtMessage(TableDumpMrtMessage): """ MRT Message for the TABLE_DUMP Type and the AFI_IPv6 subtype. """ _HEADER_FMT = '!HH16sBBI16sHH' HEADER_SIZE = struct.calcsize(_HEADER_FMT) class TableDump2MrtMessage(MrtMessage, metaclass=abc.ABCMeta): """ MRT Message for the TABLE_DUMP_V2 Type. """ @MrtRecord.register_type(MrtRecord.TYPE_TABLE_DUMP_V2) class TableDump2MrtRecord(MrtCommonRecord): MESSAGE_CLS = TableDump2MrtMessage # MRT Subtype SUBTYPE_PEER_INDEX_TABLE = 1 SUBTYPE_RIB_IPV4_UNICAST = 2 SUBTYPE_RIB_IPV4_MULTICAST = 3 SUBTYPE_RIB_IPV6_UNICAST = 4 SUBTYPE_RIB_IPV6_MULTICAST = 5 SUBTYPE_RIB_GENERIC = 6 SUBTYPE_RIB_IPV4_UNICAST_ADDPATH = 8 SUBTYPE_RIB_IPV4_MULTICAST_ADDPATH = 9 SUBTYPE_RIB_IPV6_UNICAST_ADDPATH = 10 SUBTYPE_RIB_IPV6_MULTICAST_ADDPATH = 11 SUBTYPE_RIB_GENERIC_ADDPATH = 12 @TableDump2MrtMessage.register_type( TableDump2MrtRecord.SUBTYPE_PEER_INDEX_TABLE) class TableDump2PeerIndexTableMrtMessage(TableDump2MrtMessage): """ MRT Message for the TABLE_DUMP_V2 Type and the PEER_INDEX_TABLE subtype. """ # 0 1 2 3 # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Collector BGP ID | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | View Name Length | View Name (variable) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Peer Count | Peer Entries (variable) # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ _HEADER_FMT = '!4sH' HEADER_SIZE = struct.calcsize(_HEADER_FMT) _PEER_COUNT_FMT = '!H' PEER_COUNT_SIZE = struct.calcsize(_PEER_COUNT_FMT) _TYPE = { 'ascii': [ 'bgp_id', ], } def __init__(self, bgp_id, peer_entries, view_name='', view_name_len=None, peer_count=None): self.bgp_id = bgp_id assert isinstance(peer_entries, (list, tuple)) for p in peer_entries: assert isinstance(p, MrtPeer) self.peer_entries = peer_entries assert isinstance(view_name, str) self.view_name = view_name self.view_name_len = view_name_len self.peer_count = peer_count @classmethod def parse(cls, buf): (bgp_id, view_name_len) = struct.unpack_from(cls._HEADER_FMT, buf) bgp_id = addrconv.ipv4.bin_to_text(bgp_id) offset = cls.HEADER_SIZE (view_name,) = struct.unpack_from('!%ds' % view_name_len, buf, offset) view_name = str(view_name.decode('utf-8')) offset += view_name_len (peer_count,) = struct.unpack_from(cls._PEER_COUNT_FMT, buf, offset) offset += cls.PEER_COUNT_SIZE rest = buf[offset:] peer_entries = [] for i in range(peer_count): p, rest = MrtPeer.parse(rest) peer_entries.insert(i, p) return cls(bgp_id, peer_entries, view_name, view_name_len, peer_count) def serialize(self): view_name = self.view_name.encode('utf-8') self.view_name_len = len(view_name) # fixup self.peer_count = len(self.peer_entries) # fixup buf = struct.pack(self._HEADER_FMT, addrconv.ipv4.text_to_bin(self.bgp_id), self.view_name_len) + view_name buf += struct.pack(self._PEER_COUNT_FMT, self.peer_count) for p in self.peer_entries: buf += p.serialize() return buf class MrtPeer(stringify.StringifyMixin): """ MRT Peer. """ # 0 1 2 3 # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Peer Type | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Peer BGP ID | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Peer IP Address (variable) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Peer AS (variable) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ _HEADER_FMT = '!B4s' HEADER_SIZE = struct.calcsize(_HEADER_FMT) # Peer Type field: # # 0 1 2 3 4 5 6 7 # +-+-+-+-+-+-+-+-+ # | | | | | | |A|I| # +-+-+-+-+-+-+-+-+ # # Bit 6: Peer AS number size: 0 = 2 bytes, 1 = 4 bytes # Bit 7: Peer IP Address family: 0 = IPv4(4 bytes), 1 = IPv6(16 bytes) IP_ADDR_FAMILY_BIT = 1 << 0 AS_NUMBER_SIZE_BIT = 1 << 1 _TYPE = { 'ascii': [ 'bgp_id', 'ip_addr', ], } def __init__(self, bgp_id, ip_addr, as_num, type_=0): self.type = type_ self.bgp_id = bgp_id self.ip_addr = ip_addr self.as_num = as_num @classmethod def parse(cls, buf): (type_, bgp_id) = struct.unpack_from(cls._HEADER_FMT, buf) bgp_id = addrconv.ipv4.bin_to_text(bgp_id) offset = cls.HEADER_SIZE if type_ & cls.IP_ADDR_FAMILY_BIT: # IPv6 address family ip_addr_len = 16 else: # IPv4 address family ip_addr_len = 4 ip_addr = ip.bin_to_text(buf[offset:offset + ip_addr_len]) offset += ip_addr_len if type_ & cls.AS_NUMBER_SIZE_BIT: # Four octet AS number (as_num,) = struct.unpack_from('!I', buf, offset) offset += 4 else: # Two octet AS number (as_num,) = struct.unpack_from('!H', buf, offset) offset += 2 return cls(bgp_id, ip_addr, as_num, type_), buf[offset:] def serialize(self): if ip.valid_ipv6(self.ip_addr): # Sets Peer IP Address family bit to IPv6 self.type |= self.IP_ADDR_FAMILY_BIT ip_addr = ip.text_to_bin(self.ip_addr) if self.type & self.AS_NUMBER_SIZE_BIT or self.as_num > 0xffff: # Four octet AS number self.type |= self.AS_NUMBER_SIZE_BIT as_num = struct.pack('!I', self.as_num) else: # Two octet AS number as_num = struct.pack('!H', self.as_num) buf = struct.pack(self._HEADER_FMT, self.type, addrconv.ipv4.text_to_bin(self.bgp_id)) return buf + ip_addr + as_num class TableDump2AfiSafiSpecificRibMrtMessage(TableDump2MrtMessage, metaclass=abc.ABCMeta): """ MRT Message for the TABLE_DUMP_V2 Type and the AFI/SAFI-specific RIB subtypes. The AFI/SAFI-specific RIB subtypes consist of the RIB_IPV4_UNICAST, RIB_IPV4_MULTICAST, RIB_IPV6_UNICAST, RIB_IPV6_MULTICAST and their additional-path version subtypes. """ # 0 1 2 3 # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Sequence Number | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Prefix Length | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Prefix (variable) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Entry Count | RIB Entries (variable) # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ _HEADER_FMT = '!I' HEADER_SIZE = struct.calcsize(_HEADER_FMT) # Parser class to parse the Prefix field _PREFIX_CLS = None # should be defined in subclass # Is additional-path version? _IS_ADDPATH = False def __init__(self, seq_num, prefix, rib_entries, entry_count=None): self.seq_num = seq_num assert isinstance(prefix, self._PREFIX_CLS) self.prefix = prefix self.entry_count = entry_count assert isinstance(rib_entries, (list, tuple)) for rib_entry in rib_entries: assert isinstance(rib_entry, MrtRibEntry) self.rib_entries = rib_entries @classmethod def parse_rib_entries(cls, buf): (entry_count,) = struct.unpack_from('!H', buf) rest = buf[2:] rib_entries = [] for i in range(entry_count): r, rest = MrtRibEntry.parse(rest, is_addpath=cls._IS_ADDPATH) rib_entries.insert(i, r) return entry_count, rib_entries, rest @classmethod def parse(cls, buf): (seq_num,) = struct.unpack_from(cls._HEADER_FMT, buf) rest = buf[cls.HEADER_SIZE:] prefix, rest = cls._PREFIX_CLS.parser(rest) entry_count, rib_entries, _ = cls.parse_rib_entries(rest) return cls(seq_num, prefix, rib_entries, entry_count) def serialize_rib_entries(self): self.entry_count = len(self.rib_entries) # fixup rib_entries_bin = bytearray() for r in self.rib_entries: rib_entries_bin += r.serialize() return struct.pack('!H', self.entry_count) + rib_entries_bin def serialize(self): prefix_bin = self.prefix.serialize() rib_bin = self.serialize_rib_entries() # entry_count + rib_entries return struct.pack(self._HEADER_FMT, self.seq_num) + prefix_bin + rib_bin @TableDump2MrtMessage.register_type( TableDump2MrtRecord.SUBTYPE_RIB_IPV4_UNICAST) class TableDump2RibIPv4UnicastMrtMessage( TableDump2AfiSafiSpecificRibMrtMessage): """ MRT Message for the TABLE_DUMP_V2 Type and the SUBTYPE_RIB_IPV4_UNICAST subtype. """ _PREFIX_CLS = bgp.IPAddrPrefix @TableDump2MrtMessage.register_type( TableDump2MrtRecord.SUBTYPE_RIB_IPV4_MULTICAST) class TableDump2RibIPv4MulticastMrtMessage( TableDump2AfiSafiSpecificRibMrtMessage): """ MRT Message for the TABLE_DUMP_V2 Type and the SUBTYPE_RIB_IPV4_MULTICAST subtype. """ _PREFIX_CLS = bgp.IPAddrPrefix @TableDump2MrtMessage.register_type( TableDump2MrtRecord.SUBTYPE_RIB_IPV6_UNICAST) class TableDump2RibIPv6UnicastMrtMessage( TableDump2AfiSafiSpecificRibMrtMessage): """ MRT Message for the TABLE_DUMP_V2 Type and the SUBTYPE_RIB_IPV6_MULTICAST subtype. """ _PREFIX_CLS = bgp.IP6AddrPrefix @TableDump2MrtMessage.register_type( TableDump2MrtRecord.SUBTYPE_RIB_IPV6_MULTICAST) class TableDump2RibIPv6MulticastMrtMessage( TableDump2AfiSafiSpecificRibMrtMessage): """ MRT Message for the TABLE_DUMP_V2 Type and the SUBTYPE_RIB_IPV6_MULTICAST subtype. """ _PREFIX_CLS = bgp.IP6AddrPrefix @TableDump2MrtMessage.register_type( TableDump2MrtRecord.SUBTYPE_RIB_IPV4_UNICAST_ADDPATH) class TableDump2RibIPv4UnicastAddPathMrtMessage( TableDump2AfiSafiSpecificRibMrtMessage): """ MRT Message for the TABLE_DUMP_V2 Type and the SUBTYPE_RIB_IPV4_UNICAST_ADDPATH subtype. """ _PREFIX_CLS = bgp.IPAddrPrefix _IS_ADDPATH = True @TableDump2MrtMessage.register_type( TableDump2MrtRecord.SUBTYPE_RIB_IPV4_MULTICAST_ADDPATH) class TableDump2RibIPv4MulticastAddPathMrtMessage( TableDump2AfiSafiSpecificRibMrtMessage): """ MRT Message for the TABLE_DUMP_V2 Type and the SUBTYPE_RIB_IPV4_MULTICAST_ADDPATH subtype. """ _PREFIX_CLS = bgp.IPAddrPrefix _IS_ADDPATH = True @TableDump2MrtMessage.register_type( TableDump2MrtRecord.SUBTYPE_RIB_IPV6_UNICAST_ADDPATH) class TableDump2RibIPv6UnicastAddPathMrtMessage( TableDump2AfiSafiSpecificRibMrtMessage): """ MRT Message for the TABLE_DUMP_V2 Type and the SUBTYPE_RIB_IPV6_UNICAST_ADDPATH subtype. """ _PREFIX_CLS = bgp.IP6AddrPrefix _IS_ADDPATH = True @TableDump2MrtMessage.register_type( TableDump2MrtRecord.SUBTYPE_RIB_IPV6_MULTICAST_ADDPATH) class TableDump2RibIPv6MulticastAddPathMrtMessage( TableDump2AfiSafiSpecificRibMrtMessage): """ MRT Message for the TABLE_DUMP_V2 Type and the SUBTYPE_RIB_IPV6_MULTICAST_ADDPATH subtype. """ _PREFIX_CLS = bgp.IP6AddrPrefix _IS_ADDPATH = True @TableDump2MrtMessage.register_type( TableDump2MrtRecord.SUBTYPE_RIB_GENERIC) class TableDump2RibGenericMrtMessage(TableDump2MrtMessage): """ MRT Message for the TABLE_DUMP_V2 Type and the generic RIB subtypes. The generic RIB subtypes consist of the RIB_GENERIC and RIB_GENERIC_ADDPATH subtypes. """ # 0 1 2 3 # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Sequence Number | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Address Family Identifier |Subsequent AFI | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Network Layer Reachability Information (variable) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Entry Count | RIB Entries (variable) # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ _HEADER_FMT = '!IHB' HEADER_SIZE = struct.calcsize(_HEADER_FMT) # Is additional-path version? _IS_ADDPATH = False def __init__(self, seq_num, afi, safi, nlri, rib_entries, entry_count=None): self.seq_num = seq_num self.afi = afi self.safi = safi assert isinstance(nlri, bgp._AddrPrefix) self.nlri = nlri self.entry_count = entry_count assert isinstance(rib_entries, (list, tuple)) for rib_entry in rib_entries: assert isinstance(rib_entry, MrtRibEntry) self.rib_entries = rib_entries @classmethod def parse_rib_entries(cls, buf): (entry_count,) = struct.unpack_from('!H', buf) rest = buf[2:] rib_entries = [] for i in range(entry_count): r, rest = MrtRibEntry.parse(rest, is_addpath=cls._IS_ADDPATH) rib_entries.insert(i, r) return entry_count, rib_entries, rest @classmethod def parse(cls, buf): (seq_num, afi, safi) = struct.unpack_from(cls._HEADER_FMT, buf) rest = buf[cls.HEADER_SIZE:] nlri, rest = bgp.BGPNLRI.parser(rest) entry_count, rib_entries, _ = cls.parse_rib_entries(rest) return cls(seq_num, afi, safi, nlri, rib_entries, entry_count) def serialize_rib_entries(self): self.entry_count = len(self.rib_entries) # fixup rib_entries_bin = bytearray() for r in self.rib_entries: rib_entries_bin += r.serialize() return struct.pack('!H', self.entry_count) + rib_entries_bin def serialize(self): nlri_bin = self.nlri.serialize() rib_bin = self.serialize_rib_entries() # entry_count + rib_entries return struct.pack(self._HEADER_FMT, self.seq_num, self.afi, self.safi) + nlri_bin + rib_bin @TableDump2MrtMessage.register_type( TableDump2MrtRecord.SUBTYPE_RIB_GENERIC_ADDPATH) class TableDump2RibGenericAddPathMrtMessage(TableDump2RibGenericMrtMessage): """ MRT Message for the TABLE_DUMP_V2 Type and the RIB_GENERIC_ADDPATH subtype. """ _IS_ADDPATH = True class MrtRibEntry(stringify.StringifyMixin): """ MRT RIB Entry. """ # 0 1 2 3 # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Peer Index | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Originated Time | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | (Path Identifier) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Attribute Length | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | BGP Attributes... (variable) # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # peer_index, originated_time, attr_len _HEADER_FMT = '!HIH' HEADER_SIZE = struct.calcsize(_HEADER_FMT) # peer_index, originated_time, path_id, attr_len _HEADER_FMT_ADDPATH = '!HIIH' HEADER_SIZE_ADDPATH = struct.calcsize(_HEADER_FMT_ADDPATH) def __init__(self, peer_index, originated_time, bgp_attributes, attr_len=None, path_id=None): self.peer_index = peer_index self.originated_time = originated_time assert isinstance(bgp_attributes, (list, tuple)) for attr in bgp_attributes: assert isinstance(attr, bgp._PathAttribute) self.bgp_attributes = bgp_attributes self.attr_len = attr_len self.path_id = path_id @classmethod def parse(cls, buf, is_addpath=False): path_id = None if not is_addpath: (peer_index, originated_time, attr_len) = struct.unpack_from(cls._HEADER_FMT, buf) _header_size = cls.HEADER_SIZE else: (peer_index, originated_time, path_id, attr_len) = struct.unpack_from(cls._HEADER_FMT_ADDPATH, buf) _header_size = cls.HEADER_SIZE_ADDPATH bgp_attr_bin = buf[_header_size:_header_size + attr_len] bgp_attributes = [] while bgp_attr_bin: attr, bgp_attr_bin = bgp._PathAttribute.parser(bgp_attr_bin) bgp_attributes.append(attr) return cls(peer_index, originated_time, bgp_attributes, attr_len, path_id), buf[_header_size + attr_len:] def serialize(self): bgp_attrs_bin = bytearray() for attr in self.bgp_attributes: bgp_attrs_bin += attr.serialize() self.attr_len = len(bgp_attrs_bin) # fixup if self.path_id is None: return struct.pack(self._HEADER_FMT, self.peer_index, self.originated_time, self.attr_len) + bgp_attrs_bin else: return struct.pack(self._HEADER_FMT_ADDPATH, self.peer_index, self.originated_time, self.path_id, self.attr_len) + bgp_attrs_bin class Bgp4MpMrtMessage(MrtMessage, metaclass=abc.ABCMeta): """ MRT Message for the BGP4MP Type. """ _TYPE = { 'ascii': [ 'peer_ip', 'local_ip', ], } @MrtRecord.register_type(MrtRecord.TYPE_BGP4MP) class Bgp4MpMrtRecord(MrtCommonRecord): MESSAGE_CLS = Bgp4MpMrtMessage # MRT Subtype SUBTYPE_BGP4MP_STATE_CHANGE = 0 SUBTYPE_BGP4MP_MESSAGE = 1 SUBTYPE_BGP4MP_MESSAGE_AS4 = 4 SUBTYPE_BGP4MP_STATE_CHANGE_AS4 = 5 SUBTYPE_BGP4MP_MESSAGE_LOCAL = 6 SUBTYPE_BGP4MP_MESSAGE_AS4_LOCAL = 7 SUBTYPE_BGP4MP_MESSAGE_ADDPATH = 8 SUBTYPE_BGP4MP_MESSAGE_AS4_ADDPATH = 9 SUBTYPE_BGP4MP_MESSAGE_LOCAL_ADDPATH = 10 SUBTYPE_BGP4MP_MESSAGE_AS4_LOCAL_ADDPATH = 11 @MrtRecord.register_type(MrtRecord.TYPE_BGP4MP_ET) class Bgp4MpEtMrtRecord(ExtendedTimestampMrtRecord): MESSAGE_CLS = Bgp4MpMrtMessage # MRT Subtype SUBTYPE_BGP4MP_STATE_CHANGE = 0 SUBTYPE_BGP4MP_MESSAGE = 1 SUBTYPE_BGP4MP_MESSAGE_AS4 = 4 SUBTYPE_BGP4MP_STATE_CHANGE_AS4 = 5 SUBTYPE_BGP4MP_MESSAGE_LOCAL = 6 SUBTYPE_BGP4MP_MESSAGE_AS4_LOCAL = 7 SUBTYPE_BGP4MP_MESSAGE_ADDPATH = 8 SUBTYPE_BGP4MP_MESSAGE_AS4_ADDPATH = 9 SUBTYPE_BGP4MP_MESSAGE_LOCAL_ADDPATH = 10 SUBTYPE_BGP4MP_MESSAGE_AS4_LOCAL_ADDPATH = 11 @Bgp4MpMrtMessage.register_type( Bgp4MpMrtRecord.SUBTYPE_BGP4MP_STATE_CHANGE) class Bgp4MpStateChangeMrtMessage(Bgp4MpMrtMessage): """ MRT Message for the BGP4MP Type and the BGP4MP_STATE_CHANGE subtype. """ # 0 1 2 3 # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Peer AS Number | Local AS Number | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Interface Index | Address Family | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Peer IP Address (variable) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Local IP Address (variable) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Old State | New State | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ _HEADER_FMT = '!HHHH' HEADER_SIZE = struct.calcsize(_HEADER_FMT) _ADDRS_FMT = '!%ds%ds' _STATES_FMT = '!HH' STATES_SIZE = struct.calcsize(_STATES_FMT) # FSM states STATE_IDLE = 1 STATE_CONNECT = 2 STATE_ACTIVE = 3 STATE_OPEN_SENT = 4 STATE_OPEN_CONFIRM = 5 STATE_ESTABLISHED = 6 # Address Family types AFI_IPv4 = 1 AFI_IPv6 = 2 def __init__(self, peer_as, local_as, if_index, peer_ip, local_ip, old_state, new_state, afi=None): self.peer_as = peer_as self.local_as = local_as self.if_index = if_index self.afi = afi self.peer_ip = peer_ip self.local_ip = local_ip self.old_state = old_state self.new_state = new_state @classmethod def parse(cls, buf): (peer_as, local_as, if_index, afi) = struct.unpack_from( cls._HEADER_FMT, buf) offset = cls.HEADER_SIZE if afi == cls.AFI_IPv4: # IPv4 Address addrs_fmt = cls._ADDRS_FMT % (4, 4) elif afi == cls.AFI_IPv6: # IPv6 Address addrs_fmt = cls._ADDRS_FMT % (16, 16) else: raise struct.error('Unsupported address family: %d' % afi) (peer_ip, local_ip) = struct.unpack_from(addrs_fmt, buf, offset) peer_ip = ip.bin_to_text(peer_ip) local_ip = ip.bin_to_text(local_ip) offset += struct.calcsize(addrs_fmt) (old_state, new_state) = struct.unpack_from( cls._STATES_FMT, buf, offset) return cls(peer_as, local_as, if_index, peer_ip, local_ip, old_state, new_state, afi) def serialize(self): # fixup if ip.valid_ipv4(self.peer_ip) and ip.valid_ipv4(self.local_ip): self.afi = self.AFI_IPv4 elif ip.valid_ipv6(self.peer_ip) and ip.valid_ipv6(self.local_ip): self.afi = self.AFI_IPv6 else: raise ValueError( 'peer_ip and local_ip must be the same address family: ' 'peer_ip=%s, local_ip=%s' % (self.peer_ip, self.local_ip)) buf = struct.pack(self._HEADER_FMT, self.peer_as, self.local_as, self.if_index, self.afi) buf += ip.text_to_bin(self.peer_ip) buf += ip.text_to_bin(self.local_ip) buf += struct.pack(self._STATES_FMT, self.old_state, self.new_state) return buf @Bgp4MpMrtMessage.register_type( Bgp4MpMrtRecord.SUBTYPE_BGP4MP_MESSAGE) class Bgp4MpMessageMrtMessage(Bgp4MpMrtMessage): """ MRT Message for the BGP4MP Type and the BGP4MP_MESSAGE subtype. """ # 0 1 2 3 # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Peer AS Number | Local AS Number | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Interface Index | Address Family | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Peer IP Address (variable) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Local IP Address (variable) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | BGP Message... (variable) # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ _HEADER_FMT = '!HHHH' HEADER_SIZE = struct.calcsize(_HEADER_FMT) _ADDRS_FMT = '!%ds%ds' # Address Family types AFI_IPv4 = 1 AFI_IPv6 = 2 def __init__(self, peer_as, local_as, if_index, peer_ip, local_ip, bgp_message, afi=None): self.peer_as = peer_as self.local_as = local_as self.if_index = if_index self.peer_ip = peer_ip self.local_ip = local_ip assert isinstance(bgp_message, bgp.BGPMessage) self.bgp_message = bgp_message self.afi = afi @classmethod def parse(cls, buf): (peer_as, local_as, if_index, afi) = struct.unpack_from( cls._HEADER_FMT, buf) offset = cls.HEADER_SIZE if afi == cls.AFI_IPv4: # IPv4 Address addrs_fmt = cls._ADDRS_FMT % (4, 4) elif afi == cls.AFI_IPv6: # IPv6 Address addrs_fmt = cls._ADDRS_FMT % (16, 16) else: raise struct.error('Unsupported address family: %d' % afi) (peer_ip, local_ip) = struct.unpack_from(addrs_fmt, buf, offset) peer_ip = ip.bin_to_text(peer_ip) local_ip = ip.bin_to_text(local_ip) offset += struct.calcsize(addrs_fmt) rest = buf[offset:] bgp_message, _, _ = bgp.BGPMessage.parser(rest) return cls(peer_as, local_as, if_index, peer_ip, local_ip, bgp_message, afi) def serialize(self): # fixup if ip.valid_ipv4(self.peer_ip) and ip.valid_ipv4(self.local_ip): self.afi = self.AFI_IPv4 elif ip.valid_ipv6(self.peer_ip) and ip.valid_ipv6(self.local_ip): self.afi = self.AFI_IPv6 else: raise ValueError( 'peer_ip and local_ip must be the same address family: ' 'peer_ip=%s, local_ip=%s' % (self.peer_ip, self.local_ip)) buf = struct.pack(self._HEADER_FMT, self.peer_as, self.local_as, self.if_index, self.afi) buf += ip.text_to_bin(self.peer_ip) buf += ip.text_to_bin(self.local_ip) buf += self.bgp_message.serialize() return buf @Bgp4MpMrtMessage.register_type( Bgp4MpMrtRecord.SUBTYPE_BGP4MP_MESSAGE_AS4) class Bgp4MpMessageAs4MrtMessage(Bgp4MpMessageMrtMessage): """ MRT Message for the BGP4MP Type and the BGP4MP_MESSAGE_AS4 subtype. """ # 0 1 2 3 # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Peer AS Number | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Local AS Number | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Interface Index | Address Family | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Peer IP Address (variable) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Local IP Address (variable) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | BGP Message... (variable) # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ _HEADER_FMT = '!IIHH' HEADER_SIZE = struct.calcsize(_HEADER_FMT) @Bgp4MpMrtMessage.register_type( Bgp4MpMrtRecord.SUBTYPE_BGP4MP_STATE_CHANGE_AS4) class Bgp4MpStateChangeAs4MrtMessage(Bgp4MpStateChangeMrtMessage): """ MRT Message for the BGP4MP Type and the BGP4MP_STATE_CHANGE_AS4 subtype. """ # 0 1 2 3 # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Peer AS Number | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Local AS Number | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Interface Index | Address Family | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Peer IP Address (variable) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Local IP Address (variable) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Old State | New State | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ _HEADER_FMT = '!IIHH' HEADER_SIZE = struct.calcsize(_HEADER_FMT) @Bgp4MpMrtMessage.register_type( Bgp4MpMrtRecord.SUBTYPE_BGP4MP_MESSAGE_LOCAL) class Bgp4MpMessageLocalMrtMessage(Bgp4MpMessageMrtMessage): """ MRT Message for the BGP4MP Type and the BGP4MP_MESSAGE_LOCAL subtype. """ @Bgp4MpMrtMessage.register_type( Bgp4MpMrtRecord.SUBTYPE_BGP4MP_MESSAGE_AS4_LOCAL) class Bgp4MpMessageAs4LocalMrtMessage(Bgp4MpMessageAs4MrtMessage): """ MRT Message for the BGP4MP Type and the BGP4MP_MESSAGE_AS4_LOCAL subtype. """ # TODO: # Currently, OSKen does not provide the packet library for ISIS protocol. # Implement parser for ISIS MRT message. # class IsisMrtRecord(MrtCommonRecord): # class IsisMrtMessage(MrtMessage): # TODO: # Currently, OSKen does not provide the packet library for OSPFv3 protocol. # Implement the parser for OSPFv3 MRT message. # class Ospf3MrtRecord(MrtCommonRecord): # class Ospf3MrtMessage(MrtMessage): class Reader(object): """ MRT format file reader. ========= ================================================ Argument Description ========= ================================================ f File object which reading MRT format file in binary mode. ========= ================================================ Example of Usage:: import bz2 from os_ken.lib import mrtlib count = 0 for record in mrtlib.Reader( bz2.BZ2File('rib.YYYYMMDD.hhmm.bz2', 'rb')): print("%d, %s" % (count, record)) count += 1 """ def __init__(self, f): self._f = f def __iter__(self): return self def next(self): header_buf = self._f.read(MrtRecord.HEADER_SIZE) if len(header_buf) < MrtRecord.HEADER_SIZE: raise StopIteration() # Hack to avoid eating memory up self._f.seek(-MrtRecord.HEADER_SIZE, 1) required_len = MrtRecord.parse_pre(header_buf) buf = self._f.read(required_len) record, _ = MrtRecord.parse(buf) return record # for Python 3 compatible __next__ = next def close(self): self._f.close() def __del__(self): self.close() class Writer(object): """ MRT format file writer. ========= ================================================ Argument Description ========= ================================================ f File object which writing MRT format file in binary mode. ========= ================================================ Example of usage:: import bz2 import time from os_ken.lib import mrtlib from os_ken.lib.packet import bgp mrt_writer = mrtlib.Writer( bz2.BZ2File('rib.YYYYMMDD.hhmm.bz2', 'wb')) prefix = bgp.IPAddrPrefix(24, '10.0.0.0') rib_entry = mrtlib.MrtRibEntry( peer_index=0, originated_time=int(time.time()), bgp_attributes=[bgp.BGPPathAttributeOrigin(0)]) message = mrtlib.TableDump2RibIPv4UnicastMrtMessage( seq_num=0, prefix=prefix, rib_entries=[rib_entry]) record = mrtlib.TableDump2MrtRecord( message=message) mrt_writer.write(record) """ def __init__(self, f): self._f = f def write(self, record): if not isinstance(record, MrtRecord): raise ValueError( 'record should be an instance of MrtRecord subclass') self._f.write(record.serialize()) def close(self): self._f.close() def __del__(self): self.close() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.0781038 os-ken-2.10.0/os_ken/lib/netconf/0000775000175000017500000000000000000000000016471 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/netconf/__init__.py0000664000175000017500000000152300000000000020603 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013 Isaku Yamahata # # 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. """ NETCONF definitions used by os_ken/lib/of_config. """ import os.path SCHEMA_DIR = os.path.dirname(__file__) NETCONF_XSD = os.path.join(SCHEMA_DIR, 'netconf.xsd') ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/netconf/constants.py0000664000175000017500000000753400000000000021070 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013 Isaku Yamahata # # 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. # based on netconf.xsd # rpc RPC = 'rpc' MESSAGE_ID = 'message-id' # message-id attribute # error TRANSPORT = 'transport' PROTOCOL = 'protocol' APPLICATION = 'application' # error-tag IN_USE = 'in-use' INVALID_VALUE = 'invalid-value' TOO_BIG = 'too-big' MISSING_ATTRIBUTE = 'missing-attribute' BAD_ATTRIBUTE = 'bad-attribute' UNKNOWN_ATTRIBUTE = 'unknown-attribute' MISSING_ELEMENT = 'missing-element' BAD_ELEMENT = 'bad-element' UNKNOWN_ELEMENT = 'unknown-element' UNKNOWN_NAMESPACE = 'unknown-namespace' ACCESS_DENIED = 'access-denied' LOCK_DENIED = 'lock-denied' RESOURCE_DENIED = 'resource-denied' ROLLBACK_FAILED = 'rollback-failed' DATA_EXISTS = 'data-exists' DATA_MISSING = 'data-missing' OPERATION_NOT_SUPPORTED = 'operation-not-supported' OPERATION_FAILED = 'operation-failed' PARTIAL_OPERATION = 'partial-operation' MALFORMED_MESSAGE = 'malformed-message' # error-severity ERROR = 'error' WARNING = 'warning' # error-info # bad-attribute, bad-element and ok-element are defined above # BAD_ATTRIBUTE = 'bad-attribute' # BAD_ELEMENT = 'bad-element' # OK_ELEMENT = 'ok-element' ERR_ELEMENT = 'err-element' NOOP_ELEMENT = 'noop-element' BAD_NAMESPACE = 'bad-namespace' # rpc-error ERROR_TYPE = 'error-type' ERROR_TAG = 'error-tag' ERROR_SEVERITY = 'error-severity' ERROR_APP_TAG = 'error-app-tag' ERROR_PATH = 'error-path' ERROR_MESSAGE = 'error-message' ERROR_INFO = 'error-info' # edit-operation OPERATION = 'operation' # operation attribute MERGE = 'merge' REPLACE = 'replace' CREATE = 'create' DELETE = 'delete' REMOVE = 'remove' # default-operation # merge and replace are defined above # MERGE = 'merge' # REPLACE = 'replace' NONE = 'none' DEFAULT_OPERATION = 'default-operation' # rpc-reply OK = 'ok' RPC_REPLY = 'rpc-reply' # data-inline DATA = 'data' RPC_ERROR = 'rpc-error' # rpc-operation RPCOPERATION = 'rpcOperation' # rpc-response RPCRESPONSE = 'rpcResponse' HELLO = 'hello' CAPABILITIES = 'capabilities' CAPABILITY = 'capability' # config-inline CONFIG = 'config' # config-name CONFIG_NAME = 'config-name' STARTUP = 'startup' CANDIDATE = 'candidate' RUNNING = 'running' # config-uri URL = 'url' # rpc-operation-source SOURCE = 'source' # rpc-operation-target TARGET = 'target' # filter SUBTREE = 'subtree' XPATH = 'xpath' # filter-inline TYPE = 'type' # type attribute FILTER = 'filter' # test-option TEST_THEN_SET = 'test-then-set' SET = 'set' TEST_OPTION = 'test-option' # error-option STOP_ON_ERROR = 'stop-on-error' IGNORE_ERROR = 'ignore-error' ROLLBACK_ON_ERROR = 'rollback-on-error' ERROR_OPTION = 'error-option' # get GET = 'get' # get-config GET_CONFIG = 'get-config' # edit-config EDIT_CONFIG = 'edit-config' # copy-config COPY_CONFIG = 'copy-config' # delete-config DELETE_CONFIG = 'delete-config' # lock LOCK = 'lock' # unlock UNLOCK = 'unlock' # validate VALIDATE = 'validate' # commit CONFIRMED = 'confirmed' CONFIRM_TIMEOUT = 'confirm-timeout' PERSIST = 'persist' PERSIST_ID = 'persist-id' COMMIT = 'commit' # cancel-commit # persist-id is defined above # PERSIST_ID = 'persist-id' CANCEL_COMMIT = 'cancel-commit' # discard-changes DISCARD_CHANGES = 'discard-changes' # close-session CLOSE_SESSION = 'close-session' # kill-session KILL_SESSION = 'kill-session' ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/netconf/netconf.xsd0000664000175000017500000004115300000000000020651 0ustar00zuulzuul00000000000000 This schema defines the syntax for the NETCONF Messages layer messages 'hello', 'rpc', and 'rpc-reply'. This import accesses the xml: attribute groups for the xml:lang as declared on the error-message element. ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/netconf/xml.xsd0000664000175000017500000000152600000000000020015 0ustar00zuulzuul00000000000000 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/netdevice.py0000664000175000017500000000770200000000000017363 0ustar00zuulzuul00000000000000# Copyright (C) 2017 Nippon Telegraph and Telephone 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. # Constants defined in netdevice(7) # Interface flags # from net/if.h IFF_UP = 1 << 0 # Interface is running. IFF_BROADCAST = 1 << 1 # Valid broadcast address set. IFF_DEBUG = 1 << 2 # Internal debugging flag. IFF_LOOPBACK = 1 << 3 # Interface is a loopback interface. IFF_POINTOPOINT = 1 << 4 # Interface is a point-to-point link. IFF_NOTRAILERS = 1 << 5 # Avoid use of trailers. IFF_RUNNING = 1 << 6 # Resources allocated. IFF_NOARP = 1 << 7 # No arp protocol, L2 destination address not set. IFF_PROMISC = 1 << 8 # Interface is in promiscuous mode. IFF_ALLMULTI = 1 << 9 # Receive all multicast packets. IFF_MASTER = 1 << 10 # Master of a load balancing bundle. IFF_SLAVE = 1 << 11 # Slave of a load balancing bundle. IFF_MULTICAST = 1 << 12 # Supports multicast. IFF_PORTSEL = 1 << 13 # Is able to select media type via ifmap. IFF_AUTOMEDIA = 1 << 14 # Auto media selection active. IFF_DYNAMIC = 1 << 15 # The addresses are lost when the interface goes down. # from linux/if.h IFF_LOWER_UP = 1 << 16 # Driver signals L1 up. (since Linux 2.6.17) IFF_DORMANT = 1 << 17 # Driver signals dormant. (since Linux 2.6.17) IFF_ECHO = 1 << 18 # Echo sent packets. (since Linux 2.6.25) # Private interface flags # from linux/netdevice.h IFF_802_1Q_VLAN = 1 << 0 # 802.1Q VLAN device. IFF_EBRIDGE = 1 << 1 # Ethernet bridging device. IFF_BONDING = 1 << 2 # bonding master or slave. IFF_ISATAP = 1 << 3 # ISATAP interface (RFC4214). IFF_WAN_HDLC = 1 << 4 # WAN HDLC device. IFF_XMIT_DST_RELEASE = 1 << 5 # dev_hard_start_xmit() is allowed to release skb->dst. IFF_DONT_BRIDGE = 1 << 6 # disallow bridging this ether dev. IFF_DISABLE_NETPOLL = 1 << 7 # disable netpoll at run-time. IFF_MACVLAN_PORT = 1 << 8 # device used as macvlan port. IFF_BRIDGE_PORT = 1 << 9 # device used as bridge port. IFF_OVS_DATAPATH = 1 << 10 # device used as Open vSwitch datapath port. IFF_TX_SKB_SHARING = 1 << 11 # The interface supports sharing skbs on transmit. IFF_UNICAST_FLT = 1 << 12 # Supports unicast filtering. IFF_TEAM_PORT = 1 << 13 # device used as team port. IFF_SUPP_NOFCS = 1 << 14 # device supports sending custom FCS. IFF_LIVE_ADDR_CHANGE = 1 << 15 # device supports hardware address change when it's running. IFF_MACVLAN = 1 << 16 # Macvlan device. IFF_XMIT_DST_RELEASE_PERM = 1 << 17 # IFF_XMIT_DST_RELEASE not taking into account underlying stacked devices. IFF_IPVLAN_MASTER = 1 << 18 # IPvlan master device. IFF_IPVLAN_SLAVE = 1 << 19 # IPvlan slave device. IFF_L3MDEV_MASTER = 1 << 20 # device is an L3 master device. IFF_NO_QUEUE = 1 << 21 # device can run without qdisc attached. IFF_OPENVSWITCH = 1 << 22 # device is a Open vSwitch master. IFF_L3MDEV_SLAVE = 1 << 23 # device is enslaved to an L3 master device. IFF_TEAM = 1 << 24 # device is a team device. IFF_RXFH_CONFIGURED = 1 << 25 # device has had Rx Flow indirection table configured. IFF_PHONY_HEADROOM = 1 << 26 # the headroom value is controlled by an external entity. (i.e. the master device for bridged veth) IFF_MACSEC = 1 << 27 # device is a MACsec device. ././@PaxHeader0000000000000000000000000000003300000000000011451 xustar000000000000000027 mtime=1724334546.082104 os-ken-2.10.0/os_ken/lib/of_config/0000775000175000017500000000000000000000000016766 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/of_config/__init__.py0000664000175000017500000000303700000000000021102 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013 Isaku Yamahata # # 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. """ OF-Config implementation. """ import glob import os.path import sys SCHEMA_DIR = os.path.dirname(__file__) _PREFIX = 'of-config-' _SUFFIX = '.xsd' _files = glob.glob(os.path.join(SCHEMA_DIR, 'of-config-*.xsd')) OF_CONFIG_XSD_FILES = dict( (os.path.basename(f)[len(_PREFIX):-len(_SUFFIX)], f) for f in _files) # For convenience # OF_CONFIG_1_0_XSD = os.path.join(SCHEMA_DIR, 'of-config-1.0.xsd') # and so on _this_module = sys.modules[__name__] for (version, xsd_file) in OF_CONFIG_XSD_FILES.items(): setattr(_this_module, 'OF_CONFIG_%s_XSD' % version.replace('.', '_'), xsd_file) OFCONFIG_1_1_CONFIG = 'urn:onf:params:xml:ns:onf:of12:config' OFCONFIG_1_1_YANG = 'urn:onf:of12:config:yang' # LINC specific? OFCONFIG_1_1_1_YANG = 'urn:onf:of111:config:yang' OFCONFIG_YANG_NAMESPACES = { '1.1': OFCONFIG_1_1_YANG, '1.1.1': OFCONFIG_1_1_1_YANG, } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/of_config/base.py0000664000175000017500000001037200000000000020255 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013 YAMAMOTO Takashi # # 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. # convenient classes to manipulate OF-Config XML # in a little more pythonic way. # currently assuming OF-Config 1.1.1. from os_ken.lib import stringify from lxml import objectify import lxml.etree as ET _ns_of111 = 'urn:onf:of111:config:yang' _ns_netconf = 'urn:ietf:params:xml:ns:netconf:base:1.0' _nsmap = { 'of111': _ns_of111, 'nc': _ns_netconf, } def _pythonify(name): return name.replace('-', '_') class _e(object): def __init__(self, name, is_list): self.name = name self.cls = None self.is_list = is_list # complexType class _ct(_e): def __init__(self, name, cls, is_list): super(_ct, self).__init__(name, is_list) self.cls = cls class _Base(stringify.StringifyMixin): _M = objectify.ElementMaker(annotate=False, namespace=_ns_of111, nsmap=_nsmap) def __init__(self, **kwargs): for e in self._ELEMENTS: k = _pythonify(e.name) try: v = kwargs.pop(k) assert e.name not in kwargs except KeyError: k = e.name try: v = kwargs.pop(k) except KeyError: if e.is_list: v = [] else: v = None setattr(self, k, v) if kwargs: raise TypeError('unknown kwargs %s' % kwargs) def to_et(self, tag): def convert(v): if isinstance(v, _Base): return v.to_et(e.name) elif isinstance(v, objectify.ObjectifiedElement): assert ET.QName(v.tag).localname == itag return v return self._M(itag, v) args = [] for e in self._ELEMENTS: itag = e.name k = _pythonify(itag) v = getattr(self, k) if v is None: continue if isinstance(v, list): assert e.is_list ele = list(map(convert, v)) else: assert not e.is_list ele = [convert(v)] args.extend(ele) return self._M(tag, *args) def to_xml(self, tag): e = self.to_et(tag) return ET.tostring(e, pretty_print=True) @classmethod def from_xml(cls, xmlstring): et = objectify.fromstring(xmlstring) return cls.from_et(et) @classmethod def from_et(cls, et): def convert(v): if e.cls is not None: return e.cls.from_et(v) return v kwargs = {} for e in cls._ELEMENTS: try: v = et[e.name] except AttributeError: continue assert isinstance(v, objectify.ObjectifiedElement) if len(v) == 1: v = convert(v) if e.is_list: v = [v] else: assert e.is_list v = list(map(convert, v)) k = _pythonify(e.name) assert k not in kwargs kwargs[k] = v return cls(**kwargs) def __getattribute__(self, k): return stringify.StringifyMixin.__getattribute__(self, _pythonify(k)) def __setattr__(self, k, v): stringify.StringifyMixin.__setattr__(self, _pythonify(k), v) class _Unimpl(_Base): _ELEMENTS = [ _e('raw_et', is_list=False), ] def to_et(self, tag): assert self.raw_et.tag == tag return self.raw_et @classmethod def from_et(cls, et): return cls(raw_et=et) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/of_config/capable_switch.py0000664000175000017500000001065200000000000022314 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013 Isaku Yamahata # # 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. import ncclient import ncclient.manager import ncclient.xml_ from os_ken import exception as os_ken_exc from os_ken.lib import of_config from os_ken.lib.of_config import constants as ofc_consts from os_ken.lib.of_config import classes as ofc # TODO: When we re-organize ncclient, its NCClientError will be # subclass of OSKenException. class OFConfigCapableSwitchNotFound(os_ken_exc.OSKenException, ncclient.NCClientError): message = 'OpenFlow Capable Switch not found' def get_ns_tag(tag): if tag[0] == '{': return tuple(tag[1:].split('}', 1)) return (None, tag) class OFCapableSwitch(object): def __init__(self, connect_method='connect_ssh', *args, **kwargs): super(OFCapableSwitch, self).__init__() self._connect_method = connect_method self._connect_args = args self._connect_kwargs = kwargs self.version = None self.namespace = None connect = getattr(ncclient.manager, self._connect_method) self.netconf = connect(*self._connect_args, **self._connect_kwargs) def close_session(self): if self.netconf: self.netconf.close_session() self.netconf = None def __enter__(self): return self def __exit__(self): self.close_session() def client_capabilities(self): return self.netconf.client_capabilities def server_capabilities(self): return self.netconf.server_capabilities def _find_capable_switch(self, tree): capable_switch = None for element in tree: ns, tag = get_ns_tag(element.tag) if tag != ofc_consts.CAPABLE_SWITCH: continue # assumes that returns only single capable switch assert capable_switch is None capable_switch = element if not self.version: versions = [(version, ns_) for version, ns_ in of_config.OFCONFIG_YANG_NAMESPACES.items() if ns == ns_] if versions: assert len(versions) == 1 version = versions[0] self.version, self.namespace = version if not capable_switch: raise OFConfigCapableSwitchNotFound() return capable_switch def _find_capable_switch_xml(self, tree): return ncclient.xml_.to_xml(self._find_capable_switch(tree)) def raw_get(self, filter=None): reply = self.netconf.get(filter) return self._find_capable_switch_xml(reply.data_ele) def raw_get_config(self, source, filter=None): reply = self.netconf.get_config(source, filter) return self._find_capable_switch_xml(reply.data_ele) def raw_edit_config(self, target, config, default_operation=None, test_option=None, error_option=None): self.netconf.edit_config(target, config, default_operation, test_option, error_option) def get(self): return ofc.OFCapableSwitchType.from_xml(self.raw_get()) def get_config(self, source): return ofc.OFCapableSwitchType.from_xml(self.raw_get_config(source)) def edit_config(self, target, capable_switch, default_operation=None): xml = ofc.NETCONF_Config(capable_switch=capable_switch).to_xml() self.raw_edit_config(target, xml, default_operation) def delete_config(self, source): self.netconf.delete_config(source) def copy_config(self, source, target): self.netconf.copy_config(source, target) def commit(self): self.netconf.commit() def discard_changes(self): self.netconf.discard_changes() # TODO: more netconf operations # TODO: convinience(higher level) methods ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/of_config/classes.py0000664000175000017500000000224300000000000020776 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013 YAMAMOTO Takashi # # 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. # convenient classes to manipulate OF-Config XML # in a little more pythonic way. # currently assuming OF-Config 1.1.1. from os_ken.lib import stringify from .base import _Base, _ct, _e, _ns_netconf from .generated_classes import * # probably should not be here but for convenience class NETCONF_Config(_Base): _ELEMENTS = [ _ct('capable-switch', OFCapableSwitchType, is_list=False), ] def to_xml(self): return super(NETCONF_Config, self).to_xml('{%s}config' % _ns_netconf) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/of_config/constants.py0000664000175000017500000002256000000000000021361 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013 Isaku Yamahata # # 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. # based on of-config-1.1.1.xsd # commonly used TYPE = 'type' ID = 'id' OPERATION = 'operation' PORT = 'port' PROTOCOL = 'protocol' # of-configuration-point-protocol SSH = 'ssh' SOAP = 'soap' TLS = 'tls' BEEP = 'beep' # of-open-flow-version VERSION = 'version' NOT_APPLICABLE = 'not-applicable' OF_VERSION_1_0 = '1.0' OF_VERSION_1_0_1 = '1.0.1' OF_VERSION_1_1 = '1.1' OF_VERSION_1_2 = '1.2' OF_VERSION_1_3 = '1.3' OF_VERSION_1_3_1 = '1.3.1' # of-up-down-state UP = 'up' DOWN = 'down' # of-port-rate PORT_RATE_10MB_HD = '10Mb-HD' PORT_RATE_10MB_FD = '10Mb-FD' PORT_RATE_100MB_HD = '100Mb-HD' PORT_RATE_100MB_FD = '100Mb-FD' PORT_RATE_1GB_HD = '1Gb-HD' PORT_RATE_1GB_FD = '1Gb-FD' PORT_RATE_10GB = '10Gb' PORT_RATE_40GB = '40Gb' PORT_RATE_100GB = '100Gb' PORT_RATE_1TB = '1 Tb' PORT_RATE_1TB_ = '1Tb' # of-config-1.1.1.xsd uses non space version # to be checked after of-config 1.1.1 is # publicly release PORT_RATE_OTHER = 'Other' PORT_RATE_other = 'other' # of-config-1.1.1 uses lower case. # to be checked after of-config 1.1.1 is # publicly release # of-action OUTPUT = 'output' COPY_TTL_OUT = 'copy-ttl-out' COPY_TTL_IN = 'copy-ttl-in' SET_MPLS_TTL = 'set-mpls-ttl' DEC_MPLS_TTL = 'dec-mpls-ttl' PUSH_VLAN = 'push-vlan' POP_VLAN = 'pop-vlan' PUSH_MPLS = 'push-mpls' POP_MPLS = 'pop-mpls' SET_QUEUE = 'set-queue' GROUP = 'group' SET_NW_TTL = 'set-nw-ttl' DEC_NW_TTL = 'dec-nw-ttl' SET_FIELD = 'set-field' # of-instruction APPLY_ACTIONS = 'apply-actions' CLEAR_ACTIONS = 'clear-actions' WRITE_ACTIONS = 'write-actions' WRITE_METADATA = 'write-metadata' GOTO_TABLE = 'goto-table' # of-match-field INPUT_PORT = 'input-port' PHYSICAL_INPUT_PORT = 'physical-input-port' METADATA = 'metadata' ETHERNET_DEST = 'ethernet-dest' ETHERNET_SRC = 'ethernet-src' ETHERNET_FRAME_TYPE = 'ethernet-frame-type' VLAN_ID = 'vlan-id' VLAN_PRIORITY = 'vlan-priority' IP_DSCP = 'ip-dscp' IP_ECN = 'ip-ecn' IP_PROTOCOL = 'ip-protocol' IPV4_SRC = 'ipv4-src' IPV4_DEST = 'ipv4-dest' TCP_SRC = 'tcp-src' TCP_DEST = 'tcp-dest' UDP_SRC = 'udp-src' UDP_DEST = 'udp-dest' SCTP_SRC = 'sctp-src' SCTP_DEST = 'sctp-dest' ICMPV4_TYPE = 'icmpv4-type' ICMPV4_CODE = 'icmpv4-code' ARP_OP = 'arp-op' ARP_SRC_IP_ADDRESS = 'arp-src-ip-address' ARP_TARGET_IP_ADDRESS = 'arp-target-ip-address' ARP_SRC_HARDWARE_ADDRESS = 'arp-src-hardware-address' ARP_TARGET_HARDWARE_ADDRESS = 'arp-target-hardware-address' IPV6_SRC = 'ipv6-src' IPV6_DEST = 'ipv6-dest' IPV6_FLOW_LABEL = 'ipv6-flow-label' ICMPV6_TYPE = 'icmpv6-type' ICMPV6_CODE = 'icmpv6-code' IPV6_ND_TARGET = 'ipv6-nd-target' IPV6_ND_SOURCE_LINK_LAYER = 'ipv6-nd-source-link-layer' IPV6_ND_TARGET_LINK_LAYER = 'ipv6-nd-target-link-layer' MPLS_LABEL = 'mpls-label' MPLS_TC = 'mpls-tc' # of-port-current-feature-list and of-port-other-feature-list RATE = 'rate' AUTO_NEGOTIATE = 'auto-negotiate' MEDIUM = 'medium' COPPER = 'copper' FIBER = 'fiber' PAUSE = 'pause' UNSUPPORTED = 'unsupported' SYMMETRIC = 'symmetric' ASYMMETRIC = 'asymmetric' # DSA-key-value DSA_KEY_VALUE_P = 'P' DSA_KEY_VALUE_Q = 'Q' DSA_KEY_VALUE_J = 'J' DSA_KEY_VALUE_G = 'G' DSA_KEY_VALUE_Y = 'Y' DSA_KEY_VALUE_SEED = 'Seed' DSA_KEY_VALUE_PGENCOUNTER = 'PgenCounter' # of-port-base-tunnel LOCAL_ENDPOINT_IPV4_ADDRESS = 'local-endpoint-ipv4-address' REMOTE_ENDPOINT_IPV4_ADDRESS = 'remote-endpoint-ipv4-address' LOCAL_ENDPOINT_IPV6_ADDRESS = 'local-endpoint-ipv6-address' REMOTE_ENDPOINT_IPV6_ADDRESS = 'remote-endpoint-ipv6-address' LOCAL_ENDPOINT_MAC_ADRESS = 'local-endpoint-mac-adress' REMOTE_ENDPOINT_MAC_ADRESS = 'remote-endpoint-mac-adress' # of-port-ip-gre-tunnel CHECKSUM_PRESENT = 'checksum-present' KEY_PRESENT = 'key-present' KEY = 'key' SEQUENCE_NUMBER_PRESENT = 'sequence-number-present' # of-port-nvgre-tunnel TNI = 'tni' TNI_RESV = 'tni-resv' TNI_MULTICAST_GROUP = 'tni-multicast-group' # of-queue # ID = 'id' # PORT = 'port' PROPERTIES = 'properties' MIN_RATE = 'min-rate' MAX_RATE = 'max-rate' EXPERIMENTER = 'experimenter' # of-owned-certificate and of-external-certificate CERTIFICATE = 'certificate' PRIVATE_KEY = 'private-key' # of-configuration-point # ID = 'id' URI = 'uri' # PROTOCOL = 'protocol' # rsa-key-value MODULUS = 'Modulus' EXPONENT = 'Exponent' # of-flow-table MAX_ENTRIES = 'max-entries' NEXT_TABLES = 'next-tables' TABLE_ID = 'table-id' INSTRUCTIONS = 'instructions' # TYPE = 'type' MATCHES = 'matches' # TYPE = 'type' # WRITE_ACTIONS = 'write-actions' # TYPE = 'type' # APPLY_ACTIONS = 'apply-actions' # TYPE = 'type' # WRITE_SETFIELDS = 'write-setfields' # TYPE = 'type' # APPLY_SETFIELDS = 'apply-setfields' # TYPE = 'type' WILDCARDS = 'wildcards' # TYPE = 'type' METADATA_MATCH = 'metadata-match' METADATA_WRITE = 'metadata-write' # of-logical-switch # ID = 'id' CAPABILITIES = 'capabilities' DATAPATH_ID = 'datapath-id' ENABLED = 'enabled' CHECK_CONTROLLER_CERTIFICATE = 'check-controller-certificate' LOST_CONNECTION_BEHAVIOR = 'lost-connection-behavior' FAILSECUREMODE = 'failSecureMode' FAILSTANDALONEMODE = 'failStandaloneMode' CONTROLLERS = 'controllers' CONTROLLER = 'controller' # OPERATION = 'operation' KEY_CONTROLLERS_CONTROLLER = 'key_controllers_controller' RESOURCES = 'resources' # PORT = 'port' QUEUE = 'queue' # CERTIFICATE = 'certificate' # FLOW_TABLE = 'flow-table' # key-value DSAKEYVALUE = 'DSAKeyValue' RSAKEYVALUE = 'RSAKeyValue' # of-logical-switch-capabilities MAX_BUFFERED_PACKETS = 'max-buffered-packets' MAX_TABLES = 'max-tables' MAX_PORTS = 'max-ports' FLOW_STATISTICS = 'flow-statistics' TABLE_STATISTICS = 'table-statistics' # PORT_STATISTICS = 'port-statistics' GROUP_STATISTICS = 'group-statistics' QUEUE_STATISTICS = 'queue-statistics' REASSEMBLE_IP_FRAGMENTS = 'reassemble-ip-fragments' BLOCK_LOOPING_PORTS = 'block-looping-ports' RESERVED_PORT_TYPES = 'reserved-port-types' # TYPE = 'type' ALL = 'all' # CONTROLLER = 'controller' TABLE = 'table' INPORT = 'inport' ANY = 'any' NORMAL = 'normal' FLOOD = 'flood' GROUP_TYPES = 'group-types' # TYPE = 'type' # ALL = 'all' SELECT = 'select' INDIRECT = 'indirect' FAST_FAILOVER = 'fast-failover' GROUP_CAPABILITIES = 'group-capabilities' CAPABILITY = 'capability' SELECT_WEIGHT = 'select-weight' SELECT_LIVENESS = 'select-liveness' CHAINING = 'chaining' CHAINING_CHECK = 'chaining-check' ACTION_TYPES = 'action-types' # TYPE = 'type' INSTRUCTION_TYPES = 'instruction-types' # TYPE = 'type' # of-port NUMBER = 'number' NAME = 'name' CURRENT_RATE = 'current-rate' # MAX_RATE = 'max-rate' CONFIGURATION = 'configuration' ADMIN_STATE = 'admin-state' NO_RECEIVE = 'no-receive' NO_FORWARD = 'no-forward' NO_PACKET_IN = 'no-packet-in' # OPERATION = 'operation' STATE = 'state' OPER_STATE = 'oper-state' BLOCKED = 'blocked' LIVE = 'live' FEATURES = 'features' CURRENT = 'current' ADVERTISED = 'advertised' # OPERATION = 'operation' SUPPORTED = 'supported' ADVERTISED_PEER = 'advertised-peer' TUNNEL = 'tunnel' IPGRE_TUNNEL = 'ipgre-tunnel' VXLAN_TUNNEL = 'vxlan-tunnel' NVGRE_TUNNEL = 'nvgre-tunnel' # of-resource RESOURCE_ID = 'resource-id' # of-port-vxlan-tunnel VNI_VALID = 'vni-valid' VNI = 'vni' VNI_MULTICAST_GROUP = 'vni-multicast-group' UDP_SOURCE_PORT = 'udp-source-port' UDP_DEST_PORT = 'udp-dest-port' UDP_CHECKSUM = 'udp-checksum' # of-controller # ID = 'id' ROLE = 'role' MASTER = 'master' SLAVE = 'slave' EQUAL = 'equal' IP_ADDRESS = 'ip-address' # PORT = 'port' LOCAL_IP_ADDRESS = 'local-ip-address' LOCAL_PORT = 'local-port' # PROTOCOL = 'protocol' TCP = 'tcp' # TLS = 'tls' # STATE = 'state' CONNECTION_STATE = 'connection-state' CURRENT_VERSION = 'current-version' SUPPORTED_VERSIONS = 'supported-versions' LOCAL_IP_ADDRESS_IN_USE = 'local-ip-address-in-use' LOCAL_PORT_IN_USE = 'local-port-in-use' CAPABLE_SWITCH = 'capable-switch' # ID = 'id' CONFIG_VERSION = 'config-version' CONFIGURATION_POINTS = 'configuration-points' CONFIGURATION_POINT = 'configuration-point' KEY_CONFIGURATION_POINTS_CAPABLESWITCH_CONFIGURATION_POINT = ( 'key_configuration-points_capableswitch_configuration-point') # RESOURCES = 'resources' # PORT = 'port' # QUEUE = 'queue' # OPERATION = 'operation' OWNED_CERTIFICATE = 'owned-certificate' EXTERNAL_CERTIFICATE = 'external-certificate' # OPERATION = 'operation' FLOW_TABLE = 'flow-table' KEY_RESOURCES_CAPABLE_SWITCH_PORT = 'key_resources_capable-switch_port' KEY_RESOURCES_CAPABLE_SWITCH_QUEUE = 'key_resources_capable-switch_queue' KEY_RESOURCES_CAPABLE_SWITCH_OWNED_CERTIFICATE = ( 'key_resources_capable-switch_owned-certificate') KEY_RESOURCES_CAPABLE_SWITCH_EXTERNAL_CERTIFICATE = ( 'key_resources_capable-switch_external-certificate') KEY_RESOURCES_CAPABLE_SWITCH_FLOW_TABLE = ( 'key_resources_capable-switch_flow-table') LOGICAL_SWITCHES = 'logical-switches' SWITCH = 'switch' KEY_LOGICAL_SWITCHES_CAPABLE_SWITCH_SWITCH = ( 'key_logical-switches_capable-switch_switch') ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/of_config/generated_classes.py0000664000175000017500000001203100000000000023010 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013 YAMAMOTO Takashi # # 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. # NOTE: this file is intendend to be replaced with mechanically generated # file if/when OF-Config yang specification is available with a suitable # license. from os_ken.lib.of_config.base import _Base, _e, _ct class OFPortConfigurationType(_Base): _ELEMENTS = [ _e('admin-state', is_list=False), _e('no-receive', is_list=False), _e('no-forward', is_list=False), _e('no-packet-in', is_list=False), ] class OFPortStateType(_Base): _ELEMENTS = [ _e('oper-state', is_list=False), _e('blocked', is_list=False), _e('live', is_list=False), ] class OFPortType(_Base): _ELEMENTS = [ _e('resource-id', is_list=False), _e('number', is_list=False), _e('name', is_list=False), _e('current-rate', is_list=False), _e('max-rate', is_list=False), _ct('configuration', OFPortConfigurationType, is_list=False), _ct('state', OFPortStateType, is_list=False), _ct('features', None, is_list=False), _ct('tunnel-type', None, is_list=False), ] class OFQueuePropertiesType(_Base): _ELEMENTS = [ _e('min-rate', is_list=False), _e('max-rate', is_list=False), _e('experimenter', is_list=True), ] class OFQueueType(_Base): _ELEMENTS = [ _e('resource-id', is_list=False), _e('id', is_list=False), _e('port', is_list=False), _ct('properties', OFQueuePropertiesType, is_list=False), ] class OFCapableSwitchResourcesType(_Base): _ELEMENTS = [ _ct('port', OFPortType, is_list=True), _ct('queue', OFQueueType, is_list=True), _ct('owned-certificate', None, is_list=True), _ct('external-certificate', None, is_list=True), _ct('flow-table', None, is_list=True), ] class OFControllerStateType(_Base): _ELEMENTS = [ _e('connection-state', is_list=False), _e('current-version', is_list=False), # XXX OF-Config 1.1.1 is inconsistent about supported-versions. # # according to its xml schema (p.43), i believe this should look # like the following. it's what linc/of_config does, too. # 1.3 # # on the other hand, it has an example (p.45) like the following. # this one is compatible with OF-Config 1.1. # # 1.2 # 1.1 # _e('supported-versions', is_list=True), _e('local-ip-address-in-use', is_list=False), _e('local-port-in-use', is_list=False), ] class OFControllerType(_Base): _ELEMENTS = [ _e('id', is_list=False), _e('role', is_list=False), _e('ip-address', is_list=False), _e('port', is_list=False), _e('local-ip-address', is_list=False), _e('local-port', is_list=False), _e('protocol', is_list=False), _ct('state', OFControllerStateType, is_list=False), ] class OFLogicalSwitchControllersType(_Base): _ELEMENTS = [ _ct('controller', OFControllerType, is_list=True), ] class OFLogicalSwitchResourcesType(_Base): _ELEMENTS = [ _e('port', is_list=True), _e('queue', is_list=True), _e('certificate', is_list=False), _e('flow-table', is_list=True), ] class OFLogicalSwitchType(_Base): _ELEMENTS = [ _e('id', is_list=False), _ct('capabilities', None, is_list=False), _e('datapath-id', is_list=False), _e('enabled', is_list=False), _e('check-controller-certificate', is_list=False), _e('lost-connection-behavior', is_list=False), _ct('controllers', OFLogicalSwitchControllersType, is_list=False), _ct('resources', OFLogicalSwitchResourcesType, is_list=False), ] class OFCapableSwitchLogicalSwitchesType(_Base): _ELEMENTS = [ # this is named 'logical-switch' for OF-Config 1.1. _ct('switch', OFLogicalSwitchType, is_list=True), ] class OFCapableSwitchType(_Base): _ELEMENTS = [ _e('id', is_list=False), _e('config-version', is_list=False), _ct('configuration-points', None, is_list=False), _ct('resources', OFCapableSwitchResourcesType, is_list=False), _ct('logical-switches', OFCapableSwitchLogicalSwitchesType, is_list=False), ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/of_config/ietf-inet-types.xsd0000664000175000017500000003632100000000000022541 0ustar00zuulzuul00000000000000 This schema was generated from the YANG module ietf-inet-types by pyang version 1.0. The schema describes an instance document consisting of the entire configuration data store, operational data, rpc operations, and notifications. This schema can thus NOT be used as-is to validate NETCONF PDUs. This module contains a collection of generally useful derived YANG data types for Internet addresses and related things. Copyright (c) 2010 IETF Trust and the persons identified as authors of the code. All rights reserved. Redistribution and use in source and binary forms, with or without modification, is permitted pursuant to, and subject to the license terms contained in, the Simplified BSD License set forth in Section 4.c of the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info). This version of this YANG module is part of RFC 6021; see the RFC itself for full legal notices. This value represents the version of the IP protocol. In the value set and its semantics, this type is equivalent to the InetVersion textual convention of the SMIv2. The dscp type represents a Differentiated Services Code-Point that may be used for marking packets in a traffic stream. In the value set and its semantics, this type is equivalent to the Dscp textual convention of the SMIv2. The flow-label type represents flow identifier or Flow Label in an IPv6 packet header that may be used to discriminate traffic flows. In the value set and its semantics, this type is equivalent to the IPv6FlowLabel textual convention of the SMIv2. The port-number type represents a 16-bit port number of an Internet transport layer protocol such as UDP, TCP, DCCP, or SCTP. Port numbers are assigned by IANA. A current list of all assignments is available from <http://www.iana.org/>. Note that the port number value zero is reserved by IANA. In situations where the value zero does not make sense, it can be excluded by subtyping the port-number type. In the value set and its semantics, this type is equivalent to the InetPortNumber textual convention of the SMIv2. The as-number type represents autonomous system numbers which identify an Autonomous System (AS). An AS is a set of routers under a single technical administration, using an interior gateway protocol and common metrics to route packets within the AS, and using an exterior gateway protocol to route packets to other ASs'. IANA maintains the AS number space and has delegated large parts to the regional registries. Autonomous system numbers were originally limited to 16 bits. BGP extensions have enlarged the autonomous system number space to 32 bits. This type therefore uses an uint32 base type without a range restriction in order to support a larger autonomous system number space. In the value set and its semantics, this type is equivalent to the InetAutonomousSystemNumber textual convention of the SMIv2. The ip-address type represents an IP address and is IP version neutral. The format of the textual representations implies the IP version. The ipv4-address type represents an IPv4 address in dotted-quad notation. The IPv4 address may include a zone index, separated by a % sign. The zone index is used to disambiguate identical address values. For link-local addresses, the zone index will typically be the interface index number or the name of an interface. If the zone index is not present, the default zone of the device will be used. The canonical format for the zone index is the numerical format The ipv6-address type represents an IPv6 address in full, mixed, shortened, and shortened-mixed notation. The IPv6 address may include a zone index, separated by a % sign. The zone index is used to disambiguate identical address values. For link-local addresses, the zone index will typically be the interface index number or the name of an interface. If the zone index is not present, the default zone of the device will be used. The canonical format of IPv6 addresses uses the compressed format described in RFC 4291, Section 2.2, item 2 with the following additional rules: the :: substitution must be applied to the longest sequence of all-zero 16-bit chunks in an IPv6 address. If there is a tie, the first sequence of all-zero 16-bit chunks is replaced by ::. Single all-zero 16-bit chunks are not compressed. The canonical format uses lowercase characters and leading zeros are not allowed. The canonical format for the zone index is the numerical format as described in RFC 4007, Section 11.2. The ip-prefix type represents an IP prefix and is IP version neutral. The format of the textual representations implies the IP version. The ipv4-prefix type represents an IPv4 address prefix. The prefix length is given by the number following the slash character and must be less than or equal to 32. A prefix length value of n corresponds to an IP address mask that has n contiguous 1-bits from the most significant bit (MSB) and all other bits set to 0. The canonical format of an IPv4 prefix has all bits of the IPv4 address set to zero that are not part of the IPv4 prefix. The ipv6-prefix type represents an IPv6 address prefix. The prefix length is given by the number following the slash character and must be less than or equal 128. A prefix length value of n corresponds to an IP address mask that has n contiguous 1-bits from the most significant bit (MSB) and all other bits set to 0. The IPv6 address should have all bits that do not belong to the prefix set to zero. The canonical format of an IPv6 prefix has all bits of the IPv6 address set to zero that are not part of the IPv6 prefix. Furthermore, IPv6 address is represented in the compressed format described in RFC 4291, Section 2.2, item 2 with the following additional rules: the :: substitution must be applied to the longest sequence of all-zero 16-bit chunks in an IPv6 address. If there is a tie, the first sequence of all-zero 16-bit chunks is replaced by ::. Single all-zero 16-bit chunks are not compressed. The canonical format uses lowercase characters and leading zeros are not allowed. The domain-name type represents a DNS domain name. The name SHOULD be fully qualified whenever possible. Internet domain names are only loosely specified. Section 3.5 of RFC 1034 recommends a syntax (modified in Section 2.1 of RFC 1123). The pattern above is intended to allow for current practice in domain name use, and some possible future expansion. It is designed to hold various types of domain names, including names used for A or AAAA records (host names) and other records, such as SRV records. Note that Internet host names have a stricter syntax (described in RFC 952) than the DNS recommendations in RFCs 1034 and 1123, and that systems that want to store host names in schema nodes using the domain-name type are recommended to adhere to this stricter standard to ensure interoperability. The encoding of DNS names in the DNS protocol is limited to 255 characters. Since the encoding consists of labels prefixed by a length bytes and there is a trailing NULL byte, only 253 characters can appear in the textual dotted notation. The description clause of schema nodes using the domain-name type MUST describe when and how these names are resolved to IP addresses. Note that the resolution of a domain-name value may require to query multiple DNS records (e.g., A for IPv4 and AAAA for IPv6). The order of the resolution process and which DNS record takes precedence can either be defined explicitely or it may depend on the configuration of the resolver. Domain-name values use the US-ASCII encoding. Their canonical format uses lowercase US-ASCII characters. Internationalized domain names MUST be encoded in punycode as described in RFC 3492 The host type represents either an IP address or a DNS domain name. The uri type represents a Uniform Resource Identifier (URI) as defined by STD 66. Objects using the uri type MUST be in US-ASCII encoding, and MUST be normalized as described by RFC 3986 Sections 6.2.1, 6.2.2.1, and 6.2.2.2. All unnecessary percent-encoding is removed, and all case-insensitive characters are set to lowercase except for hexadecimal digits, which are normalized to uppercase as described in Section 6.2.2.1. The purpose of this normalization is to help provide unique URIs. Note that this normalization is not sufficient to provide uniqueness. Two URIs that are textually distinct after this normalization may still be equivalent. Objects using the uri type may restrict the schemes that they permit. For example, 'data:' and 'urn:' schemes might not be appropriate. A zero-length URI is not a valid URI. This can be used to express 'URI absent' where required. In the value set and its semantics, this type is equivalent to the Uri SMIv2 textual convention defined in RFC 5017. ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/of_config/ietf-yang-types.xsd0000664000175000017500000004022200000000000022533 0ustar00zuulzuul00000000000000 This schema was generated from the YANG module ietf-yang-types by pyang version 1.0. The schema describes an instance document consisting of the entire configuration data store, operational data, rpc operations, and notifications. This schema can thus NOT be used as-is to validate NETCONF PDUs. This module contains a collection of generally useful derived YANG data types. Copyright (c) 2010 IETF Trust and the persons identified as authors of the code. All rights reserved. Redistribution and use in source and binary forms, with or without modification, is permitted pursuant to, and subject to the license terms contained in, the Simplified BSD License set forth in Section 4.c of the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info). This version of this YANG module is part of RFC 6021; see the RFC itself for full legal notices. The counter32 type represents a non-negative integer that monotonically increases until it reaches a maximum value of 2^32-1 (4294967295 decimal), when it wraps around and starts increasing again from zero. Counters have no defined 'initial' value, and thus, a single value of a counter has (in general) no information content. Discontinuities in the monotonically increasing value normally occur at re-initialization of the management system, and at other times as specified in the description of a schema node using this type. If such other times can occur, for example, the creation of a schema node of type counter32 at times other than re-initialization, then a corresponding schema node should be defined, with an appropriate type, to indicate the last discontinuity. The counter32 type should not be used for configuration schema nodes. A default statement SHOULD NOT be used in combination with the type counter32. In the value set and its semantics, this type is equivalent to the Counter32 type of the SMIv2. The zero-based-counter32 type represents a counter32 that has the defined 'initial' value zero. A schema node of this type will be set to zero (0) on creation and will thereafter increase monotonically until it reaches a maximum value of 2^32-1 (4294967295 decimal), when it wraps around and starts increasing again from zero. Provided that an application discovers a new schema node of this type within the minimum time to wrap, it can use the 'initial' value as a delta. It is important for a management station to be aware of this minimum time and the actual time between polls, and to discard data if the actual time is too long or there is no defined minimum time. In the value set and its semantics, this type is equivalent to the ZeroBasedCounter32 textual convention of the SMIv2. The counter64 type represents a non-negative integer that monotonically increases until it reaches a maximum value of 2^64-1 (18446744073709551615 decimal), when it wraps around and starts increasing again from zero. Counters have no defined 'initial' value, and thus, a single value of a counter has (in general) no information content. Discontinuities in the monotonically increasing value normally occur at re-initialization of the management system, and at other times as specified in the description of a schema node using this type. If such other times can occur, for example, the creation of a schema node of type counter64 at times other than re-initialization, then a corresponding schema node should be defined, with an appropriate type, to indicate the last discontinuity. The counter64 type should not be used for configuration schema nodes. A default statement SHOULD NOT be used in combination with the type counter64. In the value set and its semantics, this type is equivalent to the Counter64 type of the SMIv2. The zero-based-counter64 type represents a counter64 that has the defined 'initial' value zero. A schema node of this type will be set to zero (0) on creation and will thereafter increase monotonically until it reaches a maximum value of 2^64-1 (18446744073709551615 decimal), when it wraps around and starts increasing again from zero. Provided that an application discovers a new schema node of this type within the minimum time to wrap, it can use the 'initial' value as a delta. It is important for a management station to be aware of this minimum time and the actual time between polls, and to discard data if the actual time is too long or there is no defined minimum time. In the value set and its semantics, this type is equivalent to the ZeroBasedCounter64 textual convention of the SMIv2. The gauge32 type represents a non-negative integer, which may increase or decrease, but shall never exceed a maximum value, nor fall below a minimum value. The maximum value cannot be greater than 2^32-1 (4294967295 decimal), and the minimum value cannot be smaller than 0. The value of a gauge32 has its maximum value whenever the information being modeled is greater than or equal to its maximum value, and has its minimum value whenever the information being modeled is smaller than or equal to its minimum value. If the information being modeled subsequently decreases below (increases above) the maximum (minimum) value, the gauge32 also decreases (increases). In the value set and its semantics, this type is equivalent to the Gauge32 type of the SMIv2. The gauge64 type represents a non-negative integer, which may increase or decrease, but shall never exceed a maximum value, nor fall below a minimum value. The maximum value cannot be greater than 2^64-1 (18446744073709551615), and the minimum value cannot be smaller than 0. The value of a gauge64 has its maximum value whenever the information being modeled is greater than or equal to its maximum value, and has its minimum value whenever the information being modeled is smaller than or equal to its minimum value. If the information being modeled subsequently decreases below (increases above) the maximum (minimum) value, the gauge64 also decreases (increases). In the value set and its semantics, this type is equivalent to the CounterBasedGauge64 SMIv2 textual convention defined in RFC 2856 The object-identifier type represents administratively assigned names in a registration-hierarchical-name tree. Values of this type are denoted as a sequence of numerical non-negative sub-identifier values. Each sub-identifier value MUST NOT exceed 2^32-1 (4294967295). Sub-identifiers are separated by single dots and without any intermediate whitespace. The ASN.1 standard restricts the value space of the first sub-identifier to 0, 1, or 2. Furthermore, the value space of the second sub-identifier is restricted to the range 0 to 39 if the first sub-identifier is 0 or 1. Finally, the ASN.1 standard requires that an object identifier has always at least two sub-identifier. The pattern captures these restrictions. Although the number of sub-identifiers is not limited, module designers should realize that there may be implementations that stick with the SMIv2 limit of 128 sub-identifiers. This type is a superset of the SMIv2 OBJECT IDENTIFIER type since it is not restricted to 128 sub-identifiers. Hence, this type SHOULD NOT be used to represent the SMIv2 OBJECT IDENTIFIER type, the object-identifier-128 type SHOULD be used instead. This type represents object-identifiers restricted to 128 sub-identifiers. In the value set and its semantics, this type is equivalent to the OBJECT IDENTIFIER type of the SMIv2. The date-and-time type is a profile of the ISO 8601 standard for representation of dates and times using the Gregorian calendar. The profile is defined by the date-time production in Section 5.6 of RFC 3339. The date-and-time type is compatible with the dateTime XML schema type with the following notable exceptions: (a) The date-and-time type does not allow negative years. (b) The date-and-time time-offset -00:00 indicates an unknown time zone (see RFC 3339) while -00:00 and +00:00 and Z all represent the same time zone in dateTime. (c) The canonical format (see below) of data-and-time values differs from the canonical format used by the dateTime XML schema type, which requires all times to be in UTC using the time-offset 'Z'. This type is not equivalent to the DateAndTime textual convention of the SMIv2 since RFC 3339 uses a different separator between full-date and full-time and provides higher resolution of time-secfrac. The canonical format for date-and-time values with a known time zone uses a numeric time zone offset that is calculated using the device's configured known offset to UTC time. A change of the device's offset to UTC time will cause date-and-time values to change accordingly. Such changes might happen periodically in case a server follows automatically daylight saving time (DST) time zone offset changes. The canonical format for date-and-time values with an unknown time zone (usually referring to the notion of local time) uses the time-offset -00:00. The timeticks type represents a non-negative integer that represents the time, modulo 2^32 (4294967296 decimal), in hundredths of a second between two epochs. When a schema node is defined that uses this type, the description of the schema node identifies both of the reference epochs. In the value set and its semantics, this type is equivalent to the TimeTicks type of the SMIv2. The timestamp type represents the value of an associated timeticks schema node at which a specific occurrence happened. The specific occurrence must be defined in the description of any schema node defined using this type. When the specific occurrence occurred prior to the last time the associated timeticks attribute was zero, then the timestamp value is zero. Note that this requires all timestamp values to be reset to zero when the value of the associated timeticks attribute reaches 497+ days and wraps around to zero. The associated timeticks schema node must be specified in the description of any schema node using this type. In the value set and its semantics, this type is equivalent to the TimeStamp textual convention of the SMIv2. Represents media- or physical-level addresses represented as a sequence octets, each octet represented by two hexadecimal numbers. Octets are separated by colons. The canonical representation uses lowercase characters. In the value set and its semantics, this type is equivalent to the PhysAddress textual convention of the SMIv2. The mac-address type represents an IEEE 802 MAC address. The canonical representation uses lowercase characters. In the value set and its semantics, this type is equivalent to the MacAddress textual convention of the SMIv2. This type represents an XPATH 1.0 expression. When a schema node is defined that uses this type, the description of the schema node MUST specify the XPath context in which the XPath expression is evaluated. ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/of_config/of-config-1.0.xsd0000664000175000017500000005114000000000000021652 0ustar00zuulzuul00000000000000 The OpenFlow Capable Switch and its configuration points, logical switches and resources available to logical switches. Representation of an OpenFlow Capable Switch. An unique but locally arbitrary identifier that identifies a Capable Switch towards management systems and that is persistent across reboots of the system. The list of all configuration points known to the OpenFlow Capable Switch that may manage it using OF-CONFIG. This element contains lists of all resources of the OpenFlow Capable Switch that can be used by OpenFlow Logical Switches. List of all OpenFlow Logical Switches available on the OpenFlow Capable Switch. Representation of an OpenFlow Configuration Point. An identifier that identifies a Configuration Point of the OpenFlow Capable Switch. A locator of the Configuration Point. This element MAY contain a locator of the configuration point including, for example, an IP address and a port number. The transport protocol that the Configuration Point uses when communicating via NETCONF with the OpenFlow Capable Switch. The mappings of NETCONF to different transport protocols are defined in RFC 6242 for SSH, RFC 4743 for SOAP, RFC 4744 for BEEP, and RFC 5539 for TLS. The representation of an OpenFlow Logical Switch An unique but locally arbitrary identifier that identifies an OpenFlow Logical Switch within an OpenFlow Capable Switch. It is persistent across reboots of the system. A unique identifier that identifiers an OpenFlow Logical Switch within the context of an OpenFlow Controller. The list of controllers that are assigned to the OpenFlow Logical Switch. The list of references to all resources of the OpenFlow Capable Switch that the OpenFlow Logical Switch has exclusive access to. Representation of an OpenFlow Controller An unique but locally arbitrary identifier that identifies an OpenFlow Controller within the context of an OpenFlow Capable Switch. It is persistent across reboots of the system. The predefined role of the controller. The remote IP of the controller to connect to. The port number the controller listens on. This specifies the source IP for packets sent to this controller and overrides the default IP used. The port number the controller listens on. If 0 the port is chosen dynamically. The protocol used for connecting to the controller. Both sides must support the chosen protocol for a successful establishment of a connection. This element represents the state of the OpenFlow protocol connection to the controller. This element represents the run-time state of the OpenFlow connection to the Contoller. This element denotes the version of OpenFlow that Contoller is currently communicating with. It is only relevant when the connection-state element is set to "up". This element denotes all of the versions of the OpenFlow protocol that the contoller supports. A Base Class for OpenFlow Resources. An unique but locally arbitrary identifier that identifies a resource within the context of and OpenFlow Capable Switch and is persistent across reboots of the system. An unique but locally arbitrary number that identifies a queue within the context of and OpenFlow Logical Switch and is persistent across reboots of the system. Port in the context of the same Logical Switch which this Queue is associated with. Properties of the Queue. The minimal rate that is reserved for this queue in 1/10 of a percent of the actual rate. The maximum rate that is reserved for this queue in 1/10 of a percent of the actual rate. Experimental Properties ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/of_config/of-config-1.1.1.xsd0000664000175000017500000036132700000000000022025 0ustar00zuulzuul00000000000000 This schema was generated from the YANG module of-config1.1.1 by pyang version 1.2. The schema describes an instance document consisting of the entire configuration data store, operational data, rpc operations, and notifications. This schema can thus NOT be used as-is to validate NETCONF PDUs. NETCONF Operational Considerations Elements that are configurable, optional and have a default value MAY be reported by replies to NETCONF <get-config> requests. All non-configurable values SHOULD be reported by replies to NETCONF <get> requests. Attemps to modify non-configurable elements with a NETCONF <edit-config> operation MUST result in an 'operation-not-supported' error with type 'application'. When validating an <edit‐config> operation the following errors MUST be detected: * Delete requests for non-existent data. In this case a 'data-missing' error is returned. * Create requests for existent data. In this case a 'data-exists' error is returned. * If the NETCONF operation creates data nodes under a 'choice', any existing nodes from other branches are deleted. Generic type of an identifier in OF-CONFIG Possible protocols to connect ot an OF Configuration Point This enumeration contains the all OpenFlow versions released so far. The datapath-id type represents an OpenFlow datapath identifier. This type defines a value in tenth of a percent. Type to specify state information for a port or a connection. Type to specify the rate of a port including the duplex transmission feature. Possible rates are 10Mb, 100Mb, 1Gb, 10Gb, 40Gb, 100Gb, 1Tb or other. Rates of 10Mb, 100Mb and 1 Gb can support half or full duplex transmission. The types of actions defined in OpenFlow Switch Specification versions 1.2, 1.3, and 1.3.1 The types of instructions defined in OpenFlow Switch Specification versions 1.2, 1.3, and 1.3.1. The types of match field defined in OpenFlow Switch Specification versions 1.2, 1.3, and 1.3.1. hex binary encoded string The current features of a port. Elements in the type OFPortCurrentFeatureListType are not configurable and can only be retrieved by NETCONF <get> operations. Attemps to modify this element and its children with a NETCONF <edit-config> operation MUST result in an 'operation-not-supported' error with type 'application'. The transmission rate that is currently used. The value MUST indicate a valid forwarding rate. The current Port Feature set MUST contain this element exactly once. The other Port Feature sets MAY contain this element more than once. If this element appears more than once in a Port Feature set than the value MUST be unique within the Port Feature set. Specifies the administrative state of the forwarding rate auto-negotiation protocol at this OpenFlow Port. This element MUST indicate a valid physical medium used by the OpenFlow Port. The current Port Feature set MUST contain this element exactly once. The other Port Feature sets MAY contain this element more than once. If this element appears more than once in a Port Feature set than the value MUST be unique within the Port Feature set. Specifies if pausing of transmission is supported at all and if yes if it is asymmetric or symmetric. The features of a port that are supported or advertised. If the elements in the OFPortOtherFeatureListType ares used as configurable elements the NETCONF <edit-config> operations MUST be implemented as follows: * The 'resource-id' element MUST be present in the path or in the filter at all <edit-config> operations to identify the resource. * If the operation is 'merge' or 'replace', the element is created if it does not exist, and its value is set to the value found in the XML RPC data. * If the operation is 'create', the element is created if it does not exist. If the element already exists, a 'data‑exists' error is returned. * If the operation is 'delete', the element is deleted if it exists. If the element does not exist, a 'data‑missing' error is returned. If elements in the type OFPortOtherFeatureListType are used in an non-configurable way, they only be retrieved by NETCONF <get> operations. Attemps to modify this element and its children with a NETCONF <edit-config> operation MUST result in an 'operation-not-supported' error with type 'application'. The transmission rate that is supported or advertised. Multiple transmissions rates are allowed. At least one element MUST be present in the NETCONF data store. If none of this elements is are present in a NETCONF <edit-config> operation 'create', 'merge' or 'replace' and the parent element does not exist, a 'data-missing' error is returned. Specifies if auto-negotiation of transmission parameters is enabled for the port. This element is optional. If this element is not present it defaults to 'true'. The transmission medium used by the port. Multiple media are allowed. At least one element MUST be present in the NETCONF data store. If none of this elements is are present in a NETCONF <edit-config> operation 'create', 'merge' or 'replace' and the parent element does not exist, a 'data-missing' error is returned. Specifies if pausing of transmission is supported at all and if yes if it is asymmetric or symmetric. This element MUST be present in the NETCONF data store. If this element is not present in a NETCONF <edit-config> operation 'create', 'merge' or 'replace' and the parent element does not exist, a 'data-missing' error is returned. DSA keys and the DSA signature algorithm are specified in 'FIPS PUB 186-2, Digital Signature Standard (DSS), U.S. Department of Commerce/National Institute of Standards and Technology, http://csrc.nist.gov/publications/fips/fips186-2/fips186-2.pdf'. DSA public key values can have the following fields: P a prime modulus meeting the requirements of the standard above Q an integer in the range 2**159 < Q < 2**160 which is a prime divisor of P-1 G an integer with certain properties with respect to P and Q J (P - 1) / Q Y G**X mod P (where X is part of the private key and not made public) seed a DSA prime generation seed pgenCounter a DSA prime generation counter Parameter J is avilable for inclusion solely for efficiency as it is calculatable from P and Q. Parameters seed and pgenCounter are used in the DSA prime number generation algorithm specified in the above standard. As such, they are optional but MUST either both be present or both be absent. This prime generation algorithm is designed to provide assurance that a weak prime is not being used and it yields a P and Q value. Parameters P, Q, and G can be public and common to a group of users. They might be known from application context. As such, they are optional but P and Q MUST either both appear or both be absent. If all of P, Q, seed, and pgenCounter are present, implementations are not required to check if they are consistent and are free to use either P and Q or seed and pgenCounter. All parameters are encoded as base64 values. This element is optional. It MUST be present in the NETCONF data store, if the element 'Q' is present. If element 'Q' is present in a NETCONF <edit-config> operation 'create', 'merge' or 'replace' and this element is missing, a 'data-missing' error is returned. This element is optional. It MUST be present in the NETCONF data store, if the element 'P' is present. If element 'P' is present in a NETCONF <edit-config> operation 'create', 'merge' or 'replace' and this element is missing, a 'data-missing' error is returned. This element is optional. This element is optional. This element MUST be present in the NETCONF data store. If this element is not present in a NETCONF <edit-config> operation 'create', 'merge' or 'replace' and the parent element does not exist, a 'data-missing' error is returned. This element is optional. It MUST be present in the NETCONF data store, if the element 'PgenCounter' is present. If element 'PgenCounter' is present in a NETCONF <edit-config> operation 'create', 'merge' or 'replace' and this element is missing, a 'data-missing' error is returned. This element is optional. It MUST be present in the NETCONF data store, if the element 'Seed' is present. If element 'Seed' is present in a NETCONF <edit-config> operation 'create', 'merge' or 'replace' and this element is missing, a 'data-missing' error is returned. A group of common elements that are included in every supported tunnel type. Tunnels are modeled as logical ports. One pair of local/remote endpoints must exist for a tunnel configuration. Only elements from one choice must exist at a time. The IPv4 address of the local tunnel endpoint. The IPv4 address of the remote tunnel endpoint. The IPv6 address of the local tunnel endpoint. The IPv6 address of the remote tunnel endpoint. The MAC address of the local tunnel endpoint. The MAC address of the remote tunnel endpoint. Properties of a IP-in-GRE tunnel with key, checksum, and sequence number information. Indicates presence of the GRE checksum. Indicates presence of the GRE key. The (optional) key of the GRE tunnel. It MAY be used to set the OXM_OF_TUNNEL_ID match field metadata in the OpenFlow protocol Indicates presence of the GRE sequence number. Properties of a NVGRE tunnel. Specifies the tenant network identifier assigned to all packets sent on the tunnel Used to set the reserved user-defined bits of the GRE key field If IP multicast is used to support broadcast on the tunnel this element specifies the corresponding multicast IP address This grouping specifies all properties of a queue resource. NETCONF <edit-config> operations MUST be implemented as follows: * The 'resource-id' element of OFResoureType MUST be present at all <edit-config> operations to identify the port. * If the operation is 'merge' or 'replace', the element is created if it does not exist, and its value is set to the value found in the XML RPC data. * If the operation is 'create', the element is created if it does not exist. If the element already exists, a 'data‑exists' error is returned. * If the operation is 'delete', the element is deleted if it exists. If the element does not exist, a 'data‑missing' error is returned. This id identifies the OpenFlow Queue to OpenFlow Controllers. It is assigned to an OpenFlow Queue latest when the OpenFlow Queue is associated with and OpenFlow Logical Switch. If the OpenFlow Queue is associated with an OpenFlow Logical Switch, this element MUST be unique within the context of the OpenFlow Logical Switch. OpenFlow Capable Switch implementations may choose to assign values to OpenFlow Queues that are unique within the context of the OpenFlow Logical Switch. These id can be used independent of assignments to OpenFlow Logical Switches. Other implementations may assign values to this element only if the OpenFlow Queue is assigned to an OpenFlow Logical Switch. If no value is currently assigned to this element then this element MUST NOT be included in replies to NETCONF <get> requests. Since this element is not configurable with the NETCONF protocol it MUST NOT be included in replies to NETCONF <get-config> requests. Reference to port resources in the Capable Switch. This element associates an OpenFlow Queue with an OpenFlow Port. If the OpenFlow Queue is associated with an OpenFlow Logical Switch S and this element is present, then it MUST be set to the value of element resource-id of an OpenFlow Port which is associated with the OpenFlow Logical Switch S. The element MUST refer to an element at the following path: /capable-switch/resources/port/resource-id The queue properties currently configured. The minimal rate that is reserved for this queue in 1/10 of a percent of the actual rate. This element is optional. If not present a min-rate is not set. The maximum rate that is reserved for this queue in 1/10 of a percent of the actual rate. This element is optional. If not present the max-rate is not set. A list of experimenter identifiers of queue properties used. This element is optional. This grouping specifies a certificate and a private key. It can be used by an OpenFlow Logical Switch for authenticating itself to a controller when a TLS connection is established. An X.509 certificate in DER format base64 encoded. This element MUST be present in the NETCONF data store. If this element is not present in a NETCONF <edit-config> operation 'create', 'merge' or 'replace' and the parent element does not exist, a 'data-missing' error is returned. This element contains the private key corresponding to the certificate. The private key is encoded as specified in XML-Signature Syntax and Processing (http://www.w3.org/TR/2001/PR-xmldsig-core-20010820/). Currently the specification only support DSA and RSA keys. This element MUST be present in the NETCONF data store. If this element is not present in a NETCONF <edit-config> operation 'create', 'merge' or 'replace' and the parent element does not exist, a 'data-missing' error is returned. This grouping specifies a certificate that can be used by an OpenFlow Logical Switch for authenticating a controller when a TLS connection is established. An X.509 certificate in DER format base64 encoded. This element MUST be present in the NETCONF data store. If this element is not present in a NETCONF <edit-config> operation 'create', 'merge' or 'replace' and the parent element does not exist, a 'data-missing' error is returned. Representation of an OpenFlow Configuration Point. Instances of the Configuration Point class SHOULD be stored persistently across reboots of the OpenFlow Capable Switch. When a connection is established between an OpenFlow Capable Switch and a Configuration Point the switch MUST store the connection information in an instance of the Configuration Point class. If such an instance does not exist, the OpenFlow Capable Switch MUST create an instance where it then stores the connection information. An OpenFlow Capable Switch that cannot initiate a connection to a configuration point does not have to implement the Configuration Point class. It SHOULD block attempts to write to instances of the Configuration Point class with NETCONF <edit-config> operations. NETCONF <edit-config> operations MUST be implemented as follows: * The 'id' element MUST be present at all <edit-config> operations to identify the configuration point. * If the operation is 'merge' or 'replace', the element is created if it does not exist, and its value is set to the value found in the XML RPC data. * If the operation is 'create', the element is created if it does not exist. If the element already exists, a 'data‑exists' error is returned. * If the operation is 'delete', the element is deleted if it exists. If the element does not exist, a 'data‑missing' error is returned. A unique but locally arbitrary identifier that identifies a Configuration Point within the context of an OpenFlow Capable Switch. This element MUST be present to identify the configuration point. A locator of the Configuration Point. It identifies the location of the Configuration Point as a service resource and MUST include all information necessary for the OpenFlow Capable Switch to connect to the Configuration Point or re-connect to it should it become disconnected. Such information MAY include, for example, protocol, fully qualified domain name, IP address, port number, etc. This element MUST be present in the NETCONF data store. If this element is not present in a NETCONF <edit-config> operation 'create', 'merge' or 'replace' and the parent element does not exist, a 'data-missing' error is returned. The transport protocol that the Configuration Point uses when communicating via NETCONF with the OpenFlow Capable Switch. This element is optional. If it is not present its value defaults to 'ssh'. RSA key values have two fields: Modulus and Exponent. This element MUST be present in the NETCONF data store. If this element is not present in a NETCONF <edit-config> operation 'create', 'merge' or 'replace' and the parent element does not exist, a 'data-missing' error is returned. This element MUST be present in the NETCONF data store. If this element is not present in a NETCONF <edit-config> operation 'create', 'merge' or 'replace' and the parent element does not exist, a 'data-missing' error is returned. Representation of an OpenFlow Flow Table Resource. Elements in the type OFFlowTableType are not configurable and can only be retrieved by NETCONF <get> operations. Attemps to modify this element and its children with a NETCONF <edit-config> operation MUST result in an 'operation-not-supported' error with type 'application'. The maximum number of flow entries supported by the flow table. An array of resource-ids of all flow tables that can be directly reached from this table using the 'goto-table' instruction. The list of all instruction types supported by the flow table. The list of all match types supported by the flow table. The list of all write action types supported by the flow table. The list of all apply action types supported by the flow table. The list of all 'set-field' action types supported by the table using write actions. The list of all 'set-field' action types supported by the table using apply actions. The list of all fields for which the table supports wildcarding. This element indicates the bits of the metadata field on which the flow table can match. It is represented as 64-bit integer in hexadecimal digits([0-9a-fA-F]) format. This element indicates the bits of the metadata field on which flow table can write using the 'write-metadata' instruction. It is represented as 64-bit integer in hexadecimal digits([0-9a-fA-F]) format. This grouping specifies all properties of an OpenFlow Logical Switch. Elements of type OFLogicalSwitchType cannot be created or deleted with NETCONF <edit-config> operations 'create' or 'delete'. The other NETCONF <edit-config> operations MUST be implemented as follows: * The 'id' element MUST be present at all <edit-config> operations to identify the OpenFlow Logical Switch. * If the operation is 'merge' or 'replace', and the element does not exist, a 'data-missing' error is returned. If the element exists its value is set to the value found in the XML RPC data. * If the operation is 'create', a 'operation-not-supported' error with type 'application' is returned. * If the operation is 'delete', 'operation-not-supported' error with type 'application' is returned. A unique but locally arbitrary identifier that identifies a Logical Switch within the context of an OpenFlow Capable Switch. It MUST be persistent across reboots of the OpenFlow Capable Switch. This element MUST be present to identify the OpenFlow Logical Switch. This element contains all capability items that an OpenFlow Logical Switch MAY implement. This element and its children can only be retrieved by NETCONF <get> operation since it contain no configuration data. The datapath identifier of the Logical Switch that uniquely identifies this Logical Switch within the context of all OpenFlow Controllers associated with the OpenFlow Logical Switch. The datapath identifier is a string value that MUST be formatted as a sequence of 8 2-digit hexadecimal numbers that are separated by colons, for example, '01:23:45:67:89:ab:cd:ef'. When processing a datapath identifier, the case of the decimal digits MUST be ignored. This element MUST be present in the NETCONF data store. If this element is not present in a NETCONF <edit-config> operation 'create', 'merge' or 'replace' and the parent element does not exist, a 'data-missing' error is returned. This element indicates the administrative state of the OpenFlow Logical Switch. A value of 'false' means the OpenFlow Logical Switch MUST NOT communicate with any OpenFlow Controllers, MUST NOT conduct any OpenFlow processing, and SHOULD NOT be utilizing computational or network resources of the underlying platform. This element is optional. If this element is not present it defaults to 'false'. This element indicates the behavior of the OpenFlow Logical Switch when connecting to an OpenFlow Controller. If set to value 'false', the logical switch will connect to a controller without checking any controller certificate. If set to value 'true', then the logical switch will connect to a controller with element <protocol> set to 'TLS', only if the controller provides a certificate that can be verified with one of the certificates stored in the list called external-certificates in the OpenFlow Capable Switch. If a certificate cannot be validated, the OpenFlow Logical Switch MUST terminate communication with the corresponding OpenFlow Controller, MUST NOT conduct any OpenFlow processing on requests of this OpenFlow controller, and SHOULD NOT further utilize any computational or network resources of for dealing with this connection. If set to value 'true', the OpenFlow Logical Switch MUST NOT connect to any OpenFlow Controller that does not provide a certificate. This implies that it cannot connect to an OpenFlow controller that has the value of element protocol set to 'TCP'. Only connections with protocol 'TLS' are possible in this case. This element is optional. If this element is not present it defaults to 'false'. This element indicates the the behavior of the OpenFlow Logical Switch in case it loses contact with all OpenFlow Controllers. There are two alternative modes in such a case: fails secure mode and fail standalone mode as defined by the OpenFlow protocol specification version 1.2, section 6.4. These are the only allowed values for this element. Default is the fail secure mode. This element is optional. If this element is not present it defaults to 'failSecureMode'. The list of controllers for this Logical switch. The element 'id' of OFControllerType MUST be unique within this list. The list of OpenFlow Controllers that are assigned to the OpenFlow Logical Switch. The switch MUST NOT connect to any OpenFlow Controller that is not contained in this list. NETCONF <edit-config> operations MUST be implemented as follows: * The 'id' element MUST be present at all <editconfig> operations to identify the controller. * If the operation is 'merge' or 'replace', the element is created if it does not exist, and its value is set to the value found in the XML RPC data. * If the operation is 'create', the element is created if it does not exist. If the element already exists, a 'data‑exists' error is returned. * If the operation is 'delete', the element is deleted if it exists. If the element does not exist, a 'data‑missing' error is returned. The list of identifiers of all resources of the OpenFlow Capable Switch that the OpenFlow Logical Switch has exclusive or non-exclusive access to. A resource is identified by the value of its resource-identifier element. For each resource identifier value in this list, there MUST be an element with a matching resource identifier value in the resources list of the OpenFlow Capable Switch. Identifiers of this list are contained in elements indicating the type of resource: 'port', 'queue', 'certificate', or 'flow-table'. Depending on the type, different constraints apply. These are specified in separate descriptions per type. At present the elements in this lists are not configurable and can only be retrieved by NETCONF <get> or <getconfig> operations. Attemps to modify this element and its children with a NETCONF <edit-config> operation MUST result in an 'operation-not-supported' error with type 'application'. A resource identifier of a port of the OpenFlow Capable Switch that the OpenFlow Logical Switch has exclusive access to. The elements in this list MUST refer to elements at the following path: /capable-switch/resources/port/resource-id Elements in this list MUST be unique. This means each port element can only be referenced once. A resource identifier of a queue of the OpenFlow Capable Switch that the OpenFlow Logical Switch has exclusive access to. The elements in this list MUST refer to elements at the following path: /capable-switch/resources/queue/resource-id Elements in this list MUST be unique. This means each queue element can only be referenced once. The resource identifier of the owned certificate in the OpenFlow Capable Switch that the OpenFlow Logical Switch uses to identify itself. This element MUST NOT occur more than once in an OpenFlow Logical Switch's resource list. If no such element is in an OpenFlow Logical Switch's resource list, then the OpenFlow Logical Switch does not authenticate itself towards an OpenFloe Controller with a certificate. If this element is present, then the OpenFlow Logical Switch MUST provide this certificate for authentication to an OpenFlow Controller when setting up a TLS connection. For TCP connections this element is irrelevant. The element MUST refer to an element at the following path: /capable-switch/resources/owned-certificate/resource-id A resource identifier of a flow table of the OpenFlow Capable Switch that the OpenFlow Logical Switch has exclusive access to. The elements in this list MUST refer to elements at the following path: /capable-switch/resources/flow-table/resource-id Elements in this list MUST be unique. This means each flow-table element can only be referenced once. The KeyValue element contains a single public key that may be useful in validating the signature. NETCONF <edit-config> operations MUST be implemented as follows: * Exactly one of the elemenst 'DSAKeyValue' or 'RSAKeyValue' all <edit-config> operations. * If the operation is 'merge' or 'replace', the element is created if it does not exist, and its value is set to the value found in the XML RPC data. * If the operation is 'create', the element is created if it does not exist. If the element already exists, a 'data‑exists' error is returned. * If the operation is 'delete', the element is deleted if it exists. If the element does not exist, a 'data‑missing' error is returned. This grouping specifies all properties of an OpenFlow logical switch's capabilities. Elements in the type OFLogicalSwitchCapabilitiesType are not configurable and can only be retrieved by NETCONF <get> operations. Attemps to modify this element and its children with a NETCONF <edit-config> operation MUST result in an 'operation-not-supported' error with type 'application'. The maximum number of packets the logical switch can buffer when sending packets to the controller using packet-in messages. The number of flow tables supported by the logical switch. The number of flow tables supported by the logical switch. Specifies if the logical switch supports flow statistics. Specifies if the logical switch supports table statistics. Specifies if the logical switch supports port statistics. Specifies if the logical switch supports group statistics. Specifies if the logical switch supports queue statistics. Specifies if the logical switch supports reassemble IP fragments. 'true' indicates that a switch protocol outside of OpenFlow, such as 802.1D Spanning Tree, will detect topology loops and block ports to prevent packet loops. Specify generic forwarding actions such as sending to the controller, flooding, or forwarding using non-OpenFlow methods, such as 'normal' switch processing. Specify the group types supported by the logical switch. Specify the group capabilities supported by the logical switch. Specify the action types supported by the logical switch. Specify the instruction types supported by the logical switch. This element specifies all properties of an OpenFlow resource of type OpenFlow Port. It represent a physical port or a logical port of the OpenFlow Capable Switch and can be assigned for exclusive use to an OpenFlow Logical Switch. A logical port represents a tunnel endpoint as described in the OpenFlow protocol specification versions 1.3 - 1.3.1. NETCONF <edit-config> operations MUST be implemented as follows: * The 'resource-id' element of OFResoureType MUST be present at all <edit-config> operations to identify the port. * If the operation is 'merge' or 'replace', the element is created if it does not exist, and its value is set to the value found in the XML RPC data. * If the operation is 'create', the element is created if it does not exist. If the element already exists, a 'data‑exists' error is returned. * If the operation is 'delete', the element is deleted if it exists. If the element does not exist, a 'data‑missing' error is returned. This number identifies the OpenFlow Port to OpenFlow Controllers. It is assigned to an OpenFlow Port latest when the OpenFlow Port is associated with and OpenFlow Logical Switch. If the OpenFlow Port is associated with an OpenFlow Logical Switch, this element MUST be unique within the context of the OpenFlow Logical Switch. OpenFlow Capable Switch implementations may choose to assign values to OpenFlow Ports that are unique within the context of the OpenFlow Logical Switch. These numbers can be used independent of assignments to OpenFlow Logical Switches. Other implementations may assign values to this element only if the OpenFlow Port is assigned to an OpenFlow Logical Switch. If no value is currently assigned to this element then this element MUST NOT be included in replies to NETCONF <get> requests. Since this element is not configurable with the NETCONF protocol it MUST NOT be included in replies to NETCONF <get-config> requests. This element assists OpenFlow Controllers in identifying OpenFlow Ports. This element is not to be set by the OP-CONFIG protocol, but it is set by the switch implementation. It may be set at start-up time of an OpenFlow Capable Switch or when the OpenFlow Port is assigned to an OpenFlow Logical Switch. It MAY also be not set at all. If this element is set to a value other than the empty string when being assigned to an OpenFlow Logical Switch, then the value of this element MUST be unique within the context of the OpenFlow Logical Switch. If no value or the empty string is currently assigned to this element then this element MUST not be included in replies to NETCONF <get> requests. Since this element is not configurable with the NETCONF protocol it MUST NOT be included in replies to NETCONF <get-config> requests. This element indicates the current bit rate of the port. Its values is to be provided in units of kilobit per second (kbps). This element is only valid if the element called 'rate' in the current Port Features has a value of 'other'. Since this element is not configurable with the NETCONF protocol it MUST NOT be included in replies to NETCONF <get-config> requests. This element indicates the maximum bit rate of the port. Its values is to be provided in units of kilobit per second (kbps). This element is only valid if the element called 'rate' in the current Port Features has a value of 'other'. Since this element is not configurable with the NETCONF protocol it MUST NOT be included in replies to NETCONF <get-config> requests. This element represents the general adminitrative configuration of the OpenFlow Port. The administrative state of the port. If true, the port has been administratively brought down and SHOULD not be used by OpenFlow. This element is optional. If this element is not present it defaults to 'up'. If true, packets received at this OpenFlow port SHOULD be dropped. This element is optional. If this element is not present it defaults to 'false'. If true, packets forwarded to this OpenFlow port SHOULD be dropped. This element is optional. If this element is not present it defaults to 'false'. If true, packets received on that port that generate a table miss should never trigger a packet-in message to the OpenFlow Controller. This element is optional. If this element is not present it defaults to 'false'. This element represents the general operational state of the OpenFlow Port. Children of this element are not configurable and can only be retrieved by NETCONF <get> operations. Attemps to modify this element and its children with a NETCONF <edit-config> operation MUST result in an 'operation-not-supported' error with type 'application'. If the value of this element is 'down', it indicates that there is no physical link present. If the value of this element is 'true', it indicates that a switch protocol outside of OpenFlow, such as 802.1D Spanning Tree, is preventing the use of this OpenFlow port for OpenFlow flooding. If the value of this element is 'true', it indicates that this OpenFlow Port is live and can be used for fast failover. The features (rates, duplex, etc.) of the port, that are currently in use. Children of this element are not configurable and can only be retrieved by NETCONF <get> operations. Attemps to modify this element and its children with a NETCONF <edit-config> operation MUST result in an 'operation-not-supported' error with type 'application'. The features (rates, duplex, etc.) of the port, that are advertised to the peer port. NETCONF <edit-config> operations MUST be implemented as follows: * The 'resource-id' element of OFResoureType MUST be present in the path or in the filter at all <edit-config> operations to identify the port. * If the operation is 'merge' or 'replace', the element is created if it does not exist, and its value is set to the value found in the XML RPC data. * If the operation is 'create', the element is created if it does not exist. If the element already exists, a 'data‑exists' error is returned. * If the operation is 'delete', the element is deleted if it exists. If the element does not exist, a 'data‑missing' error is returned. The features (rates, duplex, etc.) of the port, that are supported on the port. Children of this element are not configurable and can only be retrieved by NETCONF <get> operations. Attemps to modify this element and its children with a NETCONF <edit-config> operation MUST result in an 'operation-not-supported' error with type 'application'. The features (rates, duplex, etc.) that are currently advertised by the peer port. Children of this element are not configurable and can only be retrieved by NETCONF <get> operations. Attemps to modify this element and its children with a NETCONF <edit-config> operation MUST result in an 'operation-not-supported' error with type 'application'. Tunnels are modeled as logical ports. Elements in this choice are not configurable and can only be retrieved by NETCONF <get> operations. Attemps to modify this element and its children with a NETCONF <edit-config> operation MUST result in an 'operation-not-supported' error with type 'application'. Only elements from one choice must exist at a time. Properties of a basic IP-in-GRE tunnel. Properties of a IP-in-GRE tunnel. Properties of a VxLAN tunnel. Properties of a NVGRE tunnel. This element specifies a generic OpenFlow resource that is used as a basis for specific resources. Even though this element is not used on its own the following rules for NETCONF operations MUST be obeyed also by elemnts using this element. NETCONF <edit-config> operations MUST be implemented as follows: * The 'id' element MUST be present at all <edit-config> operations to identify the resource. * If the operation is 'merge' or 'replace', the element is created if it does not exist, and its value is set to the value found in the XML RPC data. * If the operation is 'create', the element is created if it does not exist. If the element already exists, a 'data‑exists' error is returned. * If the operation is 'delete', the element is deleted if it exists. If the element does not exist, a 'data‑missing' error is returned. A unique but locally arbitrary identifier that uniquely identifies an OpenFlow Port within the context of an OpenFlow Logical Switch. It MUST be persistent across reboots of the OpenFlow Capable Switch. This element MUST be present to identify the OpenFlow resource. Properties of a VxLAN tunnel. Indicates how the corresponding flag should be set in packets sent on the tunnel. Virtual network identifier assigned to all packets sent on the tunnel. A VxLAN implementation MAY use the this element to set the OXM_OF_TUNNEL_ID match field metadata in the OpenFlow protocol. If IP multicast is used to support broadcast on the tunnel this specifies the corresponding multicast IP address Specifies the outer UDP source port number. If this element is absent, the port number MAY be chosen dynamically. Specifies the outer UDP destination port number. It is intended to reserve a port number for VxLAN at IANA. As soon as this has been reserved, the reserved number SHOULD become the default value for this element. Boolean flag to indicate whether or not the outer UDP checksum should be set This grouping specifies all properties of an OpenFlow Logical Switch Controller. NETCONF <edit-config> operations MUST be implemented as follows: * The 'id' element MUST be present at all <edit-config> operations to identify the controller. * If the operation is 'merge' or 'replace', the element is created if it does not exist, and its value is set to the value found in the XML RPC data. * If the operation is 'create', the element is created if it does not exist. If the element already exists, a 'data‑exists' error is returned. * If the operation is 'delete', the element is deleted if it exists. If the element does not exist, a 'data‑missing' error is returned. A unique but locally arbitrary identifier that uniquely identifies an OpenFlow Controller within the context of an OpenFlow Capable Switch. It MUST be persistent across reboots of the OpenFlow Capable Switch. This element MUST be present to identify the OpenFlow controller. This element indicates the role of the OpenFlow Controller. Semantics of these roles are specified in the OpenFlow specifications 1.0 - 1.3.1. It is RECOMMENDED that the roles of controllers are not configured by OF-CONFIG 1.1.1 but determined using the OpenFlow protocol. OpenFlow Controllers configured by OF-CONFIG 1.1.1 have the default role 'equal'. A role other than 'equal' MAY be assigned to a controller. Roles 'slave' and 'equal' MAY be assigned to multiple controllers. Role 'master' MUST NOT be assigned to more than one controller. This element is optional. If this element is not present it defaults to 'equal'. The IP address of the OpenFlow Controller. This IP address is used by the OpenFlow Logical Switch when connecting to the OpenFlow Controller. This element MUST be present in the NETCONF data store. If this element is not present in a NETCONF <edit-config> operation 'create', 'merge' or 'replace' and the parent element does not exist, a 'data-missing' error is returned. The TCP port number at the OpenFlow Controller. This port number is used by the OpenFlow Logical Switch when connecting to the OpenFlow Controller using TCP or TLS. The default value is 6633. This element is optional. If this element is not present it defaults to 6633. The local IP address of the OpenFlow Logical Switch when connecting to this OpenFlow Controller. It is the source IP address of packets sent to this OpenFlow Controller. If present, this element overrides any default IP address. This element is optional. Attempts to set this element to an IP address that cannot be used by the OpenFlow Logical Switch MUST result in an 'bad-element' error with type 'application'. The <error-info> element MUST contain the name of this element in the <bad-element> element. The local TCP port number of the OpenFlow Logical Switch when connecting to this OpenFlow Controller. It is the source TCP port number of packets sent to this OpenFlow Controller. If this element is not present, then the port number is chosen arbitrarily by the OpenFlow Logical Switch. This element is optional. Attempts to set this element to a port number that cannot be used by the OpenFlow Logical Switch MUST result in an 'bad-element' error with type 'application'. The <error-info> element MUST contain the name of this element in the <bad-element> element. The default protocol tha the OpenFlow Logical Switch uses to connect to this OpenFlow Controller. 'tls' is the default value. This element is optional. If this element is not present it defaults to 'tls'. This container holds connection state information that indicate the connection state of the OpenFlow Logical Switch and the OpenFlow protocol version used for the connection. Children of this element are not configurable and can only be retrieved by NETCONF <get> operations. Attemps to modify this element and its children with a NETCONF <edit-config> operation MUST result in an 'operation-not-supported' error with type 'application'. This object indicates the connections state of the OpenFlow Logical Switch to this controller. This object indicates the version of the OpenFlow protocol used between the OpenFlow Logical Switch and this Controller. If element connection-state has value 'up', then this element indicates the actual version in use. If element connection-state has value 'down', then this element indicates the version number of the last established connection with this OpenFlow Controller. The value of this element MAY be persistent across reboots of the OpenFlow Logical Switch in such a case. If element connection-state has value 'down'and there is no information about previous connections to this OpenFlow controller, then this element is not present or has the value '0'. This list of elements includes one entry for each OpenFlow protocol version that this OpenFlow controller supports. It SHOULD contain all The local IP address of the OpenFlow Logical Switch when connecting to this OpenFlow Controller. It is the source IP address of packets sent to this OpenFlow Controller. If present, this element overrides any default IP address. The local TCP port number of the OpenFlow Logical Switch. If element connection-state has value 'up', then this element indicates the actual port number in use. If element connection-state has value 'down', then this element indicates the port number used for the last attempt to establish a connection with this OpenFlow Controller.??? When connecting to this OpenFlow Controller, it is the source TCP port number of packets sent to this OpenFlow Controller. If this element has its defaqult value 0, then port number is chosen arbitrarily by the OpenFlow Logical Switch. The OpenFlow Capable Switch serves as the root element for an OpenFlow configuration. It contains logical switches and resources that can be assigned to logical switches. It may have relations to OpenFlow Configuration Points. A unique but locally arbitrary identifier that uniquely identifies a Capable Switch within the context of potential OpenFlow Configuration Points. It MUST be persistent across reboots of the OpenFlow Capable Switch. This element MUST be present in the NETCONF data store. If this element is not present in a NETCONF <edit-config> operation 'create', 'merge' or 'replace' and the parent element does not exist, a 'data-missing' error is returned. The maximum supported OF-CONFIG version that is supported by the OpenFlow Capable Switch. For switches implementing this version of the OF-CONFIG protocol this MUST always be 1.1.1. This object can be used to identify the OF-CONFIG version a capable switch supports beginning with version 1.1.1 of OF-CONFIG. In addtion the supported version can be determined by the namespace the OpenFlow Capable Switch returns to configuration request of an element (like capable-switch) that is present in all OF-CONFIG versions specified so far. This is the only possiblity to identify OF-CONFIG versions prior to OF-CONFIG 1.1.1. The list of all Configuration Points known to the OpenFlow Capable Switch that may manage it using OF-CONFIG. The element 'id' of OFConfigurationType MUST be unique within this list. A lists containing all resources of the OpenFlow Capable Switch that can be used by OpenFlow Logical Switches. Resources are listed here independent of their actual assignment to OpenFlow Logical Switches. They may be available to be assigned to an OpenFlow Logical Switch or already in use by an OpenFlow Logical Switch. The list contains all port resources of the OpenFlow Capable Switch. The element 'resource-id' of OFPortType MUST be unique within this list. The list contains all queue resources of the OpenFlow Capable Switch. The element 'resource-id' of OFQueueType MUST be unique within this list. The list contains all owned certificate resources of the OpenFlow Capable Switch. The element 'resource-id' of OFOwnedCertificateType MUST be unique within this list. The list contains all external certificate resources of the OpenFlow Capable Switch. The element 'resource-id' of OFExternalCertificateType MUST be unique within this list. The list contains all flow table resources of the OpenFlow Capable Switch. The element 'resource-id' of OFFlowTableType MUST be unique within this list. This element contains a list of all OpenFlow Logical Switches available at the OpenFlow Capable Switch. The list of all OpenFlow Logical Switches on the OpenFlow Capable Switch. The element 'resource-id' of OFLogicalSwitchType MUST be unique within this list. ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/of_config/of-config-1.1.xsd0000664000175000017500000011064200000000000021656 0ustar00zuulzuul00000000000000 The OpenFlow Capable Switch and its configurationpoints, logical switches and resources available to logicalswitches. Representation of an OpenFlow Capable Switch. An unique but locally arbitrary identifier that identifies a Capable Switch towards management systems and that is persistent across reboots of the system. The list of all configuration points known to the OpenFlow Capable Switch that may manage it using OF-CONFIG. This element contains lists of all resources of the OpenFlow Capable Switch that can be used by OpenFlow Logical Switches. List of all OpenFlow Logical Switches available on the OpenFlow Capable Switch. Representation of an OpenFlow Configuration Point. An identifier that identifies a Configuration Point of the OpenFlow Capable Switch. A locator of the Configuration Point. This element MAY contain a locator of the configuration point including, for example, an IP address and a port number. The transport protocol that the Configuration Point uses when communicating via NETCONF with the OpenFlow Capable Switch. The mappings of NETCONF to different transport protocols are defined in RFC 6242 for SSH, RFC 4743 for SOAP, RFC 4744 for BEEP, and RFC 5539 for TLS. The representation of an OpenFlow Logical Switch An unique but locally arbitrary identifier that identifies an OpenFlow Logical Switch within an OpenFlow Capable Switch. It is persistent across reboots of the system. Capability items of logical switch. A unique identifier that identifiers an OpenFlow Logical Switch within the context of an OpenFlow Controller. The list of controllers that are assigned to the OpenFlow Logical Switch. The list of references to all resources of the OpenFlow Capable Switch that the OpenFlow Logical Switch has exclusive access to. The maximum number of packets the switch can buffer when sending packets to the controller using packet-in messages. See OpenFlow protocol 1.2 section A.3.1 The number of flow tables supported by the switch. See OpenFlow protocol 1.2 section A.3.1 The number of ports supported by the switch. See OpenFlow protocol 1.2 section A.3.1 Whether the switch supports flow statistics. See OpenFlow protocol 1.2 section A.3.1 Whether the switch supports table statistics. See OpenFlow protocol 1.2 section A.3.1 Whether the switch supports port statistics. See OpenFlow protocol 1.2 section A.3.1 Whether the switch supports group statistics. See OpenFlow protocol 1.2 section A.3.1 Whether the switch supports queue statistics. See OpenFlow protocol 1.2 section A.3.1 Whether the switch supports reassemble IP fragments. See OpenFlow protocol 1.2 section A.3.1 "true" indicates that a switch protocol outside of OpenFlow, such as 802.1D Spanning Tree, will detect topology loops and block ports to prevent packet loops. See OpenFlow protocol 1.2 section A.3.1 Specify generic forwarding actions such as sending to the controller, ooding, or forwarding using non-OpenFlow methods, such as "normal" switch processing. SeeOpenFlow protocol 1.2 section 4.5. The group types supported by the switch. SeeOpenFlow protocol 1.2 section 5.4.1. The group capabilities supported by the switch. SeeOpenFlow protocol 1.2 section A.3.5.9. The action types supported by the switch. See OpenFlow protocol 1.2 section 5.9 and A.2.5. The instruction types supported by the switch. See OpenFlow protocol 1.2 section 5.6. Representation of an OpenFlow Controller An unique but locally arbitrary identifier that identifies an OpenFlow Controller within the context of an OpenFlow Capable Switch. It is persistent across reboots of the system. The predefined role of the controller. The remote IP of the controller to connect to. The port number the controller listens on. This specifies the source IP for packets sent to this controller and overrides the default IP used. The port number the controller listens on. If 0 the port is chosen dynamically. The protocol used for connecting to the controller. Both sides must support the chosen protocol for a successful establishment of a connection. This element represents the state of the OpenFlow protocol connection to the controller. This element represents the run-time state of the OpenFlow connection to the Controller. This element denotes the version of OpenFlow that Controller is currently communicating with. It is only relevant when the connection-state element is set to "up". This element denotes all of the versions of the OpenFlow protocol that the controller supports. A Base Class for OpenFlow Resources. An unique but locally arbitrary identifier that identifies a resource within the context of and OpenFlow Capable Switch and is persistent across reboots of the system. An unique but locally arbitrary number that identifies a queue within the context of and OpenFlow Logical Switch and is persistent across reboots of the system. Port in the context of the same Logical Switch which this Queue is associated with. Properties of the Queue. The minimal rate that is reserved for this queue in 1/10 of a percent of the actual rate. The maximum rate that is reserved for this queue in 1/10 of a percent of the actual rate. Experimental Properties The open flow match field types. See OpenFlow protocol 1.2 section A.2.3.7 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/of_config/xmldsig-core-schema.xsd0000664000175000017500000002374400000000000023353 0ustar00zuulzuul00000000000000 ]> ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/ofctl_nicira_ext.py0000664000175000017500000001310100000000000020717 0ustar00zuulzuul00000000000000# Copyright (C) 2016 Rackspace US, Inc. # # 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. import base64 import logging from os_ken.ofproto import nicira_ext LOG = logging.getLogger(__name__) def action_to_str(act, ofctl_action_to_str): sub_type = act.subtype if sub_type == nicira_ext.NXAST_RESUBMIT: return 'NX_RESUBMIT: {port: %s, table: %s}' % (act.in_port, act.table_id) elif sub_type == nicira_ext.NXAST_REG_MOVE: src_start = act.src_ofs dst_start = act.dst_ofs src_end = src_start + act.n_bits dst_end = dst_start + act.n_bits return 'NX_MOVE: {%s[%s..%s]: %s[%s..%s]}' % (act.dst_field, dst_start, dst_end, act.src_field, src_start, src_end) elif sub_type == nicira_ext.NXAST_REG_LOAD: return 'NX_LOAD: {%s%s: %x}' % (act.dst, nicira_ext.ofs_nbits_str(act.ofs_nbits), act.value) elif sub_type == nicira_ext.NXAST_LEARN: specs = [] add_spec = specs.append for spec in act.specs: dst_type = spec._dst_type if dst_type == 0: # match if isinstance(spec.src, (tuple, list)): src = spec.src[0] start = spec.src[1] end = start + spec.n_bits start_end = '%s..%s' % (start, end) else: src = spec.src start_end = '[]' add_spec('%s[%s]' % (src, start_end)) elif dst_type == 1: # load if isinstance(spec.src, (tuple, list)): src = spec.src[0] start = spec.src[1] end = start + spec.n_bits src_start_end = '[%s..%s]' % (start, end) else: src = spec.src src_start_end = '[]' if isinstance(spec.dst, (tuple, list)): dst = spec.dst[0] start = spec.dst[1] end = start + spec.n_bits dst_start_end = '[%s..%s]' % (start, end) else: dst = spec.dst dst_start_end = '[]' add_spec('NX_LOAD {%s%s: %s%s}' % (dst, dst_start_end, src, src_start_end)) elif dst_type == 2: # output if isinstance(spec.src, (tuple, list)): src = spec.src[0] start = spec.src[1] end = start + spec.n_bits start_end = '%s..%s' % (start, end) else: src = spec.src start_end = '[]' add_spec('output:%s%s' % (src, start_end)) return ('NX_LEARN: {idle_timeout: %s, ' 'hard_timeouts: %s, ' 'priority: %s, ' 'cookie: %s, ' 'flags: %s, ' 'table_id: %s, ' 'fin_idle_timeout: %s, ' 'fin_hard_timeout: %s, ' 'specs: %s}' % (act.idle_timeout, act.hard_timeout, act.priority, act.cookie, act.flags, act.table_id, act.fin_idle_timeout, act.self.fin_hard_timeout, specs)) elif sub_type == nicira_ext.NXAST_CONJUNCTION: return ('NX_CONJUNCTION: {clause: %s, number_of_clauses: %s, id: %s}' % (act.clause, act.n_clauses, act.id)) elif sub_type == nicira_ext.NXAST_CT: if act.zone_ofs_nbits != 0: start = act.zone_ofs_nbits end = start + 16 zone = act.zone_src + ('[%s..%s]' % (start, end)) else: zone = act.zone_src actions = [ofctl_action_to_str(action) for action in act.actions] return ('NX_CT: {flags: %s, ' 'zone: %s, ' 'table: %s, ' 'alg: %s, ' 'actions: %s}' % (act.flags, zone, act.recirc_table, act.alg, actions)) elif sub_type == nicira_ext.NXAST_NAT: return ('NX_NAT: {flags: %s, ' 'range_ipv4_min: %s, ' 'range_ipv4_max: %s, ' 'range_ipv6_min: %s, ' 'range_ipv6_max: %s, ' 'range_proto_min: %s, ' 'range_proto_max: %s}' % (act.flags, act.range_ipv4_min, act.range_ipv4_max, act.range_ipv6_min, act.range_ipv6_max, act.range_proto_min, act.range_proto_max)) data_str = base64.b64encode(act.data) return 'NX_UNKNOWN: {subtype: %s, data: %s}' % (sub_type, data_str.decode('utf-8')) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/ofctl_string.py0000664000175000017500000002640700000000000020115 0ustar00zuulzuul00000000000000# Copyright (C) 2017 Nippon Telegraph and Telephone 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. import re import os_ken.exception from os_ken.lib.ofctl_utils import str_to_int from os_ken.ofproto import nicira_ext def ofp_instruction_from_str(ofproto, action_str): """ Parse an ovs-ofctl style action string and return a list of jsondict representations of OFPInstructionActions, which can then be passed to ofproto_parser.ofp_instruction_from_jsondict. Please note that this is for making transition from ovs-ofctl easier. Please consider using OFPAction constructors when writing new codes. This function takes the following arguments. =========== ================================================= Argument Description =========== ================================================= ofproto An ofproto module. action_str An action string. =========== ================================================= """ action_re = re.compile(r"([a-z_]+)(\([^)]*\)|[^a-z_,()][^,()]*)*") result = [] while len(action_str): m = action_re.match(action_str) if not m: raise os_ken.exception.OFPInvalidActionString(action_str=action_str) action_name = m.group(1) this_action = m.group(0) paren_level = this_action.count('(') - this_action.count(')') assert paren_level >= 0 try: # Parens can be nested. Look for as many ')'s as '('s. if paren_level > 0: this_action, rest = _tokenize_paren_block(action_str, m.end(0)) else: rest = action_str[m.end(0):] if len(rest): assert rest[0] == ',' rest = rest[1:] except Exception: raise os_ken.exception.OFPInvalidActionString(action_str=action_str) if action_name == 'drop': assert this_action == 'drop' assert len(result) == 0 and rest == '' return [] converter = getattr(OfctlActionConverter, action_name, None) if converter is None or not callable(converter): raise os_ken.exception.OFPInvalidActionString(action_str=action_name) result.append(converter(ofproto, this_action)) action_str = rest return result def _tokenize_paren_block(string, pos): paren_re = re.compile("[()]") paren_level = string[:pos].count('(') - string[:pos].count(')') while paren_level > 0: m = paren_re.search(string[pos:]) if m.group(0) == '(': paren_level += 1 else: paren_level -= 1 pos += m.end(0) return string[:pos], string[pos:] def tokenize_ofp_instruction_arg(arg): """ Tokenize an argument portion of ovs-ofctl style action string. """ arg_re = re.compile("[^,()]*") try: rest = arg result = [] while len(rest): m = arg_re.match(rest) if m.end(0) == len(rest): result.append(rest) return result if rest[m.end(0)] == '(': this_block, rest = _tokenize_paren_block( rest, m.end(0) + 1) result.append(this_block) elif rest[m.end(0)] == ',': result.append(m.group(0)) rest = rest[m.end(0):] else: # is ')' raise Exception if len(rest): assert rest[0] == ',' rest = rest[1:] return result except Exception: raise os_ken.exception.OFPInvalidActionString(action_str=arg) _OXM_FIELD_OFCTL_ALIASES = { 'tun_id': 'tunnel_id', 'in_port': 'in_port_nxm', 'in_port_oxm': 'in_port', 'dl_src': 'eth_src', 'dl_type': 'eth_type', 'nw_src': 'ipv4_src', 'ip_src': 'ipv4_src', 'nw_proto': 'ip_proto', 'nw_ecn': 'ip_ecn', 'tp_src': 'tcp_src', 'icmp_type': 'icmpv4_type', 'icmp_code': 'icmpv4_code', 'nd_target': 'ipv6_nd_target', 'nd_sll': 'ipv6_nd_sll', 'nd_tll': 'ipv6_nd_tll', # Nicira extension 'tun_src': 'tun_ipv4_src' } def ofp_ofctl_field_name_to_os_ken(field): """Convert an ovs-ofctl field name to os_ken equivalent.""" mapped = _OXM_FIELD_OFCTL_ALIASES.get(field) if mapped: return mapped if field.endswith("_dst"): mapped = _OXM_FIELD_OFCTL_ALIASES.get(field[:-3] + "src") if mapped: return mapped[:-3] + "dst" return field _NXM_FIELD_MAP = dict([(key, key + '_nxm') for key in [ 'arp_sha', 'arp_tha', 'ipv6_src', 'ipv6_dst', 'icmpv6_type', 'icmpv6_code', 'ip_ecn', 'tcp_flags']]) _NXM_FIELD_MAP.update({ 'tun_id': 'tunnel_id_nxm', 'ip_ttl': 'nw_ttl'}) _NXM_OF_FIELD_MAP = dict([(key, key + '_nxm') for key in [ 'in_port', 'eth_dst', 'eth_src', 'eth_type', 'ip_proto', 'tcp_src', 'tcp_dst', 'udp_src', 'udp_dst', 'arp_op', 'arp_spa', 'arp_tpa']]) _NXM_OF_FIELD_MAP.update({ 'ip_src': 'ipv4_src_nxm', 'ip_dst': 'ipv4_dst_nxm', 'icmp_type': 'icmpv4_type_nxm', 'icmp_code': 'icmpv4_code_nxm'}) def nxm_field_name_to_os_ken(field): """ Convert an ovs-ofctl style NXM_/OXM_ field name to a os_ken match field name. """ if field.endswith("_W"): field = field[:-2] prefix = field[:7] field = field[7:].lower() mapped_result = None if prefix == 'NXM_NX_': mapped_result = _NXM_FIELD_MAP.get(field) elif prefix == "NXM_OF_": mapped_result = _NXM_OF_FIELD_MAP.get(field) elif prefix == "OXM_OF_": # no mapping needed pass else: raise ValueError if mapped_result is not None: return mapped_result return field class OfctlActionConverter(object): @classmethod def goto_table(cls, ofproto, action_str): assert action_str.startswith('goto_table:') table_id = str_to_int(action_str[len('goto_table:'):]) return dict(OFPInstructionGotoTable={'table_id': table_id}) @classmethod def normal(cls, ofproto, action_str): return cls.output(ofproto, action_str) @classmethod def output(cls, ofproto, action_str): if action_str == 'normal': port = ofproto.OFPP_NORMAL else: assert action_str.startswith('output:') port = str_to_int(action_str[len('output:'):]) return dict(OFPActionOutput={'port': port}) @classmethod def pop_vlan(cls, ofproto, action_str): return dict(OFPActionPopVlan={}) @classmethod def set_field(cls, ofproto, action_str): try: assert action_str.startswith("set_field:") value, key = action_str[len("set_field:"):].split("->", 1) fieldarg = dict(field=ofp_ofctl_field_name_to_os_ken(key)) m = value.find('/') if m >= 0: fieldarg['value'] = str_to_int(value[:m]) fieldarg['mask'] = str_to_int(value[m + 1:]) else: fieldarg['value'] = str_to_int(value) except Exception: raise os_ken.exception.OFPInvalidActionString(action_str=action_str) return dict(OFPActionSetField={ 'field': {'OXMTlv': fieldarg}}) # NX actions @classmethod def resubmit(cls, ofproto, action_str): arg = action_str[len("resubmit"):] kwargs = {} try: if arg[0] == ':': kwargs['in_port'] = str_to_int(arg[1:]) elif arg[0] == '(' and arg[-1] == ')': in_port, table_id = arg[1:-1].split(',') if in_port: kwargs['in_port'] = str_to_int(in_port) if table_id: kwargs['table_id'] = str_to_int(table_id) else: raise Exception return dict(NXActionResubmitTable=kwargs) except Exception: raise os_ken.exception.OFPInvalidActionString( action_str=action_str) @classmethod def conjunction(cls, ofproto, action_str): try: assert action_str.startswith('conjunction(') assert action_str[-1] == ')' args = action_str[len('conjunction('):-1].split(',') assert len(args) == 2 id_ = str_to_int(args[0]) clauses = list(map(str_to_int, args[1].split('/'))) assert len(clauses) == 2 return dict(NXActionConjunction={ 'clause': clauses[0] - 1, 'n_clauses': clauses[1], 'id': id_}) except Exception: raise os_ken.exception.OFPInvalidActionString( action_str=action_str) @classmethod def ct(cls, ofproto, action_str): str_to_port = {'ftp': 21, 'tftp': 69} flags = 0 zone_src = "" zone_ofs_nbits = 0 recirc_table = nicira_ext.NX_CT_RECIRC_NONE alg = 0 ct_actions = [] if len(action_str) > 2: if (not action_str.startswith('ct(') or action_str[-1] != ')'): raise os_ken.exception.OFPInvalidActionString( action_str=action_str) rest = tokenize_ofp_instruction_arg(action_str[len('ct('):-1]) else: rest = [] for arg in rest: if arg == 'commit': flags |= nicira_ext.NX_CT_F_COMMIT rest = rest[len('commit'):] elif arg == 'force': flags |= nicira_ext.NX_CT_F_FORCE elif arg.startswith('exec('): ct_actions = ofp_instruction_from_str( ofproto, arg[len('exec('):-1]) else: try: k, v = arg.split('=', 1) if k == 'table': recirc_table = str_to_int(v) elif k == 'zone': m = re.search(r'\[(\d*)\.\.(\d*)\]', v) if m: zone_ofs_nbits = nicira_ext.ofs_nbits( int(m.group(1)), int(m.group(2))) zone_src = nxm_field_name_to_os_ken( v[:m.start(0)]) else: zone_ofs_nbits = str_to_int(v) elif k == 'alg': alg = str_to_port[arg[len('alg='):]] except Exception: raise os_ken.exception.OFPInvalidActionString( action_str=action_str) return dict(NXActionCT={'flags': flags, 'zone_src': zone_src, 'zone_ofs_nbits': zone_ofs_nbits, 'recirc_table': recirc_table, 'alg': alg, 'actions': ct_actions}) @classmethod def ct_clear(cls, ofproto, action_str): return dict(NXActionCTClear={}) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/ofctl_utils.py0000664000175000017500000003437600000000000017753 0ustar00zuulzuul00000000000000# Copyright (C) 2016 Nippon Telegraph and Telephone 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. import base64 import logging import netaddr from os_ken.lib import dpid from os_ken.lib import hub from os_ken.ofproto import ofproto_v1_2 LOG = logging.getLogger(__name__) DEFAULT_TIMEOUT = 1.0 # NOTE(jkoelker) Constants for converting actions OUTPUT = 'OUTPUT' COPY_TTL_OUT = 'COPY_TTL_OUT' COPY_TTL_IN = 'COPY_TTL_IN' SET_MPLS_TTL = 'SET_MPLS_TTL' DEC_MPLS_TTL = 'DEC_MPLS_TTL' PUSH_VLAN = 'PUSH_VLAN' POP_VLAN = 'POP_VLAN' PUSH_MPLS = 'PUSH_MPLS' POP_MPLS = 'POP_MPLS' SET_QUEUE = 'SET_QUEUE' GROUP = 'GROUP' SET_NW_TTL = 'SET_NW_TTL' DEC_NW_TTL = 'DEC_NW_TTL' SET_FIELD = 'SET_FIELD' PUSH_PBB = 'PUSH_PBB' # OpenFlow 1.3 or later POP_PBB = 'POP_PBB' # OpenFlow 1.3 or later COPY_FIELD = 'COPY_FIELD' # OpenFlow 1.5 or later METER = 'METER' # OpenFlow 1.5 or later EXPERIMENTER = 'EXPERIMENTER' def get_logger(logger=None): # NOTE(jkoelker) use the logger the calling code wants us to if logger is not None: return logger return LOG def match_vid_to_str(value, mask, ofpvid_present): if mask is not None: return '0x%04x/0x%04x' % (value, mask) if value & ofpvid_present: return str(value & ~ofpvid_present) return '0x%04x' % value def to_action(dic, ofp, parser, action_type, util): actions = {COPY_TTL_OUT: parser.OFPActionCopyTtlOut, COPY_TTL_IN: parser.OFPActionCopyTtlIn, DEC_MPLS_TTL: parser.OFPActionDecMplsTtl, POP_VLAN: parser.OFPActionPopVlan, DEC_NW_TTL: parser.OFPActionDecNwTtl} if ofp.OFP_VERSION > ofproto_v1_2.OFP_VERSION: actions[POP_PBB] = parser.OFPActionPopPbb need_ethertype = {PUSH_VLAN: parser.OFPActionPushVlan, PUSH_MPLS: parser.OFPActionPushMpls, POP_MPLS: parser.OFPActionPopMpls} if ofp.OFP_VERSION > ofproto_v1_2.OFP_VERSION: need_ethertype[PUSH_PBB] = parser.OFPActionPushPbb if action_type in actions: return actions[action_type]() elif action_type in need_ethertype: ethertype = str_to_int(dic.get('ethertype')) return need_ethertype[action_type](ethertype) elif action_type == OUTPUT: out_port = util.ofp_port_from_user(dic.get('port', ofp.OFPP_ANY)) max_len = util.ofp_cml_from_user(dic.get('max_len', ofp.OFPCML_MAX)) return parser.OFPActionOutput(out_port, max_len) elif action_type == SET_MPLS_TTL: mpls_ttl = str_to_int(dic.get('mpls_ttl')) return parser.OFPActionSetMplsTtl(mpls_ttl) elif action_type == SET_QUEUE: queue_id = util.ofp_queue_from_user(dic.get('queue_id')) return parser.OFPActionSetQueue(queue_id) elif action_type == GROUP: group_id = util.ofp_group_from_user(dic.get('group_id')) return parser.OFPActionGroup(group_id) elif action_type == SET_NW_TTL: nw_ttl = str_to_int(dic.get('nw_ttl')) return parser.OFPActionSetNwTtl(nw_ttl) elif action_type == SET_FIELD: field = dic.get('field') value = dic.get('value') return parser.OFPActionSetField(**{field: value}) elif action_type == 'COPY_FIELD': n_bits = str_to_int(dic.get('n_bits')) src_offset = str_to_int(dic.get('src_offset')) dst_offset = str_to_int(dic.get('dst_offset')) oxm_ids = [parser.OFPOxmId(str(dic.get('src_oxm_id'))), parser.OFPOxmId(str(dic.get('dst_oxm_id')))] return parser.OFPActionCopyField( n_bits, src_offset, dst_offset, oxm_ids) elif action_type == 'METER': if hasattr(parser, 'OFPActionMeter'): # OpenFlow 1.5 or later meter_id = str_to_int(dic.get('meter_id')) return parser.OFPActionMeter(meter_id) else: # OpenFlow 1.4 or earlier return None elif action_type == EXPERIMENTER: experimenter = str_to_int(dic.get('experimenter')) data_type = dic.get('data_type', 'ascii') if data_type not in ('ascii', 'base64'): LOG.error('Unknown data type: %s', data_type) return None data = dic.get('data', '') if data_type == 'base64': data = base64.b64decode(data) return parser.OFPActionExperimenterUnknown(experimenter, data) return None def to_match_eth(value): if '/' in value: value = value.split('/') return value[0], value[1] return value def to_match_ip(value): if '/' in value: (ip_addr, ip_mask) = value.split('/') if ip_mask.isdigit(): ip = netaddr.ip.IPNetwork(value) ip_addr = str(ip.ip) ip_mask = str(ip.netmask) return ip_addr, ip_mask return value def to_match_vid(value, ofpvid_present): # NOTE: If "vlan_id" field is described as decimal int value # (and decimal string value), it is treated as values of # VLAN tag, and OFPVID_PRESENT(0x1000) bit is automatically # applied. OTOH, If it is described as hexadecimal string, # treated as values of oxm_value (including OFPVID_PRESENT # bit), and OFPVID_PRESENT bit is NOT automatically applied if isinstance(value, int): # described as decimal int value return value | ofpvid_present else: if '/' in value: val = value.split('/') return str_to_int(val[0]), str_to_int(val[1]) else: if value.isdigit(): # described as decimal string value return int(value, 10) | ofpvid_present return str_to_int(value) def to_match_masked_int(value): if isinstance(value, str) and '/' in value: value = value.split('/') return str_to_int(value[0]), str_to_int(value[1]) return str_to_int(value) def to_match_packet_type(value): if isinstance(value, (list, tuple)): return str_to_int(value[0]) << 16 | str_to_int(value[1]) else: return str_to_int(value) def send_experimenter(dp, exp, logger=None): experimenter = exp.get('experimenter', 0) exp_type = exp.get('exp_type', 0) data_type = exp.get('data_type', 'ascii') data = exp.get('data', '') if data_type == 'base64': data = base64.b64decode(data) elif data_type == 'ascii': data = data.encode('ascii') else: get_logger(logger).error('Unknown data type: %s', data_type) return expmsg = dp.ofproto_parser.OFPExperimenter( dp, experimenter, exp_type, data) send_msg(dp, expmsg, logger) def send_msg(dp, msg, logger=None): if msg.xid is None: dp.set_xid(msg) log = get_logger(logger) # NOTE(jkoelker) Prevent unnecessary string formating by including the # format rules in the log_msg log_msg = ('Sending message with xid(%x) to ' 'datapath(' + dpid._DPID_FMT + '): %s') log.debug(log_msg, msg.xid, dp.id, msg) dp.send_msg(msg) def send_stats_request(dp, stats, waiters, msgs, logger=None): dp.set_xid(stats) waiters_per_dp = waiters.setdefault(dp.id, {}) lock = hub.Event() previous_msg_len = len(msgs) waiters_per_dp[stats.xid] = (lock, msgs) send_msg(dp, stats, logger) lock.wait(timeout=DEFAULT_TIMEOUT) current_msg_len = len(msgs) while current_msg_len > previous_msg_len: previous_msg_len = current_msg_len lock.wait(timeout=DEFAULT_TIMEOUT) current_msg_len = len(msgs) if not lock.is_set(): del waiters_per_dp[stats.xid] def str_to_int(str_num): return int(str(str_num), 0) def get_role(dp, waiters, to_user): stats = dp.ofproto_parser.OFPRoleRequest( dp, dp.ofproto.OFPCR_ROLE_NOCHANGE, generation_id=0) msgs = [] send_stats_request(dp, stats, waiters, msgs, LOG) descs = [] for msg in msgs: d = msg.to_jsondict()[msg.__class__.__name__] if to_user: d['role'] = OFCtlUtil(dp.ofproto).ofp_role_to_user(d['role']) descs.append(d) return {str(dp.id): descs} class OFCtlUtil(object): def __init__(self, ofproto): self.ofproto = ofproto self.deprecated_value = [ 'OFPTFPT_EXPERIMENTER_SLAVE', 'OFPTFPT_EXPERIMENTER_MASTER', 'OFPQCFC_EPERM'] def _reserved_num_from_user(self, num, prefix): try: return str_to_int(num) except ValueError: try: if num.startswith(prefix): return getattr(self.ofproto, num.upper()) else: return getattr(self.ofproto, prefix + num.upper()) except AttributeError: LOG.warning( "Cannot convert argument to reserved number: %s", num) return num def _reserved_num_to_user(self, num, prefix): for k, v in self.ofproto.__dict__.items(): if k not in self.deprecated_value and \ k.startswith(prefix) and v == num: return k.replace(prefix, '') return num def ofp_port_features_from_user(self, act): return self._reserved_num_from_user(act, 'OFPPF_') def ofp_port_features_to_user(self, act): return self._reserved_num_to_user(act, 'OFPPF_') def ofp_port_mod_prop_type_from_user(self, act): return self._reserved_num_from_user(act, 'OFPPMPT_') def ofp_port_mod_prop_type_to_user(self, act): return self._reserved_num_to_user(act, 'OFPPMPT_') def ofp_port_desc_prop_type_from_user(self, act): return self._reserved_num_from_user(act, 'OFPPDPT_') def ofp_port_desc_prop_type_to_user(self, act): return self._reserved_num_to_user(act, 'OFPPDPT_') def ofp_action_type_from_user(self, act): return self._reserved_num_from_user(act, 'OFPAT_') def ofp_action_type_to_user(self, act): return self._reserved_num_to_user(act, 'OFPAT_') def ofp_instruction_type_from_user(self, act): return self._reserved_num_from_user(act, 'OFPIT_') def ofp_instruction_type_to_user(self, act): return self._reserved_num_to_user(act, 'OFPIT_') def ofp_group_type_from_user(self, act): return self._reserved_num_from_user(act, 'OFPGT_') def ofp_group_type_to_user(self, act): return self._reserved_num_to_user(act, 'OFPGT_') def ofp_meter_band_type_from_user(self, act): return self._reserved_num_from_user(act, 'OFPMBT_') def ofp_meter_band_type_to_user(self, act): return self._reserved_num_to_user(act, 'OFPMBT_') def ofp_table_feature_prop_type_from_user(self, act): return self._reserved_num_from_user(act, 'OFPTFPT_') def ofp_table_feature_prop_type_to_user(self, act): return self._reserved_num_to_user(act, 'OFPTFPT_') def ofp_port_stats_prop_type_from_user(self, act): return self._reserved_num_from_user(act, 'OFPPSPT_') def ofp_port_stats_prop_type_to_user(self, act): return self._reserved_num_to_user(act, 'OFPPSPT_') def ofp_queue_desc_prop_type_from_user(self, act): return self._reserved_num_from_user(act, 'OFPQDPT_') def ofp_queue_desc_prop_type_to_user(self, act): return self._reserved_num_to_user(act, 'OFPQDPT_') def ofp_queue_stats_prop_type_from_user(self, act): return self._reserved_num_from_user(act, 'OFPQSPT_') def ofp_queue_stats_prop_type_to_user(self, act): return self._reserved_num_to_user(act, 'OFPQSPT_') def ofp_meter_flags_from_user(self, act): return self._reserved_num_from_user(act, 'OFPMF_') def ofp_meter_flags_to_user(self, act): return self._reserved_num_to_user(act, 'OFPMF_') def ofp_port_from_user(self, port): return self._reserved_num_from_user(port, 'OFPP_') def ofp_port_to_user(self, port): return self._reserved_num_to_user(port, 'OFPP_') def ofp_table_from_user(self, table): return self._reserved_num_from_user(table, 'OFPTT_') def ofp_table_to_user(self, table): return self._reserved_num_to_user(table, 'OFPTT_') def ofp_cml_from_user(self, max_len): return self._reserved_num_from_user(max_len, 'OFPCML_') def ofp_cml_to_user(self, max_len): return self._reserved_num_to_user(max_len, 'OFPCML_') def ofp_group_from_user(self, group): return self._reserved_num_from_user(group, 'OFPG_') def ofp_group_to_user(self, group): return self._reserved_num_to_user(group, 'OFPG_') def ofp_group_capabilities_from_user(self, group): return self._reserved_num_from_user(group, 'OFPGFC_') def ofp_group_capabilities_to_user(self, group): return self._reserved_num_to_user(group, 'OFPGFC_') def ofp_group_bucket_prop_type_from_user(self, group): return self._reserved_num_from_user(group, 'OFPGBPT_') def ofp_group_bucket_prop_type_to_user(self, group): return self._reserved_num_to_user(group, 'OFPGBPT_') def ofp_buffer_from_user(self, buffer): if buffer in ['OFP_NO_BUFFER', 'NO_BUFFER']: return self.ofproto.OFP_NO_BUFFER else: return buffer def ofp_buffer_to_user(self, buffer): if self.ofproto.OFP_NO_BUFFER == buffer: return 'NO_BUFFER' else: return buffer def ofp_meter_from_user(self, meter): return self._reserved_num_from_user(meter, 'OFPM_') def ofp_meter_to_user(self, meter): return self._reserved_num_to_user(meter, 'OFPM_') def ofp_queue_from_user(self, queue): return self._reserved_num_from_user(queue, 'OFPQ_') def ofp_queue_to_user(self, queue): return self._reserved_num_to_user(queue, 'OFPQ_') def ofp_role_from_user(self, role): return self._reserved_num_from_user(role, 'OFPCR_ROLE_') def ofp_role_to_user(self, role): return self._reserved_num_to_user(role, 'OFPCR_ROLE_') ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/ofctl_v1_0.py0000664000175000017500000004472200000000000017354 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone 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. import struct import socket import logging from os_ken.ofproto import ofproto_v1_0 from os_ken.lib import ofctl_utils from os_ken.lib.mac import haddr_to_bin, haddr_to_str LOG = logging.getLogger('os_ken.lib.ofctl_v1_0') DEFAULT_TIMEOUT = 1.0 # TODO:XXX UTIL = ofctl_utils.OFCtlUtil(ofproto_v1_0) str_to_int = ofctl_utils.str_to_int def to_actions(dp, acts): actions = [] for a in acts: action_type = a.get('type') if action_type == 'OUTPUT': port = UTIL.ofp_port_from_user( a.get('port', ofproto_v1_0.OFPP_NONE)) # NOTE: The reason of this magic number (0xffe5) # is because there is no good constant in of1.0. # The same value as OFPCML_MAX of of1.2 and of1.3 is used. max_len = str_to_int(a.get('max_len', 0xffe5)) actions.append(dp.ofproto_parser.OFPActionOutput(port, max_len)) elif action_type == 'SET_VLAN_VID': vlan_vid = str_to_int(a.get('vlan_vid', 0xffff)) actions.append(dp.ofproto_parser.OFPActionVlanVid(vlan_vid)) elif action_type == 'SET_VLAN_PCP': vlan_pcp = str_to_int(a.get('vlan_pcp', 0)) actions.append(dp.ofproto_parser.OFPActionVlanPcp(vlan_pcp)) elif action_type == 'STRIP_VLAN': actions.append(dp.ofproto_parser.OFPActionStripVlan()) elif action_type == 'SET_DL_SRC': dl_src = haddr_to_bin(a.get('dl_src')) actions.append(dp.ofproto_parser.OFPActionSetDlSrc(dl_src)) elif action_type == 'SET_DL_DST': dl_dst = haddr_to_bin(a.get('dl_dst')) actions.append(dp.ofproto_parser.OFPActionSetDlDst(dl_dst)) elif action_type == 'SET_NW_SRC': nw_src = ipv4_to_int(a.get('nw_src')) actions.append(dp.ofproto_parser.OFPActionSetNwSrc(nw_src)) elif action_type == 'SET_NW_DST': nw_dst = ipv4_to_int(a.get('nw_dst')) actions.append(dp.ofproto_parser.OFPActionSetNwDst(nw_dst)) elif action_type == 'SET_NW_TOS': nw_tos = str_to_int(a.get('nw_tos', 0)) actions.append(dp.ofproto_parser.OFPActionSetNwTos(nw_tos)) elif action_type == 'SET_TP_SRC': tp_src = str_to_int(a.get('tp_src', 0)) actions.append(dp.ofproto_parser.OFPActionSetTpSrc(tp_src)) elif action_type == 'SET_TP_DST': tp_dst = str_to_int(a.get('tp_dst', 0)) actions.append(dp.ofproto_parser.OFPActionSetTpDst(tp_dst)) elif action_type == 'ENQUEUE': port = UTIL.ofp_port_from_user( a.get('port', ofproto_v1_0.OFPP_NONE)) queue_id = UTIL.ofp_queue_from_user(a.get('queue_id', 0)) actions.append(dp.ofproto_parser.OFPActionEnqueue(port, queue_id)) else: LOG.error('Unknown action type') return actions def actions_to_str(acts): actions = [] for a in acts: action_type = a.cls_action_type if action_type == ofproto_v1_0.OFPAT_OUTPUT: port = UTIL.ofp_port_to_user(a.port) buf = 'OUTPUT:' + str(port) elif action_type == ofproto_v1_0.OFPAT_SET_VLAN_VID: buf = 'SET_VLAN_VID:' + str(a.vlan_vid) elif action_type == ofproto_v1_0.OFPAT_SET_VLAN_PCP: buf = 'SET_VLAN_PCP:' + str(a.vlan_pcp) elif action_type == ofproto_v1_0.OFPAT_STRIP_VLAN: buf = 'STRIP_VLAN' elif action_type == ofproto_v1_0.OFPAT_SET_DL_SRC: buf = 'SET_DL_SRC:' + haddr_to_str(a.dl_addr) elif action_type == ofproto_v1_0.OFPAT_SET_DL_DST: buf = 'SET_DL_DST:' + haddr_to_str(a.dl_addr) elif action_type == ofproto_v1_0.OFPAT_SET_NW_SRC: buf = 'SET_NW_SRC:' + \ socket.inet_ntoa(struct.pack('!I', a.nw_addr)) elif action_type == ofproto_v1_0.OFPAT_SET_NW_DST: buf = 'SET_NW_DST:' + \ socket.inet_ntoa(struct.pack('!I', a.nw_addr)) elif action_type == ofproto_v1_0.OFPAT_SET_NW_TOS: buf = 'SET_NW_TOS:' + str(a.tos) elif action_type == ofproto_v1_0.OFPAT_SET_TP_SRC: buf = 'SET_TP_SRC:' + str(a.tp) elif action_type == ofproto_v1_0.OFPAT_SET_TP_DST: buf = 'SET_TP_DST:' + str(a.tp) elif action_type == ofproto_v1_0.OFPAT_ENQUEUE: port = UTIL.ofp_port_to_user(a.port) queue = UTIL.ofp_queue_to_user(a.queue_id) buf = 'ENQUEUE:' + str(port) + ":" + str(queue) elif action_type == ofproto_v1_0.OFPAT_VENDOR: buf = 'VENDOR' else: buf = 'UNKNOWN' actions.append(buf) return actions def ipv4_to_int(addr): ip = addr.split('.') assert len(ip) == 4 i = 0 for b in ip: b = int(b) i = (i << 8) | b return i def to_match(dp, attrs): ofp = dp.ofproto wildcards = ofp.OFPFW_ALL in_port = 0 dl_src = 0 dl_dst = 0 dl_vlan = 0 dl_vlan_pcp = 0 dl_type = 0 nw_tos = 0 nw_proto = 0 nw_src = 0 nw_dst = 0 tp_src = 0 tp_dst = 0 for key, value in attrs.items(): if key == 'in_port': in_port = UTIL.ofp_port_from_user(value) wildcards &= ~ofp.OFPFW_IN_PORT elif key == 'dl_src': dl_src = haddr_to_bin(value) wildcards &= ~ofp.OFPFW_DL_SRC elif key == 'dl_dst': dl_dst = haddr_to_bin(value) wildcards &= ~ofp.OFPFW_DL_DST elif key == 'dl_vlan': dl_vlan = str_to_int(value) wildcards &= ~ofp.OFPFW_DL_VLAN elif key == 'dl_vlan_pcp': dl_vlan_pcp = str_to_int(value) wildcards &= ~ofp.OFPFW_DL_VLAN_PCP elif key == 'dl_type': dl_type = str_to_int(value) wildcards &= ~ofp.OFPFW_DL_TYPE elif key == 'nw_tos': nw_tos = str_to_int(value) wildcards &= ~ofp.OFPFW_NW_TOS elif key == 'nw_proto': nw_proto = str_to_int(value) wildcards &= ~ofp.OFPFW_NW_PROTO elif key == 'nw_src': ip = value.split('/') nw_src = struct.unpack('!I', socket.inet_aton(ip[0]))[0] mask = 32 if len(ip) == 2: mask = int(ip[1]) assert 0 < mask <= 32 v = (32 - mask) << ofp.OFPFW_NW_SRC_SHIFT | \ ~ofp.OFPFW_NW_SRC_MASK wildcards &= v elif key == 'nw_dst': ip = value.split('/') nw_dst = struct.unpack('!I', socket.inet_aton(ip[0]))[0] mask = 32 if len(ip) == 2: mask = int(ip[1]) assert 0 < mask <= 32 v = (32 - mask) << ofp.OFPFW_NW_DST_SHIFT | \ ~ofp.OFPFW_NW_DST_MASK wildcards &= v elif key == 'tp_src': tp_src = str_to_int(value) wildcards &= ~ofp.OFPFW_TP_SRC elif key == 'tp_dst': tp_dst = str_to_int(value) wildcards &= ~ofp.OFPFW_TP_DST else: LOG.error("unknown match name %s, %s, %d", key, value, len(key)) match = dp.ofproto_parser.OFPMatch( wildcards, in_port, dl_src, dl_dst, dl_vlan, dl_vlan_pcp, dl_type, nw_tos, nw_proto, nw_src, nw_dst, tp_src, tp_dst) return match def match_to_str(m): match = {} if ~m.wildcards & ofproto_v1_0.OFPFW_IN_PORT: match['in_port'] = UTIL.ofp_port_to_user(m.in_port) if ~m.wildcards & ofproto_v1_0.OFPFW_DL_SRC: match['dl_src'] = haddr_to_str(m.dl_src) if ~m.wildcards & ofproto_v1_0.OFPFW_DL_DST: match['dl_dst'] = haddr_to_str(m.dl_dst) if ~m.wildcards & ofproto_v1_0.OFPFW_DL_VLAN: match['dl_vlan'] = m.dl_vlan if ~m.wildcards & ofproto_v1_0.OFPFW_DL_VLAN_PCP: match['dl_vlan_pcp'] = m.dl_vlan_pcp if ~m.wildcards & ofproto_v1_0.OFPFW_DL_TYPE: match['dl_type'] = m.dl_type if ~m.wildcards & ofproto_v1_0.OFPFW_NW_TOS: match['nw_tos'] = m.nw_tos if ~m.wildcards & ofproto_v1_0.OFPFW_NW_PROTO: match['nw_proto'] = m.nw_proto if ~m.wildcards & ofproto_v1_0.OFPFW_NW_SRC_ALL: match['nw_src'] = nw_src_to_str(m.wildcards, m.nw_src) if ~m.wildcards & ofproto_v1_0.OFPFW_NW_DST_ALL: match['nw_dst'] = nw_dst_to_str(m.wildcards, m.nw_dst) if ~m.wildcards & ofproto_v1_0.OFPFW_TP_SRC: match['tp_src'] = m.tp_src if ~m.wildcards & ofproto_v1_0.OFPFW_TP_DST: match['tp_dst'] = m.tp_dst return match def nw_src_to_str(wildcards, addr): ip = socket.inet_ntoa(struct.pack('!I', addr)) mask = 32 - ((wildcards & ofproto_v1_0.OFPFW_NW_SRC_MASK) >> ofproto_v1_0.OFPFW_NW_SRC_SHIFT) if mask == 32: mask = 0 if mask: ip += '/%d' % mask return ip def nw_dst_to_str(wildcards, addr): ip = socket.inet_ntoa(struct.pack('!I', addr)) mask = 32 - ((wildcards & ofproto_v1_0.OFPFW_NW_DST_MASK) >> ofproto_v1_0.OFPFW_NW_DST_SHIFT) if mask == 32: mask = 0 if mask: ip += '/%d' % mask return ip def get_desc_stats(dp, waiters): stats = dp.ofproto_parser.OFPDescStatsRequest(dp, 0) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) s = {} for msg in msgs: stats = msg.body s = stats.to_jsondict()[stats.__class__.__name__] return {str(dp.id): s} def get_queue_stats(dp, waiters, port=None, queue_id=None): if port is None: port = dp.ofproto.OFPP_ALL else: port = str_to_int(port) if queue_id is None: queue_id = dp.ofproto.OFPQ_ALL else: queue_id = str_to_int(queue_id) stats = dp.ofproto_parser.OFPQueueStatsRequest(dp, 0, port, queue_id) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) s = [] for msg in msgs: stats = msg.body for stat in stats: s.append({'port_no': stat.port_no, 'queue_id': stat.queue_id, 'tx_bytes': stat.tx_bytes, 'tx_errors': stat.tx_errors, 'tx_packets': stat.tx_packets}) return {str(dp.id): s} def get_flow_stats(dp, waiters, flow=None): flow = flow if flow else {} match = to_match(dp, flow.get('match', {})) table_id = UTIL.ofp_table_from_user( flow.get('table_id', 0xff)) out_port = UTIL.ofp_port_from_user( flow.get('out_port', dp.ofproto.OFPP_NONE)) # Note: OpenFlow does not allow to filter flow entries by priority, # but for efficiency, ofctl provides the way to do it. priority = str_to_int(flow.get('priority', -1)) stats = dp.ofproto_parser.OFPFlowStatsRequest( dp, 0, match, table_id, out_port) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) flows = [] for msg in msgs: for stats in msg.body: if 0 <= priority != stats.priority: continue actions = actions_to_str(stats.actions) match = match_to_str(stats.match) s = {'priority': stats.priority, 'cookie': stats.cookie, 'idle_timeout': stats.idle_timeout, 'hard_timeout': stats.hard_timeout, 'actions': actions, 'match': match, 'byte_count': stats.byte_count, 'duration_sec': stats.duration_sec, 'duration_nsec': stats.duration_nsec, 'packet_count': stats.packet_count, 'table_id': UTIL.ofp_table_to_user(stats.table_id)} flows.append(s) return {str(dp.id): flows} def get_aggregate_flow_stats(dp, waiters, flow=None): flow = flow if flow else {} match = to_match(dp, flow.get('match', {})) table_id = UTIL.ofp_table_from_user( flow.get('table_id', 0xff)) out_port = UTIL.ofp_port_from_user( flow.get('out_port', dp.ofproto.OFPP_NONE)) stats = dp.ofproto_parser.OFPAggregateStatsRequest( dp, 0, match, table_id, out_port) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) flows = [] for msg in msgs: stats = msg.body for st in stats: s = {'packet_count': st.packet_count, 'byte_count': st.byte_count, 'flow_count': st.flow_count} flows.append(s) return {str(dp.id): flows} def get_table_stats(dp, waiters): stats = dp.ofproto_parser.OFPTableStatsRequest(dp, 0) ofp = dp.ofproto msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) match_convert = {ofp.OFPFW_IN_PORT: 'IN_PORT', ofp.OFPFW_DL_VLAN: 'DL_VLAN', ofp.OFPFW_DL_SRC: 'DL_SRC', ofp.OFPFW_DL_DST: 'DL_DST', ofp.OFPFW_DL_TYPE: 'DL_TYPE', ofp.OFPFW_NW_PROTO: 'NW_PROTO', ofp.OFPFW_TP_SRC: 'TP_SRC', ofp.OFPFW_TP_DST: 'TP_DST', ofp.OFPFW_NW_SRC_SHIFT: 'NW_SRC_SHIFT', ofp.OFPFW_NW_SRC_BITS: 'NW_SRC_BITS', ofp.OFPFW_NW_SRC_MASK: 'NW_SRC_MASK', ofp.OFPFW_NW_SRC: 'NW_SRC', ofp.OFPFW_NW_SRC_ALL: 'NW_SRC_ALL', ofp.OFPFW_NW_DST_SHIFT: 'NW_DST_SHIFT', ofp.OFPFW_NW_DST_BITS: 'NW_DST_BITS', ofp.OFPFW_NW_DST_MASK: 'NW_DST_MASK', ofp.OFPFW_NW_DST: 'NW_DST', ofp.OFPFW_NW_DST_ALL: 'NW_DST_ALL', ofp.OFPFW_DL_VLAN_PCP: 'DL_VLAN_PCP', ofp.OFPFW_NW_TOS: 'NW_TOS', ofp.OFPFW_ALL: 'ALL', ofp.OFPFW_ICMP_TYPE: 'ICMP_TYPE', ofp.OFPFW_ICMP_CODE: 'ICMP_CODE'} tables = [] for msg in msgs: stats = msg.body for stat in stats: wildcards = [] for k, v in match_convert.items(): if (1 << k) & stat.wildcards: wildcards.append(v) s = {'table_id': UTIL.ofp_table_to_user(stat.table_id), 'name': stat.name.decode('utf-8'), 'wildcards': wildcards, 'max_entries': stat.max_entries, 'active_count': stat.active_count, 'lookup_count': stat.lookup_count, 'matched_count': stat.matched_count} tables.append(s) return {str(dp.id): tables} def get_port_stats(dp, waiters, port=None): if port is None: port = dp.ofproto.OFPP_NONE else: port = str_to_int(port) stats = dp.ofproto_parser.OFPPortStatsRequest( dp, 0, port) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) ports = [] for msg in msgs: for stats in msg.body: s = {'port_no': UTIL.ofp_port_to_user(stats.port_no), 'rx_packets': stats.rx_packets, 'tx_packets': stats.tx_packets, 'rx_bytes': stats.rx_bytes, 'tx_bytes': stats.tx_bytes, 'rx_dropped': stats.rx_dropped, 'tx_dropped': stats.tx_dropped, 'rx_errors': stats.rx_errors, 'tx_errors': stats.tx_errors, 'rx_frame_err': stats.rx_frame_err, 'rx_over_err': stats.rx_over_err, 'rx_crc_err': stats.rx_crc_err, 'collisions': stats.collisions} ports.append(s) return {str(dp.id): ports} def get_port_desc(dp, waiters): stats = dp.ofproto_parser.OFPFeaturesRequest(dp) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) descs = [] for msg in msgs: stats = msg.ports for stat in stats.values(): d = {'port_no': UTIL.ofp_port_to_user(stat.port_no), 'hw_addr': stat.hw_addr, 'name': stat.name.decode('utf-8'), 'config': stat.config, 'state': stat.state, 'curr': stat.curr, 'advertised': stat.advertised, 'supported': stat.supported, 'peer': stat.peer} descs.append(d) return {str(dp.id): descs} def mod_flow_entry(dp, flow, cmd): cookie = str_to_int(flow.get('cookie', 0)) priority = str_to_int( flow.get('priority', dp.ofproto.OFP_DEFAULT_PRIORITY)) buffer_id = UTIL.ofp_buffer_from_user( flow.get('buffer_id', dp.ofproto.OFP_NO_BUFFER)) out_port = UTIL.ofp_port_from_user( flow.get('out_port', dp.ofproto.OFPP_NONE)) flags = str_to_int(flow.get('flags', 0)) idle_timeout = str_to_int(flow.get('idle_timeout', 0)) hard_timeout = str_to_int(flow.get('hard_timeout', 0)) actions = to_actions(dp, flow.get('actions', [])) match = to_match(dp, flow.get('match', {})) flow_mod = dp.ofproto_parser.OFPFlowMod( datapath=dp, match=match, cookie=cookie, command=cmd, idle_timeout=idle_timeout, hard_timeout=hard_timeout, priority=priority, buffer_id=buffer_id, out_port=out_port, flags=flags, actions=actions) ofctl_utils.send_msg(dp, flow_mod, LOG) def delete_flow_entry(dp): match = dp.ofproto_parser.OFPMatch( dp.ofproto.OFPFW_ALL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) flow_mod = dp.ofproto_parser.OFPFlowMod( datapath=dp, match=match, cookie=0, command=dp.ofproto.OFPFC_DELETE) ofctl_utils.send_msg(dp, flow_mod, LOG) def mod_port_behavior(dp, port_config): port_no = UTIL.ofp_port_from_user(port_config.get('port_no', 0)) hw_addr = str(port_config.get('hw_addr')) config = str_to_int(port_config.get('config', 0)) mask = str_to_int(port_config.get('mask', 0)) advertise = str_to_int(port_config.get('advertise')) port_mod = dp.ofproto_parser.OFPPortMod( dp, port_no, hw_addr, config, mask, advertise) ofctl_utils.send_msg(dp, port_mod, LOG) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/ofctl_v1_2.py0000664000175000017500000007614700000000000017364 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone 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. import logging import netaddr from os_ken.ofproto import ether from os_ken.ofproto import inet from os_ken.ofproto import ofproto_v1_2 from os_ken.ofproto import ofproto_v1_2_parser from os_ken.lib import ofctl_utils LOG = logging.getLogger('os_ken.lib.ofctl_v1_2') DEFAULT_TIMEOUT = 1.0 UTIL = ofctl_utils.OFCtlUtil(ofproto_v1_2) str_to_int = ofctl_utils.str_to_int def to_action(dp, dic): ofp = dp.ofproto parser = dp.ofproto_parser action_type = dic.get('type') return ofctl_utils.to_action(dic, ofp, parser, action_type, UTIL) def to_actions(dp, acts): inst = [] actions = [] ofp = dp.ofproto parser = dp.ofproto_parser for a in acts: action = to_action(dp, a) if action is not None: actions.append(action) else: action_type = a.get('type') if action_type == 'WRITE_ACTIONS': write_actions = [] write_acts = a.get('actions') for act in write_acts: action = to_action(dp, act) if action is not None: write_actions.append(action) else: LOG.error('Unknown action type: %s', action_type) if write_actions: inst.append( parser.OFPInstructionActions(ofp.OFPIT_WRITE_ACTIONS, write_actions)) elif action_type == 'CLEAR_ACTIONS': inst.append( parser.OFPInstructionActions(ofp.OFPIT_CLEAR_ACTIONS, [])) elif action_type == 'GOTO_TABLE': table_id = UTIL.ofp_table_from_user(a.get('table_id')) inst.append(parser.OFPInstructionGotoTable(table_id)) elif action_type == 'WRITE_METADATA': metadata = str_to_int(a.get('metadata')) metadata_mask = (str_to_int(a['metadata_mask']) if 'metadata_mask' in a else parser.UINT64_MAX) inst.append( parser.OFPInstructionWriteMetadata( metadata, metadata_mask)) else: LOG.error('Unknown action type: %s', action_type) if actions: inst.append(parser.OFPInstructionActions(ofp.OFPIT_APPLY_ACTIONS, actions)) return inst def action_to_str(act): action_type = act.cls_action_type if action_type == ofproto_v1_2.OFPAT_OUTPUT: port = UTIL.ofp_port_to_user(act.port) buf = 'OUTPUT:' + str(port) elif action_type == ofproto_v1_2.OFPAT_COPY_TTL_OUT: buf = 'COPY_TTL_OUT' elif action_type == ofproto_v1_2.OFPAT_COPY_TTL_IN: buf = 'COPY_TTL_IN' elif action_type == ofproto_v1_2.OFPAT_SET_MPLS_TTL: buf = 'SET_MPLS_TTL:' + str(act.mpls_ttl) elif action_type == ofproto_v1_2.OFPAT_DEC_MPLS_TTL: buf = 'DEC_MPLS_TTL' elif action_type == ofproto_v1_2.OFPAT_PUSH_VLAN: buf = 'PUSH_VLAN:' + str(act.ethertype) elif action_type == ofproto_v1_2.OFPAT_POP_VLAN: buf = 'POP_VLAN' elif action_type == ofproto_v1_2.OFPAT_PUSH_MPLS: buf = 'PUSH_MPLS:' + str(act.ethertype) elif action_type == ofproto_v1_2.OFPAT_POP_MPLS: buf = 'POP_MPLS:' + str(act.ethertype) elif action_type == ofproto_v1_2.OFPAT_SET_QUEUE: queue_id = UTIL.ofp_queue_to_user(act.queue_id) buf = 'SET_QUEUE:' + str(queue_id) elif action_type == ofproto_v1_2.OFPAT_GROUP: group_id = UTIL.ofp_group_to_user(act.group_id) buf = 'GROUP:' + str(group_id) elif action_type == ofproto_v1_2.OFPAT_SET_NW_TTL: buf = 'SET_NW_TTL:' + str(act.nw_ttl) elif action_type == ofproto_v1_2.OFPAT_DEC_NW_TTL: buf = 'DEC_NW_TTL' elif action_type == ofproto_v1_2.OFPAT_SET_FIELD: buf = 'SET_FIELD: {%s:%s}' % (act.key, act.value) else: buf = 'UNKNOWN' return buf def actions_to_str(instructions): actions = [] for instruction in instructions: if isinstance(instruction, ofproto_v1_2_parser.OFPInstructionActions): if instruction.type == ofproto_v1_2.OFPIT_APPLY_ACTIONS: for a in instruction.actions: actions.append(action_to_str(a)) elif instruction.type == ofproto_v1_2.OFPIT_WRITE_ACTIONS: write_actions = [] for a in instruction.actions: write_actions.append(action_to_str(a)) if write_actions: actions.append({'WRITE_ACTIONS': write_actions}) elif instruction.type == ofproto_v1_2.OFPIT_CLEAR_ACTIONS: actions.append('CLEAR_ACTIONS') else: actions.append('UNKNOWN') elif isinstance(instruction, ofproto_v1_2_parser.OFPInstructionGotoTable): table_id = UTIL.ofp_table_to_user(instruction.table_id) buf = 'GOTO_TABLE:' + str(table_id) actions.append(buf) elif isinstance(instruction, ofproto_v1_2_parser.OFPInstructionWriteMetadata): buf = ('WRITE_METADATA:0x%x/0x%x' % (instruction.metadata, instruction.metadata_mask) if instruction.metadata_mask else 'WRITE_METADATA:0x%x' % instruction.metadata) actions.append(buf) else: continue return actions def to_match(dp, attrs): convert = {'in_port': UTIL.ofp_port_from_user, 'in_phy_port': str_to_int, 'metadata': ofctl_utils.to_match_masked_int, 'dl_dst': ofctl_utils.to_match_eth, 'dl_src': ofctl_utils.to_match_eth, 'eth_dst': ofctl_utils.to_match_eth, 'eth_src': ofctl_utils.to_match_eth, 'dl_type': str_to_int, 'eth_type': str_to_int, 'dl_vlan': to_match_vid, 'vlan_vid': to_match_vid, 'vlan_pcp': str_to_int, 'ip_dscp': str_to_int, 'ip_ecn': str_to_int, 'nw_proto': str_to_int, 'ip_proto': str_to_int, 'nw_src': ofctl_utils.to_match_ip, 'nw_dst': ofctl_utils.to_match_ip, 'ipv4_src': ofctl_utils.to_match_ip, 'ipv4_dst': ofctl_utils.to_match_ip, 'tp_src': str_to_int, 'tp_dst': str_to_int, 'tcp_src': str_to_int, 'tcp_dst': str_to_int, 'udp_src': str_to_int, 'udp_dst': str_to_int, 'sctp_src': str_to_int, 'sctp_dst': str_to_int, 'icmpv4_type': str_to_int, 'icmpv4_code': str_to_int, 'arp_op': str_to_int, 'arp_spa': ofctl_utils.to_match_ip, 'arp_tpa': ofctl_utils.to_match_ip, 'arp_sha': ofctl_utils.to_match_eth, 'arp_tha': ofctl_utils.to_match_eth, 'ipv6_src': ofctl_utils.to_match_ip, 'ipv6_dst': ofctl_utils.to_match_ip, 'ipv6_flabel': str_to_int, 'icmpv6_type': str_to_int, 'icmpv6_code': str_to_int, 'ipv6_nd_target': ofctl_utils.to_match_ip, 'ipv6_nd_sll': ofctl_utils.to_match_eth, 'ipv6_nd_tll': ofctl_utils.to_match_eth, 'mpls_label': str_to_int, 'mpls_tc': str_to_int} keys = {'dl_dst': 'eth_dst', 'dl_src': 'eth_src', 'dl_type': 'eth_type', 'dl_vlan': 'vlan_vid', 'nw_src': 'ipv4_src', 'nw_dst': 'ipv4_dst', 'nw_proto': 'ip_proto'} if attrs.get('dl_type') == ether.ETH_TYPE_ARP or \ attrs.get('eth_type') == ether.ETH_TYPE_ARP: if 'nw_src' in attrs and 'arp_spa' not in attrs: attrs['arp_spa'] = attrs['nw_src'] del attrs['nw_src'] if 'nw_dst' in attrs and 'arp_tpa' not in attrs: attrs['arp_tpa'] = attrs['nw_dst'] del attrs['nw_dst'] kwargs = {} for key, value in attrs.items(): if key in keys: # For old field name key = keys[key] if key in convert: value = convert[key](value) if key == 'tp_src' or key == 'tp_dst': # TCP/UDP port conv = {inet.IPPROTO_TCP: {'tp_src': 'tcp_src', 'tp_dst': 'tcp_dst'}, inet.IPPROTO_UDP: {'tp_src': 'udp_src', 'tp_dst': 'udp_dst'}} ip_proto = attrs.get('nw_proto', attrs.get('ip_proto', 0)) key = conv[ip_proto][key] kwargs[key] = value else: # others kwargs[key] = value else: LOG.error('Unknown match field: %s', key) return dp.ofproto_parser.OFPMatch(**kwargs) def to_match_vid(value): return ofctl_utils.to_match_vid(value, ofproto_v1_2.OFPVID_PRESENT) def match_to_str(ofmatch): keys = {'eth_src': 'dl_src', 'eth_dst': 'dl_dst', 'eth_type': 'dl_type', 'vlan_vid': 'dl_vlan', 'ipv4_src': 'nw_src', 'ipv4_dst': 'nw_dst', 'ip_proto': 'nw_proto', 'tcp_src': 'tp_src', 'tcp_dst': 'tp_dst', 'udp_src': 'tp_src', 'udp_dst': 'tp_dst'} match = {} ofmatch = ofmatch.to_jsondict()['OFPMatch'] ofmatch = ofmatch['oxm_fields'] for match_field in ofmatch: key = match_field['OXMTlv']['field'] if key in keys: key = keys[key] mask = match_field['OXMTlv']['mask'] value = match_field['OXMTlv']['value'] if key == 'dl_vlan': value = match_vid_to_str(value, mask) elif key == 'in_port': value = UTIL.ofp_port_to_user(value) else: if mask is not None: value = str(value) + '/' + str(mask) match.setdefault(key, value) return match def match_vid_to_str(value, mask): return ofctl_utils.match_vid_to_str( value, mask, ofproto_v1_2.OFPVID_PRESENT) def get_desc_stats(dp, waiters): stats = dp.ofproto_parser.OFPDescStatsRequest(dp) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) s = {} for msg in msgs: stats = msg.body s = stats.to_jsondict()[stats.__class__.__name__] return {str(dp.id): s} def get_queue_stats(dp, waiters, port=None, queue_id=None): ofp = dp.ofproto if port is None: port = ofp.OFPP_ANY else: port = str_to_int(port) if queue_id is None: queue_id = ofp.OFPQ_ALL else: queue_id = str_to_int(queue_id) stats = dp.ofproto_parser.OFPQueueStatsRequest(dp, port, queue_id, 0) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) s = [] for msg in msgs: stats = msg.body for stat in stats: s.append({'port_no': stat.port_no, 'queue_id': stat.queue_id, 'tx_bytes': stat.tx_bytes, 'tx_errors': stat.tx_errors, 'tx_packets': stat.tx_packets}) return {str(dp.id): s} def get_queue_config(dp, waiters, port=None): ofp = dp.ofproto if port is None: port = ofp.OFPP_ANY else: port = UTIL.ofp_port_from_user(str_to_int(port)) stats = dp.ofproto_parser.OFPQueueGetConfigRequest(dp, port) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) prop_type = { dp.ofproto.OFPQT_MIN_RATE: 'MIN_RATE', dp.ofproto.OFPQT_MAX_RATE: 'MAX_RATE', dp.ofproto.OFPQT_EXPERIMENTER: 'EXPERIMENTER', } configs = [] for config in msgs: queue_list = [] for queue in config.queues: prop_list = [] for prop in queue.properties: p = {'property': prop_type.get(prop.property, 'UNKNOWN')} if prop.property == dp.ofproto.OFPQT_MIN_RATE or \ prop.property == dp.ofproto.OFPQT_MAX_RATE: p['rate'] = prop.rate elif prop.property == dp.ofproto.OFPQT_EXPERIMENTER: p['experimenter'] = prop.experimenter p['data'] = prop.data prop_list.append(p) q = {'port': UTIL.ofp_port_to_user(queue.port), 'properties': prop_list, 'queue_id': UTIL.ofp_queue_to_user(queue.queue_id)} queue_list.append(q) c = {'port': UTIL.ofp_port_to_user(config.port), 'queues': queue_list} configs.append(c) return {str(dp.id): configs} def get_flow_stats(dp, waiters, flow=None): flow = flow if flow else {} table_id = UTIL.ofp_table_from_user( flow.get('table_id', dp.ofproto.OFPTT_ALL)) out_port = UTIL.ofp_port_from_user( flow.get('out_port', dp.ofproto.OFPP_ANY)) out_group = UTIL.ofp_group_from_user( flow.get('out_group', dp.ofproto.OFPG_ANY)) cookie = str_to_int(flow.get('cookie', 0)) cookie_mask = str_to_int(flow.get('cookie_mask', 0)) match = to_match(dp, flow.get('match', {})) # Note: OpenFlow does not allow to filter flow entries by priority, # but for efficiency, ofctl provides the way to do it. priority = str_to_int(flow.get('priority', -1)) stats = dp.ofproto_parser.OFPFlowStatsRequest( dp, table_id, out_port, out_group, cookie, cookie_mask, match) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) flows = [] for msg in msgs: for stats in msg.body: if 0 <= priority != stats.priority: continue actions = actions_to_str(stats.instructions) match = match_to_str(stats.match) s = {'priority': stats.priority, 'cookie': stats.cookie, 'idle_timeout': stats.idle_timeout, 'hard_timeout': stats.hard_timeout, 'actions': actions, 'match': match, 'byte_count': stats.byte_count, 'duration_sec': stats.duration_sec, 'duration_nsec': stats.duration_nsec, 'packet_count': stats.packet_count, 'table_id': UTIL.ofp_table_to_user(stats.table_id), 'length': stats.length} flows.append(s) return {str(dp.id): flows} def get_aggregate_flow_stats(dp, waiters, flow=None): flow = flow if flow else {} table_id = UTIL.ofp_table_from_user( flow.get('table_id', dp.ofproto.OFPTT_ALL)) out_port = UTIL.ofp_port_from_user( flow.get('out_port', dp.ofproto.OFPP_ANY)) out_group = UTIL.ofp_group_from_user( flow.get('out_group', dp.ofproto.OFPG_ANY)) cookie = str_to_int(flow.get('cookie', 0)) cookie_mask = str_to_int(flow.get('cookie_mask', 0)) match = to_match(dp, flow.get('match', {})) stats = dp.ofproto_parser.OFPAggregateStatsRequest( dp, table_id, out_port, out_group, cookie, cookie_mask, match) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) flows = [] for msg in msgs: stats = msg.body s = {'packet_count': stats.packet_count, 'byte_count': stats.byte_count, 'flow_count': stats.flow_count} flows.append(s) return {str(dp.id): flows} def get_table_stats(dp, waiters): stats = dp.ofproto_parser.OFPTableStatsRequest(dp) ofp = dp.ofproto msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) oxm_type_convert = {ofp.OFPXMT_OFB_IN_PORT: 'IN_PORT', ofp.OFPXMT_OFB_IN_PHY_PORT: 'IN_PHY_PORT', ofp.OFPXMT_OFB_METADATA: 'METADATA', ofp.OFPXMT_OFB_ETH_DST: 'ETH_DST', ofp.OFPXMT_OFB_ETH_SRC: 'ETH_SRC', ofp.OFPXMT_OFB_ETH_TYPE: 'ETH_TYPE', ofp.OFPXMT_OFB_VLAN_VID: 'VLAN_VID', ofp.OFPXMT_OFB_VLAN_PCP: 'VLAN_PCP', ofp.OFPXMT_OFB_IP_DSCP: 'IP_DSCP', ofp.OFPXMT_OFB_IP_ECN: 'IP_ECN', ofp.OFPXMT_OFB_IP_PROTO: 'IP_PROTO', ofp.OFPXMT_OFB_IPV4_SRC: 'IPV4_SRC', ofp.OFPXMT_OFB_IPV4_DST: 'IPV4_DST', ofp.OFPXMT_OFB_TCP_SRC: 'TCP_SRC', ofp.OFPXMT_OFB_TCP_DST: 'TCP_DST', ofp.OFPXMT_OFB_UDP_SRC: 'UDP_SRC', ofp.OFPXMT_OFB_UDP_DST: 'UDP_DST', ofp.OFPXMT_OFB_SCTP_SRC: 'SCTP_SRC', ofp.OFPXMT_OFB_SCTP_DST: 'SCTP_DST', ofp.OFPXMT_OFB_ICMPV4_TYPE: 'ICMPV4_TYPE', ofp.OFPXMT_OFB_ICMPV4_CODE: 'ICMPV4_CODE', ofp.OFPXMT_OFB_ARP_OP: 'ARP_OP', ofp.OFPXMT_OFB_ARP_SPA: 'ARP_SPA', ofp.OFPXMT_OFB_ARP_TPA: 'ARP_TPA', ofp.OFPXMT_OFB_ARP_SHA: 'ARP_SHA', ofp.OFPXMT_OFB_ARP_THA: 'ARP_THA', ofp.OFPXMT_OFB_IPV6_SRC: 'IPV6_SRC', ofp.OFPXMT_OFB_IPV6_DST: 'IPV6_DST', ofp.OFPXMT_OFB_IPV6_FLABEL: 'IPV6_FLABEL', ofp.OFPXMT_OFB_ICMPV6_TYPE: 'ICMPV6_TYPE', ofp.OFPXMT_OFB_ICMPV6_CODE: 'ICMPV6_CODE', ofp.OFPXMT_OFB_IPV6_ND_TARGET: 'IPV6_ND_TARGET', ofp.OFPXMT_OFB_IPV6_ND_SLL: 'IPV6_ND_SLL', ofp.OFPXMT_OFB_IPV6_ND_TLL: 'IPV6_ND_TLL', ofp.OFPXMT_OFB_MPLS_LABEL: 'MPLS_LABEL', ofp.OFPXMT_OFB_MPLS_TC: 'MPLS_TC'} act_convert = {ofp.OFPAT_OUTPUT: 'OUTPUT', ofp.OFPAT_COPY_TTL_OUT: 'COPY_TTL_OUT', ofp.OFPAT_COPY_TTL_IN: 'COPY_TTL_IN', ofp.OFPAT_SET_MPLS_TTL: 'SET_MPLS_TTL', ofp.OFPAT_DEC_MPLS_TTL: 'DEC_MPLS_TTL', ofp.OFPAT_PUSH_VLAN: 'PUSH_VLAN', ofp.OFPAT_POP_VLAN: 'POP_VLAN', ofp.OFPAT_PUSH_MPLS: 'PUSH_MPLS', ofp.OFPAT_POP_MPLS: 'POP_MPLS', ofp.OFPAT_SET_QUEUE: 'SET_QUEUE', ofp.OFPAT_GROUP: 'GROUP', ofp.OFPAT_SET_NW_TTL: 'SET_NW_TTL', ofp.OFPAT_DEC_NW_TTL: 'DEC_NW_TTL', ofp.OFPAT_SET_FIELD: 'SET_FIELD'} inst_convert = {ofp.OFPIT_GOTO_TABLE: 'GOTO_TABLE', ofp.OFPIT_WRITE_METADATA: 'WRITE_METADATA', ofp.OFPIT_WRITE_ACTIONS: 'WRITE_ACTIONS', ofp.OFPIT_APPLY_ACTIONS: 'APPLY_ACTIONS', ofp.OFPIT_CLEAR_ACTIONS: 'CLEAR_ACTIONS', ofp.OFPIT_EXPERIMENTER: 'EXPERIMENTER'} table_conf_convert = { ofp.OFPTC_TABLE_MISS_CONTROLLER: 'TABLE_MISS_CONTROLLER', ofp.OFPTC_TABLE_MISS_CONTINUE: 'TABLE_MISS_CONTINUE', ofp.OFPTC_TABLE_MISS_DROP: 'TABLE_MISS_DROP', ofp.OFPTC_TABLE_MISS_MASK: 'TABLE_MISS_MASK'} tables = [] for msg in msgs: stats = msg.body for stat in stats: match = [] wildcards = [] write_setfields = [] apply_setfields = [] for k, v in oxm_type_convert.items(): if (1 << k) & stat.match: match.append(v) if (1 << k) & stat.wildcards: wildcards.append(v) if (1 << k) & stat.write_setfields: write_setfields.append(v) if (1 << k) & stat.apply_setfields: apply_setfields.append(v) write_actions = [] apply_actions = [] for k, v in act_convert.items(): if (1 << k) & stat.write_actions: write_actions.append(v) if (1 << k) & stat.apply_actions: apply_actions.append(v) instructions = [] for k, v in inst_convert.items(): if (1 << k) & stat.instructions: instructions.append(v) config = [] for k, v in table_conf_convert.items(): if (1 << k) & stat.config: config.append(v) s = {'table_id': UTIL.ofp_table_to_user(stat.table_id), 'name': stat.name.decode('utf-8'), 'match': match, 'wildcards': wildcards, 'write_actions': write_actions, 'apply_actions': apply_actions, 'write_setfields': write_setfields, 'apply_setfields': apply_setfields, 'metadata_match': stat.metadata_match, 'metadata_write': stat.metadata_write, 'instructions': instructions, 'config': config, 'max_entries': stat.max_entries, 'active_count': stat.active_count, 'lookup_count': stat.lookup_count, 'matched_count': stat.matched_count} tables.append(s) return {str(dp.id): tables} def get_port_stats(dp, waiters, port=None): if port is None: port = dp.ofproto.OFPP_ANY else: port = str_to_int(port) stats = dp.ofproto_parser.OFPPortStatsRequest( dp, port, 0) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) ports = [] for msg in msgs: for stats in msg.body: s = {'port_no': UTIL.ofp_port_to_user(stats.port_no), 'rx_packets': stats.rx_packets, 'tx_packets': stats.tx_packets, 'rx_bytes': stats.rx_bytes, 'tx_bytes': stats.tx_bytes, 'rx_dropped': stats.rx_dropped, 'tx_dropped': stats.tx_dropped, 'rx_errors': stats.rx_errors, 'tx_errors': stats.tx_errors, 'rx_frame_err': stats.rx_frame_err, 'rx_over_err': stats.rx_over_err, 'rx_crc_err': stats.rx_crc_err, 'collisions': stats.collisions} ports.append(s) return {str(dp.id): ports} def get_group_stats(dp, waiters, group_id=None): if group_id is None: group_id = dp.ofproto.OFPG_ALL else: group_id = str_to_int(group_id) stats = dp.ofproto_parser.OFPGroupStatsRequest( dp, group_id, 0) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) groups = [] for msg in msgs: for stats in msg.body: bucket_counters = [] for bucket_counter in stats.bucket_counters: c = {'packet_count': bucket_counter.packet_count, 'byte_count': bucket_counter.byte_count} bucket_counters.append(c) g = {'length': stats.length, 'group_id': UTIL.ofp_group_to_user(stats.group_id), 'ref_count': stats.ref_count, 'packet_count': stats.packet_count, 'byte_count': stats.byte_count, 'bucket_stats': bucket_counters} groups.append(g) return {str(dp.id): groups} def get_group_features(dp, waiters): ofp = dp.ofproto type_convert = {ofp.OFPGT_ALL: 'ALL', ofp.OFPGT_SELECT: 'SELECT', ofp.OFPGT_INDIRECT: 'INDIRECT', ofp.OFPGT_FF: 'FF'} cap_convert = {ofp.OFPGFC_SELECT_WEIGHT: 'SELECT_WEIGHT', ofp.OFPGFC_SELECT_LIVENESS: 'SELECT_LIVENESS', ofp.OFPGFC_CHAINING: 'CHAINING', ofp.OFPGFC_CHAINING_CHECKS: 'CHAINING_CHECKS'} act_convert = {ofp.OFPAT_OUTPUT: 'OUTPUT', ofp.OFPAT_COPY_TTL_OUT: 'COPY_TTL_OUT', ofp.OFPAT_COPY_TTL_IN: 'COPY_TTL_IN', ofp.OFPAT_SET_MPLS_TTL: 'SET_MPLS_TTL', ofp.OFPAT_DEC_MPLS_TTL: 'DEC_MPLS_TTL', ofp.OFPAT_PUSH_VLAN: 'PUSH_VLAN', ofp.OFPAT_POP_VLAN: 'POP_VLAN', ofp.OFPAT_PUSH_MPLS: 'PUSH_MPLS', ofp.OFPAT_POP_MPLS: 'POP_MPLS', ofp.OFPAT_SET_QUEUE: 'SET_QUEUE', ofp.OFPAT_GROUP: 'GROUP', ofp.OFPAT_SET_NW_TTL: 'SET_NW_TTL', ofp.OFPAT_DEC_NW_TTL: 'DEC_NW_TTL', ofp.OFPAT_SET_FIELD: 'SET_FIELD'} stats = dp.ofproto_parser.OFPGroupFeaturesStatsRequest(dp, 0) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) features = [] for msg in msgs: feature = msg.body types = [] for k, v in type_convert.items(): if (1 << k) & feature.types: types.append(v) capabilities = [] for k, v in cap_convert.items(): if k & feature.capabilities: capabilities.append(v) max_groups = [] for k, v in type_convert.items(): max_groups.append({v: feature.max_groups[k]}) actions = [] for k1, v1 in type_convert.items(): acts = [] for k2, v2 in act_convert.items(): if (1 << k2) & feature.actions[k1]: acts.append(v2) actions.append({v1: acts}) f = {'types': types, 'capabilities': capabilities, 'max_groups': max_groups, 'actions': actions} features.append(f) return {str(dp.id): features} def get_group_desc(dp, waiters): type_convert = {dp.ofproto.OFPGT_ALL: 'ALL', dp.ofproto.OFPGT_SELECT: 'SELECT', dp.ofproto.OFPGT_INDIRECT: 'INDIRECT', dp.ofproto.OFPGT_FF: 'FF'} stats = dp.ofproto_parser.OFPGroupDescStatsRequest(dp, 0) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) descs = [] for msg in msgs: for stats in msg.body: buckets = [] for bucket in stats.buckets: actions = [] for action in bucket.actions: actions.append(action_to_str(action)) b = {'weight': bucket.weight, 'watch_port': bucket.watch_port, 'watch_group': bucket.watch_group, 'actions': actions} buckets.append(b) d = {'type': type_convert.get(stats.type), 'group_id': UTIL.ofp_group_to_user(stats.group_id), 'buckets': buckets} descs.append(d) return {str(dp.id): descs} def get_port_desc(dp, waiters): stats = dp.ofproto_parser.OFPFeaturesRequest(dp) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) descs = [] for msg in msgs: stats = msg.ports for stat in stats.values(): d = {'port_no': UTIL.ofp_port_to_user(stat.port_no), 'hw_addr': stat.hw_addr, 'name': stat.name.decode('utf-8'), 'config': stat.config, 'state': stat.state, 'curr': stat.curr, 'advertised': stat.advertised, 'supported': stat.supported, 'peer': stat.peer, 'curr_speed': stat.curr_speed, 'max_speed': stat.max_speed} descs.append(d) return {str(dp.id): descs} def get_role(dp, waiters, to_user=True): return ofctl_utils.get_role(dp, waiters, to_user) def mod_flow_entry(dp, flow, cmd): cookie = str_to_int(flow.get('cookie', 0)) cookie_mask = str_to_int(flow.get('cookie_mask', 0)) table_id = UTIL.ofp_table_from_user(flow.get('table_id', 0)) idle_timeout = str_to_int(flow.get('idle_timeout', 0)) hard_timeout = str_to_int(flow.get('hard_timeout', 0)) priority = str_to_int(flow.get('priority', 0)) buffer_id = UTIL.ofp_buffer_from_user( flow.get('buffer_id', dp.ofproto.OFP_NO_BUFFER)) out_port = UTIL.ofp_port_from_user( flow.get('out_port', dp.ofproto.OFPP_ANY)) out_group = UTIL.ofp_group_from_user( flow.get('out_group', dp.ofproto.OFPG_ANY)) flags = str_to_int(flow.get('flags', 0)) match = to_match(dp, flow.get('match', {})) inst = to_actions(dp, flow.get('actions', [])) flow_mod = dp.ofproto_parser.OFPFlowMod( dp, cookie, cookie_mask, table_id, cmd, idle_timeout, hard_timeout, priority, buffer_id, out_port, out_group, flags, match, inst) ofctl_utils.send_msg(dp, flow_mod, LOG) def mod_group_entry(dp, group, cmd): type_convert = {'ALL': dp.ofproto.OFPGT_ALL, 'SELECT': dp.ofproto.OFPGT_SELECT, 'INDIRECT': dp.ofproto.OFPGT_INDIRECT, 'FF': dp.ofproto.OFPGT_FF} type_ = type_convert.get(group.get('type', 'ALL')) if type_ is None: LOG.error('Unknown group type: %s', group.get('type')) group_id = UTIL.ofp_group_from_user(group.get('group_id', 0)) buckets = [] for bucket in group.get('buckets', []): weight = str_to_int(bucket.get('weight', 0)) watch_port = str_to_int( bucket.get('watch_port', dp.ofproto.OFPP_ANY)) watch_group = str_to_int( bucket.get('watch_group', dp.ofproto.OFPG_ANY)) actions = [] for dic in bucket.get('actions', []): action = to_action(dp, dic) if action is not None: actions.append(action) buckets.append(dp.ofproto_parser.OFPBucket( weight, watch_port, watch_group, actions)) group_mod = dp.ofproto_parser.OFPGroupMod( dp, cmd, type_, group_id, buckets) ofctl_utils.send_msg(dp, group_mod, LOG) def mod_port_behavior(dp, port_config): port_no = UTIL.ofp_port_from_user(port_config.get('port_no', 0)) hw_addr = str(port_config.get('hw_addr')) config = str_to_int(port_config.get('config', 0)) mask = str_to_int(port_config.get('mask', 0)) advertise = str_to_int(port_config.get('advertise')) port_mod = dp.ofproto_parser.OFPPortMod( dp, port_no, hw_addr, config, mask, advertise) ofctl_utils.send_msg(dp, port_mod, LOG) def set_role(dp, role): r = UTIL.ofp_role_from_user(role.get('role', dp.ofproto.OFPCR_ROLE_EQUAL)) role_request = dp.ofproto_parser.OFPRoleRequest(dp, r, 0) ofctl_utils.send_msg(dp, role_request, LOG) # NOTE(jkoelker) Alias common funcitons send_experimenter = ofctl_utils.send_experimenter ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/ofctl_v1_3.py0000664000175000017500000012036300000000000017353 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone 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. import base64 import logging from os_ken.ofproto import ether from os_ken.ofproto import inet from os_ken.ofproto import ofproto_common from os_ken.ofproto import ofproto_v1_3 from os_ken.ofproto import ofproto_v1_3_parser from os_ken.lib import ofctl_nicira_ext from os_ken.lib import ofctl_utils LOG = logging.getLogger('os_ken.lib.ofctl_v1_3') DEFAULT_TIMEOUT = 1.0 UTIL = ofctl_utils.OFCtlUtil(ofproto_v1_3) str_to_int = ofctl_utils.str_to_int def to_action(dp, dic): ofp = dp.ofproto parser = dp.ofproto_parser action_type = dic.get('type') return ofctl_utils.to_action(dic, ofp, parser, action_type, UTIL) def to_actions(dp, acts): inst = [] actions = [] ofp = dp.ofproto parser = dp.ofproto_parser for a in acts: action = to_action(dp, a) if action is not None: actions.append(action) else: action_type = a.get('type') if action_type == 'WRITE_ACTIONS': write_actions = [] write_acts = a.get('actions') for act in write_acts: action = to_action(dp, act) if action is not None: write_actions.append(action) else: LOG.error('Unknown action type: %s', action_type) if write_actions: inst.append( parser.OFPInstructionActions(ofp.OFPIT_WRITE_ACTIONS, write_actions)) elif action_type == 'CLEAR_ACTIONS': inst.append( parser.OFPInstructionActions(ofp.OFPIT_CLEAR_ACTIONS, [])) elif action_type == 'GOTO_TABLE': table_id = UTIL.ofp_table_from_user(a.get('table_id')) inst.append(parser.OFPInstructionGotoTable(table_id)) elif action_type == 'WRITE_METADATA': metadata = str_to_int(a.get('metadata')) metadata_mask = (str_to_int(a['metadata_mask']) if 'metadata_mask' in a else parser.UINT64_MAX) inst.append( parser.OFPInstructionWriteMetadata( metadata, metadata_mask)) elif action_type == 'METER': meter_id = UTIL.ofp_meter_from_user(a.get('meter_id')) inst.append(parser.OFPInstructionMeter(meter_id)) else: LOG.error('Unknown action type: %s', action_type) if actions: inst.append(parser.OFPInstructionActions(ofp.OFPIT_APPLY_ACTIONS, actions)) return inst def action_to_str(act): action_type = act.cls_action_type if action_type == ofproto_v1_3.OFPAT_OUTPUT: port = UTIL.ofp_port_to_user(act.port) buf = 'OUTPUT:' + str(port) elif action_type == ofproto_v1_3.OFPAT_COPY_TTL_OUT: buf = 'COPY_TTL_OUT' elif action_type == ofproto_v1_3.OFPAT_COPY_TTL_IN: buf = 'COPY_TTL_IN' elif action_type == ofproto_v1_3.OFPAT_SET_MPLS_TTL: buf = 'SET_MPLS_TTL:' + str(act.mpls_ttl) elif action_type == ofproto_v1_3.OFPAT_DEC_MPLS_TTL: buf = 'DEC_MPLS_TTL' elif action_type == ofproto_v1_3.OFPAT_PUSH_VLAN: buf = 'PUSH_VLAN:' + str(act.ethertype) elif action_type == ofproto_v1_3.OFPAT_POP_VLAN: buf = 'POP_VLAN' elif action_type == ofproto_v1_3.OFPAT_PUSH_MPLS: buf = 'PUSH_MPLS:' + str(act.ethertype) elif action_type == ofproto_v1_3.OFPAT_POP_MPLS: buf = 'POP_MPLS:' + str(act.ethertype) elif action_type == ofproto_v1_3.OFPAT_SET_QUEUE: queue_id = UTIL.ofp_queue_to_user(act.queue_id) buf = 'SET_QUEUE:' + str(queue_id) elif action_type == ofproto_v1_3.OFPAT_GROUP: group_id = UTIL.ofp_group_to_user(act.group_id) buf = 'GROUP:' + str(group_id) elif action_type == ofproto_v1_3.OFPAT_SET_NW_TTL: buf = 'SET_NW_TTL:' + str(act.nw_ttl) elif action_type == ofproto_v1_3.OFPAT_DEC_NW_TTL: buf = 'DEC_NW_TTL' elif action_type == ofproto_v1_3.OFPAT_SET_FIELD: buf = 'SET_FIELD: {%s:%s}' % (act.key, act.value) elif action_type == ofproto_v1_3.OFPAT_PUSH_PBB: buf = 'PUSH_PBB:' + str(act.ethertype) elif action_type == ofproto_v1_3.OFPAT_POP_PBB: buf = 'POP_PBB' elif action_type == ofproto_v1_3.OFPAT_EXPERIMENTER: if act.experimenter == ofproto_common.NX_EXPERIMENTER_ID: try: return ofctl_nicira_ext.action_to_str(act, action_to_str) except Exception: LOG.debug('Error parsing NX_ACTION(%s)', act.__class__.__name__, exc_info=True) data_str = base64.b64encode(act.data) buf = 'EXPERIMENTER: {experimenter:%s, data:%s}' % \ (act.experimenter, data_str.decode('utf-8')) else: buf = 'UNKNOWN' return buf def actions_to_str(instructions): actions = [] for instruction in instructions: if isinstance(instruction, ofproto_v1_3_parser.OFPInstructionActions): if instruction.type == ofproto_v1_3.OFPIT_APPLY_ACTIONS: for a in instruction.actions: actions.append(action_to_str(a)) elif instruction.type == ofproto_v1_3.OFPIT_WRITE_ACTIONS: write_actions = [] for a in instruction.actions: write_actions.append(action_to_str(a)) if write_actions: actions.append({'WRITE_ACTIONS': write_actions}) elif instruction.type == ofproto_v1_3.OFPIT_CLEAR_ACTIONS: actions.append('CLEAR_ACTIONS') else: actions.append('UNKNOWN') elif isinstance(instruction, ofproto_v1_3_parser.OFPInstructionGotoTable): table_id = UTIL.ofp_table_to_user(instruction.table_id) buf = 'GOTO_TABLE:' + str(table_id) actions.append(buf) elif isinstance(instruction, ofproto_v1_3_parser.OFPInstructionWriteMetadata): buf = ('WRITE_METADATA:0x%x/0x%x' % (instruction.metadata, instruction.metadata_mask) if instruction.metadata_mask else 'WRITE_METADATA:0x%x' % instruction.metadata) actions.append(buf) elif isinstance(instruction, ofproto_v1_3_parser.OFPInstructionMeter): meter_id = UTIL.ofp_meter_to_user(instruction.meter_id) buf = 'METER:' + str(meter_id) actions.append(buf) else: continue return actions def to_match(dp, attrs): convert = {'in_port': UTIL.ofp_port_from_user, 'in_phy_port': str_to_int, 'metadata': ofctl_utils.to_match_masked_int, 'dl_dst': ofctl_utils.to_match_eth, 'dl_src': ofctl_utils.to_match_eth, 'eth_dst': ofctl_utils.to_match_eth, 'eth_src': ofctl_utils.to_match_eth, 'dl_type': str_to_int, 'eth_type': str_to_int, 'dl_vlan': to_match_vid, 'vlan_vid': to_match_vid, 'vlan_pcp': str_to_int, 'ip_dscp': str_to_int, 'ip_ecn': str_to_int, 'nw_proto': str_to_int, 'ip_proto': str_to_int, 'nw_src': ofctl_utils.to_match_ip, 'nw_dst': ofctl_utils.to_match_ip, 'ipv4_src': ofctl_utils.to_match_ip, 'ipv4_dst': ofctl_utils.to_match_ip, 'tp_src': str_to_int, 'tp_dst': str_to_int, 'tcp_src': str_to_int, 'tcp_dst': str_to_int, 'udp_src': str_to_int, 'udp_dst': str_to_int, 'sctp_src': str_to_int, 'sctp_dst': str_to_int, 'icmpv4_type': str_to_int, 'icmpv4_code': str_to_int, 'arp_op': str_to_int, 'arp_spa': ofctl_utils.to_match_ip, 'arp_tpa': ofctl_utils.to_match_ip, 'arp_sha': ofctl_utils.to_match_eth, 'arp_tha': ofctl_utils.to_match_eth, 'ipv6_src': ofctl_utils.to_match_ip, 'ipv6_dst': ofctl_utils.to_match_ip, 'ipv6_flabel': str_to_int, 'icmpv6_type': str_to_int, 'icmpv6_code': str_to_int, 'ipv6_nd_target': ofctl_utils.to_match_ip, 'ipv6_nd_sll': ofctl_utils.to_match_eth, 'ipv6_nd_tll': ofctl_utils.to_match_eth, 'mpls_label': str_to_int, 'mpls_tc': str_to_int, 'mpls_bos': str_to_int, 'pbb_isid': ofctl_utils.to_match_masked_int, 'tunnel_id': ofctl_utils.to_match_masked_int, 'ipv6_exthdr': ofctl_utils.to_match_masked_int} keys = {'dl_dst': 'eth_dst', 'dl_src': 'eth_src', 'dl_type': 'eth_type', 'dl_vlan': 'vlan_vid', 'nw_src': 'ipv4_src', 'nw_dst': 'ipv4_dst', 'nw_proto': 'ip_proto'} if attrs.get('dl_type') == ether.ETH_TYPE_ARP or \ attrs.get('eth_type') == ether.ETH_TYPE_ARP: if 'nw_src' in attrs and 'arp_spa' not in attrs: attrs['arp_spa'] = attrs['nw_src'] del attrs['nw_src'] if 'nw_dst' in attrs and 'arp_tpa' not in attrs: attrs['arp_tpa'] = attrs['nw_dst'] del attrs['nw_dst'] kwargs = {} for key, value in attrs.items(): if key in keys: # For old field name key = keys[key] if key in convert: value = convert[key](value) if key == 'tp_src' or key == 'tp_dst': # TCP/UDP port conv = {inet.IPPROTO_TCP: {'tp_src': 'tcp_src', 'tp_dst': 'tcp_dst'}, inet.IPPROTO_UDP: {'tp_src': 'udp_src', 'tp_dst': 'udp_dst'}} ip_proto = attrs.get('nw_proto', attrs.get('ip_proto', 0)) key = conv[ip_proto][key] kwargs[key] = value else: # others kwargs[key] = value else: LOG.error('Unknown match field: %s', key) return dp.ofproto_parser.OFPMatch(**kwargs) def to_match_vid(value): return ofctl_utils.to_match_vid(value, ofproto_v1_3.OFPVID_PRESENT) def match_to_str(ofmatch): keys = {'eth_src': 'dl_src', 'eth_dst': 'dl_dst', 'eth_type': 'dl_type', 'vlan_vid': 'dl_vlan', 'ipv4_src': 'nw_src', 'ipv4_dst': 'nw_dst', 'ip_proto': 'nw_proto', 'tcp_src': 'tp_src', 'tcp_dst': 'tp_dst', 'udp_src': 'tp_src', 'udp_dst': 'tp_dst'} match = {} ofmatch = ofmatch.to_jsondict()['OFPMatch'] ofmatch = ofmatch['oxm_fields'] for match_field in ofmatch: key = match_field['OXMTlv']['field'] if key in keys: key = keys[key] mask = match_field['OXMTlv']['mask'] value = match_field['OXMTlv']['value'] if key == 'dl_vlan': value = match_vid_to_str(value, mask) elif key == 'in_port': value = UTIL.ofp_port_to_user(value) else: if mask is not None: value = str(value) + '/' + str(mask) match.setdefault(key, value) return match def match_vid_to_str(value, mask): return ofctl_utils.match_vid_to_str( value, mask, ofproto_v1_3.OFPVID_PRESENT) def wrap_dpid_dict(dp, value, to_user=True): if to_user: return {str(dp.id): value} return {dp.id: value} def get_desc_stats(dp, waiters, to_user=True): stats = dp.ofproto_parser.OFPDescStatsRequest(dp, 0) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) s = {} for msg in msgs: stats = msg.body s = stats.to_jsondict()[stats.__class__.__name__] return wrap_dpid_dict(dp, s, to_user) def get_queue_stats(dp, waiters, port=None, queue_id=None, to_user=True): ofp = dp.ofproto if port is None: port = ofp.OFPP_ANY else: port = str_to_int(port) if queue_id is None: queue_id = ofp.OFPQ_ALL else: queue_id = str_to_int(queue_id) stats = dp.ofproto_parser.OFPQueueStatsRequest(dp, 0, port, queue_id) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) s = [] for msg in msgs: stats = msg.body for stat in stats: s.append({'duration_nsec': stat.duration_nsec, 'duration_sec': stat.duration_sec, 'port_no': stat.port_no, 'queue_id': stat.queue_id, 'tx_bytes': stat.tx_bytes, 'tx_errors': stat.tx_errors, 'tx_packets': stat.tx_packets}) return wrap_dpid_dict(dp, s, to_user) def get_queue_config(dp, waiters, port=None, to_user=True): ofp = dp.ofproto if port is None: port = ofp.OFPP_ANY else: port = UTIL.ofp_port_from_user(str_to_int(port)) stats = dp.ofproto_parser.OFPQueueGetConfigRequest(dp, port) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) prop_type = {dp.ofproto.OFPQT_MIN_RATE: 'MIN_RATE', dp.ofproto.OFPQT_MAX_RATE: 'MAX_RATE', dp.ofproto.OFPQT_EXPERIMENTER: 'EXPERIMENTER'} configs = [] for config in msgs: queue_list = [] for queue in config.queues: prop_list = [] for prop in queue.properties: p = {'property': prop_type.get(prop.property, 'UNKNOWN')} if prop.property == dp.ofproto.OFPQT_MIN_RATE or \ prop.property == dp.ofproto.OFPQT_MAX_RATE: p['rate'] = prop.rate elif prop.property == dp.ofproto.OFPQT_EXPERIMENTER: p['experimenter'] = prop.experimenter p['data'] = prop.data prop_list.append(p) q = {'properties': prop_list} if to_user: q['port'] = UTIL.ofp_port_to_user(queue.port) q['queue_id'] = UTIL.ofp_queue_to_user(queue.queue_id) else: q['port'] = queue.port q['queue_id'] = queue.queue_id queue_list.append(q) c = {'queues': queue_list} if to_user: c['port'] = UTIL.ofp_port_to_user(config.port) else: c['port'] = config.port configs.append(c) return wrap_dpid_dict(dp, configs, to_user) def get_flow_stats(dp, waiters, flow=None, to_user=True): flow = flow if flow else {} table_id = UTIL.ofp_table_from_user( flow.get('table_id', dp.ofproto.OFPTT_ALL)) flags = str_to_int(flow.get('flags', 0)) out_port = UTIL.ofp_port_from_user( flow.get('out_port', dp.ofproto.OFPP_ANY)) out_group = UTIL.ofp_group_from_user( flow.get('out_group', dp.ofproto.OFPG_ANY)) cookie = str_to_int(flow.get('cookie', 0)) cookie_mask = str_to_int(flow.get('cookie_mask', 0)) match = to_match(dp, flow.get('match', {})) # Note: OpenFlow does not allow to filter flow entries by priority, # but for efficiency, ofctl provides the way to do it. priority = str_to_int(flow.get('priority', -1)) stats = dp.ofproto_parser.OFPFlowStatsRequest( dp, flags, table_id, out_port, out_group, cookie, cookie_mask, match) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) flows = [] for msg in msgs: for stats in msg.body: if 0 <= priority != stats.priority: continue s = {'priority': stats.priority, 'cookie': stats.cookie, 'idle_timeout': stats.idle_timeout, 'hard_timeout': stats.hard_timeout, 'byte_count': stats.byte_count, 'duration_sec': stats.duration_sec, 'duration_nsec': stats.duration_nsec, 'packet_count': stats.packet_count, 'length': stats.length, 'flags': stats.flags} if to_user: s['actions'] = actions_to_str(stats.instructions) s['match'] = match_to_str(stats.match) s['table_id'] = UTIL.ofp_table_to_user(stats.table_id) else: s['actions'] = stats.instructions s['instructions'] = stats.instructions s['match'] = stats.match s['table_id'] = stats.table_id flows.append(s) return wrap_dpid_dict(dp, flows, to_user) def get_aggregate_flow_stats(dp, waiters, flow=None, to_user=True): flow = flow if flow else {} table_id = UTIL.ofp_table_from_user( flow.get('table_id', dp.ofproto.OFPTT_ALL)) flags = str_to_int(flow.get('flags', 0)) out_port = UTIL.ofp_port_from_user( flow.get('out_port', dp.ofproto.OFPP_ANY)) out_group = UTIL.ofp_group_from_user( flow.get('out_group', dp.ofproto.OFPG_ANY)) cookie = str_to_int(flow.get('cookie', 0)) cookie_mask = str_to_int(flow.get('cookie_mask', 0)) match = to_match(dp, flow.get('match', {})) stats = dp.ofproto_parser.OFPAggregateStatsRequest( dp, flags, table_id, out_port, out_group, cookie, cookie_mask, match) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) flows = [] for msg in msgs: stats = msg.body s = {'packet_count': stats.packet_count, 'byte_count': stats.byte_count, 'flow_count': stats.flow_count} flows.append(s) return wrap_dpid_dict(dp, flows, to_user) def get_table_stats(dp, waiters, to_user=True): stats = dp.ofproto_parser.OFPTableStatsRequest(dp, 0) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) tables = [] for msg in msgs: stats = msg.body for stat in stats: s = {'active_count': stat.active_count, 'lookup_count': stat.lookup_count, 'matched_count': stat.matched_count} if to_user: s['table_id'] = UTIL.ofp_table_to_user(stat.table_id) else: s['table_id'] = stat.table_id tables.append(s) return wrap_dpid_dict(dp, tables, to_user) def get_table_features(dp, waiters, to_user=True): stats = dp.ofproto_parser.OFPTableFeaturesStatsRequest(dp, 0, []) msgs = [] ofproto = dp.ofproto ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) prop_type = {ofproto.OFPTFPT_INSTRUCTIONS: 'INSTRUCTIONS', ofproto.OFPTFPT_INSTRUCTIONS_MISS: 'INSTRUCTIONS_MISS', ofproto.OFPTFPT_NEXT_TABLES: 'NEXT_TABLES', ofproto.OFPTFPT_NEXT_TABLES_MISS: 'NEXT_TABLES_MISS', ofproto.OFPTFPT_WRITE_ACTIONS: 'WRITE_ACTIONS', ofproto.OFPTFPT_WRITE_ACTIONS_MISS: 'WRITE_ACTIONS_MISS', ofproto.OFPTFPT_APPLY_ACTIONS: 'APPLY_ACTIONS', ofproto.OFPTFPT_APPLY_ACTIONS_MISS: 'APPLY_ACTIONS_MISS', ofproto.OFPTFPT_MATCH: 'MATCH', ofproto.OFPTFPT_WILDCARDS: 'WILDCARDS', ofproto.OFPTFPT_WRITE_SETFIELD: 'WRITE_SETFIELD', ofproto.OFPTFPT_WRITE_SETFIELD_MISS: 'WRITE_SETFIELD_MISS', ofproto.OFPTFPT_APPLY_SETFIELD: 'APPLY_SETFIELD', ofproto.OFPTFPT_APPLY_SETFIELD_MISS: 'APPLY_SETFIELD_MISS', ofproto.OFPTFPT_EXPERIMENTER: 'EXPERIMENTER', ofproto.OFPTFPT_EXPERIMENTER_MISS: 'EXPERIMENTER_MISS'} if not to_user: prop_type = dict((k, k) for k in prop_type.keys()) p_type_instructions = [ofproto.OFPTFPT_INSTRUCTIONS, ofproto.OFPTFPT_INSTRUCTIONS_MISS] p_type_next_tables = [ofproto.OFPTFPT_NEXT_TABLES, ofproto.OFPTFPT_NEXT_TABLES_MISS] p_type_actions = [ofproto.OFPTFPT_WRITE_ACTIONS, ofproto.OFPTFPT_WRITE_ACTIONS_MISS, ofproto.OFPTFPT_APPLY_ACTIONS, ofproto.OFPTFPT_APPLY_ACTIONS_MISS] p_type_oxms = [ofproto.OFPTFPT_MATCH, ofproto.OFPTFPT_WILDCARDS, ofproto.OFPTFPT_WRITE_SETFIELD, ofproto.OFPTFPT_WRITE_SETFIELD_MISS, ofproto.OFPTFPT_APPLY_SETFIELD, ofproto.OFPTFPT_APPLY_SETFIELD_MISS] p_type_experimenter = [ofproto.OFPTFPT_EXPERIMENTER, ofproto.OFPTFPT_EXPERIMENTER_MISS] tables = [] for msg in msgs: stats = msg.body for stat in stats: properties = [] for prop in stat.properties: p = {'type': prop_type.get(prop.type, 'UNKNOWN')} if prop.type in p_type_instructions: instruction_ids = [] for i in prop.instruction_ids: inst = {'len': i.len, 'type': i.type} instruction_ids.append(inst) p['instruction_ids'] = instruction_ids elif prop.type in p_type_next_tables: table_ids = [] for i in prop.table_ids: table_ids.append(i) p['table_ids'] = table_ids elif prop.type in p_type_actions: action_ids = [] for i in prop.action_ids: act = {'len': i.len, 'type': i.type} action_ids.append(act) p['action_ids'] = action_ids elif prop.type in p_type_oxms: oxm_ids = [] for i in prop.oxm_ids: oxm = {'hasmask': i.hasmask, 'length': i.length, 'type': i.type} oxm_ids.append(oxm) p['oxm_ids'] = oxm_ids elif prop.type in p_type_experimenter: pass properties.append(p) s = { 'name': stat.name.decode('utf-8'), 'metadata_match': stat.metadata_match, 'metadata_write': stat.metadata_write, 'config': stat.config, 'max_entries': stat.max_entries, 'properties': properties, } if to_user: s['table_id'] = UTIL.ofp_table_to_user(stat.table_id) else: s['table_id'] = stat.table_id tables.append(s) return wrap_dpid_dict(dp, tables, to_user) def get_port_stats(dp, waiters, port=None, to_user=True): if port is None: port = dp.ofproto.OFPP_ANY else: port = str_to_int(port) stats = dp.ofproto_parser.OFPPortStatsRequest( dp, 0, port) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) ports = [] for msg in msgs: for stats in msg.body: s = {'rx_packets': stats.rx_packets, 'tx_packets': stats.tx_packets, 'rx_bytes': stats.rx_bytes, 'tx_bytes': stats.tx_bytes, 'rx_dropped': stats.rx_dropped, 'tx_dropped': stats.tx_dropped, 'rx_errors': stats.rx_errors, 'tx_errors': stats.tx_errors, 'rx_frame_err': stats.rx_frame_err, 'rx_over_err': stats.rx_over_err, 'rx_crc_err': stats.rx_crc_err, 'collisions': stats.collisions, 'duration_sec': stats.duration_sec, 'duration_nsec': stats.duration_nsec} if to_user: s['port_no'] = UTIL.ofp_port_to_user(stats.port_no) else: s['port_no'] = stats.port_no ports.append(s) return wrap_dpid_dict(dp, ports, to_user) def get_meter_stats(dp, waiters, meter_id=None, to_user=True): if meter_id is None: meter_id = dp.ofproto.OFPM_ALL else: meter_id = str_to_int(meter_id) stats = dp.ofproto_parser.OFPMeterStatsRequest( dp, 0, meter_id) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) meters = [] for msg in msgs: for stats in msg.body: bands = [] for band in stats.band_stats: b = {'packet_band_count': band.packet_band_count, 'byte_band_count': band.byte_band_count} bands.append(b) s = {'len': stats.len, 'flow_count': stats.flow_count, 'packet_in_count': stats.packet_in_count, 'byte_in_count': stats.byte_in_count, 'duration_sec': stats.duration_sec, 'duration_nsec': stats.duration_nsec, 'band_stats': bands} if to_user: s['meter_id'] = UTIL.ofp_meter_to_user(stats.meter_id) else: s['meter_id'] = stats.meter_id meters.append(s) return wrap_dpid_dict(dp, meters, to_user) def get_meter_features(dp, waiters, to_user=True): ofp = dp.ofproto type_convert = {ofp.OFPMBT_DROP: 'DROP', ofp.OFPMBT_DSCP_REMARK: 'DSCP_REMARK'} capa_convert = {ofp.OFPMF_KBPS: 'KBPS', ofp.OFPMF_PKTPS: 'PKTPS', ofp.OFPMF_BURST: 'BURST', ofp.OFPMF_STATS: 'STATS'} stats = dp.ofproto_parser.OFPMeterFeaturesStatsRequest(dp, 0) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) features = [] for msg in msgs: for feature in msg.body: band_types = [] for k, v in type_convert.items(): if (1 << k) & feature.band_types: if to_user: band_types.append(v) else: band_types.append(k) capabilities = [] for k, v in sorted(capa_convert.items()): if k & feature.capabilities: if to_user: capabilities.append(v) else: capabilities.append(k) f = {'max_meter': feature.max_meter, 'band_types': band_types, 'capabilities': capabilities, 'max_bands': feature.max_bands, 'max_color': feature.max_color} features.append(f) return wrap_dpid_dict(dp, features, to_user) def get_meter_config(dp, waiters, meter_id=None, to_user=True): flags = {dp.ofproto.OFPMF_KBPS: 'KBPS', dp.ofproto.OFPMF_PKTPS: 'PKTPS', dp.ofproto.OFPMF_BURST: 'BURST', dp.ofproto.OFPMF_STATS: 'STATS'} band_type = {dp.ofproto.OFPMBT_DROP: 'DROP', dp.ofproto.OFPMBT_DSCP_REMARK: 'DSCP_REMARK', dp.ofproto.OFPMBT_EXPERIMENTER: 'EXPERIMENTER'} if meter_id is None: meter_id = dp.ofproto.OFPM_ALL else: meter_id = str_to_int(meter_id) stats = dp.ofproto_parser.OFPMeterConfigStatsRequest( dp, 0, meter_id) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) configs = [] for msg in msgs: for config in msg.body: bands = [] for band in config.bands: b = {'rate': band.rate, 'burst_size': band.burst_size} if to_user: b['type'] = band_type.get(band.type, '') else: b['type'] = band.type if band.type == dp.ofproto.OFPMBT_DSCP_REMARK: b['prec_level'] = band.prec_level elif band.type == dp.ofproto.OFPMBT_EXPERIMENTER: b['experimenter'] = band.experimenter bands.append(b) c_flags = [] for k, v in sorted(flags.items()): if k & config.flags: if to_user: c_flags.append(v) else: c_flags.append(k) c = {'flags': c_flags, 'bands': bands} if to_user: c['meter_id'] = UTIL.ofp_meter_to_user(config.meter_id) else: c['meter_id'] = config.meter_id configs.append(c) return wrap_dpid_dict(dp, configs, to_user) def get_group_stats(dp, waiters, group_id=None, to_user=True): if group_id is None: group_id = dp.ofproto.OFPG_ALL else: group_id = str_to_int(group_id) stats = dp.ofproto_parser.OFPGroupStatsRequest( dp, 0, group_id) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) groups = [] for msg in msgs: for stats in msg.body: bucket_stats = [] for bucket_stat in stats.bucket_stats: c = {'packet_count': bucket_stat.packet_count, 'byte_count': bucket_stat.byte_count} bucket_stats.append(c) g = {'length': stats.length, 'ref_count': stats.ref_count, 'packet_count': stats.packet_count, 'byte_count': stats.byte_count, 'duration_sec': stats.duration_sec, 'duration_nsec': stats.duration_nsec, 'bucket_stats': bucket_stats} if to_user: g['group_id'] = UTIL.ofp_group_to_user(stats.group_id) else: g['group_id'] = stats.group_id groups.append(g) return wrap_dpid_dict(dp, groups, to_user) def get_group_features(dp, waiters, to_user=True): ofp = dp.ofproto type_convert = {ofp.OFPGT_ALL: 'ALL', ofp.OFPGT_SELECT: 'SELECT', ofp.OFPGT_INDIRECT: 'INDIRECT', ofp.OFPGT_FF: 'FF'} cap_convert = {ofp.OFPGFC_SELECT_WEIGHT: 'SELECT_WEIGHT', ofp.OFPGFC_SELECT_LIVENESS: 'SELECT_LIVENESS', ofp.OFPGFC_CHAINING: 'CHAINING', ofp.OFPGFC_CHAINING_CHECKS: 'CHAINING_CHECKS'} act_convert = {ofp.OFPAT_OUTPUT: 'OUTPUT', ofp.OFPAT_COPY_TTL_OUT: 'COPY_TTL_OUT', ofp.OFPAT_COPY_TTL_IN: 'COPY_TTL_IN', ofp.OFPAT_SET_MPLS_TTL: 'SET_MPLS_TTL', ofp.OFPAT_DEC_MPLS_TTL: 'DEC_MPLS_TTL', ofp.OFPAT_PUSH_VLAN: 'PUSH_VLAN', ofp.OFPAT_POP_VLAN: 'POP_VLAN', ofp.OFPAT_PUSH_MPLS: 'PUSH_MPLS', ofp.OFPAT_POP_MPLS: 'POP_MPLS', ofp.OFPAT_SET_QUEUE: 'SET_QUEUE', ofp.OFPAT_GROUP: 'GROUP', ofp.OFPAT_SET_NW_TTL: 'SET_NW_TTL', ofp.OFPAT_DEC_NW_TTL: 'DEC_NW_TTL', ofp.OFPAT_SET_FIELD: 'SET_FIELD', ofp.OFPAT_PUSH_PBB: 'PUSH_PBB', ofp.OFPAT_POP_PBB: 'POP_PBB'} stats = dp.ofproto_parser.OFPGroupFeaturesStatsRequest(dp, 0) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) features = [] for msg in msgs: feature = msg.body types = [] for k, v in type_convert.items(): if (1 << k) & feature.types: if to_user: types.append(v) else: types.append(k) capabilities = [] for k, v in cap_convert.items(): if k & feature.capabilities: if to_user: capabilities.append(v) else: capabilities.append(k) if to_user: max_groups = [] for k, v in type_convert.items(): max_groups.append({v: feature.max_groups[k]}) else: max_groups = feature.max_groups actions = [] for k1, v1 in type_convert.items(): acts = [] for k2, v2 in act_convert.items(): if (1 << k2) & feature.actions[k1]: if to_user: acts.append(v2) else: acts.append(k2) if to_user: actions.append({v1: acts}) else: actions.append({k1: acts}) f = {'types': types, 'capabilities': capabilities, 'max_groups': max_groups, 'actions': actions} features.append(f) return wrap_dpid_dict(dp, features, to_user) def get_group_desc(dp, waiters, to_user=True): type_convert = {dp.ofproto.OFPGT_ALL: 'ALL', dp.ofproto.OFPGT_SELECT: 'SELECT', dp.ofproto.OFPGT_INDIRECT: 'INDIRECT', dp.ofproto.OFPGT_FF: 'FF'} stats = dp.ofproto_parser.OFPGroupDescStatsRequest(dp, 0) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) descs = [] for msg in msgs: for stats in msg.body: buckets = [] for bucket in stats.buckets: actions = [] for action in bucket.actions: if to_user: actions.append(action_to_str(action)) else: actions.append(action) b = {'weight': bucket.weight, 'watch_port': bucket.watch_port, 'watch_group': bucket.watch_group, 'actions': actions} buckets.append(b) d = {'buckets': buckets} if to_user: d['group_id'] = UTIL.ofp_group_to_user(stats.group_id) d['type'] = type_convert.get(stats.type) else: d['group_id'] = stats.group_id d['type'] = stats.type descs.append(d) return wrap_dpid_dict(dp, descs, to_user) def get_port_desc(dp, waiters, to_user=True): stats = dp.ofproto_parser.OFPPortDescStatsRequest(dp, 0) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) descs = [] for msg in msgs: stats = msg.body for stat in stats: d = {'hw_addr': stat.hw_addr, 'name': stat.name.decode('utf-8', errors='replace'), 'config': stat.config, 'state': stat.state, 'curr': stat.curr, 'advertised': stat.advertised, 'supported': stat.supported, 'peer': stat.peer, 'curr_speed': stat.curr_speed, 'max_speed': stat.max_speed} if to_user: d['port_no'] = UTIL.ofp_port_to_user(stat.port_no) else: d['port_no'] = stat.port_no descs.append(d) return wrap_dpid_dict(dp, descs, to_user) def get_role(dp, waiters, to_user=True): return ofctl_utils.get_role(dp, waiters, to_user) def mod_flow_entry(dp, flow, cmd): cookie = str_to_int(flow.get('cookie', 0)) cookie_mask = str_to_int(flow.get('cookie_mask', 0)) table_id = UTIL.ofp_table_from_user(flow.get('table_id', 0)) idle_timeout = str_to_int(flow.get('idle_timeout', 0)) hard_timeout = str_to_int(flow.get('hard_timeout', 0)) priority = str_to_int(flow.get('priority', 0)) buffer_id = UTIL.ofp_buffer_from_user( flow.get('buffer_id', dp.ofproto.OFP_NO_BUFFER)) out_port = UTIL.ofp_port_from_user( flow.get('out_port', dp.ofproto.OFPP_ANY)) out_group = UTIL.ofp_group_from_user( flow.get('out_group', dp.ofproto.OFPG_ANY)) flags = str_to_int(flow.get('flags', 0)) match = to_match(dp, flow.get('match', {})) inst = to_actions(dp, flow.get('actions', [])) flow_mod = dp.ofproto_parser.OFPFlowMod( dp, cookie, cookie_mask, table_id, cmd, idle_timeout, hard_timeout, priority, buffer_id, out_port, out_group, flags, match, inst) ofctl_utils.send_msg(dp, flow_mod, LOG) def mod_meter_entry(dp, meter, cmd): flags_convert = {'KBPS': dp.ofproto.OFPMF_KBPS, 'PKTPS': dp.ofproto.OFPMF_PKTPS, 'BURST': dp.ofproto.OFPMF_BURST, 'STATS': dp.ofproto.OFPMF_STATS} flags = 0 if 'flags' in meter: meter_flags = meter['flags'] if not isinstance(meter_flags, list): meter_flags = [meter_flags] for flag in meter_flags: if flag not in flags_convert: LOG.error('Unknown meter flag: %s', flag) continue flags |= flags_convert.get(flag) meter_id = UTIL.ofp_meter_from_user(meter.get('meter_id', 0)) bands = [] for band in meter.get('bands', []): band_type = band.get('type') rate = str_to_int(band.get('rate', 0)) burst_size = str_to_int(band.get('burst_size', 0)) if band_type == 'DROP': bands.append( dp.ofproto_parser.OFPMeterBandDrop(rate, burst_size)) elif band_type == 'DSCP_REMARK': prec_level = str_to_int(band.get('prec_level', 0)) bands.append( dp.ofproto_parser.OFPMeterBandDscpRemark( rate, burst_size, prec_level)) elif band_type == 'EXPERIMENTER': experimenter = str_to_int(band.get('experimenter', 0)) bands.append( dp.ofproto_parser.OFPMeterBandExperimenter( rate, burst_size, experimenter)) else: LOG.error('Unknown band type: %s', band_type) meter_mod = dp.ofproto_parser.OFPMeterMod( dp, cmd, flags, meter_id, bands) ofctl_utils.send_msg(dp, meter_mod, LOG) def mod_group_entry(dp, group, cmd): type_convert = {'ALL': dp.ofproto.OFPGT_ALL, 'SELECT': dp.ofproto.OFPGT_SELECT, 'INDIRECT': dp.ofproto.OFPGT_INDIRECT, 'FF': dp.ofproto.OFPGT_FF} type_ = type_convert.get(group.get('type', 'ALL')) if type_ is None: LOG.error('Unknown group type: %s', group.get('type')) group_id = UTIL.ofp_group_from_user(group.get('group_id', 0)) buckets = [] for bucket in group.get('buckets', []): weight = str_to_int(bucket.get('weight', 0)) watch_port = str_to_int( bucket.get('watch_port', dp.ofproto.OFPP_ANY)) watch_group = str_to_int( bucket.get('watch_group', dp.ofproto.OFPG_ANY)) actions = [] for dic in bucket.get('actions', []): action = to_action(dp, dic) if action is not None: actions.append(action) buckets.append(dp.ofproto_parser.OFPBucket( weight, watch_port, watch_group, actions)) group_mod = dp.ofproto_parser.OFPGroupMod( dp, cmd, type_, group_id, buckets) ofctl_utils.send_msg(dp, group_mod, LOG) def mod_port_behavior(dp, port_config): port_no = UTIL.ofp_port_from_user(port_config.get('port_no', 0)) hw_addr = str(port_config.get('hw_addr')) config = str_to_int(port_config.get('config', 0)) mask = str_to_int(port_config.get('mask', 0)) advertise = str_to_int(port_config.get('advertise')) port_mod = dp.ofproto_parser.OFPPortMod( dp, port_no, hw_addr, config, mask, advertise) ofctl_utils.send_msg(dp, port_mod, LOG) def set_role(dp, role): r = UTIL.ofp_role_from_user(role.get('role', dp.ofproto.OFPCR_ROLE_EQUAL)) role_request = dp.ofproto_parser.OFPRoleRequest(dp, r, 0) ofctl_utils.send_msg(dp, role_request, LOG) # NOTE(jkoelker) Alias common funcitons send_experimenter = ofctl_utils.send_experimenter ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/ofctl_v1_4.py0000664000175000017500000010006200000000000017346 0ustar00zuulzuul00000000000000# Copyright (C) 2016 Nippon Telegraph and Telephone 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. import logging from os_ken.ofproto import ether from os_ken.ofproto import ofproto_v1_4 from os_ken.ofproto import ofproto_v1_4_parser from os_ken.lib import ofctl_utils LOG = logging.getLogger(__name__) DEFAULT_TIMEOUT = 1.0 UTIL = ofctl_utils.OFCtlUtil(ofproto_v1_4) str_to_int = ofctl_utils.str_to_int def to_action(dp, dic): ofp = dp.ofproto parser = dp.ofproto_parser action_type = dic.get('type') return ofctl_utils.to_action(dic, ofp, parser, action_type, UTIL) def _get_actions(dp, dics): actions = [] for d in dics: action = to_action(dp, d) if action is not None: actions.append(action) else: LOG.error('Unknown action type: %s', d) return actions def to_instructions(dp, insts): instructions = [] ofp = dp.ofproto parser = dp.ofproto_parser for i in insts: inst_type = i.get('type') if inst_type in ['APPLY_ACTIONS', 'WRITE_ACTIONS']: dics = i.get('actions', []) actions = _get_actions(dp, dics) if actions: if inst_type == 'APPLY_ACTIONS': instructions.append( parser.OFPInstructionActions(ofp.OFPIT_APPLY_ACTIONS, actions)) else: instructions.append( parser.OFPInstructionActions(ofp.OFPIT_WRITE_ACTIONS, actions)) elif inst_type == 'CLEAR_ACTIONS': instructions.append( parser.OFPInstructionActions(ofp.OFPIT_CLEAR_ACTIONS, [])) elif inst_type == 'GOTO_TABLE': table_id = str_to_int(i.get('table_id')) instructions.append(parser.OFPInstructionGotoTable(table_id)) elif inst_type == 'WRITE_METADATA': metadata = str_to_int(i.get('metadata')) metadata_mask = (str_to_int(i['metadata_mask']) if 'metadata_mask' in i else parser.UINT64_MAX) instructions.append( parser.OFPInstructionWriteMetadata( metadata, metadata_mask)) elif inst_type == 'METER': meter_id = str_to_int(i.get('meter_id')) instructions.append(parser.OFPInstructionMeter(meter_id)) else: LOG.error('Unknown instruction type: %s', inst_type) return instructions def action_to_str(act): s = act.to_jsondict()[act.__class__.__name__] t = UTIL.ofp_action_type_to_user(s['type']) s['type'] = t if t != s['type'] else 'UNKNOWN' if 'field' in s: field = s.pop('field') s['field'] = field['OXMTlv']['field'] s['mask'] = field['OXMTlv']['mask'] s['value'] = field['OXMTlv']['value'] return s def instructions_to_str(instructions): s = [] for i in instructions: v = i.to_jsondict()[i.__class__.__name__] t = UTIL.ofp_instruction_type_to_user(v['type']) inst_type = t if t != v['type'] else 'UNKNOWN' # apply/write/clear-action instruction if isinstance(i, ofproto_v1_4_parser.OFPInstructionActions): acts = [] for a in i.actions: acts.append(action_to_str(a)) v['type'] = inst_type v['actions'] = acts s.append(v) # others else: v['type'] = inst_type s.append(v) return s def to_match(dp, attrs): convert = {'in_port': UTIL.ofp_port_from_user, 'in_phy_port': str_to_int, 'metadata': ofctl_utils.to_match_masked_int, 'eth_dst': ofctl_utils.to_match_eth, 'eth_src': ofctl_utils.to_match_eth, 'eth_type': str_to_int, 'vlan_vid': to_match_vid, 'vlan_pcp': str_to_int, 'ip_dscp': str_to_int, 'ip_ecn': str_to_int, 'ip_proto': str_to_int, 'ipv4_src': ofctl_utils.to_match_ip, 'ipv4_dst': ofctl_utils.to_match_ip, 'tcp_src': str_to_int, 'tcp_dst': str_to_int, 'udp_src': str_to_int, 'udp_dst': str_to_int, 'sctp_src': str_to_int, 'sctp_dst': str_to_int, 'icmpv4_type': str_to_int, 'icmpv4_code': str_to_int, 'arp_op': str_to_int, 'arp_spa': ofctl_utils.to_match_ip, 'arp_tpa': ofctl_utils.to_match_ip, 'arp_sha': ofctl_utils.to_match_eth, 'arp_tha': ofctl_utils.to_match_eth, 'ipv6_src': ofctl_utils.to_match_ip, 'ipv6_dst': ofctl_utils.to_match_ip, 'ipv6_flabel': str_to_int, 'icmpv6_type': str_to_int, 'icmpv6_code': str_to_int, 'ipv6_nd_target': ofctl_utils.to_match_ip, 'ipv6_nd_sll': ofctl_utils.to_match_eth, 'ipv6_nd_tll': ofctl_utils.to_match_eth, 'mpls_label': str_to_int, 'mpls_tc': str_to_int, 'mpls_bos': str_to_int, 'pbb_isid': ofctl_utils.to_match_masked_int, 'tunnel_id': ofctl_utils.to_match_masked_int, 'ipv6_exthdr': ofctl_utils.to_match_masked_int, 'pbb_uca': str_to_int} keys = {'dl_dst': 'eth_dst', 'dl_src': 'eth_src', 'dl_type': 'eth_type', 'dl_vlan': 'vlan_vid', 'nw_src': 'ipv4_src', 'nw_dst': 'ipv4_dst', 'nw_proto': 'ip_proto'} if attrs.get('eth_type') == ether.ETH_TYPE_ARP: if 'ipv4_src' in attrs and 'arp_spa' not in attrs: attrs['arp_spa'] = attrs['ipv4_src'] del attrs['ipv4_src'] if 'ipv4_dst' in attrs and 'arp_tpa' not in attrs: attrs['arp_tpa'] = attrs['ipv4_dst'] del attrs['ipv4_dst'] kwargs = {} for key, value in attrs.items(): if key in keys: # For old field name key = keys[key] if key in convert: value = convert[key](value) kwargs[key] = value else: LOG.error('Unknown match field: %s', key) return dp.ofproto_parser.OFPMatch(**kwargs) def to_match_vid(value): return ofctl_utils.to_match_vid(value, ofproto_v1_4.OFPVID_PRESENT) def match_to_str(ofmatch): match = {} ofmatch = ofmatch.to_jsondict()['OFPMatch'] ofmatch = ofmatch['oxm_fields'] for match_field in ofmatch: key = match_field['OXMTlv']['field'] mask = match_field['OXMTlv']['mask'] value = match_field['OXMTlv']['value'] if key == 'vlan_vid': value = match_vid_to_str(value, mask) elif key == 'in_port': value = UTIL.ofp_port_to_user(value) else: if mask is not None: value = str(value) + '/' + str(mask) match.setdefault(key, value) return match def match_vid_to_str(value, mask): return ofctl_utils.match_vid_to_str( value, mask, ofproto_v1_4.OFPVID_PRESENT) def wrap_dpid_dict(dp, value, to_user=True): if to_user: return {str(dp.id): value} return {dp.id: value} def get_desc_stats(dp, waiters, to_user=True): stats = dp.ofproto_parser.OFPDescStatsRequest(dp, 0) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) s = {} for msg in msgs: stats = msg.body s = stats.to_jsondict()[stats.__class__.__name__] return wrap_dpid_dict(dp, s, to_user) def get_queue_stats(dp, waiters, port_no=None, queue_id=None, to_user=True): if port_no is None: port_no = dp.ofproto.OFPP_ANY else: port_no = UTIL.ofp_port_from_user(port_no) if queue_id is None: queue_id = dp.ofproto.OFPQ_ALL else: queue_id = UTIL.ofp_queue_from_user(queue_id) stats = dp.ofproto_parser.OFPQueueStatsRequest( dp, 0, port_no, queue_id) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) desc = [] for msg in msgs: stats = msg.body for stat in stats: s = stat.to_jsondict()[stat.__class__.__name__] properties = [] for prop in stat.properties: p = prop.to_jsondict()[prop.__class__.__name__] if to_user: t = UTIL.ofp_queue_stats_prop_type_to_user(prop.type) p['type'] = t if t != p['type'] else 'UNKNOWN' properties.append(p) s['properties'] = properties desc.append(s) return wrap_dpid_dict(dp, desc, to_user) def get_queue_desc(dp, waiters, port_no=None, queue_id=None, to_user=True): if port_no is None: port_no = dp.ofproto.OFPP_ANY else: port_no = UTIL.ofp_port_from_user(port_no) if queue_id is None: queue_id = dp.ofproto.OFPQ_ALL else: queue_id = UTIL.ofp_queue_from_user(queue_id) stats = dp.ofproto_parser.OFPQueueDescStatsRequest( dp, 0, port_no, queue_id) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) configs = [] for msg in msgs: for queue in msg.body: q = queue.to_jsondict()[queue.__class__.__name__] prop_list = [] for prop in queue.properties: p = prop.to_jsondict()[prop.__class__.__name__] if to_user: t = UTIL.ofp_queue_desc_prop_type_to_user(prop.type) p['type'] = t if t != prop.type else 'UNKNOWN' prop_list.append(p) q['properties'] = prop_list configs.append(q) return wrap_dpid_dict(dp, configs, to_user) def get_flow_stats(dp, waiters, flow=None, to_user=True): flow = flow if flow else {} table_id = UTIL.ofp_table_from_user( flow.get('table_id', dp.ofproto.OFPTT_ALL)) flags = str_to_int(flow.get('flags', 0)) out_port = UTIL.ofp_port_from_user( flow.get('out_port', dp.ofproto.OFPP_ANY)) out_group = UTIL.ofp_group_from_user( flow.get('out_group', dp.ofproto.OFPG_ANY)) cookie = str_to_int(flow.get('cookie', 0)) cookie_mask = str_to_int(flow.get('cookie_mask', 0)) match = to_match(dp, flow.get('match', {})) # Note: OpenFlow does not allow to filter flow entries by priority, # but for efficiency, ofctl provides the way to do it. priority = str_to_int(flow.get('priority', -1)) stats = dp.ofproto_parser.OFPFlowStatsRequest( dp, flags, table_id, out_port, out_group, cookie, cookie_mask, match) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) flows = [] for msg in msgs: for stats in msg.body: if 0 <= priority != stats.priority: continue s = stats.to_jsondict()[stats.__class__.__name__] s['instructions'] = instructions_to_str(stats.instructions) s['match'] = match_to_str(stats.match) flows.append(s) return wrap_dpid_dict(dp, flows, to_user) def get_aggregate_flow_stats(dp, waiters, flow=None, to_user=True): flow = flow if flow else {} table_id = UTIL.ofp_table_from_user( flow.get('table_id', dp.ofproto.OFPTT_ALL)) flags = str_to_int(flow.get('flags', 0)) out_port = UTIL.ofp_port_from_user( flow.get('out_port', dp.ofproto.OFPP_ANY)) out_group = UTIL.ofp_group_from_user( flow.get('out_group', dp.ofproto.OFPG_ANY)) cookie = str_to_int(flow.get('cookie', 0)) cookie_mask = str_to_int(flow.get('cookie_mask', 0)) match = to_match(dp, flow.get('match', {})) stats = dp.ofproto_parser.OFPAggregateStatsRequest( dp, flags, table_id, out_port, out_group, cookie, cookie_mask, match) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) flows = [] for msg in msgs: stats = msg.body s = stats.to_jsondict()[stats.__class__.__name__] flows.append(s) return wrap_dpid_dict(dp, flows, to_user) def get_table_stats(dp, waiters, to_user=True): stats = dp.ofproto_parser.OFPTableStatsRequest(dp, 0) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) tables = [] for msg in msgs: stats = msg.body for stat in stats: s = stat.to_jsondict()[stat.__class__.__name__] if to_user: s['table_id'] = UTIL.ofp_table_to_user(stat.table_id) tables.append(s) return wrap_dpid_dict(dp, tables, to_user) def get_table_features(dp, waiters, to_user=True): stats = dp.ofproto_parser.OFPTableFeaturesStatsRequest(dp, 0, []) msgs = [] ofproto = dp.ofproto ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) p_type_instructions = [ofproto.OFPTFPT_INSTRUCTIONS, ofproto.OFPTFPT_INSTRUCTIONS_MISS] p_type_next_tables = [ofproto.OFPTFPT_NEXT_TABLES, ofproto.OFPTFPT_NEXT_TABLES_MISS, ofproto.OFPTFPT_TABLE_SYNC_FROM] p_type_actions = [ofproto.OFPTFPT_WRITE_ACTIONS, ofproto.OFPTFPT_WRITE_ACTIONS_MISS, ofproto.OFPTFPT_APPLY_ACTIONS, ofproto.OFPTFPT_APPLY_ACTIONS_MISS] p_type_oxms = [ofproto.OFPTFPT_MATCH, ofproto.OFPTFPT_WILDCARDS, ofproto.OFPTFPT_WRITE_SETFIELD, ofproto.OFPTFPT_WRITE_SETFIELD_MISS, ofproto.OFPTFPT_APPLY_SETFIELD, ofproto.OFPTFPT_APPLY_SETFIELD_MISS] p_type_experimenter = [ofproto.OFPTFPT_EXPERIMENTER, ofproto.OFPTFPT_EXPERIMENTER_MISS] tables = [] for msg in msgs: stats = msg.body for stat in stats: s = stat.to_jsondict()[stat.__class__.__name__] properties = [] for prop in stat.properties: p = {} t = UTIL.ofp_table_feature_prop_type_to_user(prop.type) p['type'] = t if t != prop.type else 'UNKNOWN' if prop.type in p_type_instructions: instruction_ids = [] for i in prop.instruction_ids: inst = {'len': i.len, 'type': i.type} instruction_ids.append(inst) p['instruction_ids'] = instruction_ids elif prop.type in p_type_next_tables: table_ids = [] for i in prop.table_ids: table_ids.append(i) p['table_ids'] = table_ids elif prop.type in p_type_actions: action_ids = [] for i in prop.action_ids: act = i.to_jsondict()[i.__class__.__name__] action_ids.append(act) p['action_ids'] = action_ids elif prop.type in p_type_oxms: oxm_ids = [] for i in prop.oxm_ids: oxm = i.to_jsondict()[i.__class__.__name__] oxm_ids.append(oxm) p['oxm_ids'] = oxm_ids elif prop.type in p_type_experimenter: pass properties.append(p) s['name'] = stat.name.decode('utf-8') s['properties'] = properties if to_user: s['table_id'] = UTIL.ofp_table_to_user(stat.table_id) tables.append(s) return wrap_dpid_dict(dp, tables, to_user) def get_port_stats(dp, waiters, port_no=None, to_user=True): if port_no is None: port_no = dp.ofproto.OFPP_ANY else: port_no = UTIL.ofp_port_from_user(port_no) stats = dp.ofproto_parser.OFPPortStatsRequest(dp, 0, port_no) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) ports = [] for msg in msgs: for stats in msg.body: s = stats.to_jsondict()[stats.__class__.__name__] properties = [] for prop in stats.properties: p = prop.to_jsondict()[prop.__class__.__name__] t = UTIL.ofp_port_stats_prop_type_to_user(prop.type) p['type'] = t if t != prop.type else 'UNKNOWN' properties.append(p) s['properties'] = properties if to_user: s['port_no'] = UTIL.ofp_port_to_user(stats.port_no) ports.append(s) return wrap_dpid_dict(dp, ports, to_user) def get_meter_stats(dp, waiters, meter_id=None, to_user=True): if meter_id is None: meter_id = dp.ofproto.OFPM_ALL else: meter_id = UTIL.ofp_meter_from_user(meter_id) stats = dp.ofproto_parser.OFPMeterStatsRequest( dp, 0, meter_id) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) meters = [] for msg in msgs: for stats in msg.body: s = stats.to_jsondict()[stats.__class__.__name__] bands = [] for band in stats.band_stats: b = band.to_jsondict()[band.__class__.__name__] bands.append(b) s['band_stats'] = bands if to_user: s['meter_id'] = UTIL.ofp_meter_to_user(stats.meter_id) meters.append(s) return wrap_dpid_dict(dp, meters, to_user) def get_meter_features(dp, waiters, to_user=True): ofp = dp.ofproto type_convert = {ofp.OFPMBT_DROP: 'DROP', ofp.OFPMBT_DSCP_REMARK: 'DSCP_REMARK'} capa_convert = {ofp.OFPMF_KBPS: 'KBPS', ofp.OFPMF_PKTPS: 'PKTPS', ofp.OFPMF_BURST: 'BURST', ofp.OFPMF_STATS: 'STATS'} stats = dp.ofproto_parser.OFPMeterFeaturesStatsRequest(dp, 0) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) features = [] for msg in msgs: for feature in msg.body: band_types = [] for k, v in type_convert.items(): if (1 << k) & feature.band_types: if to_user: band_types.append(v) else: band_types.append(k) capabilities = [] for k, v in sorted(capa_convert.items()): if k & feature.capabilities: if to_user: capabilities.append(v) else: capabilities.append(k) f = {'max_meter': feature.max_meter, 'band_types': band_types, 'capabilities': capabilities, 'max_bands': feature.max_bands, 'max_color': feature.max_color} features.append(f) return wrap_dpid_dict(dp, features, to_user) def get_meter_config(dp, waiters, meter_id=None, to_user=True): flags = {dp.ofproto.OFPMF_KBPS: 'KBPS', dp.ofproto.OFPMF_PKTPS: 'PKTPS', dp.ofproto.OFPMF_BURST: 'BURST', dp.ofproto.OFPMF_STATS: 'STATS'} if meter_id is None: meter_id = dp.ofproto.OFPM_ALL else: meter_id = UTIL.ofp_meter_from_user(meter_id) stats = dp.ofproto_parser.OFPMeterConfigStatsRequest( dp, 0, meter_id) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) configs = [] for msg in msgs: for config in msg.body: c = config.to_jsondict()[config.__class__.__name__] bands = [] for band in config.bands: b = band.to_jsondict()[band.__class__.__name__] if to_user: t = UTIL.ofp_meter_band_type_to_user(band.type) b['type'] = t if t != band.type else 'UNKNOWN' bands.append(b) c_flags = [] for k, v in sorted(flags.items()): if k & config.flags: if to_user: c_flags.append(v) else: c_flags.append(k) c['flags'] = c_flags c['bands'] = bands if to_user: c['meter_id'] = UTIL.ofp_meter_to_user(config.meter_id) configs.append(c) return wrap_dpid_dict(dp, configs, to_user) def get_group_stats(dp, waiters, group_id=None, to_user=True): if group_id is None: group_id = dp.ofproto.OFPG_ALL else: group_id = UTIL.ofp_group_from_user(group_id) stats = dp.ofproto_parser.OFPGroupStatsRequest( dp, 0, group_id) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) groups = [] for msg in msgs: for stats in msg.body: g = stats.to_jsondict()[stats.__class__.__name__] bucket_stats = [] for bucket_stat in stats.bucket_stats: c = bucket_stat.to_jsondict()[bucket_stat.__class__.__name__] bucket_stats.append(c) g['bucket_stats'] = bucket_stats if to_user: g['group_id'] = UTIL.ofp_group_to_user(stats.group_id) groups.append(g) return wrap_dpid_dict(dp, groups, to_user) def get_group_features(dp, waiters, to_user=True): ofp = dp.ofproto type_convert = {ofp.OFPGT_ALL: 'ALL', ofp.OFPGT_SELECT: 'SELECT', ofp.OFPGT_INDIRECT: 'INDIRECT', ofp.OFPGT_FF: 'FF'} cap_convert = {ofp.OFPGFC_SELECT_WEIGHT: 'SELECT_WEIGHT', ofp.OFPGFC_SELECT_LIVENESS: 'SELECT_LIVENESS', ofp.OFPGFC_CHAINING: 'CHAINING', ofp.OFPGFC_CHAINING_CHECKS: 'CHAINING_CHECKS'} act_convert = {ofp.OFPAT_OUTPUT: 'OUTPUT', ofp.OFPAT_COPY_TTL_OUT: 'COPY_TTL_OUT', ofp.OFPAT_COPY_TTL_IN: 'COPY_TTL_IN', ofp.OFPAT_SET_MPLS_TTL: 'SET_MPLS_TTL', ofp.OFPAT_DEC_MPLS_TTL: 'DEC_MPLS_TTL', ofp.OFPAT_PUSH_VLAN: 'PUSH_VLAN', ofp.OFPAT_POP_VLAN: 'POP_VLAN', ofp.OFPAT_PUSH_MPLS: 'PUSH_MPLS', ofp.OFPAT_POP_MPLS: 'POP_MPLS', ofp.OFPAT_SET_QUEUE: 'SET_QUEUE', ofp.OFPAT_GROUP: 'GROUP', ofp.OFPAT_SET_NW_TTL: 'SET_NW_TTL', ofp.OFPAT_DEC_NW_TTL: 'DEC_NW_TTL', ofp.OFPAT_SET_FIELD: 'SET_FIELD', ofp.OFPAT_PUSH_PBB: 'PUSH_PBB', ofp.OFPAT_POP_PBB: 'POP_PBB', ofp.OFPAT_EXPERIMENTER: 'EXPERIMENTER'} stats = dp.ofproto_parser.OFPGroupFeaturesStatsRequest(dp, 0) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) features = [] for msg in msgs: feature = msg.body types = [] for k, v in type_convert.items(): if (1 << k) & feature.types: if to_user: types.append(v) else: types.append(k) capabilities = [] for k, v in cap_convert.items(): if k & feature.capabilities: if to_user: capabilities.append(v) else: capabilities.append(k) if to_user: max_groups = [] for k, v in type_convert.items(): max_groups.append({v: feature.max_groups[k]}) else: max_groups = feature.max_groups actions = [] for k1, v1 in type_convert.items(): acts = [] for k2, v2 in act_convert.items(): if (1 << k2) & feature.actions[k1]: if to_user: acts.append(v2) else: acts.append(k2) if to_user: actions.append({v1: acts}) else: actions.append({k1: acts}) f = {'types': types, 'capabilities': capabilities, 'max_groups': max_groups, 'actions': actions} features.append(f) return wrap_dpid_dict(dp, features, to_user) def get_group_desc(dp, waiters, to_user=True): stats = dp.ofproto_parser.OFPGroupDescStatsRequest(dp, 0) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) descs = [] for msg in msgs: for stats in msg.body: d = stats.to_jsondict()[stats.__class__.__name__] buckets = [] for bucket in stats.buckets: b = bucket.to_jsondict()[bucket.__class__.__name__] actions = [] for action in bucket.actions: if to_user: actions.append(action_to_str(action)) else: actions.append(action) b['actions'] = actions buckets.append(b) d['buckets'] = buckets if to_user: d['group_id'] = UTIL.ofp_group_to_user(stats.group_id) t = UTIL.ofp_group_type_to_user(stats.type) d['type'] = t if t != stats.type else 'UNKNOWN' descs.append(d) return wrap_dpid_dict(dp, descs, to_user) def get_port_desc(dp, waiters, port_no=None, to_user=True): if port_no is None: port_no = dp.ofproto.OFPP_ANY else: port_no = UTIL.ofp_port_from_user(port_no) stats = dp.ofproto_parser.OFPPortDescStatsRequest(dp, 0, port_no) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) descs = [] for msg in msgs: stats = msg.body for stat in stats: d = stat.to_jsondict()[stat.__class__.__name__] properties = [] for prop in stat.properties: p = prop.to_jsondict()[prop.__class__.__name__] if to_user: t = UTIL.ofp_port_desc_prop_type_to_user(prop.type) p['type'] = t if t != prop.type else 'UNKNOWN' properties.append(p) d['name'] = stat.name.decode('utf-8') d['properties'] = properties if to_user: d['port_no'] = UTIL.ofp_port_to_user(stat.port_no) descs.append(d) return wrap_dpid_dict(dp, descs, to_user) def get_role(dp, waiters, to_user=True): return ofctl_utils.get_role(dp, waiters, to_user) def mod_flow_entry(dp, flow, cmd): cookie = str_to_int(flow.get('cookie', 0)) cookie_mask = str_to_int(flow.get('cookie_mask', 0)) table_id = UTIL.ofp_table_from_user(flow.get('table_id', 0)) idle_timeout = str_to_int(flow.get('idle_timeout', 0)) hard_timeout = str_to_int(flow.get('hard_timeout', 0)) priority = str_to_int(flow.get('priority', 0)) buffer_id = UTIL.ofp_buffer_from_user( flow.get('buffer_id', dp.ofproto.OFP_NO_BUFFER)) out_port = UTIL.ofp_port_from_user( flow.get('out_port', dp.ofproto.OFPP_ANY)) out_group = UTIL.ofp_group_from_user( flow.get('out_group', dp.ofproto.OFPG_ANY)) importance = str_to_int(flow.get('importance', 0)) flags = str_to_int(flow.get('flags', 0)) match = to_match(dp, flow.get('match', {})) inst = to_instructions(dp, flow.get('instructions', [])) flow_mod = dp.ofproto_parser.OFPFlowMod( dp, cookie, cookie_mask, table_id, cmd, idle_timeout, hard_timeout, priority, buffer_id, out_port, out_group, flags, importance, match, inst) ofctl_utils.send_msg(dp, flow_mod, LOG) def mod_meter_entry(dp, meter, cmd): flags = 0 if 'flags' in meter: meter_flags = meter['flags'] if not isinstance(meter_flags, list): meter_flags = [meter_flags] for flag in meter_flags: t = UTIL.ofp_meter_flags_from_user(flag) f = t if t != flag else None if f is None: LOG.error('Unknown meter flag: %s', flag) continue flags |= f meter_id = UTIL.ofp_meter_from_user(meter.get('meter_id', 0)) bands = [] for band in meter.get('bands', []): band_type = band.get('type') rate = str_to_int(band.get('rate', 0)) burst_size = str_to_int(band.get('burst_size', 0)) if band_type == 'DROP': bands.append( dp.ofproto_parser.OFPMeterBandDrop(rate, burst_size)) elif band_type == 'DSCP_REMARK': prec_level = str_to_int(band.get('prec_level', 0)) bands.append( dp.ofproto_parser.OFPMeterBandDscpRemark( rate, burst_size, prec_level)) elif band_type == 'EXPERIMENTER': experimenter = str_to_int(band.get('experimenter', 0)) bands.append( dp.ofproto_parser.OFPMeterBandExperimenter( rate, burst_size, experimenter)) else: LOG.error('Unknown band type: %s', band_type) meter_mod = dp.ofproto_parser.OFPMeterMod( dp, cmd, flags, meter_id, bands) ofctl_utils.send_msg(dp, meter_mod, LOG) def mod_group_entry(dp, group, cmd): group_type = str(group.get('type', 'ALL')) t = UTIL.ofp_group_type_from_user(group_type) group_type = t if t != group_type else None if group_type is None: LOG.error('Unknown group type: %s', group.get('type')) group_id = UTIL.ofp_group_from_user(group.get('group_id', 0)) buckets = [] for bucket in group.get('buckets', []): weight = str_to_int(bucket.get('weight', 0)) watch_port = str_to_int( bucket.get('watch_port', dp.ofproto.OFPP_ANY)) watch_group = str_to_int( bucket.get('watch_group', dp.ofproto.OFPG_ANY)) actions = [] for dic in bucket.get('actions', []): action = to_action(dp, dic) if action is not None: actions.append(action) buckets.append(dp.ofproto_parser.OFPBucket( weight, watch_port, watch_group, actions)) group_mod = dp.ofproto_parser.OFPGroupMod( dp, cmd, group_type, group_id, buckets) ofctl_utils.send_msg(dp, group_mod, LOG) def mod_port_behavior(dp, port_config): ofp = dp.ofproto parser = dp.ofproto_parser port_no = UTIL.ofp_port_from_user(port_config.get('port_no', 0)) hw_addr = str(port_config.get('hw_addr')) config = str_to_int(port_config.get('config', 0)) mask = str_to_int(port_config.get('mask', 0)) properties = port_config.get('properties') prop = [] for p in properties: type_ = UTIL.ofp_port_mod_prop_type_from_user(p['type']) length = None if type_ == ofp.OFPPDPT_ETHERNET: advertise = UTIL.ofp_port_features_from_user(p['advertise']) prop.append( parser.OFPPortModPropEthernet(type_, length, advertise)) elif type_ == ofp.OFPPDPT_OPTICAL: prop.append( parser.OFPPortModPropOptical( type_, length, p['configure'], p['freq_lmda'], p['fl_offset'], p['grid_span'], p['tx_pwr'])) elif type_ == ofp.OFPPDPT_EXPERIMENTER: prop.append( parser.OFPPortModPropExperimenter( type_, length, p['experimenter'], p['exp_type'], p['data'])) else: LOG.error('Unknown port desc prop type: %s', type_) port_mod = dp.ofproto_parser.OFPPortMod( dp, port_no, hw_addr, config, mask, prop) ofctl_utils.send_msg(dp, port_mod, LOG) def set_role(dp, role): r = UTIL.ofp_role_from_user(role.get('role', dp.ofproto.OFPCR_ROLE_EQUAL)) role_request = dp.ofproto_parser.OFPRoleRequest(dp, r, 0) ofctl_utils.send_msg(dp, role_request, LOG) # NOTE(jkoelker) Alias common funcitons send_experimenter = ofctl_utils.send_experimenter ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/ofctl_v1_5.py0000664000175000017500000011352700000000000017361 0ustar00zuulzuul00000000000000# Copyright (C) 2016 Nippon Telegraph and Telephone 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. import base64 import logging from os_ken.ofproto import ether from os_ken.ofproto import ofproto_v1_5 from os_ken.ofproto import ofproto_v1_5_parser from os_ken.lib import ofctl_utils LOG = logging.getLogger(__name__) DEFAULT_TIMEOUT = 1.0 UTIL = ofctl_utils.OFCtlUtil(ofproto_v1_5) str_to_int = ofctl_utils.str_to_int def to_action(dp, dic): ofp = dp.ofproto parser = dp.ofproto_parser action_type = dic.get('type') return ofctl_utils.to_action(dic, ofp, parser, action_type, UTIL) def _get_actions(dp, dics): actions = [] for d in dics: action = to_action(dp, d) if action is not None: actions.append(action) else: LOG.error('Unknown action type: %s', d) return actions def to_instructions(dp, insts): instructions = [] ofp = dp.ofproto parser = dp.ofproto_parser for i in insts: inst_type = i.get('type') if inst_type in ['APPLY_ACTIONS', 'WRITE_ACTIONS']: dics = i.get('actions', []) actions = _get_actions(dp, dics) if actions: if inst_type == 'APPLY_ACTIONS': instructions.append( parser.OFPInstructionActions(ofp.OFPIT_APPLY_ACTIONS, actions)) else: instructions.append( parser.OFPInstructionActions(ofp.OFPIT_WRITE_ACTIONS, actions)) elif inst_type == 'CLEAR_ACTIONS': instructions.append( parser.OFPInstructionActions(ofp.OFPIT_CLEAR_ACTIONS, [])) elif inst_type == 'GOTO_TABLE': table_id = str_to_int(i.get('table_id')) instructions.append(parser.OFPInstructionGotoTable(table_id)) elif inst_type == 'WRITE_METADATA': metadata = str_to_int(i.get('metadata')) metadata_mask = (str_to_int(i['metadata_mask']) if 'metadata_mask' in i else parser.UINT64_MAX) instructions.append( parser.OFPInstructionWriteMetadata( metadata, metadata_mask)) else: LOG.error('Unknown instruction type: %s', inst_type) return instructions def action_to_str(act): s = act.to_jsondict()[act.__class__.__name__] t = UTIL.ofp_action_type_to_user(s['type']) s['type'] = t if t != s['type'] else 'UNKNOWN' if t == 'SET_FIELD': field = s.pop('field') s['field'] = field['OXMTlv']['field'] s['mask'] = field['OXMTlv']['mask'] s['value'] = field['OXMTlv']['value'] elif t == 'COPY_FIELD': oxm_ids = s.pop('oxm_ids') s['src_oxm_id'] = oxm_ids[0]['OFPOxmId']['type'] s['dst_oxm_id'] = oxm_ids[1]['OFPOxmId']['type'] return s def instructions_to_str(instructions): s = [] for i in instructions: v = i.to_jsondict()[i.__class__.__name__] t = UTIL.ofp_instruction_type_to_user(v['type']) inst_type = t if t != v['type'] else 'UNKNOWN' # apply/write/clear-action instruction if isinstance(i, ofproto_v1_5_parser.OFPInstructionActions): acts = [] for a in i.actions: acts.append(action_to_str(a)) v['type'] = inst_type v['actions'] = acts s.append(v) # others else: v['type'] = inst_type s.append(v) return s def to_match(dp, attrs): convert = {'in_port': UTIL.ofp_port_from_user, 'in_phy_port': str_to_int, 'metadata': ofctl_utils.to_match_masked_int, 'eth_dst': ofctl_utils.to_match_eth, 'eth_src': ofctl_utils.to_match_eth, 'eth_type': str_to_int, 'vlan_vid': to_match_vid, 'vlan_pcp': str_to_int, 'ip_dscp': str_to_int, 'ip_ecn': str_to_int, 'ip_proto': str_to_int, 'ipv4_src': ofctl_utils.to_match_ip, 'ipv4_dst': ofctl_utils.to_match_ip, 'tcp_src': str_to_int, 'tcp_dst': str_to_int, 'udp_src': str_to_int, 'udp_dst': str_to_int, 'sctp_src': str_to_int, 'sctp_dst': str_to_int, 'icmpv4_type': str_to_int, 'icmpv4_code': str_to_int, 'arp_op': str_to_int, 'arp_spa': ofctl_utils.to_match_ip, 'arp_tpa': ofctl_utils.to_match_ip, 'arp_sha': ofctl_utils.to_match_eth, 'arp_tha': ofctl_utils.to_match_eth, 'ipv6_src': ofctl_utils.to_match_ip, 'ipv6_dst': ofctl_utils.to_match_ip, 'ipv6_flabel': str_to_int, 'icmpv6_type': str_to_int, 'icmpv6_code': str_to_int, 'ipv6_nd_target': ofctl_utils.to_match_ip, 'ipv6_nd_sll': ofctl_utils.to_match_eth, 'ipv6_nd_tll': ofctl_utils.to_match_eth, 'mpls_label': str_to_int, 'mpls_tc': str_to_int, 'mpls_bos': str_to_int, 'pbb_isid': ofctl_utils.to_match_masked_int, 'tunnel_id': ofctl_utils.to_match_masked_int, 'ipv6_exthdr': ofctl_utils.to_match_masked_int, 'pbb_uca': str_to_int, 'tcp_flags': str_to_int, 'actset_output': str_to_int, 'packet_type': ofctl_utils.to_match_packet_type} keys = {'dl_dst': 'eth_dst', 'dl_src': 'eth_src', 'dl_type': 'eth_type', 'dl_vlan': 'vlan_vid', 'nw_src': 'ipv4_src', 'nw_dst': 'ipv4_dst', 'nw_proto': 'ip_proto'} if attrs.get('eth_type') == ether.ETH_TYPE_ARP: if 'ipv4_src' in attrs and 'arp_spa' not in attrs: attrs['arp_spa'] = attrs['ipv4_src'] del attrs['ipv4_src'] if 'ipv4_dst' in attrs and 'arp_tpa' not in attrs: attrs['arp_tpa'] = attrs['ipv4_dst'] del attrs['ipv4_dst'] kwargs = {} for key, value in attrs.items(): if key in keys: # For old field name key = keys[key] if key in convert: value = convert[key](value) kwargs[key] = value else: LOG.error('Unknown match field: %s', key) return dp.ofproto_parser.OFPMatch(**kwargs) def to_match_vid(value): return ofctl_utils.to_match_vid(value, ofproto_v1_5.OFPVID_PRESENT) def match_to_str(ofmatch): match = {} ofmatch = ofmatch.to_jsondict()['OFPMatch'] ofmatch = ofmatch['oxm_fields'] for match_field in ofmatch: key = match_field['OXMTlv']['field'] mask = match_field['OXMTlv']['mask'] value = match_field['OXMTlv']['value'] if key == 'vlan_vid': value = match_vid_to_str(value, mask) elif key == 'in_port': value = UTIL.ofp_port_to_user(value) elif key == 'packet_type': value = [value >> 16, value & 0xffff] else: if mask is not None: value = str(value) + '/' + str(mask) match.setdefault(key, value) return match def match_vid_to_str(value, mask): return ofctl_utils.match_vid_to_str( value, mask, ofproto_v1_5.OFPVID_PRESENT) def wrap_dpid_dict(dp, value, to_user=True): if to_user: return {str(dp.id): value} return {dp.id: value} def stats_to_str(ofstats): stats = {} ofstats = ofstats.to_jsondict()['OFPStats'] ofstats = ofstats['oxs_fields'] for s in ofstats: key = s['OXSTlv']['field'] if key == 'duration': value = { 'duration_sec': s['OXSTlv']['value'][0], 'duration_nsec': s['OXSTlv']['value'][1], } elif key == 'idle_time': value = { 'idle_time_sec': s['OXSTlv']['value'][0], 'idle_time_nsec': s['OXSTlv']['value'][1], } else: value = s['OXSTlv']['value'] stats.setdefault(key, value) return stats def get_desc_stats(dp, waiters, to_user=True): stats = dp.ofproto_parser.OFPDescStatsRequest(dp, 0) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) s = {} for msg in msgs: stats = msg.body s = stats.to_jsondict()[stats.__class__.__name__] return wrap_dpid_dict(dp, s, to_user) def get_queue_stats(dp, waiters, port_no=None, queue_id=None, to_user=True): if port_no is None: port_no = dp.ofproto.OFPP_ANY else: port_no = UTIL.ofp_port_from_user(port_no) if queue_id is None: queue_id = dp.ofproto.OFPQ_ALL else: queue_id = UTIL.ofp_queue_from_user(queue_id) stats = dp.ofproto_parser.OFPQueueStatsRequest( dp, 0, port_no, queue_id) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) desc = [] for msg in msgs: stats = msg.body for stat in stats: s = stat.to_jsondict()[stat.__class__.__name__] properties = [] for prop in stat.properties: p = prop.to_jsondict()[prop.__class__.__name__] if to_user: t = UTIL.ofp_queue_stats_prop_type_to_user(prop.type) p['type'] = t if t != p['type'] else 'UNKNOWN' properties.append(p) s['properties'] = properties desc.append(s) return wrap_dpid_dict(dp, desc, to_user) def get_queue_desc(dp, waiters, port_no=None, queue_id=None, to_user=True): if port_no is None: port_no = dp.ofproto.OFPP_ANY else: port_no = UTIL.ofp_port_from_user(port_no) if queue_id is None: queue_id = dp.ofproto.OFPQ_ALL else: queue_id = UTIL.ofp_queue_from_user(queue_id) stats = dp.ofproto_parser.OFPQueueDescStatsRequest( dp, 0, port_no, queue_id) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) configs = [] for msg in msgs: for queue in msg.body: q = queue.to_jsondict()[queue.__class__.__name__] prop_list = [] for prop in queue.properties: p = prop.to_jsondict()[prop.__class__.__name__] if to_user: t = UTIL.ofp_queue_desc_prop_type_to_user(prop.type) p['type'] = t if t != prop.type else 'UNKNOWN' prop_list.append(p) q['properties'] = prop_list configs.append(q) return wrap_dpid_dict(dp, configs, to_user) def get_flow_desc_stats(dp, waiters, flow=None, to_user=True): flow = flow if flow else {} table_id = UTIL.ofp_table_from_user( flow.get('table_id', dp.ofproto.OFPTT_ALL)) flags = str_to_int(flow.get('flags', 0)) out_port = UTIL.ofp_port_from_user( flow.get('out_port', dp.ofproto.OFPP_ANY)) out_group = UTIL.ofp_group_from_user( flow.get('out_group', dp.ofproto.OFPG_ANY)) cookie = str_to_int(flow.get('cookie', 0)) cookie_mask = str_to_int(flow.get('cookie_mask', 0)) match = to_match(dp, flow.get('match', {})) # Note: OpenFlow does not allow to filter flow entries by priority, # but for efficiency, ofctl provides the way to do it. priority = str_to_int(flow.get('priority', -1)) stats = dp.ofproto_parser.OFPFlowDescStatsRequest( dp, flags, table_id, out_port, out_group, cookie, cookie_mask, match) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) flows = [] for msg in msgs: for stats in msg.body: if 0 <= priority != stats.priority: continue s = stats.to_jsondict()[stats.__class__.__name__] s['instructions'] = instructions_to_str(stats.instructions) s['stats'] = stats_to_str(stats.stats) s['match'] = match_to_str(stats.match) flows.append(s) return wrap_dpid_dict(dp, flows, to_user) def get_flow_stats(dp, waiters, flow=None, to_user=True): flow = flow if flow else {} table_id = UTIL.ofp_table_from_user( flow.get('table_id', dp.ofproto.OFPTT_ALL)) flags = str_to_int(flow.get('flags', 0)) out_port = UTIL.ofp_port_from_user( flow.get('out_port', dp.ofproto.OFPP_ANY)) out_group = UTIL.ofp_group_from_user( flow.get('out_group', dp.ofproto.OFPG_ANY)) cookie = str_to_int(flow.get('cookie', 0)) cookie_mask = str_to_int(flow.get('cookie_mask', 0)) match = to_match(dp, flow.get('match', {})) # Note: OpenFlow does not allow to filter flow entries by priority, # but for efficiency, ofctl provides the way to do it. priority = str_to_int(flow.get('priority', -1)) stats = dp.ofproto_parser.OFPFlowStatsRequest( dp, flags, table_id, out_port, out_group, cookie, cookie_mask, match) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) flows = [] for msg in msgs: for stats in msg.body: if 0 <= priority != stats.priority: continue s = stats.to_jsondict()[stats.__class__.__name__] s['stats'] = stats_to_str(stats.stats) s['match'] = match_to_str(stats.match) flows.append(s) return wrap_dpid_dict(dp, flows, to_user) def get_aggregate_flow_stats(dp, waiters, flow=None, to_user=True): flow = flow if flow else {} table_id = UTIL.ofp_table_from_user( flow.get('table_id', dp.ofproto.OFPTT_ALL)) flags = str_to_int(flow.get('flags', 0)) out_port = UTIL.ofp_port_from_user( flow.get('out_port', dp.ofproto.OFPP_ANY)) out_group = UTIL.ofp_group_from_user( flow.get('out_group', dp.ofproto.OFPG_ANY)) cookie = str_to_int(flow.get('cookie', 0)) cookie_mask = str_to_int(flow.get('cookie_mask', 0)) match = to_match(dp, flow.get('match', {})) stats = dp.ofproto_parser.OFPAggregateStatsRequest( dp, flags, table_id, out_port, out_group, cookie, cookie_mask, match) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) flows = [] for msg in msgs: stats = msg.body s = stats.to_jsondict()[stats.__class__.__name__] s['stats'] = stats_to_str(stats.stats) flows.append(s) return wrap_dpid_dict(dp, flows, to_user) def get_table_stats(dp, waiters, to_user=True): stats = dp.ofproto_parser.OFPTableStatsRequest(dp, 0) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) tables = [] for msg in msgs: stats = msg.body for stat in stats: s = stat.to_jsondict()[stat.__class__.__name__] if to_user: s['table_id'] = UTIL.ofp_table_to_user(stat.table_id) tables.append(s) return wrap_dpid_dict(dp, tables, to_user) def get_table_features(dp, waiters, to_user=True): stats = dp.ofproto_parser.OFPTableFeaturesStatsRequest(dp, 0, []) msgs = [] ofproto = dp.ofproto ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) p_type_instructions = [ofproto.OFPTFPT_INSTRUCTIONS, ofproto.OFPTFPT_INSTRUCTIONS_MISS] p_type_next_tables = [ofproto.OFPTFPT_NEXT_TABLES, ofproto.OFPTFPT_NEXT_TABLES_MISS, ofproto.OFPTFPT_TABLE_SYNC_FROM] p_type_actions = [ofproto.OFPTFPT_WRITE_ACTIONS, ofproto.OFPTFPT_WRITE_ACTIONS_MISS, ofproto.OFPTFPT_APPLY_ACTIONS, ofproto.OFPTFPT_APPLY_ACTIONS_MISS] p_type_packet = ofproto.OFPTFPT_PACKET_TYPES p_type_oxms = [ofproto.OFPTFPT_MATCH, ofproto.OFPTFPT_WILDCARDS, ofproto.OFPTFPT_WRITE_SETFIELD, ofproto.OFPTFPT_WRITE_SETFIELD_MISS, ofproto.OFPTFPT_APPLY_SETFIELD, ofproto.OFPTFPT_APPLY_SETFIELD_MISS, ofproto.OFPTFPT_WRITE_COPYFIELD, ofproto.OFPTFPT_WRITE_COPYFIELD_MISS, ofproto.OFPTFPT_APPLY_COPYFIELD, ofproto.OFPTFPT_APPLY_COPYFIELD_MISS] p_type_experimenter = [ofproto.OFPTFPT_EXPERIMENTER, ofproto.OFPTFPT_EXPERIMENTER_MISS] tables = [] for msg in msgs: stats = msg.body for stat in stats: s = stat.to_jsondict()[stat.__class__.__name__] properties = [] for prop in stat.properties: p = {} t = UTIL.ofp_table_feature_prop_type_to_user(prop.type) p['type'] = t if t != prop.type else 'UNKNOWN' if prop.type in p_type_instructions: instruction_ids = [] for i in prop.instruction_ids: inst = {'len': i.len, 'type': i.type} instruction_ids.append(inst) p['instruction_ids'] = instruction_ids elif prop.type in p_type_next_tables: table_ids = [] for i in prop.table_ids: table_ids.append(i) p['table_ids'] = table_ids elif prop.type in p_type_actions: action_ids = [] for i in prop.action_ids: act = i.to_jsondict()[i.__class__.__name__] action_ids.append(act) p['action_ids'] = action_ids elif prop.type in p_type_oxms: oxm_ids = [] for i in prop.oxm_ids: oxm = i.to_jsondict()[i.__class__.__name__] oxm_ids.append(oxm) p['oxm_ids'] = oxm_ids elif prop.type == p_type_packet: oxm_values = [] for val in prop.oxm_values: i = {val[0]: val[1]} oxm_values.append(i) p['oxm_values'] = oxm_values elif prop.type in p_type_experimenter: pass properties.append(p) s['name'] = stat.name.decode('utf-8') s['properties'] = properties if to_user: s['table_id'] = UTIL.ofp_table_to_user(stat.table_id) tables.append(s) return wrap_dpid_dict(dp, tables, to_user) def get_port_stats(dp, waiters, port_no=None, to_user=True): if port_no is None: port_no = dp.ofproto.OFPP_ANY else: port_no = UTIL.ofp_port_from_user(port_no) stats = dp.ofproto_parser.OFPPortStatsRequest(dp, 0, port_no) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) ports = [] for msg in msgs: for stats in msg.body: s = stats.to_jsondict()[stats.__class__.__name__] properties = [] for prop in stats.properties: p = prop.to_jsondict()[prop.__class__.__name__] t = UTIL.ofp_port_stats_prop_type_to_user(prop.type) p['type'] = t if t != prop.type else 'UNKNOWN' properties.append(p) s['properties'] = properties if to_user: s['port_no'] = UTIL.ofp_port_to_user(stats.port_no) ports.append(s) return wrap_dpid_dict(dp, ports, to_user) def get_meter_stats(dp, waiters, meter_id=None, to_user=True): if meter_id is None: meter_id = dp.ofproto.OFPM_ALL else: meter_id = UTIL.ofp_meter_from_user(meter_id) stats = dp.ofproto_parser.OFPMeterStatsRequest( dp, 0, meter_id) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) meters = [] for msg in msgs: for stats in msg.body: s = stats.to_jsondict()[stats.__class__.__name__] bands = [] for band in stats.band_stats: b = band.to_jsondict()[band.__class__.__name__] bands.append(b) s['band_stats'] = bands if to_user: s['meter_id'] = UTIL.ofp_meter_to_user(stats.meter_id) meters.append(s) return wrap_dpid_dict(dp, meters, to_user) def get_meter_features(dp, waiters, to_user=True): ofp = dp.ofproto type_convert = {ofp.OFPMBT_DROP: 'DROP', ofp.OFPMBT_DSCP_REMARK: 'DSCP_REMARK'} capa_convert = {ofp.OFPMF_KBPS: 'KBPS', ofp.OFPMF_PKTPS: 'PKTPS', ofp.OFPMF_BURST: 'BURST', ofp.OFPMF_STATS: 'STATS'} stats = dp.ofproto_parser.OFPMeterFeaturesStatsRequest(dp, 0) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) features = [] for msg in msgs: for feature in msg.body: band_types = [] for k, v in type_convert.items(): if (1 << k) & feature.band_types: if to_user: band_types.append(v) else: band_types.append(k) capabilities = [] for k, v in sorted(capa_convert.items()): if k & feature.capabilities: if to_user: capabilities.append(v) else: capabilities.append(k) f = {'max_meter': feature.max_meter, 'band_types': band_types, 'capabilities': capabilities, 'max_bands': feature.max_bands, 'max_color': feature.max_color} features.append(f) return wrap_dpid_dict(dp, features, to_user) def get_meter_desc(dp, waiters, meter_id=None, to_user=True): flags = {dp.ofproto.OFPMF_KBPS: 'KBPS', dp.ofproto.OFPMF_PKTPS: 'PKTPS', dp.ofproto.OFPMF_BURST: 'BURST', dp.ofproto.OFPMF_STATS: 'STATS'} if meter_id is None: meter_id = dp.ofproto.OFPM_ALL else: meter_id = UTIL.ofp_meter_from_user(meter_id) stats = dp.ofproto_parser.OFPMeterDescStatsRequest( dp, 0, meter_id) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) configs = [] for msg in msgs: for config in msg.body: c = config.to_jsondict()[config.__class__.__name__] bands = [] for band in config.bands: b = band.to_jsondict()[band.__class__.__name__] if to_user: t = UTIL.ofp_meter_band_type_to_user(band.type) b['type'] = t if t != band.type else 'UNKNOWN' bands.append(b) c_flags = [] for k, v in sorted(flags.items()): if k & config.flags: if to_user: c_flags.append(v) else: c_flags.append(k) c['flags'] = c_flags c['bands'] = bands if to_user: c['meter_id'] = UTIL.ofp_meter_to_user(config.meter_id) configs.append(c) return wrap_dpid_dict(dp, configs, to_user) def get_group_stats(dp, waiters, group_id=None, to_user=True): if group_id is None: group_id = dp.ofproto.OFPG_ALL else: group_id = UTIL.ofp_group_from_user(group_id) stats = dp.ofproto_parser.OFPGroupStatsRequest( dp, 0, group_id) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) groups = [] for msg in msgs: for stats in msg.body: g = stats.to_jsondict()[stats.__class__.__name__] bucket_stats = [] for bucket_stat in stats.bucket_stats: c = bucket_stat.to_jsondict()[bucket_stat.__class__.__name__] bucket_stats.append(c) g['bucket_stats'] = bucket_stats if to_user: g['group_id'] = UTIL.ofp_group_to_user(stats.group_id) groups.append(g) return wrap_dpid_dict(dp, groups, to_user) def get_group_features(dp, waiters, to_user=True): ofp = dp.ofproto type_convert = {ofp.OFPGT_ALL: 'ALL', ofp.OFPGT_SELECT: 'SELECT', ofp.OFPGT_INDIRECT: 'INDIRECT', ofp.OFPGT_FF: 'FF'} cap_convert = {ofp.OFPGFC_SELECT_WEIGHT: 'SELECT_WEIGHT', ofp.OFPGFC_SELECT_LIVENESS: 'SELECT_LIVENESS', ofp.OFPGFC_CHAINING: 'CHAINING', ofp.OFPGFC_CHAINING_CHECKS: 'CHAINING_CHECKS'} act_convert = {ofp.OFPAT_OUTPUT: 'OUTPUT', ofp.OFPAT_COPY_TTL_OUT: 'COPY_TTL_OUT', ofp.OFPAT_COPY_TTL_IN: 'COPY_TTL_IN', ofp.OFPAT_SET_MPLS_TTL: 'SET_MPLS_TTL', ofp.OFPAT_DEC_MPLS_TTL: 'DEC_MPLS_TTL', ofp.OFPAT_PUSH_VLAN: 'PUSH_VLAN', ofp.OFPAT_POP_VLAN: 'POP_VLAN', ofp.OFPAT_PUSH_MPLS: 'PUSH_MPLS', ofp.OFPAT_POP_MPLS: 'POP_MPLS', ofp.OFPAT_SET_QUEUE: 'SET_QUEUE', ofp.OFPAT_GROUP: 'GROUP', ofp.OFPAT_SET_NW_TTL: 'SET_NW_TTL', ofp.OFPAT_DEC_NW_TTL: 'DEC_NW_TTL', ofp.OFPAT_SET_FIELD: 'SET_FIELD', ofp.OFPAT_PUSH_PBB: 'PUSH_PBB', ofp.OFPAT_POP_PBB: 'POP_PBB', ofp.OFPAT_COPY_FIELD: 'COPY_FIELD', ofp.OFPAT_METER: 'METER', ofp.OFPAT_EXPERIMENTER: 'EXPERIMENTER'} stats = dp.ofproto_parser.OFPGroupFeaturesStatsRequest(dp, 0) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) features = [] for msg in msgs: feature = msg.body types = [] for k, v in type_convert.items(): if (1 << k) & feature.types: if to_user: types.append(v) else: types.append(k) capabilities = [] for k, v in cap_convert.items(): if k & feature.capabilities: if to_user: capabilities.append(v) else: capabilities.append(k) if to_user: max_groups = [] for k, v in type_convert.items(): max_groups.append({v: feature.max_groups[k]}) else: max_groups = feature.max_groups actions = [] for k1, v1 in type_convert.items(): acts = [] for k2, v2 in act_convert.items(): if (1 << k2) & feature.actions[k1]: if to_user: acts.append(v2) else: acts.append(k2) if to_user: actions.append({v1: acts}) else: actions.append({k1: acts}) f = {'types': types, 'capabilities': capabilities, 'max_groups': max_groups, 'actions': actions} features.append(f) return wrap_dpid_dict(dp, features, to_user) def get_group_desc(dp, waiters, group_id=None, to_user=True): if group_id is None: group_id = dp.ofproto.OFPG_ALL else: group_id = UTIL.ofp_group_from_user(group_id) stats = dp.ofproto_parser.OFPGroupDescStatsRequest(dp, 0, group_id) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) descs = [] for msg in msgs: for stats in msg.body: d = stats.to_jsondict()[stats.__class__.__name__] buckets = [] for bucket in stats.buckets: b = bucket.to_jsondict()[bucket.__class__.__name__] actions = [] for action in bucket.actions: if to_user: actions.append(action_to_str(action)) else: actions.append(action) properties = [] for prop in bucket.properties: p = prop.to_jsondict()[prop.__class__.__name__] t = UTIL.ofp_group_bucket_prop_type_to_user(prop.type) p['type'] = t if t != prop.type else 'UNKNOWN' properties.append(p) b['actions'] = actions b['properties'] = properties buckets.append(b) d['buckets'] = buckets if to_user: d['group_id'] = UTIL.ofp_group_to_user(stats.group_id) t = UTIL.ofp_group_type_to_user(stats.type) d['type'] = t if t != stats.type else 'UNKNOWN' descs.append(d) return wrap_dpid_dict(dp, descs, to_user) def get_port_desc(dp, waiters, port_no=None, to_user=True): if port_no is None: port_no = dp.ofproto.OFPP_ANY else: port_no = UTIL.ofp_port_from_user(port_no) stats = dp.ofproto_parser.OFPPortDescStatsRequest(dp, 0, port_no) msgs = [] ofctl_utils.send_stats_request(dp, stats, waiters, msgs, LOG) descs = [] for msg in msgs: stats = msg.body for stat in stats: d = stat.to_jsondict()[stat.__class__.__name__] properties = [] for prop in stat.properties: p = prop.to_jsondict()[prop.__class__.__name__] if to_user: t = UTIL.ofp_port_desc_prop_type_to_user(prop.type) p['type'] = t if t != prop.type else 'UNKNOWN' properties.append(p) d['name'] = stat.name.decode('utf-8') d['properties'] = properties if to_user: d['port_no'] = UTIL.ofp_port_to_user(stat.port_no) descs.append(d) return wrap_dpid_dict(dp, descs, to_user) def get_role(dp, waiters, to_user=True): return ofctl_utils.get_role(dp, waiters, to_user) def mod_flow_entry(dp, flow, cmd): cookie = str_to_int(flow.get('cookie', 0)) cookie_mask = str_to_int(flow.get('cookie_mask', 0)) table_id = UTIL.ofp_table_from_user(flow.get('table_id', 0)) idle_timeout = str_to_int(flow.get('idle_timeout', 0)) hard_timeout = str_to_int(flow.get('hard_timeout', 0)) priority = str_to_int(flow.get('priority', 0)) buffer_id = UTIL.ofp_buffer_from_user( flow.get('buffer_id', dp.ofproto.OFP_NO_BUFFER)) out_port = UTIL.ofp_port_from_user( flow.get('out_port', dp.ofproto.OFPP_ANY)) out_group = UTIL.ofp_group_from_user( flow.get('out_group', dp.ofproto.OFPG_ANY)) importance = str_to_int(flow.get('importance', 0)) flags = str_to_int(flow.get('flags', 0)) match = to_match(dp, flow.get('match', {})) inst = to_instructions(dp, flow.get('instructions', [])) flow_mod = dp.ofproto_parser.OFPFlowMod( dp, cookie, cookie_mask, table_id, cmd, idle_timeout, hard_timeout, priority, buffer_id, out_port, out_group, importance, flags, match, inst) ofctl_utils.send_msg(dp, flow_mod, LOG) def mod_meter_entry(dp, meter, cmd): flags = 0 if 'flags' in meter: meter_flags = meter['flags'] if not isinstance(meter_flags, list): meter_flags = [meter_flags] for flag in meter_flags: t = UTIL.ofp_meter_flags_from_user(flag) f = t if t != flag else None if f is None: LOG.error('Unknown meter flag: %s', flag) continue flags |= f meter_id = UTIL.ofp_meter_from_user(meter.get('meter_id', 0)) bands = [] for band in meter.get('bands', []): band_type = band.get('type') rate = str_to_int(band.get('rate', 0)) burst_size = str_to_int(band.get('burst_size', 0)) if band_type == 'DROP': bands.append( dp.ofproto_parser.OFPMeterBandDrop(rate, burst_size)) elif band_type == 'DSCP_REMARK': prec_level = str_to_int(band.get('prec_level', 0)) bands.append( dp.ofproto_parser.OFPMeterBandDscpRemark( rate, burst_size, prec_level)) elif band_type == 'EXPERIMENTER': experimenter = str_to_int(band.get('experimenter', 0)) bands.append( dp.ofproto_parser.OFPMeterBandExperimenter( rate, burst_size, experimenter)) else: LOG.error('Unknown band type: %s', band_type) meter_mod = dp.ofproto_parser.OFPMeterMod( dp, cmd, flags, meter_id, bands) ofctl_utils.send_msg(dp, meter_mod, LOG) def mod_group_entry(dp, group, cmd): ofp = dp.ofproto parser = dp.ofproto_parser group_type = str(group.get('type', 'ALL')) t = UTIL.ofp_group_type_from_user(group_type) group_type = t if t != group_type else None if group_type is None: LOG.error('Unknown group type: %s', group.get('type')) group_id = UTIL.ofp_group_from_user(group.get('group_id', 0)) command_bucket_id = str_to_int(group.get('command_bucket_id', 0)) # Note: # The list of group property types that are currently defined # are only OFPGPT_EXPERIMENTER(Experimenter defined). properties = [] buckets = [] for bucket in group.get('buckets', []): # get bucket_id in buckets bucket_id = str_to_int(bucket.get('bucket_id', 0)) # get actions in buckets bucket_actions = [] for dic in bucket.get('actions', []): action = to_action(dp, dic) if action is not None: bucket_actions.append(action) # get properties in buckets bucket_properties = [] for p in bucket.get('properties', []): group_bp_type = str(p.get('type', 'WEIGHT')) t = UTIL.ofp_group_bucket_prop_type_from_user(group_bp_type) group_bp_type = t if t != group_bp_type else ofp.OFPGBPT_WEIGHT if group_bp_type == ofp.OFPGBPT_WEIGHT: weight = str_to_int(p.get('weight', 0)) bucket_properties.append( parser.OFPGroupBucketPropWeight( type_=group_bp_type, weight=weight)) elif group_bp_type == ofp.OFPGBPT_WATCH_PORT: watch_port = str_to_int(p.get('watch', dp.ofproto.OFPP_ANY)) bucket_properties.append( parser.OFPGroupBucketPropWatch( type_=group_bp_type, watch=watch_port)) elif group_bp_type == ofp.OFPGBPT_WATCH_GROUP: watch_group = str_to_int(p.get('watch', dp.ofproto.OFPG_ANY)) bucket_properties.append( parser.OFPGroupBucketPropWatch( type_=group_bp_type, watch=watch_group)) elif group_bp_type == ofp.OFPGBPT_EXPERIMENTER: experimenter = p.get('experimenter', 0) exp_type = p.get('exp_type', 0) data_type = p.get('data_type', 'ascii') if data_type not in ['ascii', 'base64']: LOG.error('Unknown data type: %s', data_type) data = p.get('data', '') if data_type == 'base64': data = base64.b64decode(data) bucket_properties.append( parser.OFPGroupBucketPropExperimenter( type_=group_bp_type, experimenter=experimenter, exp_type=exp_type, data=data)) else: LOG.error('Unknown group bucket prop type: %s', p['type']) # create bucket bucket = parser.OFPBucket(bucket_id=bucket_id, actions=bucket_actions, properties=bucket_properties) buckets.append(bucket) group_mod = parser.OFPGroupMod(dp, cmd, group_type, group_id, command_bucket_id, buckets, properties) ofctl_utils.send_msg(dp, group_mod, LOG) def mod_port_behavior(dp, port_config): ofp = dp.ofproto parser = dp.ofproto_parser port_no = UTIL.ofp_port_from_user(port_config.get('port_no', 0)) hw_addr = str(port_config.get('hw_addr')) config = str_to_int(port_config.get('config', 0)) mask = str_to_int(port_config.get('mask', 0)) properties = port_config.get('properties') prop = [] for p in properties: type_ = UTIL.ofp_port_mod_prop_type_from_user(p['type']) length = None if type_ == ofp.OFPPDPT_ETHERNET: advertise = UTIL.ofp_port_features_from_user(p['advertise']) prop.append( parser.OFPPortModPropEthernet(type_, length, advertise)) elif type_ == ofp.OFPPDPT_OPTICAL: prop.append( parser.OFPPortModPropOptical( type_, length, p['configure'], p['freq_lmda'], p['fl_offset'], p['grid_span'], p['tx_pwr'])) elif type_ == ofp.OFPPDPT_EXPERIMENTER: prop.append( parser.OFPPortModPropExperimenter( type_, length, p['experimenter'], p['exp_type'], p['data'])) else: LOG.error('Unknown port desc prop type: %s', type_) port_mod = dp.ofproto_parser.OFPPortMod( dp, port_no, hw_addr, config, mask, prop) ofctl_utils.send_msg(dp, port_mod, LOG) def set_role(dp, role): r = UTIL.ofp_role_from_user(role.get('role', dp.ofproto.OFPCR_ROLE_EQUAL)) role_request = dp.ofproto_parser.OFPRoleRequest(dp, r, None, 0) ofctl_utils.send_msg(dp, role_request, LOG) # NOTE(jkoelker) Alias common funcitons send_experimenter = ofctl_utils.send_experimenter ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/ofp_pktinfilter.py0000664000175000017500000000327100000000000020611 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Stratosphere Inc. # # 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. import abc import logging from os_ken.lib.packet import packet LOG = logging.getLogger(__name__) def packet_in_filter(cls, args=None, logging=False): def _packet_in_filter(packet_in_handler): def __packet_in_filter(self, ev): pkt = packet.Packet(ev.msg.data) if not packet_in_handler.pkt_in_filter.filter(pkt): if logging: LOG.debug('The packet is discarded by %s: %s', cls, pkt) return return packet_in_handler(self, ev) pkt_in_filter = cls(args) packet_in_handler.pkt_in_filter = pkt_in_filter return __packet_in_filter return _packet_in_filter class PacketInFilterBase(object, metaclass=abc.ABCMeta): def __init__(self, args): self.args = args @abc.abstractmethod def filter(self, pkt): pass class RequiredTypeFilter(PacketInFilterBase): def filter(self, pkt): required_types = self.args.get('types') or [] for required_type in required_types: if not pkt.get_protocol(required_type): return False return True ././@PaxHeader0000000000000000000000000000003300000000000011451 xustar000000000000000027 mtime=1724334546.082104 os-ken-2.10.0/os_ken/lib/ovs/0000775000175000017500000000000000000000000015644 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/ovs/__init__.py0000664000175000017500000000004300000000000017752 0ustar00zuulzuul00000000000000""" ovsdb interaction library. """ ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/ovs/bridge.py0000664000175000017500000004437400000000000017466 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2012 Isaku Yamahata # # 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 utility library of :py:mod:`os_ken.lib.ovs.vsctl` """ import functools import logging from os_ken import cfg import os_ken.exception as os_ken_exc import os_ken.lib.dpid as dpid_lib import os_ken.lib.ovs.vsctl as ovs_vsctl from os_ken.lib.ovs.vsctl import valid_ovsdb_addr LOG = logging.getLogger(__name__) CONF = cfg.CONF CONF.register_opts([ cfg.IntOpt('ovsdb-timeout', default=2, help='ovsdb timeout') ]) class OVSBridgeNotFound(os_ken_exc.OSKenException): message = 'no bridge for datapath_id %(datapath_id)s' class VifPort(object): def __init__(self, port_name, ofport, vif_id, vif_mac, switch): super(VifPort, self).__init__() self.port_name = port_name self.ofport = ofport self.vif_id = vif_id self.vif_mac = vif_mac self.switch = switch def __str__(self): return ('iface-id=%s, ' 'vif_mac=%s, ' 'port_name=%s, ' 'ofport=%d, ' 'bridge_name=%s' % (self.vif_id, self.vif_mac, self.port_name, self.ofport, self.switch.br_name)) class TunnelPort(object): def __init__(self, port_name, ofport, tunnel_type, local_ip, remote_ip): super(TunnelPort, self).__init__() self.port_name = port_name self.ofport = ofport self.tunnel_type = tunnel_type self.local_ip = local_ip self.remote_ip = remote_ip def __eq__(self, other): return (self.port_name == other.port_name and self.ofport == other.ofport and self.tunnel_type == other.tunnel_type and self.local_ip == other.local_ip and self.remote_ip == other.remote_ip) def __str__(self): return ('port_name=%s, ' 'ofport=%s, ' 'type=%s, ' 'local_ip=%s, ' 'remote_ip=%s' % (self.port_name, self.ofport, self.tunnel_type, self.local_ip, self.remote_ip)) class OVSBridge(object): """ Class to provide wrapper utilities of :py:mod:`os_ken.lib.ovs.vsctl.VSCtl` ``CONF`` is a instance of ``oslo_config.cfg.ConfigOpts``. Mostly ``self.CONF`` is sufficient to instantiate this class from your OSKen application. ``datapath_id`` specifies Datapath ID of the target OVS instance. ``ovsdb_addr`` specifies the address of the OVS instance. Automatically validated when you call ``init()`` method. Refer to :py:mod:`os_ken.lib.ovs.vsctl.valid_ovsdb_addr` for the format of this address. if ``timeout`` is omitted, ``CONF.ovsdb_timeout`` will be used as the default value. Usage of ``timeout`` and ``exception`` is the same with ``timeout_sec`` and ``exception`` of :py:mod:`os_ken.lib.ovs.vsctl.VSCtl.run_command`. """ def __init__(self, CONF, datapath_id, ovsdb_addr, timeout=None, exception=None, br_name=None): super(OVSBridge, self).__init__() self.datapath_id = datapath_id self.ovsdb_addr = ovsdb_addr self.vsctl = ovs_vsctl.VSCtl(ovsdb_addr) self.timeout = timeout or CONF.ovsdb_timeout self.exception = exception self.br_name = br_name def run_command(self, commands): """ Executes the given commands and sends OVSDB messages. ``commands`` must be a list of :py:mod:`os_ken.lib.ovs.vsctl.VSCtlCommand`. The given ``timeout`` and ``exception`` when instantiation will be used to call :py:mod:`os_ken.lib.ovs.vsctl.VSCtl.run_command`. """ self.vsctl.run_command(commands, self.timeout, self.exception) def init(self): """ Validates the given ``ovsdb_addr`` and connects to OVS instance. If failed to connect to OVS instance or the given ``datapath_id`` does not match with the Datapath ID of the connected OVS instance, raises :py:mod:`os_ken.lib.ovs.bridge.OVSBridgeNotFound` exception. """ if not valid_ovsdb_addr(self.ovsdb_addr): raise ValueError('Invalid OVSDB address: %s' % self.ovsdb_addr) if self.br_name is None: self.br_name = self._get_bridge_name() def _get_bridge_name(self): """ get Bridge name of a given 'datapath_id' """ command = ovs_vsctl.VSCtlCommand( 'find', ('Bridge', 'datapath_id=%s' % dpid_lib.dpid_to_str(self.datapath_id))) self.run_command([command]) if not isinstance(command.result, list) or len(command.result) != 1: raise OVSBridgeNotFound( datapath_id=dpid_lib.dpid_to_str(self.datapath_id)) return command.result[0].name def get_controller(self): """ Gets the configured OpenFlow controller address. This method is corresponding to the following ovs-vsctl command:: $ ovs-vsctl get-controller """ command = ovs_vsctl.VSCtlCommand('get-controller', [self.br_name]) self.run_command([command]) result = command.result return result[0] if len(result) == 1 else result def set_controller(self, controllers): """ Sets the OpenFlow controller address. This method is corresponding to the following ovs-vsctl command:: $ ovs-vsctl set-controller ... """ command = ovs_vsctl.VSCtlCommand('set-controller', [self.br_name]) command.args.extend(controllers) self.run_command([command]) def del_controller(self): """ Deletes the configured OpenFlow controller address. This method is corresponding to the following ovs-vsctl command:: $ ovs-vsctl del-controller """ command = ovs_vsctl.VSCtlCommand('del-controller', [self.br_name]) self.run_command([command]) def list_db_attributes(self, table, record=None): """ Lists 'record' (or all records) in 'table'. This method is corresponding to the following ovs-vsctl command:: $ ovs-vsctl list TBL [REC] """ command = ovs_vsctl.VSCtlCommand('list', (table, record)) self.run_command([command]) if command.result: return command.result return [] def find_db_attributes(self, table, *conditions): """ Lists records satisfying 'conditions' in 'table'. This method is corresponding to the following ovs-vsctl command:: $ ovs-vsctl find TBL CONDITION... .. Note:: Currently, only '=' condition is supported. To support other condition is TODO. """ args = [table] args.extend(conditions) command = ovs_vsctl.VSCtlCommand('find', args) self.run_command([command]) if command.result: return command.result return [] def get_db_attribute(self, table, record, column, key=None): """ Gets values of 'column' in 'record' in 'table'. This method is corresponding to the following ovs-vsctl command:: $ ovs-vsctl get TBL REC COL[:KEY] """ if key is not None: column = '%s:%s' % (column, key) command = ovs_vsctl.VSCtlCommand( 'get', (table, record, column)) self.run_command([command]) if command.result: return command.result[0] return None def set_db_attribute(self, table, record, column, value, key=None): """ Sets 'value' into 'column' in 'record' in 'table'. This method is corresponding to the following ovs-vsctl command:: $ ovs-vsctl set TBL REC COL[:KEY]=VALUE """ if key is not None: column = '%s:%s' % (column, key) command = ovs_vsctl.VSCtlCommand( 'set', (table, record, '%s=%s' % (column, value))) self.run_command([command]) def add_db_attribute(self, table, record, column, value, key=None): """ Adds ('key'=)'value' into 'column' in 'record' in 'table'. This method is corresponding to the following ovs-vsctl command:: $ ovs-vsctl add TBL REC COL [KEY=]VALUE """ if key is not None: value = '%s=%s' % (key, value) command = ovs_vsctl.VSCtlCommand( 'add', (table, record, column, value)) self.run_command([command]) def remove_db_attribute(self, table, record, column, value, key=None): """ Removes ('key'=)'value' into 'column' in 'record' in 'table'. This method is corresponding to the following ovs-vsctl command:: $ ovs-vsctl remove TBL REC COL [KEY=]VALUE """ if key is not None: value = '%s=%s' % (key, value) command = ovs_vsctl.VSCtlCommand( 'remove', (table, record, column, value)) self.run_command([command]) def clear_db_attribute(self, table, record, column): """ Clears values from 'column' in 'record' in 'table'. This method is corresponding to the following ovs-vsctl command:: $ ovs-vsctl clear TBL REC COL """ command = ovs_vsctl.VSCtlCommand('clear', (table, record, column)) self.run_command([command]) def db_get_val(self, table, record, column): """ Gets values of 'column' in 'record' in 'table'. This method is corresponding to the following ovs-vsctl command:: $ ovs-vsctl get TBL REC COL """ command = ovs_vsctl.VSCtlCommand('get', (table, record, column)) self.run_command([command]) assert len(command.result) == 1 return command.result[0] def db_get_map(self, table, record, column): """ Gets dict type value of 'column' in 'record' in 'table'. This method is corresponding to the following ovs-vsctl command:: $ ovs-vsctl get TBL REC COL """ val = self.db_get_val(table, record, column) assert isinstance(val, dict) return val def get_datapath_id(self): """ Gets Datapath ID of OVS instance. This method is corresponding to the following ovs-vsctl command:: $ ovs-vsctl get Bridge datapath_id """ return self.db_get_val('Bridge', self.br_name, 'datapath_id') def delete_port(self, port_name): """ Deletes a port on the OVS instance. This method is corresponding to the following ovs-vsctl command:: $ ovs-vsctl --if-exists del-port """ command = ovs_vsctl.VSCtlCommand( 'del-port', (self.br_name, port_name), '--if-exists') self.run_command([command]) def get_ofport(self, port_name): """ Gets the OpenFlow port number. This method is corresponding to the following ovs-vsctl command:: $ ovs-vsctl get Interface ofport """ ofport_list = self.db_get_val('Interface', port_name, 'ofport') assert len(ofport_list) == 1 return int(ofport_list[0]) def get_port_name_list(self): """ Gets a list of all ports on OVS instance. This method is corresponding to the following ovs-vsctl command:: $ ovs-vsctl list-ports """ command = ovs_vsctl.VSCtlCommand('list-ports', (self.br_name, )) self.run_command([command]) return command.result def add_bond(self, name, ifaces, bond_mode=None, lacp=None): """ Creates a bonded port. :param name: Port name to be created :param ifaces: List of interfaces containing at least 2 interfaces :param bond_mode: Bonding mode (active-backup, balance-tcp or balance-slb) :param lacp: LACP mode (active, passive or off) """ assert len(ifaces) >= 2 options = '' if bond_mode: options += 'bond_mode=%(bond_mode)s' % locals() if lacp: options += 'lacp=%(lacp)s' % locals() command_add = ovs_vsctl.VSCtlCommand( 'add-bond', (self.br_name, name, ifaces), options) self.run_command([command_add]) def add_tunnel_port(self, name, tunnel_type, remote_ip, local_ip=None, key=None, ofport=None): """ Creates a tunnel port. :param name: Port name to be created :param tunnel_type: Type of tunnel (gre or vxlan) :param remote_ip: Remote IP address of tunnel :param local_ip: Local IP address of tunnel :param key: Key of GRE or VNI of VxLAN :param ofport: Requested OpenFlow port number """ options = 'remote_ip=%(remote_ip)s' % locals() if key: options += ',key=%(key)s' % locals() if local_ip: options += ',local_ip=%(local_ip)s' % locals() args = ['Interface', name, 'type=%s' % tunnel_type, 'options:%s' % options] if ofport: args.append('ofport_request=%(ofport)s' % locals()) command_add = ovs_vsctl.VSCtlCommand('add-port', (self.br_name, name)) command_set = ovs_vsctl.VSCtlCommand('set', args) self.run_command([command_add, command_set]) def add_gre_port(self, name, remote_ip, local_ip=None, key=None, ofport=None): """ Creates a GRE tunnel port. See the description of ``add_tunnel_port()``. """ self.add_tunnel_port(name, 'gre', remote_ip, local_ip=local_ip, key=key, ofport=ofport) def add_vxlan_port(self, name, remote_ip, local_ip=None, key=None, ofport=None): """ Creates a VxLAN tunnel port. See the description of ``add_tunnel_port()``. """ self.add_tunnel_port(name, 'vxlan', remote_ip, local_ip=local_ip, key=key, ofport=ofport) def del_port(self, port_name): """ Deletes a port on OVS instance. This method is corresponding to the following ovs-vsctl command:: $ ovs-vsctl del-port """ command = ovs_vsctl.VSCtlCommand('del-port', (self.br_name, port_name)) self.run_command([command]) def _get_ports(self, get_port): ports = [] port_names = self.get_port_name_list() for name in port_names: if self.get_ofport(name) < 0: continue port = get_port(name) if port: ports.append(port) return ports def _vifport(self, name, external_ids): ofport = self.get_ofport(name) return VifPort(name, ofport, external_ids['iface-id'], external_ids['attached-mac'], self) def _get_vif_port(self, name): external_ids = self.db_get_map('Interface', name, 'external_ids') if 'iface-id' in external_ids and 'attached-mac' in external_ids: return self._vifport(name, external_ids) def get_vif_ports(self): """ Returns a VIF object for each VIF port """ return self._get_ports(self._get_vif_port) def _get_external_port(self, name): # exclude vif ports external_ids = self.db_get_map('Interface', name, 'external_ids') if external_ids: return # exclude tunnel ports options = self.db_get_map('Interface', name, 'options') if 'remote_ip' in options: return ofport = self.get_ofport(name) return VifPort(name, ofport, None, None, self) def get_external_ports(self): return self._get_ports(self._get_external_port) def get_tunnel_port(self, name, tunnel_type='gre'): type_ = self.db_get_val('Interface', name, 'type') if type_ != tunnel_type: return options = self.db_get_map('Interface', name, 'options') if 'local_ip' in options and 'remote_ip' in options: ofport = self.get_ofport(name) return TunnelPort(name, ofport, tunnel_type, options['local_ip'], options['remote_ip']) def get_tunnel_ports(self, tunnel_type='gre'): get_tunnel_port = functools.partial(self.get_tunnel_port, tunnel_type=tunnel_type) return self._get_ports(get_tunnel_port) def get_quantum_ports(self, port_name): LOG.debug('port_name %s', port_name) command = ovs_vsctl.VSCtlCommand( 'list-ifaces-verbose', [dpid_lib.dpid_to_str(self.datapath_id), port_name]) self.run_command([command]) if command.result: return command.result[0] return None def set_qos(self, port_name, type='linux-htb', max_rate=None, queues=None): """ Sets a Qos rule and creates Queues on the given port. """ queues = queues if queues else [] command_qos = ovs_vsctl.VSCtlCommand( 'set-qos', [port_name, type, max_rate]) command_queue = ovs_vsctl.VSCtlCommand( 'set-queue', [port_name, queues]) self.run_command([command_qos, command_queue]) if command_qos.result and command_queue.result: return command_qos.result + command_queue.result return None def del_qos(self, port_name): """ Deletes the Qos rule on the given port. """ command = ovs_vsctl.VSCtlCommand( 'del-qos', [port_name]) self.run_command([command]) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/ovs/db_client.py0000664000175000017500000001004500000000000020141 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2012 Isaku Yamahata # # 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. import logging import os from ovs import jsonrpc from ovs import stream from ovs import util as ovs_util from ovs.db import schema LOG = logging.getLogger(__name__) class DBClient(object): def __init__(self, remote): super(DBClient, self).__init__() self.remote = remote def run_command(self, args): _COMMANDS = { 'list-dbs': self._list_dbs, 'get-schema': self._get_schema, 'get-schema-version': self._get_schema_version, 'list-tables': self._list_tables, 'list-columns': self._list_columns, 'transact': self._transact, 'monitor': self._monitor, 'dump': self._dump, } command = args[0] args = args[1:] error, stream_ = stream.Stream.open_block( stream.Stream.open(self.remote)) if error: raise RuntimeError('can not open socket to %s: %s' % (self.remote, os.strerror(error))) rpc = jsonrpc.Connection(stream_) ret = _COMMANDS[command](rpc, *args) LOG.info('ret %s', ret) rpc.close() def _check_txn(self, error, reply): if error: ovs_util.ovs_fatal(error, os.strerror(error)) elif reply.error: ovs_util.ovs_fatal(reply.error, 'error %s' % reply.error) def _fetch_dbs(self, rpc): request = jsonrpc.Message.create_request('list_dbs', []) error, reply = rpc.transact_block(request) self._check_txn(error, reply) dbs = set() for name in reply.result: dbs.add(name) return dbs def _fetch_schema_json(self, rpc, database): request = jsonrpc.Message.create_request('get_schema', [database]) error, reply = rpc.transact_block(request) self._check_txn(error, reply) return reply.result def _fetch_schema(self, rpc, database): return schema.DbSchema.from_json(self._fetch_schema_json(rpc, database)) # commands def _list_dbs(self, rpc, *_): return self._fetch_dbs(rpc) def _get_schema(self, rpc, *args): database = args[0] return self._fetch_schema(rpc, database).to_json() def _get_schema_version(self, rpc, *_args): database = _args[0] schema_ = self._fetch_schema(rpc, database) return schema_.version def _list_tables(self, rpc, *args): database = args[0] schema_ = self._fetch_schema(rpc, database) return [table.to_json() for table in schema_.tables.values()] def _list_columns(self, rpc, *args): database = args[0] table_name = None if len(args) > 1: table_name = args[1] schema_ = self._fetch_schema(rpc, database) if table_name is None: tables = [table for table in schema_.tables.values()] else: tables = [table for table in schema_.tables.values() if table.name == table_name] columns = [] for table in tables: columns.extend(table.columns.values()) return [column.to_json() for column in columns] def _transact(self, rpc, *args): raise NotImplementedError() def _monitor(self, rpc, *args): raise NotImplementedError() def _dump(self, rpc, *args): raise NotImplementedError() ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/ovs/vsctl.py0000664000175000017500000025764100000000000017370 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2012 Isaku Yamahata # # 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. """ ``ovs-vsctl`` command like library to speak OVSDB protocol """ import logging import operator import os import re import sys import weakref import ovs.db.data import ovs.db.parser import ovs.db.schema import ovs.db.types import ovs.poller import ovs.json from ovs import jsonrpc from ovs import ovsuuid from ovs import stream from ovs.db import idl from os_ken.lib import hub from os_ken.lib import ip from os_ken.lib.ovs import vswitch_idl from os_ken.lib.stringify import StringifyMixin LOG = logging.getLogger(__name__) # use ovs.vlog? def valid_ovsdb_addr(addr): """ Returns True if the given addr is valid OVSDB server address, otherwise False. The valid formats are: - ``unix:file`` - ``tcp:ip:port`` - ``ssl:ip:port`` If ip is IPv6 address, wrap ip with brackets (e.g., ssl:[::1]:6640). :param addr: str value of OVSDB server address. :return: True if valid, otherwise False. """ # Assumes Unix socket format: "unix:file" m = re.match(r'unix:(\S+)', addr) if m: file = m.group(1) return os.path.isfile(file) # Assumes TCP/SSL socket format: "tcp:ip:port" or "ssl:ip:port" m = re.match(r'(tcp|ssl):(\S+):(\d+)', addr) if m: address = m.group(2) port = m.group(3) if '[' in address: address = address.strip('[').strip(']') return ip.valid_ipv6(address) and port.isdigit() else: return ip.valid_ipv4(address) and port.isdigit() # Assumes invalid format or unsupported type return False # for debug def ovsrec_row_changes_to_string(ovsrec_row): if not ovsrec_row._changes: return ovsrec_row._changes return dict((key, value.to_string()) for key, value in ovsrec_row._changes.items()) # for debug def ovsrec_row_to_string(ovsrec_row): output = '' output += 'uuid: %s ' % ovsrec_row.uuid if ovsrec_row._data: output += '_data: %s ' % dict((key, value.to_string()) for key, value in ovsrec_row._data.items()) else: output += '_data: %s ' % ovsrec_row._data output += '_changes: %s' % ovsrec_row_changes_to_string(ovsrec_row) return output def atom_from_string(base, value_string, symtab=None): type_ = base.type atom = None if type_ == ovs.db.types.IntegerType: atom = ovs.db.data.Atom(type_, int(value_string)) elif type_ == ovs.db.types.RealType: # TODO:XXX negation atom = ovs.db.data.Atom( type_, ovs.db.parser.float_to_int(float(value_string))) elif type_ == ovs.db.types.BooleanType: if value_string in ("true", "yes", "on", "1"): atom = ovs.db.data.Atom(type_, True) elif value_string == ("false", "no", "off", "0"): atom = ovs.db.data.Atom(type_, False) elif type_ == ovs.db.types.StringType: # TODO:XXXX escape: if value_string[0] == '"': atom = ovs.db.data.Atom(type_, value_string) elif type_ == ovs.db.types.UuidType: if value_string[0] == "@": assert symtab is not None uuid_ = symtab[value_string] atom = ovs.db.data.Atom(type_, uuid_) else: atom = ovs.db.data.Atom(type_, ovs.ovsuuid.from_string(value_string)) if atom is None: raise ValueError("expected %s" % type_.to_string(), value_string) atom.check_constraints(base) return atom def datum_from_string(type_, value_string, symtab=None): value_string = value_string.strip() if type_.is_map(): if value_string.startswith('{'): # TODO:dict case LOG.debug('value_string %s', value_string) raise NotImplementedError() d = dict(v.split('=', 1) for v in value_string.split(',')) d = dict((atom_from_string(type_.key, key, symtab), atom_from_string(type_.value, value, symtab)) for key, value in d.items()) elif type_.is_set(): if value_string.startswith('['): # TODO:set case LOG.debug('value_string %s', value_string) raise NotImplementedError() values = value_string.split(',') d = dict((atom_from_string(type_.key, value, symtab), None) for value in values) else: atom = atom_from_string(type_.key, value_string, symtab) d = {atom: None} datum = ovs.db.data.Datum(type_, d) return datum.to_json() def ifind(pred, seq): try: return [i for i in seq if pred(i)][0] except IndexError: return None def not_reached(): os.abort() def vsctl_fatal(msg): LOG.error(msg) raise Exception(msg) # not call ovs.utils.ovs_fatal for reusability class VSCtlBridge(object): def __init__(self, ovsrec_bridge, name, parent, vlan): super(VSCtlBridge, self).__init__() self.br_cfg = ovsrec_bridge self.name = name self.ports = set() self.parent = parent self.vlan = vlan self.children = set() # WeakSet is needed? def find_vlan_bridge(self, vlan): return ifind(lambda child: child.vlan == vlan, self.children) class VSCtlPort(object): def __init__(self, vsctl_bridge_parent, ovsrec_port): super(VSCtlPort, self).__init__() self.bridge = weakref.ref(vsctl_bridge_parent) # backpointer self.port_cfg = ovsrec_port self.ifaces = set() self.qos = None class VSCtlIface(object): def __init__(self, vsctl_port_parent, ovsrec_iface): super(VSCtlIface, self).__init__() self.port = weakref.ref(vsctl_port_parent) # backpointer self.iface_cfg = ovsrec_iface class VSCtlQoS(object): def __init__(self, vsctl_port_parent, ovsrec_qos): super(VSCtlQoS, self).__init__() self.port = weakref.ref(vsctl_port_parent) self.qos_cfg = ovsrec_qos self.queues = set() class VSCtlQueue(object): def __init__(self, vsctl_qos_parent, ovsrec_queue): super(VSCtlQueue, self).__init__() self.qos = weakref.ref(vsctl_qos_parent) self.queue_cfg = ovsrec_queue class VSCtlContext(object): def _invalidate_cache(self): self.cache_valid = False self.bridges.clear() self.ports.clear() self.ifaces.clear() def __init__(self, idl_, txn, ovsrec_open_vswitch): super(VSCtlContext, self).__init__() # Modifiable state # self.table = None self.idl = idl_ self.txn = txn self.ovs = ovsrec_open_vswitch self.symtab = None # TODO:XXX self.verified_ports = False # A cache of the contents of the database. self.cache_valid = False self.bridges = {} # bridge name -> VSCtlBridge self.ports = {} # port name -> VSCtlPort self.ifaces = {} # iface name -> VSCtlIface self.try_again = False # used by wait-until command def done(self): self._invalidate_cache() def verify_bridges(self): self.ovs.verify(vswitch_idl.OVSREC_OPEN_VSWITCH_COL_BRIDGES) def verify_ports(self): if self.verified_ports: return self.verify_bridges() for ovsrec_bridge in self.idl.tables[ vswitch_idl.OVSREC_TABLE_BRIDGE].rows.values(): ovsrec_bridge.verify(vswitch_idl.OVSREC_BRIDGE_COL_PORTS) for ovsrec_port in self.idl.tables[ vswitch_idl.OVSREC_TABLE_PORT].rows.values(): ovsrec_port.verify(vswitch_idl.OVSREC_PORT_COL_INTERFACES) self.verified_ports = True def add_bridge_to_cache(self, ovsrec_bridge, name, parent, vlan): vsctl_bridge = VSCtlBridge(ovsrec_bridge, name, parent, vlan) if parent: parent.children.add(vsctl_bridge) self.bridges[name] = vsctl_bridge return vsctl_bridge def del_cached_bridge(self, vsctl_bridge): assert not vsctl_bridge.ports assert not vsctl_bridge.children parent = vsctl_bridge.parent if parent: parent.children.remove(vsctl_bridge) vsctl_bridge.parent = None # break circular reference ovsrec_bridge = vsctl_bridge.br_cfg if ovsrec_bridge: ovsrec_bridge.delete() self.ovs_delete_bridge(ovsrec_bridge) del self.bridges[vsctl_bridge.name] def del_cached_qos(self, vsctl_qos): vsctl_qos.port().qos = None vsctl_qos.port = None vsctl_qos.queues = None def add_port_to_cache(self, vsctl_bridge_parent, ovsrec_port): tag = getattr(ovsrec_port, vswitch_idl.OVSREC_PORT_COL_TAG, None) if isinstance(tag, list): if len(tag) == 0: tag = 0 else: tag = tag[0] if tag is not None and 0 <= tag < 4096: vlan_bridge = vsctl_bridge_parent.find_vlan_bridge(tag) if vlan_bridge: vsctl_bridge_parent = vlan_bridge vsctl_port = VSCtlPort(vsctl_bridge_parent, ovsrec_port) vsctl_bridge_parent.ports.add(vsctl_port) self.ports[ovsrec_port.name] = vsctl_port return vsctl_port def del_cached_port(self, vsctl_port): assert not vsctl_port.ifaces vsctl_port.bridge().ports.remove(vsctl_port) vsctl_port.bridge = None port = self.ports.pop(vsctl_port.port_cfg.name) assert port == vsctl_port vsctl_port.port_cfg.delete() def add_iface_to_cache(self, vsctl_port_parent, ovsrec_iface): vsctl_iface = VSCtlIface(vsctl_port_parent, ovsrec_iface) vsctl_port_parent.ifaces.add(vsctl_iface) self.ifaces[ovsrec_iface.name] = vsctl_iface def add_qos_to_cache(self, vsctl_port_parent, ovsrec_qos): vsctl_qos = VSCtlQoS(vsctl_port_parent, ovsrec_qos) vsctl_port_parent.qos = vsctl_qos return vsctl_qos def add_queue_to_cache(self, vsctl_qos_parent, ovsrec_queue): vsctl_queue = VSCtlQueue(vsctl_qos_parent, ovsrec_queue) vsctl_qos_parent.queues.add(vsctl_queue) def del_cached_iface(self, vsctl_iface): vsctl_iface.port().ifaces.remove(vsctl_iface) vsctl_iface.port = None del self.ifaces[vsctl_iface.iface_cfg.name] vsctl_iface.iface_cfg.delete() def invalidate_cache(self): if not self.cache_valid: return self._invalidate_cache() def populate_cache(self): self._populate_cache(self.idl.tables[vswitch_idl.OVSREC_TABLE_BRIDGE]) @staticmethod def port_is_fake_bridge(ovsrec_port): tag = ovsrec_port.tag if isinstance(tag, list): if len(tag) == 0: tag = 0 else: tag = tag[0] return ovsrec_port.fake_bridge and 0 <= tag <= 4095 def _populate_cache(self, ovsrec_bridges): if self.cache_valid: return self.cache_valid = True bridges = set() ports = set() for ovsrec_bridge in ovsrec_bridges.rows.values(): name = ovsrec_bridge.name if name in bridges: LOG.warning('%s: database contains duplicate bridge name', name) bridges.add(name) vsctl_bridge = self.add_bridge_to_cache(ovsrec_bridge, name, None, 0) if not vsctl_bridge: continue for ovsrec_port in ovsrec_bridge.ports: port_name = ovsrec_port.name if port_name in ports: # Duplicate ovsrec_port name. # (We will warn about that later.) continue ports.add(port_name) if (self.port_is_fake_bridge(ovsrec_port) and port_name not in bridges): bridges.add(port_name) self.add_bridge_to_cache(None, port_name, vsctl_bridge, ovsrec_port.tag) bridges = set() for ovsrec_bridge in ovsrec_bridges.rows.values(): name = ovsrec_bridge.name if name in bridges: continue bridges.add(name) vsctl_bridge = self.bridges[name] for ovsrec_port in ovsrec_bridge.ports: port_name = ovsrec_port.name vsctl_port = self.ports.get(port_name) if vsctl_port: if ovsrec_port == vsctl_port.port_cfg: LOG.warning('%s: vsctl_port is in multiple bridges ' '(%s and %s)', port_name, vsctl_bridge.name, vsctl_port.br.name) else: LOG.error('%s: database contains duplicate ' 'vsctl_port name', ovsrec_port.name) continue if (self.port_is_fake_bridge(ovsrec_port) and port_name in bridges): continue # LOG.debug('ovsrec_port %s %s %s', # ovsrec_port, ovsrec_port._data, ovsrec_port.tag) vsctl_port = self.add_port_to_cache(vsctl_bridge, ovsrec_port) # LOG.debug('vsctl_port %s', vsctl_port) for ovsrec_iface in ovsrec_port.interfaces: iface = self.ifaces.get(ovsrec_iface.name) if iface: if ovsrec_iface == iface.iface_cfg: LOG.warning( '%s: interface is in multiple ports ' '(%s and %s)', ovsrec_iface.name, iface.port().port_cfg.name, vsctl_port.port_cfg.name) else: LOG.error( '%s: database contains duplicate interface ' 'name', ovsrec_iface.name) continue self.add_iface_to_cache(vsctl_port, ovsrec_iface) ovsrec_qos = ovsrec_port.qos vsctl_qos = self.add_qos_to_cache(vsctl_port, ovsrec_qos) if len(ovsrec_qos): for ovsrec_queue in ovsrec_qos[0].queues: self.add_queue_to_cache(vsctl_qos, ovsrec_queue) def check_conflicts(self, name, msg): self.verify_ports() if name in self.bridges: vsctl_fatal('%s because a bridge named %s already exists' % (msg, name)) if name in self.ports: vsctl_fatal('%s because a port named %s already exists on ' 'bridge %s' % (msg, name, self.ports[name].bridge().name)) if name in self.ifaces: vsctl_fatal('%s because an interface named %s already ' 'exists on bridge %s' % (msg, name, self.ifaces[name].port().bridge().name)) def find_bridge(self, name, must_exist): assert self.cache_valid vsctl_bridge = self.bridges.get(name) if must_exist and not vsctl_bridge: vsctl_fatal('no bridge named %s' % name) self.verify_bridges() return vsctl_bridge def find_real_bridge(self, name, must_exist): vsctl_bridge = self.find_bridge(name, must_exist) if vsctl_bridge and vsctl_bridge.parent: vsctl_fatal('%s is a fake bridge' % name) return vsctl_bridge def find_bridge_by_id(self, datapath_id, must_exist): assert self.cache_valid for vsctl_bridge in self.bridges.values(): if vsctl_bridge.br_cfg.datapath_id[0].strip('"') == datapath_id: self.verify_bridges() return vsctl_bridge if must_exist: vsctl_fatal('no bridge id %s' % datapath_id) return None def find_port(self, name, must_exist): assert self.cache_valid vsctl_port = self.ports.get(name) if vsctl_port and name == vsctl_port.bridge().name: vsctl_port = None if must_exist and not vsctl_port: vsctl_fatal('no vsctl_port named %s' % name) return vsctl_port def find_iface(self, name, must_exist): assert self.cache_valid vsctl_iface = self.ifaces.get(name) if vsctl_iface and name == vsctl_iface.port().bridge().name: vsctl_iface = None if must_exist and not vsctl_iface: vsctl_fatal('no interface named %s' % name) self.verify_ports() return vsctl_iface def set_qos(self, vsctl_port, type, max_rate): qos = vsctl_port.qos.qos_cfg if not len(qos): ovsrec_qos = self.txn.insert( self.txn.idl.tables[vswitch_idl.OVSREC_TABLE_QOS]) vsctl_port.port_cfg.qos = [ovsrec_qos] else: ovsrec_qos = qos[0] ovsrec_qos.type = type if max_rate is not None: value_json = ['map', [['max-rate', max_rate]]] self.set_column(ovsrec_qos, 'other_config', value_json) self.add_qos_to_cache(vsctl_port, [ovsrec_qos]) return ovsrec_qos def set_queue(self, vsctl_qos, max_rate, min_rate, queue_id): ovsrec_qos = vsctl_qos.qos_cfg[0] try: ovsrec_queue = ovsrec_qos.queues[queue_id] except (AttributeError, KeyError): ovsrec_queue = self.txn.insert( self.txn.idl.tables[vswitch_idl.OVSREC_TABLE_QUEUE]) if max_rate is not None: value_json = ['map', [['max-rate', max_rate]]] self.add_column(ovsrec_queue, 'other_config', value_json) if min_rate is not None: value_json = ['map', [['min-rate', min_rate]]] self.add_column(ovsrec_queue, 'other_config', value_json) value_json = ['map', [[queue_id, ['uuid', str(ovsrec_queue.uuid)]]]] self.add_column(ovsrec_qos, 'queues', value_json) self.add_queue_to_cache(vsctl_qos, ovsrec_queue) return ovsrec_queue @staticmethod def _column_set(ovsrec_row, column, ovsrec_value): # need to trigger Row.__setattr__() setattr(ovsrec_row, column, ovsrec_value) @staticmethod def _column_insert(ovsrec_row, column, ovsrec_add): value = getattr(ovsrec_row, column) value.append(ovsrec_add) VSCtlContext._column_set(ovsrec_row, column, value) @staticmethod def _column_delete(ovsrec_row, column, ovsrec_del): value = getattr(ovsrec_row, column) try: value.remove(ovsrec_del) except ValueError: # Datum.to_python() with _uuid_to_row trims down deleted # references. If ovsrec_del.delete() is called before # _column_delete(), value doesn't include ovsrec_del. pass VSCtlContext._column_set(ovsrec_row, column, value) @staticmethod def bridge_insert_port(ovsrec_bridge, ovsrec_port): VSCtlContext._column_insert(ovsrec_bridge, vswitch_idl.OVSREC_BRIDGE_COL_PORTS, ovsrec_port) @staticmethod def bridge_delete_port(ovsrec_bridge, ovsrec_port): VSCtlContext._column_delete(ovsrec_bridge, vswitch_idl.OVSREC_BRIDGE_COL_PORTS, ovsrec_port) @staticmethod def port_delete_qos(ovsrec_port, ovsrec_qos): VSCtlContext._column_delete(ovsrec_port, vswitch_idl.OVSREC_PORT_COL_QOS, ovsrec_qos) def ovs_insert_bridge(self, ovsrec_bridge): self._column_insert(self.ovs, vswitch_idl.OVSREC_OPEN_VSWITCH_COL_BRIDGES, ovsrec_bridge) def ovs_delete_bridge(self, ovsrec_bridge): self._column_delete(self.ovs, vswitch_idl.OVSREC_OPEN_VSWITCH_COL_BRIDGES, ovsrec_bridge) def del_port(self, vsctl_port): if vsctl_port.bridge().parent: ovsrec_bridge = vsctl_port.bridge().parent.br_cfg else: ovsrec_bridge = vsctl_port.bridge().br_cfg self.bridge_delete_port(ovsrec_bridge, vsctl_port.port_cfg) for vsctl_iface in vsctl_port.ifaces.copy(): self.del_cached_iface(vsctl_iface) self.del_cached_port(vsctl_port) def del_bridge(self, vsctl_bridge): for child in vsctl_bridge.children.copy(): self.del_bridge(child) for vsctl_port in vsctl_bridge.ports.copy(): self.del_port(vsctl_port) self.del_cached_bridge(vsctl_bridge) def del_qos(self, vsctl_qos): ovsrec_port = vsctl_qos.port().port_cfg ovsrec_qos = vsctl_qos.qos_cfg if len(ovsrec_qos): self.port_delete_qos(ovsrec_port, ovsrec_qos[0]) self.del_cached_qos(vsctl_qos) def add_port(self, br_name, port_name, may_exist, fake_iface, iface_names, settings=None): """ :type settings: list of (column, value_json) where column is str, value_json is json that is represented by Datum.to_json() """ settings = settings or [] self.populate_cache() if may_exist: vsctl_port = self.find_port(port_name, False) if vsctl_port: want_names = set(iface_names) have_names = set(ovsrec_iface.name for ovsrec_iface in vsctl_port.port_cfg.interfaces) if vsctl_port.bridge().name != br_name: vsctl_fatal('"%s" but %s is actually attached to ' 'vsctl_bridge %s' % (br_name, port_name, vsctl_port.bridge().name)) if want_names != have_names: want_names_string = ','.join(want_names) have_names_string = ','.join(have_names) vsctl_fatal('"%s" but %s actually has interface(s) %s' % (want_names_string, port_name, have_names_string)) return self.check_conflicts(port_name, 'cannot create a port named %s' % port_name) for iface_name in iface_names: self.check_conflicts( iface_name, 'cannot create an interface named %s' % iface_name) vsctl_bridge = self.find_bridge(br_name, True) ifaces = [] for iface_name in iface_names: ovsrec_iface = self.txn.insert( self.idl.tables[vswitch_idl.OVSREC_TABLE_INTERFACE]) ovsrec_iface.name = iface_name ifaces.append(ovsrec_iface) ovsrec_port = self.txn.insert( self.idl.tables[vswitch_idl.OVSREC_TABLE_PORT]) ovsrec_port.name = port_name ovsrec_port.interfaces = ifaces ovsrec_port.bond_fake_iface = fake_iface if vsctl_bridge.parent: tag = vsctl_bridge.vlan ovsrec_port.tag = tag for column, value in settings: # TODO:XXX self.symtab: self.set_column(ovsrec_port, column, value) if vsctl_bridge.parent: ovsrec_bridge = vsctl_bridge.parent.br_cfg else: ovsrec_bridge = vsctl_bridge.br_cfg self.bridge_insert_port(ovsrec_bridge, ovsrec_port) vsctl_port = self.add_port_to_cache(vsctl_bridge, ovsrec_port) for ovsrec_iface in ifaces: self.add_iface_to_cache(vsctl_port, ovsrec_iface) def add_bridge(self, br_name, parent_name=None, vlan=0, may_exist=False): self.populate_cache() if may_exist: vsctl_bridge = self.find_bridge(br_name, False) if vsctl_bridge: if not parent_name: if vsctl_bridge.parent: vsctl_fatal('"--may-exist add-vsctl_bridge %s" ' 'but %s is a VLAN bridge for VLAN %d' % (br_name, br_name, vsctl_bridge.vlan)) else: if not vsctl_bridge.parent: vsctl_fatal('"--may-exist add-vsctl_bridge %s %s %d" ' 'but %s is not a VLAN bridge' % (br_name, parent_name, vlan, br_name)) elif vsctl_bridge.parent.name != parent_name: vsctl_fatal('"--may-exist add-vsctl_bridge %s %s %d" ' 'but %s has the wrong parent %s' % (br_name, parent_name, vlan, br_name, vsctl_bridge.parent.name)) elif vsctl_bridge.vlan != vlan: vsctl_fatal('"--may-exist add-vsctl_bridge %s %s %d" ' 'but %s is a VLAN bridge for the wrong ' 'VLAN %d' % (br_name, parent_name, vlan, br_name, vsctl_bridge.vlan)) return self.check_conflicts(br_name, 'cannot create a bridge named %s' % br_name) txn = self.txn tables = self.idl.tables if not parent_name: ovsrec_iface = txn.insert( tables[vswitch_idl.OVSREC_TABLE_INTERFACE]) ovsrec_iface.name = br_name ovsrec_iface.type = 'internal' ovsrec_port = txn.insert(tables[vswitch_idl.OVSREC_TABLE_PORT]) ovsrec_port.name = br_name ovsrec_port.interfaces = [ovsrec_iface] ovsrec_port.fake_bridge = False ovsrec_bridge = txn.insert(tables[vswitch_idl.OVSREC_TABLE_BRIDGE]) ovsrec_bridge.name = br_name ovsrec_bridge.ports = [ovsrec_port] self.ovs_insert_bridge(ovsrec_bridge) else: parent = self.find_bridge(parent_name, False) if parent and parent.parent: vsctl_fatal('cannot create bridge with fake bridge as parent') if not parent: vsctl_fatal('parent bridge %s does not exist' % parent_name) ovsrec_iface = txn.insert( tables[vswitch_idl.OVSREC_TABLE_INTERFACE]) ovsrec_iface.name = br_name ovsrec_iface.type = 'internal' ovsrec_port = txn.insert(tables[vswitch_idl.OVSREC_TABLE_PORT]) ovsrec_port.name = br_name ovsrec_port.interfaces = [ovsrec_iface] ovsrec_port.fake_bridge = True ovsrec_port.tag = vlan self.bridge_insert_port(parent.br_cfg, ovsrec_port) self.invalidate_cache() @staticmethod def parse_column_key(setting_string): """ Parses 'setting_string' as str formatted in [:] and returns str type 'column' and 'key' """ if ':' in setting_string: # splits : into and column, key = setting_string.split(':', 1) else: # stores and =None column = setting_string key = None return column, key @staticmethod def parse_column_key_value(table_schema, setting_string): """ Parses 'setting_string' as str formatted in [:]= and returns str type 'column' and json formatted 'value' """ if ':' in setting_string: # splits := into and = column, value = setting_string.split(':', 1) elif '=' in setting_string: # splits = into and column, value = setting_string.split('=', 1) else: # stores and =None column = setting_string value = None if value is not None: type_ = table_schema.columns[column].type value = datum_from_string(type_, value) return column, value def get_column(self, ovsrec_row, column, key=None, if_exists=False): value = getattr(ovsrec_row, column, None) if isinstance(value, dict) and key is not None: value = value.get(key, None) column = '%s:%s' % (column, key) if value is None: if if_exists: return None vsctl_fatal('%s does not contain a column whose name matches "%s"' % (ovsrec_row._table.name, column)) return value def _pre_mod_column(self, ovsrec_row, column, value_json): if column not in ovsrec_row._table.columns: vsctl_fatal('%s does not contain a column whose name matches "%s"' % (ovsrec_row._table.name, column)) column_schema = ovsrec_row._table.columns[column] datum = ovs.db.data.Datum.from_json( column_schema.type, value_json, self.symtab) return datum.to_python(ovs.db.idl._uuid_to_row) def set_column(self, ovsrec_row, column, value_json): column_schema = ovsrec_row._table.columns[column] datum = self._pre_mod_column(ovsrec_row, column, value_json) if column_schema.type.is_map(): values = getattr(ovsrec_row, column, {}) values.update(datum) else: values = datum setattr(ovsrec_row, column, values) def add_column(self, ovsrec_row, column, value_json): column_schema = ovsrec_row._table.columns[column] datum = self._pre_mod_column(ovsrec_row, column, value_json) if column_schema.type.is_map(): values = getattr(ovsrec_row, column, {}) values.update(datum) elif column_schema.type.is_set(): values = getattr(ovsrec_row, column, []) values.extend(datum) else: values = datum setattr(ovsrec_row, column, values) def remove_column(self, ovsrec_row, column, value_json): column_schema = ovsrec_row._table.columns[column] datum = self._pre_mod_column(ovsrec_row, column, value_json) if column_schema.type.is_map(): values = getattr(ovsrec_row, column, {}) for datum_key, datum_value in datum.items(): v = values.get(datum_key, None) if v == datum_value: values.pop(datum_key) setattr(ovsrec_row, column, values) elif column_schema.type.is_set(): values = getattr(ovsrec_row, column, []) for d in datum: if d in values: values.remove(d) setattr(ovsrec_row, column, values) else: values = getattr(ovsrec_row, column, None) default = ovs.db.data.Datum.default(column_schema.type) default = default.to_python(ovs.db.idl._uuid_to_row).to_json() if values == datum: setattr(ovsrec_row, column, default) def _get_row_by_id(self, table_name, vsctl_row_id, record_id): if not vsctl_row_id.table: return None if not vsctl_row_id.name_column: if record_id != '.': return None values = list(self.idl.tables[vsctl_row_id.table].rows.values()) if not values or len(values) > 2: return None referrer = values[0] else: referrer = None for ovsrec_row in self.idl.tables[ vsctl_row_id.table].rows.values(): name = getattr(ovsrec_row, vsctl_row_id.name_column) assert isinstance(name, (list, str, str)) if not isinstance(name, list) and name == record_id: if referrer: vsctl_fatal('multiple rows in %s match "%s"' % (table_name, record_id)) referrer = ovsrec_row if not referrer: return None final = None if vsctl_row_id.uuid_column: referrer.verify(vsctl_row_id.uuid_column) uuid = getattr(referrer, vsctl_row_id.uuid_column) uuid_ = referrer._data[vsctl_row_id.uuid_column] assert uuid_.type.key.type == ovs.db.types.UuidType assert uuid_.type.value is None assert isinstance(uuid, list) if len(uuid) == 1: final = uuid[0] else: final = referrer return final def get_row(self, vsctl_table, record_id): table_name = vsctl_table.table_name if ovsuuid.is_valid_string(record_id): uuid = ovsuuid.from_string(record_id) return self.idl.tables[table_name].rows.get(uuid) else: for vsctl_row_id in vsctl_table.row_ids: ovsrec_row = self._get_row_by_id(table_name, vsctl_row_id, record_id) if ovsrec_row: return ovsrec_row return None def must_get_row(self, vsctl_table, record_id): ovsrec_row = self.get_row(vsctl_table, record_id) if not ovsrec_row: vsctl_fatal('no row "%s" in table %s' % (record_id, vsctl_table.table_name)) return ovsrec_row class _CmdShowTable(object): def __init__(self, table, name_column, columns, recurse): super(_CmdShowTable, self).__init__() self.table = table self.name_column = name_column self.columns = columns self.recurse = recurse class _VSCtlRowID(object): def __init__(self, table, name_column, uuid_column): super(_VSCtlRowID, self).__init__() self.table = table self.name_column = name_column self.uuid_column = uuid_column class _VSCtlTable(object): def __init__(self, table_name, vsctl_row_id_list): super(_VSCtlTable, self).__init__() self.table_name = table_name self.row_ids = vsctl_row_id_list class VSCtlCommand(StringifyMixin): """ Class to describe artgumens similar to those of ``ovs-vsctl`` command. ``command`` specifies the command of ``ovs-vsctl``. ``args`` specifies a list or tuple of arguments for the given command. ``options`` specifies a list or tuple of options for the given command. Please note that NOT all options of ``ovs-vsctl`` are supported. For example, ``--id`` option is not yet supported. This class supports the followings. ================= ========================================================= Option Description ================= ========================================================= ``--may-exist`` Does nothing when the given port already exists. The supported commands are ``add-port`` and ``add-bond``. ``--fake-iface`` Creates a port as a fake interface. The supported command is ``add-bond``. ``--must-exist`` Raises exception if the given port does not exist. The supported command is ``del-port``. ``--with-iface`` Takes effect to the interface which has the same name. The supported command is ``del-port``. ``--if-exists`` Ignores exception when not found. The supported command is ``get``. ================= ========================================================= """ def __init__(self, command, args=None, options=None): super(VSCtlCommand, self).__init__() self.command = command self.args = args or [] self.options = options or [] # Data modified by commands self.result = None # internally used by VSCtl self._prerequisite = None self._run = None def has_option(self, option): return option in self.options class VSCtl(object): """ A class to describe an Open vSwitch instance. ``remote`` specifies the address of the OVS instance. :py:mod:`os_ken.lib.ovs.vsctl.valid_ovsdb_addr` is a convenient function to validate this address. """ def _reset(self): self.schema_helper = None self.ovs = None self.txn = None self.wait_for_reload = True self.dry_run = False def __init__(self, remote): super(VSCtl, self).__init__() self.remote = remote self.schema_json = None self.schema = None self.schema_helper = None self.ovs = None self.txn = None self.wait_for_reload = True self.dry_run = False def _rpc_get_schema_json(self, database): LOG.debug('remote %s', self.remote) error, stream_ = stream.Stream.open_block( stream.Stream.open(self.remote)) if error: vsctl_fatal('error %s' % os.strerror(error)) rpc = jsonrpc.Connection(stream_) request = jsonrpc.Message.create_request('get_schema', [database]) error, reply = rpc.transact_block(request) rpc.close() if error: vsctl_fatal(os.strerror(error)) elif reply.error: vsctl_fatal('error %s' % reply.error) return reply.result def _init_schema_helper(self): if self.schema_json is None: self.schema_json = self._rpc_get_schema_json( vswitch_idl.OVSREC_DB_NAME) schema_helper = idl.SchemaHelper(None, self.schema_json) schema_helper.register_all() self.schema = schema_helper.get_idl_schema() # LOG.debug('schema_json %s', schema_json) self.schema_helper = idl.SchemaHelper(None, self.schema_json) @staticmethod def _idl_block(idl_): poller = ovs.poller.Poller() idl_.wait(poller) poller.block() @staticmethod def _idl_wait(idl_, seqno): while idl_.change_seqno == seqno and not idl_.run(): VSCtl._idl_block(idl_) def _run_prerequisites(self, commands): schema_helper = self.schema_helper schema_helper.register_table(vswitch_idl.OVSREC_TABLE_OPEN_VSWITCH) if self.wait_for_reload: # LOG.debug('schema_helper._tables %s', schema_helper._tables) schema_helper.register_columns( vswitch_idl.OVSREC_TABLE_OPEN_VSWITCH, [vswitch_idl.OVSREC_OPEN_VSWITCH_COL_CUR_CFG]) for command in commands: if not command._prerequisite: continue ctx = VSCtlContext(None, None, None) command._prerequisite(ctx, command) ctx.done() def _do_vsctl(self, idl_, commands): self.txn = idl.Transaction(idl_) if self.dry_run: self.txn.dry_run = True self.txn.add_comment('ovs-vsctl') # TODO:XXX add operation name. args ovs_rows = idl_.tables[vswitch_idl.OVSREC_TABLE_OPEN_VSWITCH].rows if ovs_rows: ovs_ = list(ovs_rows.values())[0] else: # XXX add verification that table is empty ovs_ = self.txn.insert( idl_.tables[vswitch_idl.OVSREC_TABLE_OPEN_VSWITCH]) if self.wait_for_reload: ovs_.increment(vswitch_idl.OVSREC_OPEN_VSWITCH_COL_NEXT_CFG) # TODO:XXX # symtab = ovsdb_symbol_table_create() ctx = VSCtlContext(idl_, self.txn, ovs_) for command in commands: if not command._run: continue command._run(ctx, command) if ctx.try_again: return False LOG.debug('result:\n%s', [command.result for command in commands]) ctx.done() # TODO:XXX check if created symbols are really created, referenced. status = self.txn.commit_block() next_cfg = 0 if self.wait_for_reload and status == idl.Transaction.SUCCESS: next_cfg = self.txn.get_increment_new_value() # TODO:XXX # if status in (idl.Transaction.UNCHANGED, idl.Transaction.SUCCESS): # for command in commands: # if not command.post_func: # continue # ctx = VSCtlContext(idl_, txn, self.ovs) # command.post_func(ctx) # ctx.done() txn_ = self.txn self.txn = None if status in (idl.Transaction.UNCOMMITTED, idl.Transaction.INCOMPLETE): not_reached() elif status == idl.Transaction.ABORTED: vsctl_fatal('transaction aborted') elif status == idl.Transaction.UNCHANGED: LOG.debug('unchanged') elif status == idl.Transaction.SUCCESS: LOG.debug('success') elif status == idl.Transaction.TRY_AGAIN: return False elif status == idl.Transaction.ERROR: vsctl_fatal('transaction error: %s' % txn_.get_error()) elif status == idl.Transaction.NOT_LOCKED: vsctl_fatal('database not locked') else: not_reached() if self.wait_for_reload and status != idl.Transaction.UNCHANGED: while True: idl_.run() if ovs_.cur_cfg >= next_cfg: break self._idl_block(idl_) return True def _do_main(self, commands): """ :type commands: list of VSCtlCommand """ self._reset() self._init_schema_helper() self._run_prerequisites(commands) idl_ = idl.Idl(self.remote, self.schema_helper) seqno = idl_.change_seqno while True: self._idl_wait(idl_, seqno) seqno = idl_.change_seqno if self._do_vsctl(idl_, commands): break if self.txn: self.txn.abort() self.txn = None # TODO:XXX # ovsdb_symbol_table_destroy(symtab) idl_.close() def _run_command(self, commands): """ :type commands: list of VSCtlCommand """ all_commands = { # Open vSwitch commands. 'init': (None, self._cmd_init), 'show': (self._pre_cmd_show, self._cmd_show), # 'emer-reset': # Bridge commands. 'add-br': (self._pre_add_br, self._cmd_add_br), 'del-br': (self._pre_get_info, self._cmd_del_br), 'list-br': (self._pre_get_info, self._cmd_list_br), 'br-exists': (self._pre_get_info, self._cmd_br_exists), 'br-to-vlan': (self._pre_get_info, self._cmd_br_to_vlan), 'br-to-parent': (self._pre_get_info, self._cmd_br_to_parent), 'br-set-external-id': (self._pre_cmd_br_set_external_id, self._cmd_br_set_external_id), 'br-get-external-id': (self._pre_cmd_br_get_external_id, self._cmd_br_get_external_id), # Port. commands 'list-ports': (self._pre_get_info, self._cmd_list_ports), 'add-port': (self._pre_cmd_add_port, self._cmd_add_port), 'add-bond': (self._pre_cmd_add_bond, self._cmd_add_bond), 'del-port': (self._pre_get_info, self._cmd_del_port), 'port-to-br': (self._pre_get_info, self._cmd_port_to_br), # Interface commands. 'list-ifaces': (self._pre_get_info, self._cmd_list_ifaces), 'iface-to-br': (self._pre_get_info, self._cmd_iface_to_br), # Controller commands. 'get-controller': (self._pre_controller, self._cmd_get_controller), 'del-controller': (self._pre_controller, self._cmd_del_controller), 'set-controller': (self._pre_controller, self._cmd_set_controller), 'get-fail-mode': (self._pre_fail_mode, self._cmd_get_fail_mode), 'del-fail-mode': (self._pre_fail_mode, self._cmd_del_fail_mode), 'set-fail-mode': (self._pre_fail_mode, self._cmd_set_fail_mode), # Manager commands. # 'get-manager': # 'del-manager': # 'set-manager': # SSL commands. # 'get-ssl': # 'del-ssl': # 'set-ssl': # Auto Attach commands. # 'add-aa-mapping': # 'del-aa-mapping': # 'get-aa-mapping': # Switch commands. # 'emer-reset': # Database commands. 'list': (self._pre_cmd_list, self._cmd_list), 'find': (self._pre_cmd_find, self._cmd_find), 'get': (self._pre_cmd_get, self._cmd_get), 'set': (self._pre_cmd_set, self._cmd_set), 'add': (self._pre_cmd_add, self._cmd_add), 'remove': (self._pre_cmd_remove, self._cmd_remove), 'clear': (self._pre_cmd_clear, self._cmd_clear), # 'create': # 'destroy': # 'wait-until': # Utility commands. (No corresponding command in ovs-vsctl) 'set-qos': (self._pre_cmd_set_qos, self._cmd_set_qos), 'set-queue': (self._pre_cmd_set_queue, self._cmd_set_queue), 'del-qos': (self._pre_get_info, self._cmd_del_qos), # for quantum_adapter 'list-ifaces-verbose': (self._pre_cmd_list_ifaces_verbose, self._cmd_list_ifaces_verbose), } for command in commands: funcs = all_commands[command.command] command._prerequisite, command._run = funcs self._do_main(commands) def run_command(self, commands, timeout_sec=None, exception=None): """ Executes the given commands and sends OVSDB messages. ``commands`` must be a list of :py:mod:`os_ken.lib.ovs.vsctl.VSCtlCommand`. If ``timeout_sec`` is specified, raises exception after the given timeout [sec]. Additionally, if ``exception`` is specified, this function will wraps exception using the given exception class. Retruns ``None`` but fills ``result`` attribute for each command instance. """ if timeout_sec is None: self._run_command(commands) else: with hub.Timeout(timeout_sec, exception): self._run_command(commands) # Open vSwitch commands: def _cmd_init(self, _ctx, _command): # nothing. Just check connection to ovsdb pass _CMD_SHOW_TABLES = [ _CmdShowTable(vswitch_idl.OVSREC_TABLE_OPEN_VSWITCH, None, [vswitch_idl.OVSREC_OPEN_VSWITCH_COL_MANAGER_OPTIONS, vswitch_idl.OVSREC_OPEN_VSWITCH_COL_BRIDGES, vswitch_idl.OVSREC_OPEN_VSWITCH_COL_OVS_VERSION], False), _CmdShowTable(vswitch_idl.OVSREC_TABLE_BRIDGE, vswitch_idl.OVSREC_BRIDGE_COL_NAME, [vswitch_idl.OVSREC_BRIDGE_COL_CONTROLLER, vswitch_idl.OVSREC_BRIDGE_COL_FAIL_MODE, vswitch_idl.OVSREC_BRIDGE_COL_PORTS], False), _CmdShowTable(vswitch_idl.OVSREC_TABLE_PORT, vswitch_idl.OVSREC_PORT_COL_NAME, [vswitch_idl.OVSREC_PORT_COL_TAG, vswitch_idl.OVSREC_PORT_COL_TRUNKS, vswitch_idl.OVSREC_PORT_COL_INTERFACES], False), _CmdShowTable(vswitch_idl.OVSREC_TABLE_INTERFACE, vswitch_idl.OVSREC_INTERFACE_COL_NAME, [vswitch_idl.OVSREC_INTERFACE_COL_TYPE, vswitch_idl.OVSREC_INTERFACE_COL_OPTIONS], False), _CmdShowTable(vswitch_idl.OVSREC_TABLE_CONTROLLER, vswitch_idl.OVSREC_CONTROLLER_COL_TARGET, [vswitch_idl.OVSREC_CONTROLLER_COL_IS_CONNECTED], False), _CmdShowTable(vswitch_idl.OVSREC_TABLE_MANAGER, vswitch_idl.OVSREC_MANAGER_COL_TARGET, [vswitch_idl.OVSREC_MANAGER_COL_IS_CONNECTED], False), ] def _pre_cmd_show(self, _ctx, _command): schema_helper = self.schema_helper for show in self._CMD_SHOW_TABLES: schema_helper.register_table(show.table) if show.name_column: schema_helper.register_columns(show.table, [show.name_column]) schema_helper.register_columns(show.table, show.columns) @staticmethod def _cmd_show_find_table_by_row(row): for show in VSCtl._CMD_SHOW_TABLES: if show.table == row._table.name: return show return None @staticmethod def _cmd_show_find_table_by_name(name): for show in VSCtl._CMD_SHOW_TABLES: if show.table == name: return show return None @staticmethod def _cmd_show_row(ctx, row, level): _INDENT_SIZE = 4 # # of spaces per indent show = VSCtl._cmd_show_find_table_by_row(row) output = '' output += ' ' * level * _INDENT_SIZE if show and show.name_column: output += '%s ' % show.table datum = getattr(row, show.name_column) output += datum else: output += str(row.uuid) output += '\n' if not show or show.recurse: return show.recurse = True for column in show.columns: datum = row._data[column] key = datum.type.key if key.type == ovs.db.types.UuidType and key.ref_table_name: ref_show = VSCtl._cmd_show_find_table_by_name( key.ref_table_name) if ref_show: for atom in datum.values: ref_row = ctx.idl.tables[ref_show.table].rows.get( atom.value) if ref_row: VSCtl._cmd_show_row(ctx, ref_row, level + 1) continue if not datum.is_default(): output += ' ' * (level + 1) * _INDENT_SIZE output += '%s: %s\n' % (column, datum) show.recurse = False return output def _cmd_show(self, ctx, command): for row in ctx.idl.tables[ self._CMD_SHOW_TABLES[0].table].rows.values(): output = self._cmd_show_row(ctx, row, 0) command.result = output # Bridge commands: def _pre_get_info(self, _ctx, _command): schema_helper = self.schema_helper schema_helper.register_columns( vswitch_idl.OVSREC_TABLE_OPEN_VSWITCH, [vswitch_idl.OVSREC_OPEN_VSWITCH_COL_BRIDGES]) schema_helper.register_columns( vswitch_idl.OVSREC_TABLE_BRIDGE, [vswitch_idl.OVSREC_BRIDGE_COL_NAME, vswitch_idl.OVSREC_BRIDGE_COL_CONTROLLER, vswitch_idl.OVSREC_BRIDGE_COL_FAIL_MODE, vswitch_idl.OVSREC_BRIDGE_COL_PORTS]) schema_helper.register_columns( vswitch_idl.OVSREC_TABLE_PORT, [vswitch_idl.OVSREC_PORT_COL_NAME, vswitch_idl.OVSREC_PORT_COL_FAKE_BRIDGE, vswitch_idl.OVSREC_PORT_COL_TAG, vswitch_idl.OVSREC_PORT_COL_INTERFACES, vswitch_idl.OVSREC_PORT_COL_QOS]) schema_helper.register_columns( vswitch_idl.OVSREC_TABLE_INTERFACE, [vswitch_idl.OVSREC_INTERFACE_COL_NAME]) schema_helper.register_columns( vswitch_idl.OVSREC_TABLE_QOS, [vswitch_idl.OVSREC_QOS_COL_QUEUES]) schema_helper.register_columns( vswitch_idl.OVSREC_TABLE_QUEUE, []) def _cmd_list_br(self, ctx, command): ctx.populate_cache() command.result = sorted(ctx.bridges.keys()) def _pre_add_br(self, ctx, command): self._pre_get_info(ctx, command) schema_helper = self.schema_helper schema_helper.register_columns( vswitch_idl.OVSREC_TABLE_INTERFACE, [vswitch_idl.OVSREC_INTERFACE_COL_TYPE]) def _cmd_add_br(self, ctx, command): br_name = command.args[0] parent_name = None vlan = 0 if len(command.args) == 1: pass elif len(command.args) == 3: parent_name = command.args[1] vlan = int(command.args[2]) if vlan < 0 or vlan > 4095: vsctl_fatal("vlan must be between 0 and 4095 %d" % vlan) else: vsctl_fatal('this command takes exactly 1 or 3 argument') ctx.add_bridge(br_name, parent_name, vlan) def _del_br(self, ctx, br_name, must_exist=False): ctx.populate_cache() br = ctx.find_bridge(br_name, must_exist) if br: ctx.del_bridge(br) def _cmd_del_br(self, ctx, command): br_name = command.args[0] self._del_br(ctx, br_name) def _br_exists(self, ctx, br_name): ctx.populate_cache() br = ctx.find_bridge(br_name, must_exist=False) return br is not None def _cmd_br_exists(self, ctx, command): br_name = command.args[0] command.result = self._br_exists(ctx, br_name) def _br_to_vlan(self, ctx, br_name): ctx.populate_cache() br = ctx.find_bridge(br_name, must_exist=True) vlan = br.vlan if isinstance(vlan, list): if len(vlan) == 0: vlan = 0 else: vlan = vlan[0] return vlan def _cmd_br_to_vlan(self, ctx, command): br_name = command.args[0] command.result = self._br_to_vlan(ctx, br_name) def _br_to_parent(self, ctx, br_name): ctx.populate_cache() br = ctx.find_bridge(br_name, must_exist=True) return br if br.parent is None else br.parent def _cmd_br_to_parent(self, ctx, command): br_name = command.args[0] command.result = self._br_to_parent(ctx, br_name) def _pre_cmd_br_set_external_id(self, ctx, _command): table_name = vswitch_idl.OVSREC_TABLE_BRIDGE columns = [vswitch_idl.OVSREC_BRIDGE_COL_EXTERNAL_IDS] self._pre_mod_columns(ctx, table_name, columns) def _br_add_external_id(self, ctx, br_name, key, value): table_name = vswitch_idl.OVSREC_TABLE_BRIDGE column = vswitch_idl.OVSREC_BRIDGE_COL_EXTERNAL_IDS vsctl_table = self._get_table(table_name) ovsrec_row = ctx.must_get_row(vsctl_table, br_name) value_json = ['map', [[key, value]]] ctx.add_column(ovsrec_row, column, value_json) ctx.invalidate_cache() def _br_clear_external_id(self, ctx, br_name, key): table_name = vswitch_idl.OVSREC_TABLE_BRIDGE column = vswitch_idl.OVSREC_BRIDGE_COL_EXTERNAL_IDS vsctl_table = self._get_table(table_name) ovsrec_row = ctx.must_get_row(vsctl_table, br_name) values = getattr(ovsrec_row, column, {}) values.pop(key, None) setattr(ovsrec_row, column, values) ctx.invalidate_cache() def _cmd_br_set_external_id(self, ctx, command): br_name = command.args[0] key = command.args[1] if len(command.args) > 2: self._br_add_external_id(ctx, br_name, key, command.args[2]) else: self._br_clear_external_id(ctx, br_name, key) def _pre_cmd_br_get_external_id(self, ctx, _command): table_name = vswitch_idl.OVSREC_TABLE_BRIDGE columns = [vswitch_idl.OVSREC_BRIDGE_COL_EXTERNAL_IDS] self._pre_get_columns(ctx, table_name, columns) def _br_get_external_id_value(self, ctx, br_name, key): external_id = self._br_get_external_id_list(ctx, br_name) return external_id.get(key, None) def _br_get_external_id_list(self, ctx, br_name): table_name = vswitch_idl.OVSREC_TABLE_BRIDGE column = vswitch_idl.OVSREC_BRIDGE_COL_EXTERNAL_IDS vsctl_table = self._get_table(table_name) ovsrec_row = ctx.must_get_row(vsctl_table, br_name) return ctx.get_column(ovsrec_row, column) def _cmd_br_get_external_id(self, ctx, command): br_name = command.args[0] if len(command.args) > 1: command.result = self._br_get_external_id_value(ctx, br_name, command.args[1]) else: command.result = self._br_get_external_id_list(ctx, br_name) # Port commands: def _list_ports(self, ctx, br_name): ctx.populate_cache() br = ctx.find_bridge(br_name, True) if br.br_cfg: br.br_cfg.verify(vswitch_idl.OVSREC_BRIDGE_COL_PORTS) else: br.parent.br_cfg.verify(vswitch_idl.OVSREC_BRIDGE_COL_PORTS) return [port.port_cfg.name for port in br.ports if port.port_cfg.name != br.name] def _cmd_list_ports(self, ctx, command): br_name = command.args[0] port_names = self._list_ports(ctx, br_name) command.result = sorted(port_names) def _pre_add_port(self, _ctx, columns): schema_helper = self.schema_helper schema_helper.register_columns( vswitch_idl.OVSREC_TABLE_PORT, [vswitch_idl.OVSREC_PORT_COL_NAME, vswitch_idl.OVSREC_PORT_COL_BOND_FAKE_IFACE]) schema_helper.register_columns( vswitch_idl.OVSREC_TABLE_PORT, columns) def _pre_cmd_add_port(self, ctx, command): self._pre_get_info(ctx, command) columns = [ ctx.parse_column_key_value( self.schema.tables[vswitch_idl.OVSREC_TABLE_PORT], setting)[0] for setting in command.args[2:]] self._pre_add_port(ctx, columns) def _pre_cmd_add_bond(self, ctx, command): self._pre_get_info(ctx, command) if len(command.args) < 3: vsctl_fatal('this command requires at least 3 arguments') columns = [ ctx.parse_column_key_value( self.schema.tables[vswitch_idl.OVSREC_TABLE_PORT], setting)[0] for setting in command.args[3:]] self._pre_add_port(ctx, columns) def _cmd_add_port(self, ctx, command): # '--may_exist' is a typo but for backword compatibility may_exist = (command.has_option('--may_exist') or command.has_option('--may-exist')) br_name = command.args[0] port_name = command.args[1] iface_names = [command.args[1]] settings = [ ctx.parse_column_key_value( self.schema.tables[vswitch_idl.OVSREC_TABLE_PORT], setting) for setting in command.args[2:]] ctx.add_port(br_name, port_name, may_exist, False, iface_names, settings) def _cmd_add_bond(self, ctx, command): # '--may_exist' is a typo but for backword compatibility may_exist = (command.has_option('--may_exist') or command.has_option('--may-exist')) fake_iface = command.has_option('--fake-iface') br_name = command.args[0] port_name = command.args[1] iface_names = list(command.args[2]) settings = [ ctx.parse_column_key_value( self.schema.tables[vswitch_idl.OVSREC_TABLE_PORT], setting) for setting in command.args[3:]] ctx.add_port(br_name, port_name, may_exist, fake_iface, iface_names, settings) def _del_port(self, ctx, br_name=None, target=None, must_exist=False, with_iface=False): assert target is not None ctx.populate_cache() if not with_iface: vsctl_port = ctx.find_port(target, must_exist) else: vsctl_port = ctx.find_port(target, False) if not vsctl_port: vsctl_iface = ctx.find_iface(target, False) if vsctl_iface: vsctl_port = vsctl_iface.port() if must_exist and not vsctl_port: vsctl_fatal('no port or interface named %s' % target) if not vsctl_port: return if not br_name: vsctl_bridge = ctx.find_bridge(br_name, True) if vsctl_port.bridge() != vsctl_bridge: if vsctl_port.bridge().parent == vsctl_bridge: vsctl_fatal('bridge %s does not have a port %s (although ' 'its parent bridge %s does)' % (br_name, target, vsctl_bridge.parent.name)) else: vsctl_fatal('bridge %s does not have a port %s' % (br_name, target)) ctx.del_port(vsctl_port) def _cmd_del_port(self, ctx, command): must_exist = command.has_option('--must-exist') with_iface = command.has_option('--with-iface') target = command.args[-1] br_name = command.args[0] if len(command.args) == 2 else None self._del_port(ctx, br_name, target, must_exist, with_iface) def _port_to_br(self, ctx, port_name): ctx.populate_cache() port = ctx.find_port(port_name, True) bridge = port.bridge() if bridge is None: vsctl_fatal('Bridge associated to port "%s" does not exist' % port_name) return bridge.name def _cmd_port_to_br(self, ctx, command): iface_name = command.args[0] command.result = self._iface_to_br(ctx, iface_name) # Interface commands: def _list_ifaces(self, ctx, br_name): ctx.populate_cache() br = ctx.find_bridge(br_name, True) ctx.verify_ports() iface_names = set() for vsctl_port in br.ports: for vsctl_iface in vsctl_port.ifaces: iface_name = vsctl_iface.iface_cfg.name if iface_name != br_name: iface_names.add(iface_name) return iface_names def _cmd_list_ifaces(self, ctx, command): br_name = command.args[0] iface_names = self._list_ifaces(ctx, br_name) command.result = sorted(iface_names) def _iface_to_br(self, ctx, iface_name): ctx.populate_cache() iface = ctx.find_iface(iface_name, True) port = iface.port() if port is None: vsctl_fatal('Port associated to iface "%s" does not exist' % iface_name) bridge = port.bridge() if bridge is None: vsctl_fatal('Bridge associated to iface "%s" does not exist' % iface_name) return bridge.name def _cmd_iface_to_br(self, ctx, command): iface_name = command.args[0] command.result = self._iface_to_br(ctx, iface_name) # Utility commands for quantum_adapter: def _pre_cmd_list_ifaces_verbose(self, ctx, command): self._pre_get_info(ctx, command) schema_helper = self.schema_helper schema_helper.register_columns( vswitch_idl.OVSREC_TABLE_BRIDGE, [vswitch_idl.OVSREC_BRIDGE_COL_DATAPATH_ID]) schema_helper.register_columns( vswitch_idl.OVSREC_TABLE_INTERFACE, [vswitch_idl.OVSREC_INTERFACE_COL_TYPE, vswitch_idl.OVSREC_INTERFACE_COL_NAME, vswitch_idl.OVSREC_INTERFACE_COL_EXTERNAL_IDS, vswitch_idl.OVSREC_INTERFACE_COL_OPTIONS, vswitch_idl.OVSREC_INTERFACE_COL_OFPORT]) @staticmethod def _iface_to_dict(iface_cfg): _ATTRIBUTE = ['name', 'ofport', 'type', 'external_ids', 'options'] attr = dict((key, getattr(iface_cfg, key)) for key in _ATTRIBUTE) if attr['ofport']: attr['ofport'] = attr['ofport'][0] return attr def _list_ifaces_verbose(self, ctx, datapath_id, port_name): ctx.populate_cache() br = ctx.find_bridge_by_id(datapath_id, True) ctx.verify_ports() iface_cfgs = [] if port_name is None: for vsctl_port in br.ports: iface_cfgs.extend(self._iface_to_dict(vsctl_iface.iface_cfg) for vsctl_iface in vsctl_port.ifaces) else: # When port is created, ofport column might be None. # So try with port name if it happended for vsctl_port in br.ports: iface_cfgs.extend( self._iface_to_dict(vsctl_iface.iface_cfg) for vsctl_iface in vsctl_port.ifaces if vsctl_iface.iface_cfg.name == port_name) return iface_cfgs def _cmd_list_ifaces_verbose(self, ctx, command): datapath_id = command.args[0] port_name = None if len(command.args) >= 2: port_name = command.args[1] LOG.debug('command.args %s', command.args) iface_cfgs = self._list_ifaces_verbose(ctx, datapath_id, port_name) command.result = sorted(iface_cfgs) # Controller commands: def _verify_controllers(self, ovsrec_bridge): ovsrec_bridge.verify(vswitch_idl.OVSREC_BRIDGE_COL_CONTROLLER) for controller in ovsrec_bridge.controller: controller.verify(vswitch_idl.OVSREC_CONTROLLER_COL_TARGET) def _pre_controller(self, ctx, command): self._pre_get_info(ctx, command) self.schema_helper.register_columns( vswitch_idl.OVSREC_TABLE_CONTROLLER, [vswitch_idl.OVSREC_CONTROLLER_COL_TARGET]) def _get_controller(self, ctx, br_name): ctx.populate_cache() br = ctx.find_bridge(br_name, True) self._verify_controllers(br.br_cfg) return set(controller.target for controller in br.br_cfg.controller) def _cmd_get_controller(self, ctx, command): br_name = command.args[0] controller_names = self._get_controller(ctx, br_name) command.result = sorted(controller_names) def _delete_controllers(self, ovsrec_controllers): for controller in ovsrec_controllers: controller.delete() def _del_controller(self, ctx, br_name): ctx.populate_cache() br = ctx.find_real_bridge(br_name, True) ovsrec_bridge = br.br_cfg self._verify_controllers(ovsrec_bridge) if ovsrec_bridge.controller: self._delete_controllers(ovsrec_bridge.controller) ovsrec_bridge.controller = [] def _cmd_del_controller(self, ctx, command): br_name = command.args[0] self._del_controller(ctx, br_name) def _insert_controllers(self, controller_names): ovsrec_controllers = [] for name in controller_names: # TODO: check if the name startswith() supported protocols ovsrec_controller = self.txn.insert( self.txn.idl.tables[vswitch_idl.OVSREC_TABLE_CONTROLLER]) ovsrec_controller.target = name ovsrec_controllers.append(ovsrec_controller) return ovsrec_controllers def _insert_qos(self): ovsrec_qos = self.txn.insert( self.txn.idl.tables[vswitch_idl.OVSREC_TABLE_QOS]) return ovsrec_qos def _set_controller(self, ctx, br_name, controller_names): ctx.populate_cache() ovsrec_bridge = ctx.find_real_bridge(br_name, True).br_cfg self._verify_controllers(ovsrec_bridge) self._delete_controllers(ovsrec_bridge.controller) controllers = self._insert_controllers(controller_names) ovsrec_bridge.controller = controllers def _cmd_set_controller(self, ctx, command): br_name = command.args[0] controller_names = command.args[1:] self._set_controller(ctx, br_name, controller_names) def _pre_fail_mode(self, ctx, command): self._pre_get_info(ctx, command) self.schema_helper.register_columns( vswitch_idl.OVSREC_TABLE_BRIDGE, [vswitch_idl.OVSREC_BRIDGE_COL_FAIL_MODE]) def _get_fail_mode(self, ctx, br_name): ctx.populate_cache() br = ctx.find_bridge(br_name, True) # Note: Returns first element of fail_mode column return getattr(br.br_cfg, vswitch_idl.OVSREC_BRIDGE_COL_FAIL_MODE)[0] def _cmd_get_fail_mode(self, ctx, command): br_name = command.args[0] command.result = self._get_fail_mode(ctx, br_name) def _del_fail_mode(self, ctx, br_name): ctx.populate_cache() br = ctx.find_bridge(br_name, True) # Note: assuming that [] means empty setattr(br.br_cfg, vswitch_idl.OVSREC_BRIDGE_COL_FAIL_MODE, []) ctx.invalidate_cache() def _cmd_del_fail_mode(self, ctx, command): br_name = command.args[0] self._del_fail_mode(ctx, br_name) def _set_fail_mode(self, ctx, br_name, mode): ctx.populate_cache() br = ctx.find_bridge(br_name, True) setattr(br.br_cfg, vswitch_idl.OVSREC_BRIDGE_COL_FAIL_MODE, mode) ctx.invalidate_cache() def _cmd_set_fail_mode(self, ctx, command): br_name = command.args[0] mode = command.args[1] if mode not in ('standalone', 'secure'): vsctl_fatal('fail-mode must be "standalone" or "secure"') self._set_fail_mode(ctx, br_name, mode) # Utility commands: def _del_qos(self, ctx, port_name): assert port_name is not None ctx.populate_cache() vsctl_port = ctx.find_port(port_name, True) vsctl_qos = vsctl_port.qos ctx.del_qos(vsctl_qos) def _cmd_del_qos(self, ctx, command): port_name = command.args[0] self._del_qos(ctx, port_name) def _set_qos(self, ctx, port_name, type, max_rate): ctx.populate_cache() vsctl_port = ctx.find_port(port_name, True) ovsrec_qos = ctx.set_qos(vsctl_port, type, max_rate) return ovsrec_qos def _cmd_set_qos(self, ctx, command): port_name = command.args[0] type = command.args[1] max_rate = command.args[2] result = self._set_qos(ctx, port_name, type, max_rate) command.result = [result] def _pre_cmd_set_qos(self, ctx, command): self._pre_get_info(ctx, command) schema_helper = self.schema_helper schema_helper.register_columns( vswitch_idl.OVSREC_TABLE_QOS, [vswitch_idl.OVSREC_QOS_COL_EXTERNAL_IDS, vswitch_idl.OVSREC_QOS_COL_OTHER_CONFIG, vswitch_idl.OVSREC_QOS_COL_QUEUES, vswitch_idl.OVSREC_QOS_COL_TYPE]) def _cmd_set_queue(self, ctx, command): ctx.populate_cache() port_name = command.args[0] queues = command.args[1] vsctl_port = ctx.find_port(port_name, True) vsctl_qos = vsctl_port.qos queue_id = 0 results = [] for queue in queues: max_rate = queue.get('max-rate', None) min_rate = queue.get('min-rate', None) ovsrec_queue = ctx.set_queue( vsctl_qos, max_rate, min_rate, queue_id) results.append(ovsrec_queue) queue_id += 1 command.result = results def _pre_cmd_set_queue(self, ctx, command): self._pre_get_info(ctx, command) schema_helper = self.schema_helper schema_helper.register_columns( vswitch_idl.OVSREC_TABLE_QUEUE, [vswitch_idl.OVSREC_QUEUE_COL_DSCP, vswitch_idl.OVSREC_QUEUE_COL_EXTERNAL_IDS, vswitch_idl.OVSREC_QUEUE_COL_OTHER_CONFIG]) # Database commands: _TABLES = [ _VSCtlTable(vswitch_idl.OVSREC_TABLE_BRIDGE, [_VSCtlRowID(vswitch_idl.OVSREC_TABLE_BRIDGE, vswitch_idl.OVSREC_BRIDGE_COL_NAME, None)]), _VSCtlTable(vswitch_idl.OVSREC_TABLE_CONTROLLER, [_VSCtlRowID(vswitch_idl.OVSREC_TABLE_BRIDGE, vswitch_idl.OVSREC_BRIDGE_COL_NAME, vswitch_idl.OVSREC_BRIDGE_COL_CONTROLLER)]), _VSCtlTable(vswitch_idl.OVSREC_TABLE_INTERFACE, [_VSCtlRowID(vswitch_idl.OVSREC_TABLE_INTERFACE, vswitch_idl.OVSREC_INTERFACE_COL_NAME, None)]), _VSCtlTable(vswitch_idl.OVSREC_TABLE_MIRROR, [_VSCtlRowID(vswitch_idl.OVSREC_TABLE_MIRROR, vswitch_idl.OVSREC_MIRROR_COL_NAME, None)]), _VSCtlTable(vswitch_idl.OVSREC_TABLE_MANAGER, [_VSCtlRowID(vswitch_idl.OVSREC_TABLE_MANAGER, vswitch_idl.OVSREC_MANAGER_COL_TARGET, None)]), _VSCtlTable(vswitch_idl.OVSREC_TABLE_NETFLOW, [_VSCtlRowID(vswitch_idl.OVSREC_TABLE_BRIDGE, vswitch_idl.OVSREC_BRIDGE_COL_NAME, vswitch_idl.OVSREC_BRIDGE_COL_NETFLOW)]), _VSCtlTable(vswitch_idl.OVSREC_TABLE_OPEN_VSWITCH, [_VSCtlRowID(vswitch_idl.OVSREC_TABLE_OPEN_VSWITCH, None, None)]), _VSCtlTable(vswitch_idl.OVSREC_TABLE_PORT, [_VSCtlRowID(vswitch_idl.OVSREC_TABLE_PORT, vswitch_idl.OVSREC_PORT_COL_NAME, None)]), _VSCtlTable(vswitch_idl.OVSREC_TABLE_QOS, [_VSCtlRowID(vswitch_idl.OVSREC_TABLE_PORT, vswitch_idl.OVSREC_PORT_COL_NAME, vswitch_idl.OVSREC_PORT_COL_QOS)]), _VSCtlTable(vswitch_idl.OVSREC_TABLE_QUEUE, [_VSCtlRowID(vswitch_idl.OVSREC_TABLE_QOS, None, vswitch_idl.OVSREC_QOS_COL_QUEUES)]), _VSCtlTable(vswitch_idl.OVSREC_TABLE_SSL, [_VSCtlRowID(vswitch_idl.OVSREC_TABLE_OPEN_VSWITCH, None, vswitch_idl.OVSREC_OPEN_VSWITCH_COL_SSL)]), _VSCtlTable(vswitch_idl.OVSREC_TABLE_SFLOW, [_VSCtlRowID(vswitch_idl.OVSREC_TABLE_BRIDGE, vswitch_idl.OVSREC_BRIDGE_COL_NAME, vswitch_idl.OVSREC_BRIDGE_COL_SFLOW)]), _VSCtlTable(vswitch_idl.OVSREC_TABLE_FLOW_TABLE, [_VSCtlRowID(vswitch_idl.OVSREC_TABLE_FLOW_TABLE, vswitch_idl.OVSREC_FLOW_TABLE_COL_NAME, None)]), ] @staticmethod def _score_partial_match(name, s): _MAX_SCORE = 0xffffffff assert len(name) < _MAX_SCORE s = s[:_MAX_SCORE - 1] # in practice, this doesn't matter if name == s: return _MAX_SCORE name = name.lower().replace('-', '_') s = s.lower().replace('-', '_') if s.startswith(name): return _MAX_SCORE - 1 if name.startswith(s): return len(s) return 0 @staticmethod def _get_table(table_name): best_match = None best_score = 0 for table in VSCtl._TABLES: score = VSCtl._score_partial_match(table.table_name, table_name) if score > best_score: best_match = table best_score = score elif score == best_score: best_match = None if best_match: return best_match elif best_score: vsctl_fatal('multiple table names match "%s"' % table_name) else: vsctl_fatal('unknown table "%s"' % table_name) def _pre_get_table(self, _ctx, table_name): vsctl_table = self._get_table(table_name) schema_helper = self.schema_helper schema_helper.register_table(vsctl_table.table_name) for row_id in vsctl_table.row_ids: if row_id.table: schema_helper.register_table(row_id.table) if row_id.name_column: schema_helper.register_columns(row_id.table, [row_id.name_column]) if row_id.uuid_column: schema_helper.register_columns(row_id.table, [row_id.uuid_column]) return vsctl_table def _get_column(self, table_name, column_name): best_match = None best_score = 0 columns = self.schema.tables[table_name].columns.keys() for column in columns: score = VSCtl._score_partial_match(column, column_name) if score > best_score: best_match = column best_score = score elif score == best_score: best_match = None if best_match: # ovs.db.schema_helper._keep_table_columns() requires that # column_name is type of str. Not unicode string return str(best_match) elif best_score: vsctl_fatal('%s contains more than one column whose name ' 'matches "%s"' % (table_name, column_name)) else: vsctl_fatal('%s does not contain a column whose name matches ' '"%s"' % (table_name, column_name)) def _pre_get_column(self, _ctx, table_name, column): column_name = self._get_column(table_name, column) self.schema_helper.register_columns(table_name, [column_name]) def _pre_get_columns(self, ctx, table_name, columns): self._pre_get_table(ctx, table_name) for column in columns: self._pre_get_column(ctx, table_name, column) def _pre_cmd_list(self, ctx, command): table_name = command.args[0] self._pre_get_table(ctx, table_name) def _list(self, ctx, table_name, record_id=None): result = [] for ovsrec_row in ctx.idl.tables[table_name].rows.values(): if record_id is not None and ovsrec_row.name != record_id: continue result.append(ovsrec_row) return result def _cmd_list(self, ctx, command): table_name = command.args[0] record_id = None if len(command.args) > 1: record_id = command.args[1] command.result = self._list(ctx, table_name, record_id) def _pre_cmd_find(self, ctx, command): table_name = command.args[0] table_schema = self.schema.tables[table_name] columns = [ ctx.parse_column_key_value(table_schema, column_key_value)[0] for column_key_value in command.args[1:]] self._pre_get_columns(ctx, table_name, columns) def _check_value(self, ovsrec_row, column_value): """ :type column_value: tuple of column and value_json """ column, value_json = column_value column_schema = ovsrec_row._table.columns[column] value = ovs.db.data.Datum.from_json( column_schema.type, value_json).to_python(ovs.db.idl._uuid_to_row) datum = getattr(ovsrec_row, column) if column_schema.type.is_map(): for k, v in value.items(): if k in datum and datum[k] == v: return True elif datum == value: return True return False def _find(self, ctx, table_name, column_values): """ :type column_values: list of (column, value_json) """ result = [] for ovsrec_row in ctx.idl.tables[table_name].rows.values(): LOG.debug('ovsrec_row %s', ovsrec_row_to_string(ovsrec_row)) if all(self._check_value(ovsrec_row, column_value) for column_value in column_values): result.append(ovsrec_row) return result def _cmd_find(self, ctx, command): table_name = command.args[0] table_schema = self.schema.tables[table_name] column_values = [ ctx.parse_column_key_value(table_schema, column_key_value) for column_key_value in command.args[1:]] command.result = self._find(ctx, table_name, column_values) def _pre_cmd_get(self, ctx, command): table_name = command.args[0] columns = [ ctx.parse_column_key(column_key)[0] for column_key in command.args[2:]] self._pre_get_columns(ctx, table_name, columns) def _get(self, ctx, table_name, record_id, column_keys, id_=None, if_exists=False): vsctl_table = self._get_table(table_name) ovsrec_row = ctx.must_get_row(vsctl_table, record_id) # TODO: Support symbol name # if id_: # symbol, new = ctx.create_symbol(id_) # if not new: # vsctl_fatal('row id "%s" specified on "get" command was ' # 'used before it was defined' % id_) # symbol.uuid = row.uuid # symbol.strong_ref = True result = [] for column, key in column_keys: result.append(ctx.get_column(ovsrec_row, column, key, if_exists)) return result def _cmd_get(self, ctx, command): id_ = None # TODO: Support --id option if_exists = command.has_option('--if-exists') table_name = command.args[0] record_id = command.args[1] column_keys = [ ctx.parse_column_key(column_key) for column_key in command.args[2:]] command.result = self._get( ctx, table_name, record_id, column_keys, id_, if_exists) def _check_mutable(self, table_name, column): column_schema = self.schema.tables[table_name].columns[column] if not column_schema.mutable: vsctl_fatal('cannot modify read-only column %s in table %s' % (column, table_name)) def _pre_mod_columns(self, ctx, table_name, columns): self._pre_get_table(ctx, table_name) for column in columns: self._pre_get_column(ctx, table_name, column) self._check_mutable(table_name, column) def _pre_cmd_set(self, ctx, command): table_name = command.args[0] table_schema = self.schema.tables[table_name] columns = [ ctx.parse_column_key_value(table_schema, column_key_value)[0] for column_key_value in command.args[2:]] self._pre_mod_columns(ctx, table_name, columns) def _set(self, ctx, table_name, record_id, column_values): """ :type column_values: list of (column, value_json) """ vsctl_table = self._get_table(table_name) ovsrec_row = ctx.must_get_row(vsctl_table, record_id) for column, value in column_values: ctx.set_column(ovsrec_row, column, value) ctx.invalidate_cache() def _cmd_set(self, ctx, command): table_name = command.args[0] record_id = command.args[1] # column_key_value: [:]= table_schema = self.schema.tables[table_name] column_values = [ ctx.parse_column_key_value(table_schema, column_key_value) for column_key_value in command.args[2:]] self._set(ctx, table_name, record_id, column_values) def _pre_cmd_add(self, ctx, command): table_name = command.args[0] columns = [command.args[2]] self._pre_mod_columns(ctx, table_name, columns) def _add(self, ctx, table_name, record_id, column_values): """ :type column_values: list of (column, value_json) """ vsctl_table = self._get_table(table_name) ovsrec_row = ctx.must_get_row(vsctl_table, record_id) for column, value in column_values: ctx.add_column(ovsrec_row, column, value) ctx.invalidate_cache() def _cmd_add(self, ctx, command): table_name = command.args[0] record_id = command.args[1] column = command.args[2] column_key_value_strings = [] for value in command.args[3:]: if '=' in value: # construct :=value column_key_value_strings.append('%s:%s' % (column, value)) else: # construct =value column_key_value_strings.append('%s=%s' % (column, value)) table_schema = self.schema.tables[table_name] column_values = [ ctx.parse_column_key_value(table_schema, column_key_value_string) for column_key_value_string in column_key_value_strings] self._add(ctx, table_name, record_id, column_values) def _pre_cmd_remove(self, ctx, command): table_name = command.args[0] columns = [command.args[2]] self._pre_mod_columns(ctx, table_name, columns) def _remove(self, ctx, table_name, record_id, column_values): """ :type column_values: list of (column, value_json) """ vsctl_table = self._get_table(table_name) ovsrec_row = ctx.must_get_row(vsctl_table, record_id) for column, value in column_values: ctx.remove_column(ovsrec_row, column, value) ctx.invalidate_cache() def _cmd_remove(self, ctx, command): table_name = command.args[0] record_id = command.args[1] column = command.args[2] column_key_value_strings = [] for value in command.args[3:]: if '=' in value: # construct :=value column_key_value_strings.append('%s:%s' % (column, value)) else: # construct =value column_key_value_strings.append('%s=%s' % (column, value)) table_schema = self.schema.tables[table_name] column_values = [ ctx.parse_column_key_value(table_schema, column_key_value_string) for column_key_value_string in column_key_value_strings] self._remove(ctx, table_name, record_id, column_values) def _pre_cmd_clear(self, ctx, command): table_name = command.args[0] column = command.args[2] self._pre_mod_columns(ctx, table_name, [column]) def _clear(self, ctx, table_name, record_id, column): vsctl_table = self._get_table(table_name) ovsrec_row = ctx.must_get_row(vsctl_table, record_id) column_schema = ctx.idl.tables[table_name].columns[column] if column_schema.type.n_min > 0: vsctl_fatal('"clear" operation cannot be applied to column %s ' 'of table %s, which is not allowed to be empty' % (column, table_name)) # assuming that default datum is empty. default_datum = ovs.db.data.Datum.default(column_schema.type) setattr(ovsrec_row, column, default_datum.to_python(ovs.db.idl._uuid_to_row)) ctx.invalidate_cache() def _cmd_clear(self, ctx, command): table_name = command.args[0] record_id = command.args[1] column = command.args[2] self._clear(ctx, table_name, record_id, column) # # Create constants from ovs db schema # def schema_print(schema_location, prefix): prefix = prefix.upper() json = ovs.json.from_file(schema_location) schema = ovs.db.schema.DbSchema.from_json(json) print('# Do NOT edit.') print('# This is automatically generated by %s' % __file__) print('# created based on version %s' % (schema.version or 'unknown')) print('') print('') print('%s_DB_NAME = \'%s\'' % (prefix, schema.name)) for table in sorted(schema.tables.values(), key=operator.attrgetter('name')): print('') print('%s_TABLE_%s = \'%s\'' % (prefix, table.name.upper(), table.name)) for column in sorted(table.columns.values(), key=operator.attrgetter('name')): print('%s_%s_COL_%s = \'%s\'' % (prefix, table.name.upper(), column.name.upper(), column.name)) def main(): if len(sys.argv) <= 2: print('Usage: %s ' % sys.argv[0]) print('e.g.: %s vswitchd/vswitch.ovsschema' % sys.argv[0]) location = sys.argv[1] prefix = 'OVSREC' schema_print(location, prefix) if __name__ == '__main__': main() ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/ovs/vswitch_idl.py0000664000175000017500000002164200000000000020542 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2012 Isaku Yamahata # # 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. # Do NOT edit. # This is automatically generated by os_ken/lib/ovs/vsctl.py # created based on version 7.14.0 OVSREC_DB_NAME = 'Open_vSwitch' OVSREC_TABLE_AUTOATTACH = 'AutoAttach' OVSREC_AUTOATTACH_COL_MAPPINGS = 'mappings' OVSREC_AUTOATTACH_COL_SYSTEM_DESCRIPTION = 'system_description' OVSREC_AUTOATTACH_COL_SYSTEM_NAME = 'system_name' OVSREC_TABLE_BRIDGE = 'Bridge' OVSREC_BRIDGE_COL_AUTO_ATTACH = 'auto_attach' OVSREC_BRIDGE_COL_CONTROLLER = 'controller' OVSREC_BRIDGE_COL_DATAPATH_ID = 'datapath_id' OVSREC_BRIDGE_COL_DATAPATH_TYPE = 'datapath_type' OVSREC_BRIDGE_COL_DATAPATH_VERSION = 'datapath_version' OVSREC_BRIDGE_COL_EXTERNAL_IDS = 'external_ids' OVSREC_BRIDGE_COL_FAIL_MODE = 'fail_mode' OVSREC_BRIDGE_COL_FLOOD_VLANS = 'flood_vlans' OVSREC_BRIDGE_COL_FLOW_TABLES = 'flow_tables' OVSREC_BRIDGE_COL_IPFIX = 'ipfix' OVSREC_BRIDGE_COL_MCAST_SNOOPING_ENABLE = 'mcast_snooping_enable' OVSREC_BRIDGE_COL_MIRRORS = 'mirrors' OVSREC_BRIDGE_COL_NAME = 'name' OVSREC_BRIDGE_COL_NETFLOW = 'netflow' OVSREC_BRIDGE_COL_OTHER_CONFIG = 'other_config' OVSREC_BRIDGE_COL_PORTS = 'ports' OVSREC_BRIDGE_COL_PROTOCOLS = 'protocols' OVSREC_BRIDGE_COL_RSTP_ENABLE = 'rstp_enable' OVSREC_BRIDGE_COL_RSTP_STATUS = 'rstp_status' OVSREC_BRIDGE_COL_SFLOW = 'sflow' OVSREC_BRIDGE_COL_STATUS = 'status' OVSREC_BRIDGE_COL_STP_ENABLE = 'stp_enable' OVSREC_TABLE_CONTROLLER = 'Controller' OVSREC_CONTROLLER_COL_CONNECTION_MODE = 'connection_mode' OVSREC_CONTROLLER_COL_CONTROLLER_BURST_LIMIT = 'controller_burst_limit' OVSREC_CONTROLLER_COL_CONTROLLER_RATE_LIMIT = 'controller_rate_limit' OVSREC_CONTROLLER_COL_ENABLE_ASYNC_MESSAGES = 'enable_async_messages' OVSREC_CONTROLLER_COL_EXTERNAL_IDS = 'external_ids' OVSREC_CONTROLLER_COL_INACTIVITY_PROBE = 'inactivity_probe' OVSREC_CONTROLLER_COL_IS_CONNECTED = 'is_connected' OVSREC_CONTROLLER_COL_LOCAL_GATEWAY = 'local_gateway' OVSREC_CONTROLLER_COL_LOCAL_IP = 'local_ip' OVSREC_CONTROLLER_COL_LOCAL_NETMASK = 'local_netmask' OVSREC_CONTROLLER_COL_MAX_BACKOFF = 'max_backoff' OVSREC_CONTROLLER_COL_OTHER_CONFIG = 'other_config' OVSREC_CONTROLLER_COL_ROLE = 'role' OVSREC_CONTROLLER_COL_STATUS = 'status' OVSREC_CONTROLLER_COL_TARGET = 'target' OVSREC_TABLE_FLOW_SAMPLE_COLLECTOR_SET = 'Flow_Sample_Collector_Set' OVSREC_FLOW_SAMPLE_COLLECTOR_SET_COL_BRIDGE = 'bridge' OVSREC_FLOW_SAMPLE_COLLECTOR_SET_COL_EXTERNAL_IDS = 'external_ids' OVSREC_FLOW_SAMPLE_COLLECTOR_SET_COL_ID = 'id' OVSREC_FLOW_SAMPLE_COLLECTOR_SET_COL_IPFIX = 'ipfix' OVSREC_TABLE_FLOW_TABLE = 'Flow_Table' OVSREC_FLOW_TABLE_COL_EXTERNAL_IDS = 'external_ids' OVSREC_FLOW_TABLE_COL_FLOW_LIMIT = 'flow_limit' OVSREC_FLOW_TABLE_COL_GROUPS = 'groups' OVSREC_FLOW_TABLE_COL_NAME = 'name' OVSREC_FLOW_TABLE_COL_OVERFLOW_POLICY = 'overflow_policy' OVSREC_FLOW_TABLE_COL_PREFIXES = 'prefixes' OVSREC_TABLE_IPFIX = 'IPFIX' OVSREC_IPFIX_COL_CACHE_ACTIVE_TIMEOUT = 'cache_active_timeout' OVSREC_IPFIX_COL_CACHE_MAX_FLOWS = 'cache_max_flows' OVSREC_IPFIX_COL_EXTERNAL_IDS = 'external_ids' OVSREC_IPFIX_COL_OBS_DOMAIN_ID = 'obs_domain_id' OVSREC_IPFIX_COL_OBS_POINT_ID = 'obs_point_id' OVSREC_IPFIX_COL_OTHER_CONFIG = 'other_config' OVSREC_IPFIX_COL_SAMPLING = 'sampling' OVSREC_IPFIX_COL_TARGETS = 'targets' OVSREC_TABLE_INTERFACE = 'Interface' OVSREC_INTERFACE_COL_ADMIN_STATE = 'admin_state' OVSREC_INTERFACE_COL_BFD = 'bfd' OVSREC_INTERFACE_COL_BFD_STATUS = 'bfd_status' OVSREC_INTERFACE_COL_CFM_FAULT = 'cfm_fault' OVSREC_INTERFACE_COL_CFM_FAULT_STATUS = 'cfm_fault_status' OVSREC_INTERFACE_COL_CFM_FLAP_COUNT = 'cfm_flap_count' OVSREC_INTERFACE_COL_CFM_HEALTH = 'cfm_health' OVSREC_INTERFACE_COL_CFM_MPID = 'cfm_mpid' OVSREC_INTERFACE_COL_CFM_REMOTE_MPIDS = 'cfm_remote_mpids' OVSREC_INTERFACE_COL_CFM_REMOTE_OPSTATE = 'cfm_remote_opstate' OVSREC_INTERFACE_COL_DUPLEX = 'duplex' OVSREC_INTERFACE_COL_ERROR = 'error' OVSREC_INTERFACE_COL_EXTERNAL_IDS = 'external_ids' OVSREC_INTERFACE_COL_IFINDEX = 'ifindex' OVSREC_INTERFACE_COL_INGRESS_POLICING_BURST = 'ingress_policing_burst' OVSREC_INTERFACE_COL_INGRESS_POLICING_RATE = 'ingress_policing_rate' OVSREC_INTERFACE_COL_LACP_CURRENT = 'lacp_current' OVSREC_INTERFACE_COL_LINK_RESETS = 'link_resets' OVSREC_INTERFACE_COL_LINK_SPEED = 'link_speed' OVSREC_INTERFACE_COL_LINK_STATE = 'link_state' OVSREC_INTERFACE_COL_LLDP = 'lldp' OVSREC_INTERFACE_COL_MAC = 'mac' OVSREC_INTERFACE_COL_MAC_IN_USE = 'mac_in_use' OVSREC_INTERFACE_COL_MTU = 'mtu' OVSREC_INTERFACE_COL_MTU_REQUEST = 'mtu_request' OVSREC_INTERFACE_COL_NAME = 'name' OVSREC_INTERFACE_COL_OFPORT = 'ofport' OVSREC_INTERFACE_COL_OFPORT_REQUEST = 'ofport_request' OVSREC_INTERFACE_COL_OPTIONS = 'options' OVSREC_INTERFACE_COL_OTHER_CONFIG = 'other_config' OVSREC_INTERFACE_COL_STATISTICS = 'statistics' OVSREC_INTERFACE_COL_STATUS = 'status' OVSREC_INTERFACE_COL_TYPE = 'type' OVSREC_TABLE_MANAGER = 'Manager' OVSREC_MANAGER_COL_CONNECTION_MODE = 'connection_mode' OVSREC_MANAGER_COL_EXTERNAL_IDS = 'external_ids' OVSREC_MANAGER_COL_INACTIVITY_PROBE = 'inactivity_probe' OVSREC_MANAGER_COL_IS_CONNECTED = 'is_connected' OVSREC_MANAGER_COL_MAX_BACKOFF = 'max_backoff' OVSREC_MANAGER_COL_OTHER_CONFIG = 'other_config' OVSREC_MANAGER_COL_STATUS = 'status' OVSREC_MANAGER_COL_TARGET = 'target' OVSREC_TABLE_MIRROR = 'Mirror' OVSREC_MIRROR_COL_EXTERNAL_IDS = 'external_ids' OVSREC_MIRROR_COL_NAME = 'name' OVSREC_MIRROR_COL_OUTPUT_PORT = 'output_port' OVSREC_MIRROR_COL_OUTPUT_VLAN = 'output_vlan' OVSREC_MIRROR_COL_SELECT_ALL = 'select_all' OVSREC_MIRROR_COL_SELECT_DST_PORT = 'select_dst_port' OVSREC_MIRROR_COL_SELECT_SRC_PORT = 'select_src_port' OVSREC_MIRROR_COL_SELECT_VLAN = 'select_vlan' OVSREC_MIRROR_COL_SNAPLEN = 'snaplen' OVSREC_MIRROR_COL_STATISTICS = 'statistics' OVSREC_TABLE_NETFLOW = 'NetFlow' OVSREC_NETFLOW_COL_ACTIVE_TIMEOUT = 'active_timeout' OVSREC_NETFLOW_COL_ADD_ID_TO_INTERFACE = 'add_id_to_interface' OVSREC_NETFLOW_COL_ENGINE_ID = 'engine_id' OVSREC_NETFLOW_COL_ENGINE_TYPE = 'engine_type' OVSREC_NETFLOW_COL_EXTERNAL_IDS = 'external_ids' OVSREC_NETFLOW_COL_TARGETS = 'targets' OVSREC_TABLE_OPEN_VSWITCH = 'Open_vSwitch' OVSREC_OPEN_VSWITCH_COL_BRIDGES = 'bridges' OVSREC_OPEN_VSWITCH_COL_CUR_CFG = 'cur_cfg' OVSREC_OPEN_VSWITCH_COL_DATAPATH_TYPES = 'datapath_types' OVSREC_OPEN_VSWITCH_COL_DB_VERSION = 'db_version' OVSREC_OPEN_VSWITCH_COL_EXTERNAL_IDS = 'external_ids' OVSREC_OPEN_VSWITCH_COL_IFACE_TYPES = 'iface_types' OVSREC_OPEN_VSWITCH_COL_MANAGER_OPTIONS = 'manager_options' OVSREC_OPEN_VSWITCH_COL_NEXT_CFG = 'next_cfg' OVSREC_OPEN_VSWITCH_COL_OTHER_CONFIG = 'other_config' OVSREC_OPEN_VSWITCH_COL_OVS_VERSION = 'ovs_version' OVSREC_OPEN_VSWITCH_COL_SSL = 'ssl' OVSREC_OPEN_VSWITCH_COL_STATISTICS = 'statistics' OVSREC_OPEN_VSWITCH_COL_SYSTEM_TYPE = 'system_type' OVSREC_OPEN_VSWITCH_COL_SYSTEM_VERSION = 'system_version' OVSREC_TABLE_PORT = 'Port' OVSREC_PORT_COL_BOND_ACTIVE_SLAVE = 'bond_active_slave' OVSREC_PORT_COL_BOND_DOWNDELAY = 'bond_downdelay' OVSREC_PORT_COL_BOND_FAKE_IFACE = 'bond_fake_iface' OVSREC_PORT_COL_BOND_MODE = 'bond_mode' OVSREC_PORT_COL_BOND_UPDELAY = 'bond_updelay' OVSREC_PORT_COL_EXTERNAL_IDS = 'external_ids' OVSREC_PORT_COL_FAKE_BRIDGE = 'fake_bridge' OVSREC_PORT_COL_INTERFACES = 'interfaces' OVSREC_PORT_COL_LACP = 'lacp' OVSREC_PORT_COL_MAC = 'mac' OVSREC_PORT_COL_NAME = 'name' OVSREC_PORT_COL_OTHER_CONFIG = 'other_config' OVSREC_PORT_COL_QOS = 'qos' OVSREC_PORT_COL_RSTP_STATISTICS = 'rstp_statistics' OVSREC_PORT_COL_RSTP_STATUS = 'rstp_status' OVSREC_PORT_COL_STATISTICS = 'statistics' OVSREC_PORT_COL_STATUS = 'status' OVSREC_PORT_COL_TAG = 'tag' OVSREC_PORT_COL_TRUNKS = 'trunks' OVSREC_PORT_COL_VLAN_MODE = 'vlan_mode' OVSREC_TABLE_QOS = 'QoS' OVSREC_QOS_COL_EXTERNAL_IDS = 'external_ids' OVSREC_QOS_COL_OTHER_CONFIG = 'other_config' OVSREC_QOS_COL_QUEUES = 'queues' OVSREC_QOS_COL_TYPE = 'type' OVSREC_TABLE_QUEUE = 'Queue' OVSREC_QUEUE_COL_DSCP = 'dscp' OVSREC_QUEUE_COL_EXTERNAL_IDS = 'external_ids' OVSREC_QUEUE_COL_OTHER_CONFIG = 'other_config' OVSREC_TABLE_SSL = 'SSL' OVSREC_SSL_COL_BOOTSTRAP_CA_CERT = 'bootstrap_ca_cert' OVSREC_SSL_COL_CA_CERT = 'ca_cert' OVSREC_SSL_COL_CERTIFICATE = 'certificate' OVSREC_SSL_COL_EXTERNAL_IDS = 'external_ids' OVSREC_SSL_COL_PRIVATE_KEY = 'private_key' OVSREC_TABLE_SFLOW = 'sFlow' OVSREC_SFLOW_COL_AGENT = 'agent' OVSREC_SFLOW_COL_EXTERNAL_IDS = 'external_ids' OVSREC_SFLOW_COL_HEADER = 'header' OVSREC_SFLOW_COL_POLLING = 'polling' OVSREC_SFLOW_COL_SAMPLING = 'sampling' OVSREC_SFLOW_COL_TARGETS = 'targets' ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/pack_utils.py0000664000175000017500000000162300000000000017547 0ustar00zuulzuul00000000000000# Copyright (C) 2011, 2012 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2011 Isaku Yamahata # # 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. import struct def msg_pack_into(fmt, buf, offset, *args): needed_len = offset + struct.calcsize(fmt) if len(buf) < needed_len: buf += bytearray(needed_len - len(buf)) struct.pack_into(fmt, buf, offset, *args) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.0901043 os-ken-2.10.0/os_ken/lib/packet/0000775000175000017500000000000000000000000016304 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/packet/__init__.py0000664000175000017500000000032700000000000020417 0ustar00zuulzuul00000000000000""" OSKen packet library. Decoder/Encoder implementations of popular protocols like TCP/IP. """ from . import (ethernet, arp, icmp, icmpv6, ipv4, ipv6, lldp, mpls, packet, packet_base, packet_utils) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/packet/afi.py0000664000175000017500000000150100000000000017412 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013 YAMAMOTO Takashi # # 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. """ Address Family Idenitifier (AFI) http://www.iana.org/assignments/address-family-numbers/\ address-family-numbers.xhtml """ IP = 1 IP6 = 2 L2VPN = 25 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/packet/arp.py0000664000175000017500000001025100000000000017437 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone 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. import struct from os_ken.lib import addrconv from . import ether_types as ether from . import packet_base ARP_HW_TYPE_ETHERNET = 1 # ethernet hardware type # arp operation codes ARP_REQUEST = 1 ARP_REPLY = 2 ARP_REV_REQUEST = 3 ARP_REV_REPLY = 4 class arp(packet_base.PacketBase): """ARP (RFC 826) header encoder/decoder class. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. IPv4 addresses are represented as a string like '192.0.2.1'. MAC addresses are represented as a string like '08:60:6e:7f:74:e7'. __init__ takes the corresponding args in this order. ============== ===================================== ===================== Attribute Description Example ============== ===================================== ===================== hwtype Hardware address. proto Protocol address. hlen byte length of each hardware address. plen byte length of each protocol address. opcode operation codes. src_mac Hardware address of sender. '08:60:6e:7f:74:e7' src_ip Protocol address of sender. '192.0.2.1' dst_mac Hardware address of target. '00:00:00:00:00:00' dst_ip Protocol address of target. '192.0.2.2' ============== ===================================== ===================== """ _PACK_STR = '!HHBBH6s4s6s4s' _MIN_LEN = struct.calcsize(_PACK_STR) _TYPE = { 'ascii': [ 'src_mac', 'src_ip', 'dst_mac', 'dst_ip' ] } def __init__(self, hwtype=ARP_HW_TYPE_ETHERNET, proto=ether.ETH_TYPE_IP, hlen=6, plen=4, opcode=ARP_REQUEST, src_mac='ff:ff:ff:ff:ff:ff', src_ip='0.0.0.0', dst_mac='ff:ff:ff:ff:ff:ff', dst_ip='0.0.0.0'): super(arp, self).__init__() self.hwtype = hwtype self.proto = proto self.hlen = hlen self.plen = plen self.opcode = opcode self.src_mac = src_mac self.src_ip = src_ip self.dst_mac = dst_mac self.dst_ip = dst_ip @classmethod def parser(cls, buf): (hwtype, proto, hlen, plen, opcode, src_mac, src_ip, dst_mac, dst_ip) = struct.unpack_from(cls._PACK_STR, buf) return cls(hwtype, proto, hlen, plen, opcode, addrconv.mac.bin_to_text(src_mac), addrconv.ipv4.bin_to_text(src_ip), addrconv.mac.bin_to_text(dst_mac), addrconv.ipv4.bin_to_text(dst_ip)), None, buf[arp._MIN_LEN:] def serialize(self, payload, prev): return struct.pack(arp._PACK_STR, self.hwtype, self.proto, self.hlen, self.plen, self.opcode, addrconv.mac.text_to_bin(self.src_mac), addrconv.ipv4.text_to_bin(self.src_ip), addrconv.mac.text_to_bin(self.dst_mac), addrconv.ipv4.text_to_bin(self.dst_ip)) def arp_ip(opcode, src_mac, src_ip, dst_mac, dst_ip): """A convenient wrapper for IPv4 ARP for Ethernet. This is an equivalent of the following code. arp(ARP_HW_TYPE_ETHERNET, ether.ETH_TYPE_IP, \ 6, 4, opcode, src_mac, src_ip, dst_mac, dst_ip) """ return arp(ARP_HW_TYPE_ETHERNET, ether.ETH_TYPE_IP, 6, # ether mac address length 4, # ipv4 address length, opcode, src_mac, src_ip, dst_mac, dst_ip) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/packet/bfd.py0000664000175000017500000006726000000000000017424 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Xinguard, Inc. # # 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. """ BFD Control packet parser/serializer [RFC 5880] BFD Control packet format:: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |Vers | Diag |Sta|P|F|C|A|D|M| Detect Mult | Length | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | My Discriminator | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Your Discriminator | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Desired Min TX Interval | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Required Min RX Interval | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Required Min Echo RX Interval | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ An optional Authentication Section MAY be present in the following format of types: 1. Format of Simple Password Authentication Section:: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Auth Type | Auth Len | Auth Key ID | Password... | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ... | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2. Format of Keyed MD5 and Meticulous Keyed MD5 Authentication Section:: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Auth Type | Auth Len | Auth Key ID | Reserved | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Sequence Number | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Auth Key/Digest... | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ... | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 3. Format of Keyed SHA1 and Meticulous Keyed SHA1 Authentication Section:: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Auth Type | Auth Len | Auth Key ID | Reserved | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Sequence Number | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Auth Key/Hash... | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ... | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ """ import hashlib import operator import struct from . import packet_base from os_ken.lib import stringify BFD_STATE_ADMIN_DOWN = 0 BFD_STATE_DOWN = 1 BFD_STATE_INIT = 2 BFD_STATE_UP = 3 BFD_STATE_NAME = {0: "AdminDown", 1: "Down", 2: "Init", 3: "Up"} BFD_FLAG_POLL = 1 << 5 BFD_FLAG_FINAL = 1 << 4 BFD_FLAG_CTRL_PLANE_INDEP = 1 << 3 BFD_FLAG_AUTH_PRESENT = 1 << 2 BFD_FLAG_DEMAND = 1 << 1 BFD_FLAG_MULTIPOINT = 1 BFD_DIAG_NO_DIAG = 0 BFD_DIAG_CTRL_DETECT_TIME_EXPIRED = 1 BFD_DIAG_ECHO_FUNC_FAILED = 2 BFD_DIAG_NEIG_SIG_SESS_DOWN = 3 BFD_DIAG_FWD_PLANE_RESET = 4 BFD_DIAG_PATH_DOWN = 5 BFD_DIAG_CONCAT_PATH_DOWN = 6 BFD_DIAG_ADMIN_DOWN = 7 BFD_DIAG_REV_CONCAT_PATH_DOWN = 8 BFD_DIAG_CODE_NAME = {0: "No Diagnostic", 1: "Control Detection Time Expired", 2: "Echo Function Failed", 3: "Neighbor Signaled Session Down", 4: "Forwarding Plane Reset", 5: "Path Down", 6: "Concatenated Path Down", 7: "Administratively Down", 8: "Reverse Concatenated Path Down"} BFD_AUTH_RESERVED = 0 BFD_AUTH_SIMPLE_PASS = 1 BFD_AUTH_KEYED_MD5 = 2 BFD_AUTH_METICULOUS_KEYED_MD5 = 3 BFD_AUTH_KEYED_SHA1 = 4 BFD_AUTH_METICULOUS_KEYED_SHA1 = 5 BFD_AUTH_TYPE_NAME = {0: "Reserved", 1: "Simple Password", 2: "Keyed MD5", 3: "Meticulous Keyed MD5", 4: "Keyed SHA1", 5: "Meticulous Keyed SHA1"} class bfd(packet_base.PacketBase): """BFD (RFC 5880) Control packet encoder/decoder class. The serialized packet would looks like the ones described in the following sections. * RFC 5880 Generic BFD Control Packet Format An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============================== ============================================ Attribute Description ============================== ============================================ ver The version number of the protocol. This class implements protocol version 1. diag A diagnostic code specifying the local system's reason for the last change in session state. state The current BFD session state as seen by the transmitting system. flags Bitmap of the following flags: ``BFD_FLAG_POLL``, ``BFD_FLAG_FINAL``, ``BFD_FLAG_CTRL_PLANE_INDEP``, ``BFD_FLAG_AUTH_PRESENT``, ``BFD_FLAG_DEMAND``, ``BFD_FLAG_MULTIPOINT`` detect_mult Detection time multiplier. my_discr My Discriminator. your_discr Your Discriminator. desired_min_tx_interval Desired Min TX Interval. (in microseconds) required_min_rx_interval Required Min RX Interval. (in microseconds) required_min_echo_rx_interval Required Min Echo RX Interval. (in microseconds) auth_cls (Optional) Authentication Section instance. It's defined only when the Authentication Present (A) bit is set in flags. Assign an instance of the following classes: ``SimplePassword``, ``KeyedMD5``, ``MeticulousKeyedMD5``, ``KeyedSHA1``, and ``MeticulousKeyedSHA1``. length (Optional) Length of the BFD Control packet, in bytes. ============================== ============================================ """ _PACK_STR = '!BBBBIIIII' _PACK_STR_LEN = struct.calcsize(_PACK_STR) _TYPE = { 'ascii': [] } _auth_parsers = {} def __init__(self, ver=1, diag=0, state=0, flags=0, detect_mult=0, my_discr=0, your_discr=0, desired_min_tx_interval=0, required_min_rx_interval=0, required_min_echo_rx_interval=0, auth_cls=None, length=None): super(bfd, self).__init__() self.ver = ver self.diag = diag self.state = state self.flags = flags self.detect_mult = detect_mult self.my_discr = my_discr self.your_discr = your_discr self.desired_min_tx_interval = desired_min_tx_interval self.required_min_rx_interval = required_min_rx_interval self.required_min_echo_rx_interval = required_min_echo_rx_interval self.auth_cls = auth_cls if isinstance(length, int): self.length = length else: self.length = len(self) def __len__(self): if self.flags & BFD_FLAG_AUTH_PRESENT and self.auth_cls is not None: return self._PACK_STR_LEN + len(self.auth_cls) else: return self._PACK_STR_LEN @classmethod def parser(cls, buf): (diag, flags, detect_mult, length, my_discr, your_discr, desired_min_tx_interval, required_min_rx_interval, required_min_echo_rx_interval) = \ struct.unpack_from(cls._PACK_STR, buf[:cls._PACK_STR_LEN]) ver = diag >> 5 diag = diag & 0x1f state = flags >> 6 flags = flags & 0x3f if flags & BFD_FLAG_AUTH_PRESENT: auth_type = operator.getitem(buf, cls._PACK_STR_LEN) auth_cls = cls._auth_parsers[auth_type].\ parser(buf[cls._PACK_STR_LEN:])[0] else: auth_cls = None msg = cls(ver, diag, state, flags, detect_mult, my_discr, your_discr, desired_min_tx_interval, required_min_rx_interval, required_min_echo_rx_interval, auth_cls) return msg, None, None def serialize(self, payload, prev): if self.flags & BFD_FLAG_AUTH_PRESENT and self.auth_cls is not None: return self.pack() + \ self.auth_cls.serialize(payload=None, prev=self) else: return self.pack() def pack(self): """ Encode a BFD Control packet without authentication section. """ diag = (self.ver << 5) + self.diag flags = (self.state << 6) + self.flags length = len(self) return struct.pack(self._PACK_STR, diag, flags, self.detect_mult, length, self.my_discr, self.your_discr, self.desired_min_tx_interval, self.required_min_rx_interval, self.required_min_echo_rx_interval) def authenticate(self, *args, **kwargs): """Authenticate this packet. Returns a boolean indicates whether the packet can be authenticated or not. Returns ``False`` if the Authentication Present (A) is not set in the flag of this packet. Returns ``False`` if the Authentication Section for this packet is not present. For the description of the arguemnts of this method, refer to the authentication method of the Authentication Section classes. """ if not self.flags & BFD_FLAG_AUTH_PRESENT or \ not issubclass(self.auth_cls.__class__, BFDAuth): return False return self.auth_cls.authenticate(self, *args, **kwargs) @classmethod def set_auth_parser(cls, auth_cls): cls._auth_parsers[auth_cls.auth_type] = auth_cls @classmethod def register_auth_type(cls, auth_type): def _set_type(auth_cls): auth_cls.set_type(auth_cls, auth_type) cls.set_auth_parser(auth_cls) return auth_cls return _set_type class BFDAuth(stringify.StringifyMixin): """Base class of BFD (RFC 5880) Authentication Section An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. .. tabularcolumns:: |l|L| =========== ============================================ Attribute Description =========== ============================================ auth_type The authentication type in use. auth_len The length, in bytes, of the authentication section, including the ``auth_type`` and ``auth_len`` fields. =========== ============================================ """ _PACK_HDR_STR = '!BB' _PACK_HDR_STR_LEN = struct.calcsize(_PACK_HDR_STR) auth_type = None def __init__(self, auth_len=None): super(BFDAuth, self).__init__() if isinstance(auth_len, int): self.auth_len = auth_len else: self.auth_len = len(self) @staticmethod def set_type(subcls, auth_type): assert issubclass(subcls, BFDAuth) subcls.auth_type = auth_type @classmethod def parser_hdr(cls, buf): """ Parser for common part of authentication section. """ return struct.unpack_from(cls._PACK_HDR_STR, buf[:cls._PACK_HDR_STR_LEN]) def serialize_hdr(self): """ Serialization function for common part of authentication section. """ return struct.pack(self._PACK_HDR_STR, self.auth_type, self.auth_len) @bfd.register_auth_type(BFD_AUTH_SIMPLE_PASS) class SimplePassword(BFDAuth): """ BFD (RFC 5880) Simple Password Authentication Section class An instance has the following attributes. Most of them are same to the on-wire counterparts but in host byte order. .. tabularcolumns:: |l|L| =========== ============================================ Attribute Description =========== ============================================ auth_type (Fixed) The authentication type in use. auth_key_id The authentication Key ID in use. password The simple password in use on this session. The password is a binary string, and MUST be from 1 to 16 bytes in length. auth_len The length, in bytes, of the authentication section, including the ``auth_type`` and ``auth_len`` fields. =========== ============================================ """ _PACK_STR = '!B' _PACK_STR_LEN = struct.calcsize(_PACK_STR) def __init__(self, auth_key_id, password, auth_len=None): assert len(password) >= 1 and len(password) <= 16 self.auth_key_id = auth_key_id self.password = password super(SimplePassword, self).__init__(auth_len) def __len__(self): return self._PACK_HDR_STR_LEN + self._PACK_STR_LEN + len(self.password) @classmethod def parser(cls, buf): (auth_type, auth_len) = cls.parser_hdr(buf) assert auth_type == cls.auth_type auth_key_id = operator.getitem(buf, cls._PACK_HDR_STR_LEN) password = buf[cls._PACK_HDR_STR_LEN + cls._PACK_STR_LEN:auth_len] msg = cls(auth_key_id, password, auth_len) return msg, None, None def serialize(self, payload, prev): """Encode a Simple Password Authentication Section. ``payload`` is the rest of the packet which will immediately follow this section. ``prev`` is a ``bfd`` instance for the BFD Control header. It's not necessary for encoding only the Simple Password section. """ return self.serialize_hdr() + \ struct.pack(self._PACK_STR, self.auth_key_id) + self.password def authenticate(self, prev=None, auth_keys=None): """Authenticate the password for this packet. This method can be invoked only when ``self.password`` is defined. Returns a boolean indicates whether the password can be authenticated or not. ``prev`` is a ``bfd`` instance for the BFD Control header. It's not necessary for authenticating the Simple Password. ``auth_keys`` is a dictionary of authentication key chain which key is an integer of *Auth Key ID* and value is a string of *Password*. """ auth_keys = auth_keys if auth_keys else {} assert isinstance(prev, bfd) if self.auth_key_id in auth_keys and \ self.password == auth_keys[self.auth_key_id]: return True else: return False @bfd.register_auth_type(BFD_AUTH_KEYED_MD5) class KeyedMD5(BFDAuth): """ BFD (RFC 5880) Keyed MD5 Authentication Section class An instance has the following attributes. Most of them are same to the on-wire counterparts but in host byte order. .. tabularcolumns:: |l|L| =========== ================================================= Attribute Description =========== ================================================= auth_type (Fixed) The authentication type in use. auth_key_id The authentication Key ID in use. seq The sequence number for this packet. This value is incremented occasionally. auth_key The shared MD5 key for this packet. digest (Optional) The 16-byte MD5 digest for the packet. auth_len (Fixed) The length of the authentication section is 24 bytes. =========== ================================================= """ _PACK_STR = '!BBL16s' _PACK_STR_LEN = struct.calcsize(_PACK_STR) def __init__(self, auth_key_id, seq, auth_key=None, digest=None, auth_len=None): self.auth_key_id = auth_key_id self.seq = seq self.auth_key = auth_key self.digest = digest super(KeyedMD5, self).__init__(auth_len) def __len__(self): # Defined in RFC5880 Section 4.3. return 24 @classmethod def parser(cls, buf): (auth_type, auth_len) = cls.parser_hdr(buf) assert auth_type == cls.auth_type assert auth_len == 24 (auth_key_id, reserved, seq, digest) = \ struct.unpack_from(cls._PACK_STR, buf[cls._PACK_HDR_STR_LEN:]) assert reserved == 0 msg = cls(auth_key_id=auth_key_id, seq=seq, auth_key=None, digest=digest) return msg, None, None def serialize(self, payload, prev): """Encode a Keyed MD5 Authentication Section. This method is used only when encoding an BFD Control packet. ``payload`` is the rest of the packet which will immediately follow this section. ``prev`` is a ``bfd`` instance for the BFD Control header which this authentication section belongs to. It's necessary to be assigned because an MD5 digest must be calculated over the entire BFD Control packet. """ assert self.auth_key is not None and len(self.auth_key) <= 16 assert isinstance(prev, bfd) bfd_bin = prev.pack() auth_hdr_bin = self.serialize_hdr() auth_data_bin = struct.pack(self._PACK_STR, self.auth_key_id, 0, self.seq, self.auth_key + (b'\x00' * (len(self.auth_key) - 16))) h = hashlib.md5() h.update(bfd_bin + auth_hdr_bin + auth_data_bin) self.digest = h.digest() return auth_hdr_bin + struct.pack(self._PACK_STR, self.auth_key_id, 0, self.seq, self.digest) def authenticate(self, prev, auth_keys=None): """Authenticate the MD5 digest for this packet. This method can be invoked only when ``self.digest`` is defined. Returns a boolean indicates whether the digest can be authenticated by the correspondent Auth Key or not. ``prev`` is a ``bfd`` instance for the BFD Control header which this authentication section belongs to. It's necessary to be assigned because an MD5 digest must be calculated over the entire BFD Control packet. ``auth_keys`` is a dictionary of authentication key chain which key is an integer of *Auth Key ID* and value is a string of *Auth Key*. """ auth_keys = auth_keys if auth_keys else {} assert isinstance(prev, bfd) if self.digest is None: return False if self.auth_key_id not in auth_keys: return False auth_key = auth_keys[self.auth_key_id] bfd_bin = prev.pack() auth_hdr_bin = self.serialize_hdr() auth_data_bin = struct.pack(self._PACK_STR, self.auth_key_id, 0, self.seq, auth_key + (b'\x00' * (len(auth_key) - 16))) h = hashlib.md5() h.update(bfd_bin + auth_hdr_bin + auth_data_bin) if self.digest == h.digest(): return True else: return False @bfd.register_auth_type(BFD_AUTH_METICULOUS_KEYED_MD5) class MeticulousKeyedMD5(KeyedMD5): """ BFD (RFC 5880) Meticulous Keyed MD5 Authentication Section class All methods of this class are inherited from ``KeyedMD5``. An instance has the following attributes. Most of them are same to the on-wire counterparts but in host byte order. .. tabularcolumns:: |l|L| =========== ================================================= Attribute Description =========== ================================================= auth_type (Fixed) The authentication type in use. auth_key_id The authentication Key ID in use. seq The sequence number for this packet. This value is incremented for each successive packet transmitted for a session. auth_key The shared MD5 key for this packet. digest (Optional) The 16-byte MD5 digest for the packet. auth_len (Fixed) The length of the authentication section is 24 bytes. =========== ================================================= """ pass @bfd.register_auth_type(BFD_AUTH_KEYED_SHA1) class KeyedSHA1(BFDAuth): """ BFD (RFC 5880) Keyed SHA1 Authentication Section class An instance has the following attributes. Most of them are same to the on-wire counterparts but in host byte order. .. tabularcolumns:: |l|L| =========== ================================================ Attribute Description =========== ================================================ auth_type (Fixed) The authentication type in use. auth_key_id The authentication Key ID in use. seq The sequence number for this packet. This value is incremented occasionally. auth_key The shared SHA1 key for this packet. auth_hash (Optional) The 20-byte SHA1 hash for the packet. auth_len (Fixed) The length of the authentication section is 28 bytes. =========== ================================================ """ _PACK_STR = '!BBL20s' _PACK_STR_LEN = struct.calcsize(_PACK_STR) def __init__(self, auth_key_id, seq, auth_key=None, auth_hash=None, auth_len=None): self.auth_key_id = auth_key_id self.seq = seq self.auth_key = auth_key self.auth_hash = auth_hash super(KeyedSHA1, self).__init__(auth_len) def __len__(self): # Defined in RFC5880 Section 4.4. return 28 @classmethod def parser(cls, buf): (auth_type, auth_len) = cls.parser_hdr(buf) assert auth_type == cls.auth_type assert auth_len == 28 (auth_key_id, reserved, seq, auth_hash) = \ struct.unpack_from(cls._PACK_STR, buf[cls._PACK_HDR_STR_LEN:]) assert reserved == 0 msg = cls(auth_key_id=auth_key_id, seq=seq, auth_key=None, auth_hash=auth_hash) return msg, None, None def serialize(self, payload, prev): """Encode a Keyed SHA1 Authentication Section. This method is used only when encoding an BFD Control packet. ``payload`` is the rest of the packet which will immediately follow this section. ``prev`` is a ``bfd`` instance for the BFD Control header which this authentication section belongs to. It's necessary to be assigned because an SHA1 hash must be calculated over the entire BFD Control packet. """ assert self.auth_key is not None and len(self.auth_key) <= 20 assert isinstance(prev, bfd) bfd_bin = prev.pack() auth_hdr_bin = self.serialize_hdr() auth_data_bin = struct.pack(self._PACK_STR, self.auth_key_id, 0, self.seq, self.auth_key + (b'\x00' * (len(self.auth_key) - 20))) h = hashlib.sha1() h.update(bfd_bin + auth_hdr_bin + auth_data_bin) self.auth_hash = h.digest() return auth_hdr_bin + struct.pack(self._PACK_STR, self.auth_key_id, 0, self.seq, self.auth_hash) def authenticate(self, prev, auth_keys=None): """Authenticate the SHA1 hash for this packet. This method can be invoked only when ``self.auth_hash`` is defined. Returns a boolean indicates whether the hash can be authenticated by the correspondent Auth Key or not. ``prev`` is a ``bfd`` instance for the BFD Control header which this authentication section belongs to. It's necessary to be assigned because an SHA1 hash must be calculated over the entire BFD Control packet. ``auth_keys`` is a dictionary of authentication key chain which key is an integer of *Auth Key ID* and value is a string of *Auth Key*. """ auth_keys = auth_keys if auth_keys else {} assert isinstance(prev, bfd) if self.auth_hash is None: return False if self.auth_key_id not in auth_keys: return False auth_key = auth_keys[self.auth_key_id] bfd_bin = prev.pack() auth_hdr_bin = self.serialize_hdr() auth_data_bin = struct.pack(self._PACK_STR, self.auth_key_id, 0, self.seq, auth_key + (b'\x00' * (len(auth_key) - 20))) h = hashlib.sha1() h.update(bfd_bin + auth_hdr_bin + auth_data_bin) if self.auth_hash == h.digest(): return True else: return False @bfd.register_auth_type(BFD_AUTH_METICULOUS_KEYED_SHA1) class MeticulousKeyedSHA1(KeyedSHA1): """ BFD (RFC 5880) Meticulous Keyed SHA1 Authentication Section class All methods of this class are inherited from ``KeyedSHA1``. An instance has the following attributes. Most of them are same to the on-wire counterparts but in host byte order. .. tabularcolumns:: |l|L| =========== ================================================ Attribute Description =========== ================================================ auth_type (Fixed) The authentication type in use. auth_key_id The authentication Key ID in use. seq The sequence number for this packet. This value is incremented for each successive packet transmitted for a session. auth_key The shared SHA1 key for this packet. auth_hash (Optional) The 20-byte SHA1 hash for the packet. auth_len (Fixed) The length of the authentication section is 28 bytes. =========== ================================================ """ pass bfd.set_classes(bfd._auth_parsers) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/packet/bgp.py0000664000175000017500000056305600000000000017445 0ustar00zuulzuul00000000000000# Copyright (C) 2013,2014 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013,2014 YAMAMOTO Takashi # # 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. """ RFC 4271 BGP-4 """ # todo # - notify data # - RFC 4364 BGP/MPLS IP Virtual Private Networks (VPNs) import abc import base64 import collections import copy import functools import io import itertools import math import operator import re import socket import struct import netaddr from os_ken.lib.stringify import StringifyMixin from os_ken.lib.packet import afi as addr_family from os_ken.lib.packet import safi as subaddr_family from os_ken.lib.packet import packet_base from os_ken.lib.packet import stream_parser from os_ken.lib.packet import vxlan from os_ken.lib.packet import mpls from os_ken.lib import addrconv from os_ken.lib import type_desc from os_ken.lib.type_desc import TypeDisp from os_ken.lib import ip from os_ken.lib.pack_utils import msg_pack_into from os_ken.utils import binary_str from os_ken.utils import import_module TCP_SERVER_PORT = 179 BGP_MSG_OPEN = 1 BGP_MSG_UPDATE = 2 BGP_MSG_NOTIFICATION = 3 BGP_MSG_KEEPALIVE = 4 BGP_MSG_ROUTE_REFRESH = 5 # RFC 2918 _VERSION = 4 _MARKER = 16 * b'\xff' BGP_OPT_CAPABILITY = 2 # RFC 5492 BGP_CAP_MULTIPROTOCOL = 1 # RFC 4760 BGP_CAP_ROUTE_REFRESH = 2 # RFC 2918 BGP_CAP_CARRYING_LABEL_INFO = 4 # RFC 3107 BGP_CAP_GRACEFUL_RESTART = 64 # RFC 4724 BGP_CAP_FOUR_OCTET_AS_NUMBER = 65 # RFC 4893 BGP_CAP_ENHANCED_ROUTE_REFRESH = 70 # https://tools.ietf.org/html/\ # draft-ietf-idr-bgp-enhanced-route-refresh-05 BGP_CAP_ROUTE_REFRESH_CISCO = 128 # in cisco routers, there are two\ # route refresh code: one using the capability code of 128 (old), # another using the capability code of 2 (new). BGP_ATTR_FLAG_OPTIONAL = 1 << 7 BGP_ATTR_FLAG_TRANSITIVE = 1 << 6 BGP_ATTR_FLAG_PARTIAL = 1 << 5 BGP_ATTR_FLAG_EXTENDED_LENGTH = 1 << 4 BGP_ATTR_TYPE_ORIGIN = 1 # 0,1,2 (1 byte) BGP_ATTR_TYPE_AS_PATH = 2 # a list of AS_SET/AS_SEQUENCE eg. {1 2 3} 4 5 BGP_ATTR_TYPE_NEXT_HOP = 3 # an IPv4 address BGP_ATTR_TYPE_MULTI_EXIT_DISC = 4 # uint32 metric BGP_ATTR_TYPE_LOCAL_PREF = 5 # uint32 BGP_ATTR_TYPE_ATOMIC_AGGREGATE = 6 # 0 bytes BGP_ATTR_TYPE_AGGREGATOR = 7 # AS number and IPv4 address BGP_ATTR_TYPE_COMMUNITIES = 8 # RFC 1997 BGP_ATTR_TYPE_ORIGINATOR_ID = 9 # RFC 4456 BGP_ATTR_TYPE_CLUSTER_LIST = 10 # RFC 4456 BGP_ATTR_TYPE_MP_REACH_NLRI = 14 # RFC 4760 BGP_ATTR_TYPE_MP_UNREACH_NLRI = 15 # RFC 4760 BGP_ATTR_TYPE_EXTENDED_COMMUNITIES = 16 # RFC 4360 BGP_ATTR_TYPE_AS4_PATH = 17 # RFC 4893 BGP_ATTR_TYPE_AS4_AGGREGATOR = 18 # RFC 4893 BGP_ATTR_TYEP_PMSI_TUNNEL_ATTRIBUTE = 22 # RFC 6514 BGP_ATTR_ORIGIN_IGP = 0x00 BGP_ATTR_ORIGIN_EGP = 0x01 BGP_ATTR_ORIGIN_INCOMPLETE = 0x02 AS_TRANS = 23456 # RFC 4893 # Well known commmunities (RFC 1997) BGP_COMMUNITY_NO_EXPORT = 0xffffff01 BGP_COMMUNITY_NO_ADVERTISE = 0xffffff02 BGP_COMMUNITY_NO_EXPORT_SUBCONFED = 0xffffff03 # RFC 4360 # The low-order octet of Type field (subtype) BGP_EXTENDED_COMMUNITY_ROUTE_TARGET = 0x02 BGP_EXTENDED_COMMUNITY_ROUTE_ORIGIN = 0x03 # NOTIFICATION Error Code and SubCode # Note: 0 is a valid SubCode. (Unspecific) # NOTIFICATION Error Code RFC 4271 4.5. BGP_ERROR_MESSAGE_HEADER_ERROR = 1 BGP_ERROR_OPEN_MESSAGE_ERROR = 2 BGP_ERROR_UPDATE_MESSAGE_ERROR = 3 BGP_ERROR_HOLD_TIMER_EXPIRED = 4 BGP_ERROR_FSM_ERROR = 5 BGP_ERROR_CEASE = 6 # NOTIFICATION Error Subcode for BGP_ERROR_MESSAGE_HEADER_ERROR BGP_ERROR_SUB_CONNECTION_NOT_SYNCHRONIZED = 1 BGP_ERROR_SUB_BAD_MESSAGE_LENGTH = 2 # Data: the erroneous Length field BGP_ERROR_SUB_BAD_MESSAGE_TYPE = 3 # Data: the erroneous Type field # NOTIFICATION Error Subcode for BGP_ERROR_OPEN_MESSAGE_ERROR BGP_ERROR_SUB_UNSUPPORTED_VERSION_NUMBER = 1 # Data: 2 octet version number BGP_ERROR_SUB_BAD_PEER_AS = 2 BGP_ERROR_SUB_BAD_BGP_IDENTIFIER = 3 BGP_ERROR_SUB_UNSUPPORTED_OPTIONAL_PARAMETER = 4 BGP_ERROR_SUB_AUTHENTICATION_FAILURE = 5 # deprecated RFC 1771 BGP_ERROR_SUB_UNACCEPTABLE_HOLD_TIME = 6 # NOTIFICATION Error Subcode for BGP_ERROR_UPDATE_MESSAGE_ERROR BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST = 1 BGP_ERROR_SUB_UNRECOGNIZED_WELL_KNOWN_ATTRIBUTE = 2 # Data: type of the attr BGP_ERROR_SUB_MISSING_WELL_KNOWN_ATTRIBUTE = 3 # Data: ditto BGP_ERROR_SUB_ATTRIBUTE_FLAGS_ERROR = 4 # Data: the attr (type, len, value) BGP_ERROR_SUB_ATTRIBUTE_LENGTH_ERROR = 5 # Data: ditto BGP_ERROR_SUB_INVALID_ORIGIN_ATTRIBUTE = 6 # Data: ditto BGP_ERROR_SUB_ROUTING_LOOP = 7 # deprecated RFC 1771 AS Routing Loop BGP_ERROR_SUB_INVALID_NEXT_HOP_ATTRIBUTE = 8 # Data: ditto BGP_ERROR_SUB_OPTIONAL_ATTRIBUTE_ERROR = 9 # Data: ditto BGP_ERROR_SUB_INVALID_NETWORK_FIELD = 10 BGP_ERROR_SUB_MALFORMED_AS_PATH = 11 # NOTIFICATION Error Subcode for BGP_ERROR_HOLD_TIMER_EXPIRED BGP_ERROR_SUB_HOLD_TIMER_EXPIRED = 1 # NOTIFICATION Error Subcode for BGP_ERROR_FSM_ERROR BGP_ERROR_SUB_FSM_ERROR = 1 # NOTIFICATION Error Subcode for BGP_ERROR_CEASE (RFC 4486) BGP_ERROR_SUB_MAXIMUM_NUMBER_OF_PREFIXES_REACHED = 1 # Data: optional BGP_ERROR_SUB_ADMINISTRATIVE_SHUTDOWN = 2 BGP_ERROR_SUB_PEER_DECONFIGURED = 3 BGP_ERROR_SUB_ADMINISTRATIVE_RESET = 4 BGP_ERROR_SUB_CONNECTION_RESET = 5 BGP_ERROR_SUB_OTHER_CONFIGURATION_CHANGE = 6 BGP_ERROR_SUB_CONNECTION_COLLISION_RESOLUTION = 7 BGP_ERROR_SUB_OUT_OF_RESOURCES = 8 class _Value(object): _VALUE_PACK_STR = None _VALUE_FIELDS = ['value'] @staticmethod def do_init(cls_type, self, kwargs, **extra_kwargs): ourfields = {} for f in cls_type._VALUE_FIELDS: v = kwargs[f] del kwargs[f] ourfields[f] = v kwargs.update(extra_kwargs) super(cls_type, self).__init__(**kwargs) self.__dict__.update(ourfields) @classmethod def parse_value(cls, buf): values = struct.unpack_from(cls._VALUE_PACK_STR, bytes(buf)) return dict(zip(cls._VALUE_FIELDS, values)) def serialize_value(self): args = [] for f in self._VALUE_FIELDS: args.append(getattr(self, f)) return struct.pack(self._VALUE_PACK_STR, *args) class BgpExc(Exception): """Base bgp exception.""" CODE = 0 """BGP error code.""" SUB_CODE = 0 """BGP error sub-code.""" SEND_ERROR = True """Flag if set indicates Notification message should be sent to peer.""" def __init__(self, data=''): super(BgpExc, self).__init__() self.data = data def __str__(self): return '<%s %r>' % (self.__class__.__name__, self.data) class BadNotification(BgpExc): SEND_ERROR = False # ============================================================================ # Message Header Errors # ============================================================================ class NotSync(BgpExc): CODE = BGP_ERROR_MESSAGE_HEADER_ERROR SUB_CODE = BGP_ERROR_SUB_CONNECTION_NOT_SYNCHRONIZED class BadLen(BgpExc): CODE = BGP_ERROR_MESSAGE_HEADER_ERROR SUB_CODE = BGP_ERROR_SUB_BAD_MESSAGE_LENGTH def __init__(self, msg_type_code, message_length): super(BadLen, self).__init__() self.msg_type_code = msg_type_code self.length = message_length self.data = struct.pack('!H', self.length) def __str__(self): return '' % (self.length, self.msg_type_code) class BadMsg(BgpExc): """Error to indicate un-recognized message type. RFC says: If the Type field of the message header is not recognized, then the Error Subcode MUST be set to Bad Message Type. The Data field MUST contain the erroneous Type field. """ CODE = BGP_ERROR_MESSAGE_HEADER_ERROR SUB_CODE = BGP_ERROR_SUB_BAD_MESSAGE_TYPE def __init__(self, msg_type): super(BadMsg, self).__init__() self.msg_type = msg_type self.data = struct.pack('B', msg_type) def __str__(self): return '' % (self.msg_type,) # ============================================================================ # OPEN Message Errors # ============================================================================ class MalformedOptionalParam(BgpExc): """If recognized optional parameters are malformed. RFC says: If one of the Optional Parameters in the OPEN message is recognized, but is malformed, then the Error Subcode MUST be set to 0 (Unspecific). """ CODE = BGP_ERROR_OPEN_MESSAGE_ERROR SUB_CODE = 0 class UnsupportedVersion(BgpExc): """Error to indicate unsupport bgp version number. RFC says: If the version number in the Version field of the received OPEN message is not supported, then the Error Subcode MUST be set to Unsupported Version Number. The Data field is a 2-octet unsigned integer, which indicates the largest, locally-supported version number less than the version the remote BGP peer bid (as indicated in the received OPEN message), or if the smallest, locally-supported version number is greater than the version the remote BGP peer bid, then the smallest, locally- supported version number. """ CODE = BGP_ERROR_OPEN_MESSAGE_ERROR SUB_CODE = BGP_ERROR_SUB_UNSUPPORTED_VERSION_NUMBER def __init__(self, locally_support_version): super(UnsupportedVersion, self).__init__() self.data = struct.pack('H', locally_support_version) class BadPeerAs(BgpExc): """Error to indicate open message has incorrect AS number. RFC says: If the Autonomous System field of the OPEN message is unacceptable, then the Error Subcode MUST be set to Bad Peer AS. The determination of acceptable Autonomous System numbers is configure peer AS. """ CODE = BGP_ERROR_OPEN_MESSAGE_ERROR SUB_CODE = BGP_ERROR_SUB_BAD_PEER_AS class BadBgpId(BgpExc): """Error to indicate incorrect BGP Identifier. RFC says: If the BGP Identifier field of the OPEN message is syntactically incorrect, then the Error Subcode MUST be set to Bad BGP Identifier. Syntactic correctness means that the BGP Identifier field represents a valid unicast IP host address. """ CODE = BGP_ERROR_OPEN_MESSAGE_ERROR SUB_CODE = BGP_ERROR_SUB_BAD_BGP_IDENTIFIER class UnsupportedOptParam(BgpExc): """Error to indicate unsupported optional parameters. RFC says: If one of the Optional Parameters in the OPEN message is not recognized, then the Error Subcode MUST be set to Unsupported Optional Parameters. """ CODE = BGP_ERROR_OPEN_MESSAGE_ERROR SUB_CODE = BGP_ERROR_SUB_UNSUPPORTED_OPTIONAL_PARAMETER class AuthFailure(BgpExc): CODE = BGP_ERROR_OPEN_MESSAGE_ERROR SUB_CODE = BGP_ERROR_SUB_AUTHENTICATION_FAILURE class UnacceptableHoldTime(BgpExc): """Error to indicate Unacceptable Hold Time in open message. RFC says: If the Hold Time field of the OPEN message is unacceptable, then the Error Subcode MUST be set to Unacceptable Hold Time. """ CODE = BGP_ERROR_OPEN_MESSAGE_ERROR SUB_CODE = BGP_ERROR_SUB_UNACCEPTABLE_HOLD_TIME # ============================================================================ # UPDATE message related errors # ============================================================================ class MalformedAttrList(BgpExc): """Error to indicate UPDATE message is malformed. RFC says: Error checking of an UPDATE message begins by examining the path attributes. If the Withdrawn Routes Length or Total Attribute Length is too large (i.e., if Withdrawn Routes Length + Total Attribute Length + 23 exceeds the message Length), then the Error Subcode MUST be set to Malformed Attribute List. """ CODE = BGP_ERROR_UPDATE_MESSAGE_ERROR SUB_CODE = BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST class UnRegWellKnowAttr(BgpExc): CODE = BGP_ERROR_UPDATE_MESSAGE_ERROR SUB_CODE = BGP_ERROR_SUB_UNRECOGNIZED_WELL_KNOWN_ATTRIBUTE class MissingWellKnown(BgpExc): """Error to indicate missing well-known attribute. RFC says: If any of the well-known mandatory attributes are not present, then the Error Subcode MUST be set to Missing Well-known Attribute. The Data field MUST contain the Attribute Type Code of the missing, well-known attribute. """ CODE = BGP_ERROR_UPDATE_MESSAGE_ERROR SUB_CODE = BGP_ERROR_SUB_MISSING_WELL_KNOWN_ATTRIBUTE def __init__(self, pattr_type_code): super(MissingWellKnown, self).__init__() self.pattr_type_code = pattr_type_code self.data = struct.pack('B', pattr_type_code) class AttrFlagError(BgpExc): """Error to indicate recognized path attributes have incorrect flags. RFC says: If any recognized attribute has Attribute Flags that conflict with the Attribute Type Code, then the Error Subcode MUST be set to Attribute Flags Error. The Data field MUST contain the erroneous attribute (type, length, and value). """ CODE = BGP_ERROR_UPDATE_MESSAGE_ERROR SUB_CODE = BGP_ERROR_SUB_ATTRIBUTE_FLAGS_ERROR class AttrLenError(BgpExc): CODE = BGP_ERROR_UPDATE_MESSAGE_ERROR SUB_CODE = BGP_ERROR_SUB_ATTRIBUTE_LENGTH_ERROR class InvalidOriginError(BgpExc): """Error indicates undefined Origin attribute value. RFC says: If the ORIGIN attribute has an undefined value, then the Error Sub- code MUST be set to Invalid Origin Attribute. The Data field MUST contain the unrecognized attribute (type, length, and value). """ CODE = BGP_ERROR_UPDATE_MESSAGE_ERROR SUB_CODE = BGP_ERROR_SUB_INVALID_ORIGIN_ATTRIBUTE class RoutingLoop(BgpExc): CODE = BGP_ERROR_UPDATE_MESSAGE_ERROR SUB_CODE = BGP_ERROR_SUB_ROUTING_LOOP class InvalidNextHop(BgpExc): CODE = BGP_ERROR_UPDATE_MESSAGE_ERROR SUB_CODE = BGP_ERROR_SUB_INVALID_NEXT_HOP_ATTRIBUTE class OptAttrError(BgpExc): """Error indicates Optional Attribute is malformed. RFC says: If an optional attribute is recognized, then the value of this attribute MUST be checked. If an error is detected, the attribute MUST be discarded, and the Error Subcode MUST be set to Optional Attribute Error. The Data field MUST contain the attribute (type, length, and value). """ CODE = BGP_ERROR_UPDATE_MESSAGE_ERROR SUB_CODE = BGP_ERROR_SUB_OPTIONAL_ATTRIBUTE_ERROR class InvalidNetworkField(BgpExc): CODE = BGP_ERROR_UPDATE_MESSAGE_ERROR SUB_CODE = BGP_ERROR_SUB_INVALID_NETWORK_FIELD class MalformedAsPath(BgpExc): """Error to indicate if AP_PATH attribute is syntactically incorrect. RFC says: The AS_PATH attribute is checked for syntactic correctness. If the path is syntactically incorrect, then the Error Subcode MUST be set to Malformed AS_PATH. """ CODE = BGP_ERROR_UPDATE_MESSAGE_ERROR SUB_CODE = BGP_ERROR_SUB_MALFORMED_AS_PATH # ============================================================================ # Hold Timer Expired # ============================================================================ class HoldTimerExpired(BgpExc): """Error to indicate Hold Timer expired. RFC says: If a system does not receive successive KEEPALIVE, UPDATE, and/or NOTIFICATION messages within the period specified in the Hold Time field of the OPEN message, then the NOTIFICATION message with the Hold Timer Expired Error Code is sent and the BGP connection is closed. """ CODE = BGP_ERROR_HOLD_TIMER_EXPIRED SUB_CODE = BGP_ERROR_SUB_HOLD_TIMER_EXPIRED # ============================================================================ # Finite State Machine Error # ============================================================================ class FiniteStateMachineError(BgpExc): """Error to indicate any Finite State Machine Error. RFC says: Any error detected by the BGP Finite State Machine (e.g., receipt of an unexpected event) is indicated by sending the NOTIFICATION message with the Error Code Finite State Machine Error. """ CODE = BGP_ERROR_FSM_ERROR SUB_CODE = BGP_ERROR_SUB_FSM_ERROR # ============================================================================ # Cease Errors # ============================================================================ class MaxPrefixReached(BgpExc): CODE = BGP_ERROR_CEASE SUB_CODE = BGP_ERROR_SUB_MAXIMUM_NUMBER_OF_PREFIXES_REACHED class AdminShutdown(BgpExc): """Error to indicate Administrative shutdown. RFC says: If a BGP speaker decides to administratively shut down its peering with a neighbor, then the speaker SHOULD send a NOTIFICATION message with the Error Code Cease and the Error Subcode 'Administrative Shutdown'. """ CODE = BGP_ERROR_CEASE SUB_CODE = BGP_ERROR_SUB_ADMINISTRATIVE_SHUTDOWN class PeerDeConfig(BgpExc): CODE = BGP_ERROR_CEASE SUB_CODE = BGP_ERROR_SUB_PEER_DECONFIGURED class AdminReset(BgpExc): CODE = BGP_ERROR_CEASE SUB_CODE = BGP_ERROR_SUB_ADMINISTRATIVE_RESET class ConnRejected(BgpExc): """Error to indicate Connection Rejected. RFC says: If a BGP speaker decides to disallow a BGP connection (e.g., the peer is not configured locally) after the speaker accepts a transport protocol connection, then the BGP speaker SHOULD send a NOTIFICATION message with the Error Code Cease and the Error Subcode "Connection Rejected". """ CODE = BGP_ERROR_CEASE SUB_CODE = BGP_ERROR_SUB_CONNECTION_RESET class OtherConfChange(BgpExc): CODE = BGP_ERROR_CEASE SUB_CODE = BGP_ERROR_SUB_OTHER_CONFIGURATION_CHANGE class CollisionResolution(BgpExc): """Error to indicate Connection Collision Resolution. RFC says: If a BGP speaker decides to send a NOTIFICATION message with the Error Code Cease as a result of the collision resolution procedure (as described in [BGP-4]), then the subcode SHOULD be set to "Connection Collision Resolution". """ CODE = BGP_ERROR_CEASE SUB_CODE = BGP_ERROR_SUB_CONNECTION_COLLISION_RESOLUTION class OutOfResource(BgpExc): CODE = BGP_ERROR_CEASE SUB_CODE = BGP_ERROR_SUB_OUT_OF_RESOURCES @functools.total_ordering class RouteFamily(StringifyMixin): def __init__(self, afi, safi): self.afi = afi self.safi = safi def __lt__(self, other): return (self.afi, self.safi) < (other.afi, other.safi) def __eq__(self, other): return (self.afi, self.safi) == (other.afi, other.safi) def __hash__(self): return hash((self.afi, self.safi)) # Route Family Singleton RF_IPv4_UC = RouteFamily(addr_family.IP, subaddr_family.UNICAST) RF_IPv6_UC = RouteFamily(addr_family.IP6, subaddr_family.UNICAST) RF_IPv4_VPN = RouteFamily(addr_family.IP, subaddr_family.MPLS_VPN) RF_IPv6_VPN = RouteFamily(addr_family.IP6, subaddr_family.MPLS_VPN) RF_IPv4_MPLS = RouteFamily(addr_family.IP, subaddr_family.MPLS_LABEL) RF_IPv6_MPLS = RouteFamily(addr_family.IP6, subaddr_family.MPLS_LABEL) RF_L2_EVPN = RouteFamily(addr_family.L2VPN, subaddr_family.EVPN) RF_IPv4_FLOWSPEC = RouteFamily(addr_family.IP, subaddr_family.IP_FLOWSPEC) RF_IPv6_FLOWSPEC = RouteFamily(addr_family.IP6, subaddr_family.IP_FLOWSPEC) RF_VPNv4_FLOWSPEC = RouteFamily(addr_family.IP, subaddr_family.VPN_FLOWSPEC) RF_VPNv6_FLOWSPEC = RouteFamily(addr_family.IP6, subaddr_family.VPN_FLOWSPEC) RF_L2VPN_FLOWSPEC = RouteFamily( addr_family.L2VPN, subaddr_family.VPN_FLOWSPEC) RF_RTC_UC = RouteFamily(addr_family.IP, subaddr_family.ROUTE_TARGET_CONSTRAINTS) _rf_map = { (addr_family.IP, subaddr_family.UNICAST): RF_IPv4_UC, (addr_family.IP6, subaddr_family.UNICAST): RF_IPv6_UC, (addr_family.IP, subaddr_family.MPLS_VPN): RF_IPv4_VPN, (addr_family.IP6, subaddr_family.MPLS_VPN): RF_IPv6_VPN, (addr_family.IP, subaddr_family.MPLS_LABEL): RF_IPv4_MPLS, (addr_family.IP6, subaddr_family.MPLS_LABEL): RF_IPv6_MPLS, (addr_family.L2VPN, subaddr_family.EVPN): RF_L2_EVPN, (addr_family.IP, subaddr_family.IP_FLOWSPEC): RF_IPv4_FLOWSPEC, (addr_family.IP6, subaddr_family.IP_FLOWSPEC): RF_IPv6_FLOWSPEC, (addr_family.IP, subaddr_family.VPN_FLOWSPEC): RF_VPNv4_FLOWSPEC, (addr_family.IP6, subaddr_family.VPN_FLOWSPEC): RF_VPNv6_FLOWSPEC, (addr_family.L2VPN, subaddr_family.VPN_FLOWSPEC): RF_L2VPN_FLOWSPEC, (addr_family.IP, subaddr_family.ROUTE_TARGET_CONSTRAINTS): RF_RTC_UC } def get_rf(afi, safi): return _rf_map[(afi, safi)] def pad(binary, len_): assert len(binary) <= len_ return binary + b'\0' * (len_ - len(binary)) class _RouteDistinguisher(StringifyMixin, TypeDisp, _Value): _PACK_STR = '!H' TWO_OCTET_AS = 0 IPV4_ADDRESS = 1 FOUR_OCTET_AS = 2 def __init__(self, admin=0, assigned=0, type_=None): if type_ is None: type_ = self._rev_lookup_type(self.__class__) self.type = type_ self.admin = admin self.assigned = assigned @classmethod def parser(cls, buf): assert len(buf) == 8 (type_,) = struct.unpack_from(cls._PACK_STR, bytes(buf)) rest = buf[struct.calcsize(cls._PACK_STR):] subcls = cls._lookup_type(type_) return subcls(**subcls.parse_value(rest)) @classmethod def from_str(cls, str_): assert isinstance(str_, str) first, second = str_.split(':') if '.' in first: type_ = cls.IPV4_ADDRESS elif int(first) > (1 << 16): type_ = cls.FOUR_OCTET_AS first = int(first) else: type_ = cls.TWO_OCTET_AS first = int(first) subcls = cls._lookup_type(type_) return subcls(admin=first, assigned=int(second)) def serialize(self): value = self.serialize_value() buf = bytearray() msg_pack_into(self._PACK_STR, buf, 0, self.type) return bytes(buf + value) @property def formatted_str(self): return "%s:%s" % (self.admin, self.assigned) @_RouteDistinguisher.register_type(_RouteDistinguisher.TWO_OCTET_AS) class BGPTwoOctetAsRD(_RouteDistinguisher): _VALUE_PACK_STR = '!HI' _VALUE_FIELDS = ['admin', 'assigned'] def __init__(self, **kwargs): super(BGPTwoOctetAsRD, self).__init__() self.do_init(BGPTwoOctetAsRD, self, kwargs) @_RouteDistinguisher.register_type(_RouteDistinguisher.IPV4_ADDRESS) class BGPIPv4AddressRD(_RouteDistinguisher): _VALUE_PACK_STR = '!4sH' _VALUE_FIELDS = ['admin', 'assigned'] _TYPE = { 'ascii': [ 'admin' ] } def __init__(self, **kwargs): super(BGPIPv4AddressRD, self).__init__() self.do_init(BGPIPv4AddressRD, self, kwargs) @classmethod def parse_value(cls, buf): d_ = super(BGPIPv4AddressRD, cls).parse_value(buf) d_['admin'] = addrconv.ipv4.bin_to_text(d_['admin']) return d_ def serialize_value(self): args = [] for f in self._VALUE_FIELDS: v = getattr(self, f) if f == 'admin': v = bytes(addrconv.ipv4.text_to_bin(v)) args.append(v) buf = bytearray() msg_pack_into(self._VALUE_PACK_STR, buf, 0, *args) return buf @_RouteDistinguisher.register_type(_RouteDistinguisher.FOUR_OCTET_AS) class BGPFourOctetAsRD(_RouteDistinguisher): _VALUE_PACK_STR = '!IH' _VALUE_FIELDS = ['admin', 'assigned'] def __init__(self, **kwargs): super(BGPFourOctetAsRD, self).__init__() self.do_init(BGPFourOctetAsRD, self, kwargs) class _AddrPrefix(StringifyMixin, metaclass=abc.ABCMeta): _PACK_STR = '!B' # length def __init__(self, length, addr, prefixes=None, **kwargs): # length is on-wire bit length of prefixes+addr. assert prefixes != () if isinstance(addr, tuple): # for _AddrPrefix.parser # also for _VPNAddrPrefix.__init__ etc (addr,) = addr self.length = length if prefixes: addr = prefixes + (addr,) self.addr = addr @classmethod @abc.abstractmethod def _to_bin(cls, addr): pass @classmethod @abc.abstractmethod def _from_bin(cls, addr): pass @classmethod def parser(cls, buf): (length, ) = struct.unpack_from(cls._PACK_STR, bytes(buf)) rest = buf[struct.calcsize(cls._PACK_STR):] byte_length = (length + 7) // 8 addr = cls._from_bin(rest[:byte_length]) rest = rest[byte_length:] return cls(length=length, addr=addr), rest def serialize(self): # fixup byte_length = (self.length + 7) // 8 bin_addr = self._to_bin(self.addr) if (self.length % 8) == 0: bin_addr = bin_addr[:byte_length] else: # clear trailing bits in the last octet. # rfc doesn't require this. mask = 0xff00 >> (self.length % 8) last_byte = struct.Struct(">B").pack( operator.getitem(bin_addr, byte_length - 1) & mask) bin_addr = bin_addr[:byte_length - 1] + last_byte self.addr = self._from_bin(bin_addr) buf = bytearray() msg_pack_into(self._PACK_STR, buf, 0, self.length) return buf + bytes(bin_addr) class _BinAddrPrefix(_AddrPrefix): @classmethod def _to_bin(cls, addr): return addr @classmethod def _from_bin(cls, addr): return addr class _LabelledAddrPrefix(_AddrPrefix): _LABEL_PACK_STR = '!3B' # RFC3107 # 3. Carrying Label Mapping Information # The label information carried (as part of NLRI) in the Withdrawn # Routes field should be set to 0x800000. (Of course, terminating the # BGP session also withdraws all the previously advertised routes.) # # RFC8227 # 2.4 How to Explicitly Withdraw the Binding of a Label to a Prefix # [RFC3107] also made it possible to withdraw a binding without specifying # the label explicitly, by setting the Compatibility field to 0x800000. # However, some implementations set it to 0x000000. In order to ensure # backwards compatibility, it is RECOMMENDED by this document that the # Compatibility field be set to 0x800000, but it is REQUIRED that it be # ignored upon reception. # _WITHDRAW_LABELS = [0x800000, 0x000000] def __init__(self, length, addr, labels=None, **kwargs): labels = labels if labels else [] assert isinstance(labels, list) is_tuple = isinstance(addr, tuple) if is_tuple: # for _AddrPrefix.parser assert not labels labels = addr[0] addr = addr[1:] else: length += struct.calcsize(self._LABEL_PACK_STR) * 8 * len(labels) assert length > struct.calcsize(self._LABEL_PACK_STR) * 8 * len(labels) prefixes = (labels,) super(_LabelledAddrPrefix, self).__init__(prefixes=prefixes, length=length, addr=addr, **kwargs) @classmethod def _label_to_bin(cls, label): buf = bytearray() msg_pack_into(cls._LABEL_PACK_STR, buf, 0, (label & 0xff0000) >> 16, (label & 0x00ff00) >> 8, (label & 0x0000ff) >> 0) return bytes(buf) @classmethod def _label_from_bin(cls, label): (b1, b2, b3) = struct.unpack_from(cls._LABEL_PACK_STR, bytes(label)) rest = label[struct.calcsize(cls._LABEL_PACK_STR):] return (b1 << 16) | (b2 << 8) | b3, rest @classmethod def _to_bin(cls, addr): labels = addr[0] rest = addr[1:] labels = [x << 4 for x in labels] if labels and labels[-1] not in cls._WITHDRAW_LABELS: labels[-1] |= 1 # bottom of stack bin_labels = list(cls._label_to_bin(l) for l in labels) return bytes( functools.reduce(lambda x, y: x + y, bin_labels, bytearray()) + cls._prefix_to_bin(rest)) @classmethod def _has_no_label(cls, bin_): try: length = len(bin_) labels = [] while True: (label, bin_) = cls._label_from_bin(bin_) labels.append(label) if label & 1 or label in cls._WITHDRAW_LABELS: break assert length > struct.calcsize(cls._LABEL_PACK_STR) * len(labels) except struct.error: return True except AssertionError: return True return False @classmethod def _from_bin(cls, addr): rest = addr labels = [] if cls._has_no_label(rest): return ([],) + cls._prefix_from_bin(rest) while True: (label, rest) = cls._label_from_bin(rest) labels.append(label >> 4) if label & 1 or label in cls._WITHDRAW_LABELS: break return (labels,) + cls._prefix_from_bin(rest) class _UnlabelledAddrPrefix(_AddrPrefix): @classmethod def _to_bin(cls, addr): return cls._prefix_to_bin((addr,)) @classmethod def _from_bin(cls, binaddr): (addr,) = cls._prefix_from_bin(binaddr) return addr class _IPAddrPrefix(_AddrPrefix): @staticmethod def _prefix_to_bin(addr): (addr,) = addr return addrconv.ipv4.text_to_bin(addr) @staticmethod def _prefix_from_bin(addr): return addrconv.ipv4.bin_to_text(pad(addr, 4)), class _IP6AddrPrefix(_AddrPrefix): @staticmethod def _prefix_to_bin(addr): (addr,) = addr return addrconv.ipv6.text_to_bin(addr) @staticmethod def _prefix_from_bin(addr): return addrconv.ipv6.bin_to_text(pad(addr, 16)), class _VPNAddrPrefix(_AddrPrefix): _RD_PACK_STR = '!Q' def __init__(self, length, addr, prefixes=(), route_dist=0): if isinstance(addr, tuple): # for _AddrPrefix.parser assert not route_dist assert length > struct.calcsize(self._RD_PACK_STR) * 8 route_dist = addr[0] addr = addr[1:] else: length += struct.calcsize(self._RD_PACK_STR) * 8 if isinstance(route_dist, str): route_dist = _RouteDistinguisher.from_str(route_dist) prefixes = prefixes + (route_dist,) super(_VPNAddrPrefix, self).__init__(prefixes=prefixes, length=length, addr=addr) @classmethod def _prefix_to_bin(cls, addr): rd = addr[0] rest = addr[1:] binrd = rd.serialize() return binrd + super(_VPNAddrPrefix, cls)._prefix_to_bin(rest) @classmethod def _prefix_from_bin(cls, binaddr): binrd = binaddr[:8] binrest = binaddr[8:] rd = _RouteDistinguisher.parser(binrd) return (rd,) + super(_VPNAddrPrefix, cls)._prefix_from_bin(binrest) class IPAddrPrefix(_UnlabelledAddrPrefix, _IPAddrPrefix): ROUTE_FAMILY = RF_IPv4_UC _TYPE = { 'ascii': [ 'addr' ] } @property def prefix(self): return self.addr + '/{0}'.format(self.length) @property def formatted_nlri_str(self): return self.prefix class IP6AddrPrefix(_UnlabelledAddrPrefix, _IP6AddrPrefix): ROUTE_FAMILY = RF_IPv6_UC _TYPE = { 'ascii': [ 'addr' ] } @property def prefix(self): return self.addr + '/{0}'.format(self.length) @property def formatted_nlri_str(self): return self.prefix class LabelledIPAddrPrefix(_LabelledAddrPrefix, _IPAddrPrefix): ROUTE_FAMILY = RF_IPv4_MPLS class LabelledIP6AddrPrefix(_LabelledAddrPrefix, _IP6AddrPrefix): ROUTE_FAMILY = RF_IPv6_MPLS class LabelledVPNIPAddrPrefix(_LabelledAddrPrefix, _VPNAddrPrefix, _IPAddrPrefix): ROUTE_FAMILY = RF_IPv4_VPN @property def prefix(self): masklen = self.length - struct.calcsize(self._RD_PACK_STR) * 8 \ - struct.calcsize(self._LABEL_PACK_STR) * 8 * len(self.addr[:-2]) return self.addr[-1] + '/{0}'.format(masklen) @property def route_dist(self): return self.addr[-2].formatted_str @property def label_list(self): return self.addr[0] @property def formatted_nlri_str(self): return "%s:%s" % (self.route_dist, self.prefix) class LabelledVPNIP6AddrPrefix(_LabelledAddrPrefix, _VPNAddrPrefix, _IP6AddrPrefix): ROUTE_FAMILY = RF_IPv6_VPN @property def prefix(self): masklen = self.length - struct.calcsize(self._RD_PACK_STR) * 8 \ - struct.calcsize(self._LABEL_PACK_STR) * 8 * len(self.addr[:-2]) return self.addr[-1] + '/{0}'.format(masklen) @property def route_dist(self): return self.addr[-2].formatted_str @property def label_list(self): return self.addr[0] @property def formatted_nlri_str(self): return "%s:%s" % (self.route_dist, self.prefix) class EvpnEsi(StringifyMixin, TypeDisp, _Value): """ Ethernet Segment Identifier The supported ESI Types: - ``EvpnEsi.ARBITRARY`` indicates EvpnArbitraryEsi. - ``EvpnEsi.LACP`` indicates EvpnLACPEsi. - ``EvpnEsi.L2_BRIDGE`` indicates EvpnL2BridgeEsi. - ``EvpnEsi.MAC_BASED`` indicates EvpnMacBasedEsi. - ``EvpnEsi.ROUTER_ID`` indicates EvpnRouterIDEsi. - ``EvpnEsi.AS_BASED`` indicates EvpnASBasedEsi. """ _PACK_STR = "!B" # ESI Type _ESI_LEN = 10 ARBITRARY = 0x00 LACP = 0x01 L2_BRIDGE = 0x02 MAC_BASED = 0x03 ROUTER_ID = 0x04 AS_BASED = 0x05 MAX = 0xff # Reserved _TYPE_NAME = None # must be defined in subclass def __init__(self, type_=None): if type_ is None: type_ = self._rev_lookup_type(self.__class__) self.type = type_ @classmethod def parser(cls, buf): (esi_type,) = struct.unpack_from( cls._PACK_STR, bytes(buf)) subcls = cls._lookup_type(esi_type) return subcls(**subcls.parse_value(buf[1:cls._ESI_LEN])) def serialize(self): buf = bytearray() msg_pack_into(EvpnEsi._PACK_STR, buf, 0, self.type) return bytes(buf + self.serialize_value()) @property def formatted_str(self): return '%s(%s)' % ( self._TYPE_NAME, ','.join(str(getattr(self, v)) for v in self._VALUE_FIELDS)) @EvpnEsi.register_unknown_type() class EvpnUnknownEsi(EvpnEsi): """ ESI value for unknown type """ _TYPE_NAME = 'unknown' _VALUE_PACK_STR = '!9s' _VALUE_FIELDS = ['value'] def __init__(self, value, type_=None): super(EvpnUnknownEsi, self).__init__(type_) self.value = value @property def formatted_str(self): return '%s(%s)' % (self._TYPE_NAME, binary_str(self.value)) @EvpnEsi.register_type(EvpnEsi.ARBITRARY) class EvpnArbitraryEsi(EvpnEsi): """ Arbitrary 9-octet ESI value This type indicates an arbitrary 9-octet ESI value, which is managed and configured by the operator. """ _TYPE_NAME = 'arbitrary' _VALUE_PACK_STR = '!9s' _VALUE_FIELDS = ['value'] def __init__(self, value, type_=None): super(EvpnArbitraryEsi, self).__init__(type_) self.value = value @property def formatted_str(self): return '%s(%s)' % (self._TYPE_NAME, binary_str(self.value)) @EvpnEsi.register_type(EvpnEsi.LACP) class EvpnLACPEsi(EvpnEsi): """ ESI value for LACP When IEEE 802.1AX LACP is used between the PEs and CEs, this ESI type indicates an auto-generated ESI value determined from LACP. """ _TYPE_NAME = 'lacp' _VALUE_PACK_STR = '!6sHx' _VALUE_FIELDS = ['mac_addr', 'port_key'] _TYPE = { 'ascii': [ 'mac_addr' ] } def __init__(self, mac_addr, port_key, type_=None): super(EvpnLACPEsi, self).__init__(type_) self.mac_addr = mac_addr self.port_key = port_key @classmethod def parse_value(cls, buf): (mac_addr, port_key) = struct.unpack_from(cls._VALUE_PACK_STR, buf) return { 'mac_addr': addrconv.mac.bin_to_text(mac_addr), 'port_key': port_key, } def serialize_value(self): return struct.pack( self._VALUE_PACK_STR, addrconv.mac.text_to_bin(self.mac_addr), self.port_key) @EvpnEsi.register_type(EvpnEsi.L2_BRIDGE) class EvpnL2BridgeEsi(EvpnEsi): """ ESI value for Layer 2 Bridge This type is used in the case of indirectly connected hosts via a bridged LAN between the CEs and the PEs. The ESI Value is auto-generated and determined based on the Layer 2 bridge protocol. """ _TYPE_NAME = 'l2_bridge' _VALUE_PACK_STR = '!6sHx' _VALUE_FIELDS = ['mac_addr', 'priority'] _TYPE = { 'ascii': [ 'mac_addr' ] } def __init__(self, mac_addr, priority, type_=None): super(EvpnL2BridgeEsi, self).__init__(type_) self.mac_addr = mac_addr self.priority = priority @classmethod def parse_value(cls, buf): (mac_addr, priority) = struct.unpack_from(cls._VALUE_PACK_STR, buf) return { 'mac_addr': addrconv.mac.bin_to_text(mac_addr), 'priority': priority, } def serialize_value(self): return struct.pack( self._VALUE_PACK_STR, addrconv.mac.text_to_bin(self.mac_addr), self.priority) @EvpnEsi.register_type(EvpnEsi.MAC_BASED) class EvpnMacBasedEsi(EvpnEsi): """ MAC-based ESI Value This type indicates a MAC-based ESI Value that can be auto-generated or configured by the operator. """ _TYPE_NAME = 'mac_based' _VALUE_PACK_STR = '!6s3s' _VALUE_FIELDS = ['mac_addr', 'local_disc'] _TYPE = { 'ascii': [ 'mac_addr' ] } def __init__(self, mac_addr, local_disc, type_=None): super(EvpnMacBasedEsi, self).__init__(type_) self.mac_addr = mac_addr self.local_disc = local_disc @classmethod def parse_value(cls, buf): (mac_addr, local_disc) = struct.unpack_from(cls._VALUE_PACK_STR, buf) return { 'mac_addr': addrconv.mac.bin_to_text(mac_addr), 'local_disc': type_desc.Int3.to_user(local_disc), } def serialize_value(self): return struct.pack( self._VALUE_PACK_STR, addrconv.mac.text_to_bin(self.mac_addr), type_desc.Int3.from_user(self.local_disc)) @EvpnEsi.register_type(EvpnEsi.ROUTER_ID) class EvpnRouterIDEsi(EvpnEsi): """ Router-ID ESI Value This type indicates a router-ID ESI Value that can be auto-generated or configured by the operator. """ _TYPE_NAME = 'router_id' _VALUE_PACK_STR = '!4sIx' _VALUE_FIELDS = ['router_id', 'local_disc'] _TYPE = { 'ascii': [ 'router_id' ] } def __init__(self, router_id, local_disc, type_=None): super(EvpnRouterIDEsi, self).__init__(type_) self.router_id = router_id self.local_disc = local_disc @classmethod def parse_value(cls, buf): (router_id, local_disc) = struct.unpack_from(cls._VALUE_PACK_STR, buf) return { 'router_id': addrconv.ipv4.bin_to_text(router_id), 'local_disc': local_disc, } def serialize_value(self): return struct.pack( self._VALUE_PACK_STR, addrconv.ipv4.text_to_bin(self.router_id), self.local_disc) @EvpnEsi.register_type(EvpnEsi.AS_BASED) class EvpnASBasedEsi(EvpnEsi): """ AS based ESI value This type indicates an Autonomous System(AS)-based ESI Value that can be auto-generated or configured by the operator. """ _TYPE_NAME = 'as_based' _VALUE_PACK_STR = '!IIx' _VALUE_FIELDS = ['as_number', 'local_disc'] def __init__(self, as_number, local_disc, type_=None): super(EvpnASBasedEsi, self).__init__(type_) self.as_number = as_number self.local_disc = local_disc class EvpnNLRI(StringifyMixin, TypeDisp): """ BGP Network Layer Reachability Information (NLRI) for EVPN """ ROUTE_FAMILY = RF_L2_EVPN # EVPN NLRI: # +-----------------------------------+ # | Route Type (1 octet) | # +-----------------------------------+ # | Length (1 octet) | # +-----------------------------------+ # | Route Type specific (variable) | # +-----------------------------------+ _PACK_STR = "!BB" _PACK_STR_SIZE = struct.calcsize(_PACK_STR) ETHERNET_AUTO_DISCOVERY = 0x01 MAC_IP_ADVERTISEMENT = 0x02 INCLUSIVE_MULTICAST_ETHERNET_TAG = 0x03 ETHERNET_SEGMENT = 0x04 IP_PREFIX_ROUTE = 0x05 ROUTE_TYPE_NAME = None # must be defined in subclass # Reserved value for Ethernet Tag ID. MAX_ET = 0xFFFFFFFF # Dictionary of ROUTE_TYPE_NAME to subclass. # e.g.) # _NAMES = {'eth_ad': EvpnEthernetAutoDiscoveryNLRI, ...} _NAMES = {} # List of the fields considered to be part of the prefix in the NLRI. # This list should be defined in subclasses to format NLRI string # representation. NLRI_PREFIX_FIELDS = [] def __init__(self, type_=None, length=None): if type_ is None: type_ = self._rev_lookup_type(self.__class__) self.type = type_ self.length = length self.route_dist = None # should be initialized in subclass @classmethod def register_type(cls, type_): cls._TYPES = cls._TYPES.copy() cls._NAMES = cls._NAMES.copy() def _register_type(subcls): cls._TYPES[type_] = subcls cls._NAMES[subcls.ROUTE_TYPE_NAME] = subcls cls._REV_TYPES = None return subcls return _register_type @classmethod def _lookup_type_name(cls, type_name): try: return cls._NAMES[type_name] except KeyError: return EvpnUnknownNLRI @classmethod def parser(cls, buf): (route_type, length) = struct.unpack_from( cls._PACK_STR, bytes(buf)) offset = cls._PACK_STR_SIZE + length subcls = cls._lookup_type(route_type) values = subcls.parse_value(buf[cls._PACK_STR_SIZE:offset]) return subcls(type_=route_type, length=length, **values), buf[offset:] def serialize_value(self): # Overrided in subclass return b'' def serialize(self): value_bin = self.serialize_value() # fixup self.length = len(value_bin) return struct.pack(EvpnNLRI._PACK_STR, self.type, self.length) + value_bin @staticmethod def _rd_from_bin(buf): return _RouteDistinguisher.parser(buf[:8]), buf[8:] @staticmethod def _rd_to_bin(rd): return bytes(rd.serialize()) @staticmethod def _esi_from_bin(buf): return EvpnEsi.parser(buf[:10]), buf[10:] @staticmethod def _esi_to_bin(esi): return esi.serialize() @staticmethod def _ethernet_tag_id_from_bin(buf): return type_desc.Int4.to_user(bytes(buf[:4])), buf[4:] @staticmethod def _ethernet_tag_id_to_bin(tag_id): return type_desc.Int4.from_user(tag_id) @staticmethod def _mac_addr_len_from_bin(buf): return type_desc.Int1.to_user(bytes(buf[:1])), buf[1:] @staticmethod def _mac_addr_len_to_bin(mac_len): return type_desc.Int1.from_user(mac_len) @staticmethod def _mac_addr_from_bin(buf, mac_len): mac_len //= 8 return addrconv.mac.bin_to_text(buf[:mac_len]), buf[mac_len:] @staticmethod def _mac_addr_to_bin(mac_addr): return addrconv.mac.text_to_bin(mac_addr) @staticmethod def _ip_addr_len_from_bin(buf): return type_desc.Int1.to_user(bytes(buf[:1])), buf[1:] @staticmethod def _ip_addr_len_to_bin(ip_len): return type_desc.Int1.from_user(ip_len) @staticmethod def _ip_addr_from_bin(buf, ip_len): return ip.bin_to_text(buf[:ip_len]), buf[ip_len:] @staticmethod def _ip_addr_to_bin(ip_addr): return ip.text_to_bin(ip_addr) @staticmethod def _mpls_label_from_bin(buf): mpls_label, is_bos = mpls.label_from_bin(buf) rest = buf[3:] return mpls_label, rest, is_bos @staticmethod def _mpls_label_to_bin(label, is_bos=True): return mpls.label_to_bin(label, is_bos=is_bos) @staticmethod def _vni_from_bin(buf): return vxlan.vni_from_bin(bytes(buf[:3])), buf[3:] @staticmethod def _vni_to_bin(vni): return vxlan.vni_to_bin(vni) @property def prefix(self): def _format(i): pairs = [] for k in i.NLRI_PREFIX_FIELDS: v = getattr(i, k) if k == 'esi': pairs.append('%s:%s' % (k, v.formatted_str)) else: pairs.append('%s:%s' % (k, v)) return ','.join(pairs) return '%s(%s)' % (self.ROUTE_TYPE_NAME, _format(self)) @property def formatted_nlri_str(self): return '%s:%s' % (self.route_dist, self.prefix) @EvpnNLRI.register_unknown_type() class EvpnUnknownNLRI(EvpnNLRI): """ Unknown route type specific EVPN NLRI """ ROUTE_TYPE_NAME = 'unknown' NLRI_PREFIX_FIELDS = ['value'] def __init__(self, value, type_, length=None): super(EvpnUnknownNLRI, self).__init__(type_, length) self.value = value @classmethod def parse_value(cls, buf): return { 'value': buf } def serialize_value(self): return self.value @property def formatted_nlri_str(self): return '%s(%s)' % (self.ROUTE_TYPE_NAME, binary_str(self.value)) @EvpnNLRI.register_type(EvpnNLRI.ETHERNET_AUTO_DISCOVERY) class EvpnEthernetAutoDiscoveryNLRI(EvpnNLRI): """ Ethernet A-D route type specific EVPN NLRI """ ROUTE_TYPE_NAME = 'eth_ad' # +---------------------------------------+ # | Route Distinguisher (RD) (8 octets) | # +---------------------------------------+ # |Ethernet Segment Identifier (10 octets)| # +---------------------------------------+ # | Ethernet Tag ID (4 octets) | # +---------------------------------------+ # | MPLS Label (3 octets) | # +---------------------------------------+ _PACK_STR = "!8s10sI3s" NLRI_PREFIX_FIELDS = ['esi', 'ethernet_tag_id'] _TYPE = { 'ascii': [ 'route_dist', ] } def __init__(self, route_dist, esi, ethernet_tag_id, mpls_label=None, vni=None, label=None, type_=None, length=None): super(EvpnEthernetAutoDiscoveryNLRI, self).__init__(type_, length) self.route_dist = route_dist self.esi = esi self.ethernet_tag_id = ethernet_tag_id if label: # If binary type label field value is specified, stores it # and decodes as MPLS label and VNI. self._label = label self._mpls_label, _, _ = self._mpls_label_from_bin(label) self._vni, _ = self._vni_from_bin(label) else: # If either MPLS label or VNI is specified, stores it # and encodes into binary type label field value. self._label = self._serialize_label(mpls_label, vni) self._mpls_label = mpls_label self._vni = vni def _serialize_label(self, mpls_label, vni): if mpls_label: return self._mpls_label_to_bin(mpls_label, is_bos=True) elif vni: return self._vni_to_bin(vni) else: return b'\x00' * 3 @classmethod def parse_value(cls, buf): route_dist, rest = cls._rd_from_bin(buf) esi, rest = cls._esi_from_bin(rest) ethernet_tag_id, rest = cls._ethernet_tag_id_from_bin(rest) return { 'route_dist': route_dist.formatted_str, 'esi': esi, 'ethernet_tag_id': ethernet_tag_id, 'label': rest, } def serialize_value(self): route_dist = _RouteDistinguisher.from_str(self.route_dist) return struct.pack( self._PACK_STR, route_dist.serialize(), self.esi.serialize(), self.ethernet_tag_id, self._label) @property def mpls_label(self): return self._mpls_label @mpls_label.setter def mpls_label(self, mpls_label): self._label = self._mpls_label_to_bin(mpls_label, is_bos=True) self._mpls_label = mpls_label self._vni = None # disables VNI @property def vni(self): return self._vni @vni.setter def vni(self, vni): self._label = self._vni_to_bin(vni) self._mpls_label = None # disables MPLS label self._vni = vni @property def label_list(self): return [self.mpls_label] @EvpnNLRI.register_type(EvpnNLRI.MAC_IP_ADVERTISEMENT) class EvpnMacIPAdvertisementNLRI(EvpnNLRI): """ MAC/IP Advertisement route type specific EVPN NLRI """ ROUTE_TYPE_NAME = 'mac_ip_adv' # +---------------------------------------+ # | RD (8 octets) | # +---------------------------------------+ # |Ethernet Segment Identifier (10 octets)| # +---------------------------------------+ # | Ethernet Tag ID (4 octets) | # +---------------------------------------+ # | MAC Address Length (1 octet) | # +---------------------------------------+ # | MAC Address (6 octets) | # +---------------------------------------+ # | IP Address Length (1 octet) | # +---------------------------------------+ # | IP Address (0, 4, or 16 octets) | # +---------------------------------------+ # | MPLS Label1 (3 octets) | # +---------------------------------------+ # | MPLS Label2 (0 or 3 octets) | # +---------------------------------------+ _PACK_STR = "!8s10sIB6sB%ds%ds" # Note: mac_addr_len and ip_addr_len are omitted for readability. NLRI_PREFIX_FIELDS = ['ethernet_tag_id', 'mac_addr', 'ip_addr'] _TYPE = { 'ascii': [ 'route_dist', 'mac_addr', 'ip_addr', ] } def __init__(self, route_dist, ethernet_tag_id, mac_addr, ip_addr, esi=None, mpls_labels=None, vni=None, labels=None, mac_addr_len=None, ip_addr_len=None, type_=None, length=None): super(EvpnMacIPAdvertisementNLRI, self).__init__(type_, length) self.route_dist = route_dist self.esi = esi self.ethernet_tag_id = ethernet_tag_id self.mac_addr_len = mac_addr_len self.mac_addr = mac_addr self.ip_addr_len = ip_addr_len self.ip_addr = ip_addr if labels: # If binary type labels field value is specified, stores it # and decodes as MPLS labels and VNI. self._mpls_labels, self._vni = self._parse_labels(labels) self._labels = labels else: # If either MPLS labels or VNI is specified, stores it # and encodes into binary type labels field value. self._labels = self._serialize_labels(mpls_labels, vni) self._mpls_labels = mpls_labels self._vni = vni def _parse_labels(self, labels): mpls_label1, rest, is_bos = self._mpls_label_from_bin(labels) mpls_labels = [mpls_label1] if rest and not is_bos: mpls_label2, rest, _ = self._mpls_label_from_bin(rest) mpls_labels.append(mpls_label2) vni, _ = self._vni_from_bin(labels) return mpls_labels, vni def _serialize_labels(self, mpls_labels, vni): if mpls_labels: return self._serialize_mpls_labels(mpls_labels) elif vni: return self._vni_to_bin(vni) else: return b'\x00' * 3 def _serialize_mpls_labels(self, mpls_labels): if len(mpls_labels) == 1: return self._mpls_label_to_bin(mpls_labels[0], is_bos=True) elif len(mpls_labels) == 2: return (self._mpls_label_to_bin(mpls_labels[0], is_bos=False) + self._mpls_label_to_bin(mpls_labels[1], is_bos=True)) else: return b'\x00' * 3 @classmethod def parse_value(cls, buf): route_dist, rest = cls._rd_from_bin(buf) esi, rest = cls._esi_from_bin(rest) ethernet_tag_id, rest = cls._ethernet_tag_id_from_bin(rest) mac_addr_len, rest = cls._mac_addr_len_from_bin(rest) mac_addr, rest = cls._mac_addr_from_bin(rest, mac_addr_len) ip_addr_len, rest = cls._ip_addr_len_from_bin(rest) if ip_addr_len != 0: ip_addr, rest = cls._ip_addr_from_bin(rest, ip_addr_len // 8) else: ip_addr = None return { 'route_dist': route_dist.formatted_str, 'esi': esi, 'ethernet_tag_id': ethernet_tag_id, 'mac_addr_len': mac_addr_len, 'mac_addr': mac_addr, 'ip_addr_len': ip_addr_len, 'ip_addr': ip_addr, 'labels': rest, } def serialize_value(self): route_dist = _RouteDistinguisher.from_str(self.route_dist) mac_addr = self._mac_addr_to_bin(self.mac_addr) self.mac_addr_len = len(mac_addr) * 8 # fixup if self.ip_addr: ip_addr = self._ip_addr_to_bin(self.ip_addr) else: ip_addr = b'' ip_addr_len = len(ip_addr) self.ip_addr_len = ip_addr_len * 8 # fixup return struct.pack( self._PACK_STR % (ip_addr_len, len(self._labels)), route_dist.serialize(), self.esi.serialize(), self.ethernet_tag_id, self.mac_addr_len, mac_addr, self.ip_addr_len, ip_addr, self._labels) @property def mpls_labels(self): return self._mpls_labels @mpls_labels.setter def mpls_labels(self, mpls_labels): self._labels = self._serialize_mpls_labels(mpls_labels) self._mpls_labels = mpls_labels self._vni = None # disables VNI @property def vni(self): return self._vni @vni.setter def vni(self, vni): self._labels = self._vni_to_bin(vni) self._mpls_labels = None # disables MPLS labels self._vni = vni @property def label_list(self): return self.mpls_labels @EvpnNLRI.register_type(EvpnNLRI.INCLUSIVE_MULTICAST_ETHERNET_TAG) class EvpnInclusiveMulticastEthernetTagNLRI(EvpnNLRI): """ Inclusive Multicast Ethernet Tag route type specific EVPN NLRI """ ROUTE_TYPE_NAME = 'multicast_etag' # +---------------------------------------+ # | RD (8 octets) | # +---------------------------------------+ # | Ethernet Tag ID (4 octets) | # +---------------------------------------+ # | IP Address Length (1 octet) | # +---------------------------------------+ # | Originating Router's IP Address | # | (4 or 16 octets) | # +---------------------------------------+ _PACK_STR = '!8sIB%ds' NLRI_PREFIX_FIELDS = ['ethernet_tag_id', 'ip_addr'] _TYPE = { 'ascii': [ 'route_dist', 'ip_addr', ] } def __init__(self, route_dist, ethernet_tag_id, ip_addr, ip_addr_len=None, type_=None, length=None): super(EvpnInclusiveMulticastEthernetTagNLRI, self).__init__(type_, length) self.route_dist = route_dist self.ethernet_tag_id = ethernet_tag_id self.ip_addr_len = ip_addr_len self.ip_addr = ip_addr @classmethod def parse_value(cls, buf): route_dist, rest = cls._rd_from_bin(buf) ethernet_tag_id, rest = cls._ethernet_tag_id_from_bin(rest) ip_addr_len, rest = cls._ip_addr_len_from_bin(rest) ip_addr, rest = cls._ip_addr_from_bin(rest, ip_addr_len // 8) return { 'route_dist': route_dist.formatted_str, 'ethernet_tag_id': ethernet_tag_id, 'ip_addr_len': ip_addr_len, 'ip_addr': ip_addr, } def serialize_value(self): route_dist = _RouteDistinguisher.from_str(self.route_dist) ip_addr = self._ip_addr_to_bin(self.ip_addr) self.ip_addr_len = len(ip_addr) * 8 # fixup return struct.pack( self._PACK_STR % len(ip_addr), route_dist.serialize(), self.ethernet_tag_id, self.ip_addr_len, ip_addr) @EvpnNLRI.register_type(EvpnNLRI.ETHERNET_SEGMENT) class EvpnEthernetSegmentNLRI(EvpnNLRI): """ Ethernet Segment route type specific EVPN NLRI """ ROUTE_TYPE_NAME = 'eth_seg' # +---------------------------------------+ # | RD (8 octets) | # +---------------------------------------+ # |Ethernet Segment Identifier (10 octets)| # +---------------------------------------+ # | IP Address Length (1 octet) | # +---------------------------------------+ # | Originating Router's IP Address | # | (4 or 16 octets) | # +---------------------------------------+ _PACK_STR = '!8s10sB%ds' NLRI_PREFIX_FIELDS = ['esi', 'ip_addr'] _TYPE = { 'ascii': [ 'route_dist', 'ip_addr', ] } def __init__(self, route_dist, esi, ip_addr, ip_addr_len=None, type_=None, length=None): super(EvpnEthernetSegmentNLRI, self).__init__(type_, length) self.route_dist = route_dist self.esi = esi self.ip_addr_len = ip_addr_len self.ip_addr = ip_addr @classmethod def parse_value(cls, buf): route_dist, rest = cls._rd_from_bin(buf) esi, rest = cls._esi_from_bin(rest) ip_addr_len, rest = cls._ip_addr_len_from_bin(rest) ip_addr, rest = cls._ip_addr_from_bin(rest, ip_addr_len // 8) return { 'route_dist': route_dist.formatted_str, 'esi': esi, 'ip_addr_len': ip_addr_len, 'ip_addr': ip_addr, } def serialize_value(self): route_dist = _RouteDistinguisher.from_str(self.route_dist) ip_addr = self._ip_addr_to_bin(self.ip_addr) # fixup self.ip_addr_len = len(ip_addr) * 8 return struct.pack( self._PACK_STR % len(ip_addr), route_dist.serialize(), self.esi.serialize(), self.ip_addr_len, ip_addr) @EvpnNLRI.register_type(EvpnNLRI.IP_PREFIX_ROUTE) class EvpnIpPrefixNLRI(EvpnNLRI): """ IP Prefix advertisement route NLRI """ ROUTE_TYPE_NAME = 'ip_prefix' # +---------------------------------------+ # | RD (8 octets) | # +---------------------------------------+ # |Ethernet Segment Identifier (10 octets)| # +---------------------------------------+ # | Ethernet Tag ID (4 octets) | # +---------------------------------------+ # | IP Prefix Length (1 octet) | # +---------------------------------------+ # | IP Prefix (4 or 16 octets) | # +---------------------------------------+ # | GW IP Address (4 or 16 octets) | # +---------------------------------------+ # | MPLS Label (3 octets) | # +---------------------------------------+ _PACK_STR = '!8s10sIB%ds%ds3s' NLRI_PREFIX_FIELDS = ['ethernet_tag_id', 'ip_prefix'] _TYPE = { 'ascii': [ 'route_dist', 'ip_prefix', 'gw_ip_addr' ] } _LABEL_LEN = 3 def __init__(self, route_dist, ethernet_tag_id, ip_prefix, esi=None, gw_ip_addr=None, mpls_label=None, vni=None, label=None, type_=None, length=None): super(EvpnIpPrefixNLRI, self).__init__(type_, length) self.route_dist = route_dist self.esi = esi self.ethernet_tag_id = ethernet_tag_id self._ip_prefix = None self._ip_prefix_len = None self.ip_prefix = ip_prefix if gw_ip_addr is None: if ':' not in self._ip_prefix: self.gw_ip_addr = '0.0.0.0' else: self.gw_ip_addr = '::' else: self.gw_ip_addr = gw_ip_addr if label: # If binary type label field value is specified, stores it # and decodes as MPLS label and VNI. self._label = label self._mpls_label, _, _ = self._mpls_label_from_bin(label) self._vni, _ = self._vni_from_bin(label) else: # If either MPLS label or VNI is specified, stores it # and encodes into binary type label field value. self._label = self._serialize_label(mpls_label, vni) self._mpls_label = mpls_label self._vni = vni def _serialize_label(self, mpls_label, vni): if mpls_label: return self._mpls_label_to_bin(mpls_label, is_bos=True) elif vni: return vxlan.vni_to_bin(vni) else: return b'\x00' * 3 @classmethod def parse_value(cls, buf): route_dist, rest = cls._rd_from_bin(buf) esi, rest = cls._esi_from_bin(rest) ethernet_tag_id, rest = cls._ethernet_tag_id_from_bin(rest) ip_prefix_len, rest = cls._ip_addr_len_from_bin(rest) _len = (len(rest) - cls._LABEL_LEN) // 2 ip_prefix, rest = cls._ip_addr_from_bin(rest, _len) gw_ip_addr, rest = cls._ip_addr_from_bin(rest, _len) return { 'route_dist': route_dist.formatted_str, 'esi': esi, 'ethernet_tag_id': ethernet_tag_id, 'ip_prefix': '%s/%s' % (ip_prefix, ip_prefix_len), 'gw_ip_addr': gw_ip_addr, 'label': rest, } def serialize_value(self): route_dist = _RouteDistinguisher.from_str(self.route_dist) ip_prefix = self._ip_addr_to_bin(self._ip_prefix) gw_ip_addr = self._ip_addr_to_bin(self.gw_ip_addr) return struct.pack( self._PACK_STR % (len(ip_prefix), len(gw_ip_addr)), route_dist.serialize(), self.esi.serialize(), self.ethernet_tag_id, self._ip_prefix_len, ip_prefix, gw_ip_addr, self._label) @property def ip_prefix(self): return '%s/%s' % (self._ip_prefix, self._ip_prefix_len) @ip_prefix.setter def ip_prefix(self, ip_prefix): self._ip_prefix, ip_prefix_len = ip_prefix.split('/') self._ip_prefix_len = int(ip_prefix_len) @property def mpls_label(self): return self._mpls_label @mpls_label.setter def mpls_label(self, mpls_label): self._label = self._mpls_label_to_bin(mpls_label, is_bos=True) self._mpls_label = mpls_label self._vni = None # disables VNI @property def vni(self): return self._vni @vni.setter def vni(self, vni): self._label = self._vni_to_bin(vni) self._mpls_label = None # disables MPLS label self._vni = vni @property def label_list(self): return [self.mpls_label] class _FlowSpecNLRIBase(StringifyMixin, TypeDisp): """ Base class for Flow Specification NLRI """ # flow-spec NLRI: # +-----------------------------------+ # | length (0xnn or 0xfn nn) | # +-----------------------------------+ # | NLRI value (variable) | # +-----------------------------------+ ROUTE_FAMILY = None _LENGTH_SHORT_FMT = '!B' LENGTH_SHORT_SIZE = struct.calcsize(_LENGTH_SHORT_FMT) _LENGTH_LONG_FMT = '!H' LENGTH_LONG_SIZE = struct.calcsize(_LENGTH_LONG_FMT) _LENGTH_THRESHOLD = 0xf000 FLOWSPEC_FAMILY = '' def __init__(self, length=0, rules=None): self.length = length rules = rules or [] for r in rules: assert isinstance(r, _FlowSpecComponentBase) self.rules = rules @classmethod def parser(cls, buf): (length,) = struct.unpack_from( cls._LENGTH_LONG_FMT, bytes(buf)) if length < cls._LENGTH_THRESHOLD: length >>= 8 offset = cls.LENGTH_SHORT_SIZE else: offset = cls.LENGTH_LONG_SIZE kwargs = {'length': length} rest = buf[offset:offset + length] if cls.ROUTE_FAMILY.safi == subaddr_family.VPN_FLOWSPEC: route_dist = _RouteDistinguisher.parser(rest[:8]) kwargs['route_dist'] = route_dist.formatted_str rest = rest[8:] rules = [] while rest: subcls, rest = _FlowSpecComponentBase.parse_header( rest, cls.ROUTE_FAMILY.afi) while rest: rule, rest = subcls.parse_body(rest) rules.append(rule) if (not isinstance(rule, _FlowSpecOperatorBase) or rule.operator & rule.END_OF_LIST): break kwargs['rules'] = rules return cls(**kwargs), rest def serialize(self): rules_bin = b'' if self.ROUTE_FAMILY.safi == subaddr_family.VPN_FLOWSPEC: route_dist = _RouteDistinguisher.from_str(self.route_dist) rules_bin += route_dist.serialize() self.rules.sort(key=lambda x: x.type) for _, rules in itertools.groupby(self.rules, key=lambda x: x.type): rules = list(rules) rules_bin += rules[0].serialize_header() if isinstance(rules[-1], _FlowSpecOperatorBase): rules[-1].operator |= rules[-1].END_OF_LIST for r in rules: rules_bin += r.serialize_body() self.length = len(rules_bin) if self.length < self._LENGTH_THRESHOLD: buf = struct.pack(self._LENGTH_SHORT_FMT, self.length) else: buf = struct.pack(self._LENGTH_LONG_FMT, self.length) return buf + rules_bin @classmethod def _from_user(cls, **kwargs): rules = [] for k, v in kwargs.items(): subcls = _FlowSpecComponentBase.lookup_type_name( k, cls.ROUTE_FAMILY.afi) rule = subcls.from_str(str(v)) rules.extend(rule) rules.sort(key=lambda x: x.type) return cls(rules=rules) @property def prefix(self): def _format(i): pairs = [] i.rules.sort(key=lambda x: x.type) previous_type = None for r in i.rules: if r.type == previous_type: if r.to_str()[0] != '&': pairs[-1] += '|' pairs[-1] += r.to_str() else: pairs.append('%s:%s' % (r.COMPONENT_NAME, r.to_str())) previous_type = r.type return ','.join(pairs) return '%s(%s)' % (self.FLOWSPEC_FAMILY, _format(self)) @property def formatted_nlri_str(self): return self.prefix class FlowSpecIPv4NLRI(_FlowSpecNLRIBase): """ Flow Specification NLRI class for IPv4 [RFC 5575] """ ROUTE_FAMILY = RF_IPv4_FLOWSPEC FLOWSPEC_FAMILY = 'ipv4fs' @classmethod def from_user(cls, **kwargs): """ Utility method for creating a NLRI instance. This function returns a NLRI instance from human readable format value. :param kwargs: The following arguments are available. =========== ============= ========= ============================== Argument Value Operator Description =========== ============= ========= ============================== dst_prefix IPv4 Prefix Nothing Destination Prefix. src_prefix IPv4 Prefix Nothing Source Prefix. ip_proto Integer Numeric IP Protocol. port Integer Numeric Port number. dst_port Integer Numeric Destination port number. src_port Integer Numeric Source port number. icmp_type Integer Numeric ICMP type. icmp_code Integer Numeric ICMP code. tcp_flags Fixed string Bitmask TCP flags. Supported values are ``CWR``, ``ECN``, ``URGENT``, ``ACK``, ``PUSH``, ``RST``, ``SYN`` and ``FIN``. packet_len Integer Numeric Packet length. dscp Integer Numeric Differentiated Services Code Point. fragment Fixed string Bitmask Fragment. Supported values are ``DF`` (Don't fragment), ``ISF`` (Is a fragment), ``FF`` (First fragment) and ``LF`` (Last fragment) =========== ============= ========= ============================== Example:: >>> msg = bgp.FlowSpecIPv4NLRI.from_user( ... dst_prefix='10.0.0.0/24', ... src_prefix='20.0.0.1/24', ... ip_proto=6, ... port='80 | 8000', ... dst_port='>9000 & <9050', ... src_port='>=8500 & <=9000', ... icmp_type=0, ... icmp_code=6, ... tcp_flags='SYN+ACK & !=URGENT', ... packet_len=1000, ... dscp='22 | 24', ... fragment='LF | ==FF') >>> You can specify conditions with the following keywords. The following keywords can be used when the operator type is Numeric. ========== ============================================================ Keyword Description ========== ============================================================ < Less than comparison between data and value. <= Less than or equal to comparison between data and value. > Greater than comparison between data and value. >= Greater than or equal to comparison between data and value. == Equality between data and value. This operator can be omitted. ========== ============================================================ The following keywords can be used when the operator type is Bitmask. ========== ================================================ Keyword Description ========== ================================================ != Not equal operation. == Exact match operation if specified. Otherwise partial match operation. `+` Used for the summation of bitmask values. (e.g., SYN+ACK) ========== ================================================ You can combine the multiple conditions with the following operators. ========== ======================================= Keyword Description ========== ======================================= `|` Logical OR operation & Logical AND operation ========== ======================================= :return: A instance of FlowSpecVPNv4NLRI. """ return cls._from_user(**kwargs) class FlowSpecVPNv4NLRI(_FlowSpecNLRIBase): """ Flow Specification NLRI class for VPNv4 [RFC 5575] """ # flow-spec NLRI: # +-----------------------------------+ # | length (0xnn or 0xfn nn) | # +-----------------------------------+ # | RD (8 octets) | # +-----------------------------------+ # | NLRI value (variable) | # +-----------------------------------+ ROUTE_FAMILY = RF_VPNv4_FLOWSPEC FLOWSPEC_FAMILY = 'vpnv4fs' def __init__(self, length=0, route_dist=None, rules=None): super(FlowSpecVPNv4NLRI, self).__init__(length, rules) assert route_dist is not None self.route_dist = route_dist @classmethod def _from_user(cls, route_dist, **kwargs): rules = [] for k, v in kwargs.items(): subcls = _FlowSpecComponentBase.lookup_type_name( k, cls.ROUTE_FAMILY.afi) rule = subcls.from_str(str(v)) rules.extend(rule) rules.sort(key=lambda x: x.type) return cls(route_dist=route_dist, rules=rules) @classmethod def from_user(cls, route_dist, **kwargs): """ Utility method for creating a NLRI instance. This function returns a NLRI instance from human readable format value. :param route_dist: Route Distinguisher. :param kwargs: See :py:mod:`os_ken.lib.packet.bgp.FlowSpecIPv4NLRI` Example:: >>> msg = bgp.FlowSpecIPv4NLRI.from_user( ... route_dist='65000:1000', ... dst_prefix='10.0.0.0/24', ... src_prefix='20.0.0.1/24', ... ip_proto=6, ... port='80 | 8000', ... dst_port='>9000 & <9050', ... src_port='>=8500 & <=9000', ... icmp_type=0, ... icmp_code=6, ... tcp_flags='SYN+ACK & !=URGENT', ... packet_len=1000, ... dscp='22 | 24', ... fragment='LF | ==FF') >>> """ return cls._from_user(route_dist, **kwargs) @property def formatted_nlri_str(self): return '%s:%s' % (self.route_dist, self.prefix) class FlowSpecIPv6NLRI(_FlowSpecNLRIBase): """ Flow Specification NLRI class for IPv6 [RFC draft-ietf-idr-flow-spec-v6-08] """ ROUTE_FAMILY = RF_IPv6_FLOWSPEC FLOWSPEC_FAMILY = 'ipv6fs' @classmethod def from_user(cls, **kwargs): """ Utility method for creating a NLRI instance. This function returns a NLRI instance from human readable format value. :param kwargs: The following arguments are available. =========== ============= ========= ============================== Argument Value Operator Description =========== ============= ========= ============================== dst_prefix IPv6 Prefix Nothing Destination Prefix. src_prefix IPv6 Prefix Nothing Source Prefix. next_header Integer Numeric Next Header. port Integer Numeric Port number. dst_port Integer Numeric Destination port number. src_port Integer Numeric Source port number. icmp_type Integer Numeric ICMP type. icmp_code Integer Numeric ICMP code. tcp_flags Fixed string Bitmask TCP flags. Supported values are ``CWR``, ``ECN``, ``URGENT``, ``ACK``, ``PUSH``, ``RST``, ``SYN`` and ``FIN``. packet_len Integer Numeric Packet length. dscp Integer Numeric Differentiated Services Code Point. fragment Fixed string Bitmask Fragment. Supported values are ``ISF`` (Is a fragment), ``FF`` (First fragment) and ``LF`` (Last fragment) flow_label Intefer Numeric Flow Label. =========== ============= ========= ============================== .. Note:: For ``dst_prefix`` and ``src_prefix``, you can give "offset" value like this: ``2001::2/128/32``. At this case, ``offset`` is 32. ``offset`` can be omitted, then ``offset`` is treated as 0. """ return cls._from_user(**kwargs) class FlowSpecVPNv6NLRI(_FlowSpecNLRIBase): """ Flow Specification NLRI class for VPNv6 [draft-ietf-idr-flow-spec-v6-08] """ # flow-spec NLRI: # +-----------------------------------+ # | length (0xnn or 0xfn nn) | # +-----------------------------------+ # | RD (8 octets) | # +-----------------------------------+ # | NLRI value (variable) | # +-----------------------------------+ ROUTE_FAMILY = RF_VPNv6_FLOWSPEC FLOWSPEC_FAMILY = 'vpnv6fs' def __init__(self, length=0, route_dist=None, rules=None): super(FlowSpecVPNv6NLRI, self).__init__(length, rules) assert route_dist is not None self.route_dist = route_dist @classmethod def _from_user(cls, route_dist, **kwargs): rules = [] for k, v in kwargs.items(): subcls = _FlowSpecComponentBase.lookup_type_name( k, cls.ROUTE_FAMILY.afi) rule = subcls.from_str(str(v)) rules.extend(rule) rules.sort(key=lambda x: x.type) return cls(route_dist=route_dist, rules=rules) @classmethod def from_user(cls, route_dist, **kwargs): """ Utility method for creating a NLRI instance. This function returns a NLRI instance from human readable format value. :param route_dist: Route Distinguisher. :param kwargs: See :py:mod:`os_ken.lib.packet.bgp.FlowSpecIPv6NLRI` """ return cls._from_user(route_dist, **kwargs) @property def formatted_nlri_str(self): return '%s:%s' % (self.route_dist, self.prefix) class FlowSpecL2VPNNLRI(_FlowSpecNLRIBase): """ Flow Specification NLRI class for L2VPN [draft-ietf-idr-flowspec-l2vpn-05] """ # flow-spec NLRI: # +-----------------------------------+ # | length (0xnn or 0xfn nn) | # +-----------------------------------+ # | RD (8 octets) | # +-----------------------------------+ # | NLRI value (variable) | # +-----------------------------------+ ROUTE_FAMILY = RF_L2VPN_FLOWSPEC FLOWSPEC_FAMILY = 'l2vpnfs' def __init__(self, length=0, route_dist=None, rules=None): super(FlowSpecL2VPNNLRI, self).__init__(length, rules) assert route_dist is not None self.route_dist = route_dist @classmethod def _from_user(cls, route_dist, **kwargs): rules = [] for k, v in kwargs.items(): subcls = _FlowSpecComponentBase.lookup_type_name( k, cls.ROUTE_FAMILY.afi) rule = subcls.from_str(str(v)) rules.extend(rule) rules.sort(key=lambda x: x.type) return cls(route_dist=route_dist, rules=rules) @classmethod def from_user(cls, route_dist, **kwargs): """ Utility method for creating a L2VPN NLRI instance. This function returns a L2VPN NLRI instance from human readable format value. :param kwargs: The following arguments are available. ============== ============= ========= ============================== Argument Value Operator Description ============== ============= ========= ============================== ether_type Integer Numeric Ethernet Type. src_mac Mac Address Nothing Source Mac address. dst_mac Mac Address Nothing Destination Mac address. llc_ssap Integer Numeric Source Service Access Point in LLC. llc_dsap Integer Numeric Destination Service Access Point in LLC. llc_control Integer Numeric Control field in LLC. snap Integer Numeric Sub-Network Access Protocol field. vlan_id Integer Numeric VLAN ID. vlan_cos Integer Numeric VLAN COS field. inner_vlan_id Integer Numeric Inner VLAN ID. inner_vlan_cos Integer Numeric Inner VLAN COS field. ============== ============= ========= ============================== """ return cls._from_user(route_dist, **kwargs) @property def formatted_nlri_str(self): return '%s:%s' % (self.route_dist, self.prefix) class _FlowSpecComponentBase(StringifyMixin, TypeDisp): """ Base class for Flow Specification NLRI component """ COMPONENT_NAME = None _BASE_STR = '!B' _BASE_STR_SIZE = struct.calcsize(_BASE_STR) # Dictionary of COMPONENT_NAME to subclass. # e.g.) # _NAMES = {'dst_prefix': FlowSpecDestPrefix, ...} _NAMES = {} def __init__(self, type_=None): if type_ is None: type_, _ = self._rev_lookup_type(self.__class__) self.type = type_ @classmethod def register_type(cls, type_, afi): cls._TYPES = cls._TYPES.copy() cls._NAMES = cls._NAMES.copy() def _register_type(subcls): cls._TYPES[(type_, afi)] = subcls cls._NAMES[(subcls.COMPONENT_NAME, afi)] = subcls cls._REV_TYPES = None return subcls return _register_type @classmethod def lookup_type_name(cls, type_name, afi): return cls._NAMES[(type_name, afi)] @classmethod def _lookup_type(cls, type_, afi): try: return cls._TYPES[(type_, afi)] except KeyError: return cls._UNKNOWN_TYPE @classmethod def parse_header(cls, rest, afi): (type_,) = struct.unpack_from( cls._BASE_STR, bytes(rest)) rest = rest[cls._BASE_STR_SIZE:] return cls._lookup_type(type_, afi), rest def serialize_header(self): return struct.pack(self._BASE_STR, self.type) class _FlowSpecIPv4Component(_FlowSpecComponentBase): """ Base class for Flow Specification for IPv4 NLRI component """ TYPE_DESTINATION_PREFIX = 0x01 TYPE_SOURCE_PREFIX = 0x02 TYPE_PROTOCOL = 0x03 TYPE_PORT = 0x04 TYPE_DESTINATION_PORT = 0x05 TYPE_SOURCE_PORT = 0x06 TYPE_ICMP = 0x07 TYPE_ICMP_CODE = 0x08 TYPE_TCP_FLAGS = 0x09 TYPE_PACKET_LENGTH = 0x0a TYPE_DIFFSERV_CODE_POINT = 0x0b TYPE_FRAGMENT = 0x0c class _FlowSpecIPv6Component(_FlowSpecComponentBase): """ Base class for Flow Specification for IPv6 NLRI component """ TYPE_DESTINATION_PREFIX = 0x01 TYPE_SOURCE_PREFIX = 0x02 TYPE_NEXT_HEADER = 0x03 TYPE_PORT = 0x04 TYPE_DESTINATION_PORT = 0x05 TYPE_SOURCE_PORT = 0x06 TYPE_ICMP = 0x07 TYPE_ICMP_CODE = 0x08 TYPE_TCP_FLAGS = 0x09 TYPE_PACKET_LENGTH = 0x0a TYPE_DIFFSERV_CODE_POINT = 0x0b TYPE_FRAGMENT = 0x0c TYPE_FLOW_LABEL = 0x0d class _FlowSpecL2VPNComponent(_FlowSpecComponentBase): """ Base class for Flow Specification for L2VPN NLRI component """ TYPE_ETHER_TYPE = 0x0e TYPE_SOURCE_MAC = 0x0f TYPE_DESTINATION_MAC = 0x10 TYPE_LLC_DSAP = 0x11 TYPE_LLC_SSAP = 0x12 TYPE_LLC_CONTROL = 0x13 TYPE_SNAP = 0x14 TYPE_VLAN_ID = 0x15 TYPE_VLAN_COS = 0x16 TYPE_INNER_VLAN_ID = 0x17 TYPE_INNER_VLAN_COS = 0x18 @_FlowSpecComponentBase.register_unknown_type() class FlowSpecComponentUnknown(_FlowSpecComponentBase): """ Unknown component type for Flow Specification NLRI component """ def __init__(self, buf, type_=None): super(FlowSpecComponentUnknown, self).__init__(type_) self.buf = buf @classmethod def parse_body(cls, buf): return cls(buf), None def serialize_body(self): return self.buf class _FlowSpecPrefixBase(_FlowSpecIPv4Component, IPAddrPrefix): """ Prefix base class for Flow Specification NLRI component """ def __init__(self, length, addr, type_=None): super(_FlowSpecPrefixBase, self).__init__(type_) self.length = length prefix = "%s/%s" % (addr, length) self.addr = str(netaddr.ip.IPNetwork(prefix).network) @classmethod def parse_body(cls, buf): return cls.parser(buf) def serialize_body(self): return self.serialize() @classmethod def from_str(cls, value): rule = [] addr, length = value.split('/') rule.append(cls(int(length), addr)) return rule @property def value(self): return "%s/%s" % (self.addr, self.length) def to_str(self): return self.value class _FlowSpecIPv6PrefixBase(_FlowSpecIPv6Component, IP6AddrPrefix): """ Prefix base class for Flow Specification NLRI component """ _PACK_STR = '!BB' # length, offset def __init__(self, length, addr, offset=0, type_=None): super(_FlowSpecIPv6PrefixBase, self).__init__(type_) self.length = length self.offset = offset prefix = "%s/%s" % (addr, length) self.addr = str(netaddr.ip.IPNetwork(prefix).network) @classmethod def parser(cls, buf): (length, offset) = struct.unpack_from( cls._PACK_STR, bytes(buf)) rest = buf[struct.calcsize(cls._PACK_STR):] byte_length = (length + 7) // 8 addr = cls._from_bin(rest[:byte_length]) rest = rest[byte_length:] return cls(length=length, offset=offset, addr=addr), rest @classmethod def parse_body(cls, buf): return cls.parser(buf) def serialize(self): byte_length = (self.length + 7) // 8 bin_addr = self._to_bin(self.addr)[:byte_length] buf = bytearray() msg_pack_into(self._PACK_STR, buf, 0, self.length, self.offset) return buf + bin_addr def serialize_body(self): return self.serialize() @classmethod def from_str(cls, value): rule = [] values = value.split('/') if len(values) == 3: rule.append(cls(int(values[1]), values[0], offset=int(values[2]))) else: rule.append(cls(int(values[1]), values[0])) return rule @property def value(self): return "%s/%s/%s" % (self.addr, self.length, self.offset) def to_str(self): return self.value class _FlowSpecL2VPNPrefixBase(_FlowSpecL2VPNComponent): """ Prefix base class for Flow Specification NLRI component """ _PACK_STR = "!B6s" def __init__(self, length, addr, type_=None): super(_FlowSpecL2VPNPrefixBase, self).__init__(type_) self.length = length self.addr = addr.lower() @classmethod def parse_body(cls, buf): (length, addr) = struct.unpack_from( cls._PACK_STR, bytes(buf)) rest = buf[struct.calcsize(cls._PACK_STR):] addr = addrconv.mac.bin_to_text(addr) return cls(length=length, addr=addr), rest def serialize(self): addr = addrconv.mac.text_to_bin(self.addr) return struct.pack(self._PACK_STR, self.length, addr) def serialize_body(self): return self.serialize() @classmethod def from_str(cls, value): return [cls(len(value.split(':')), value)] @property def value(self): return self.addr def to_str(self): return self.value @_FlowSpecComponentBase.register_type( _FlowSpecIPv4Component.TYPE_DESTINATION_PREFIX, addr_family.IP) class FlowSpecDestPrefix(_FlowSpecPrefixBase): """ Destination Prefix for Flow Specification NLRI component """ COMPONENT_NAME = 'dst_prefix' @_FlowSpecComponentBase.register_type( _FlowSpecIPv4Component.TYPE_SOURCE_PREFIX, addr_family.IP) class FlowSpecSrcPrefix(_FlowSpecPrefixBase): """ Source Prefix for Flow Specification NLRI component """ COMPONENT_NAME = 'src_prefix' @_FlowSpecComponentBase.register_type( _FlowSpecIPv6Component.TYPE_DESTINATION_PREFIX, addr_family.IP6) class FlowSpecIPv6DestPrefix(_FlowSpecIPv6PrefixBase): """ IPv6 destination Prefix for Flow Specification NLRI component """ COMPONENT_NAME = 'dst_prefix' @_FlowSpecComponentBase.register_type( _FlowSpecIPv6Component.TYPE_SOURCE_PREFIX, addr_family.IP6) class FlowSpecIPv6SrcPrefix(_FlowSpecIPv6PrefixBase): """ IPv6 source Prefix for Flow Specification NLRI component """ COMPONENT_NAME = 'src_prefix' class _FlowSpecOperatorBase(_FlowSpecComponentBase): """Operator base class for Flow Specification NLRI component ===================== =============================================== Attribute Description ===================== =============================================== operator Match conditions. value Value of component. ===================== =============================================== """ _OPE_PACK_STR = '!B' _OPE_PACK_STR_SIZE = struct.calcsize(_OPE_PACK_STR) _VAL_PACK_STR = '!%ds' END_OF_LIST = 1 << 7 # END OF LIST bit AND = 1 << 6 # AND bit OR = 0 # OR _LENGTH_BIT_MASK = 0x30 # The mask for length of the value _logical_conditions = { "|": OR, "&": AND, } _comparison_conditions = {} def __init__(self, operator, value, type_=None): super(_FlowSpecOperatorBase, self).__init__(type_) self.operator = operator self.value = value @classmethod def parse_body(cls, rest): (operator,) = struct.unpack_from(cls._OPE_PACK_STR, bytes(rest)) rest = rest[cls._OPE_PACK_STR_SIZE:] length = 1 << ((operator & cls._LENGTH_BIT_MASK) >> 4) value_type = type_desc.IntDescr(length) value = value_type.to_user(rest) rest = rest[length:] return cls(operator, value), rest def serialize_body(self): byte_length = (self.value.bit_length() + 7) // 8 or 1 length = int(math.ceil(math.log(byte_length, 2))) self.operator |= length << 4 buf = struct.pack(self._OPE_PACK_STR, self.operator) value_type = type_desc.IntDescr(1 << length) buf += struct.pack(self._VAL_PACK_STR % (1 << length), value_type.from_user(self.value)) return buf @classmethod def from_str(cls, val): operator = 0 rules = [] # e.g.) # value = '80 | ==90|>=8000&<=9000 | <100 & >110' # elements = ['80', '|', '==', '90', '|', '>=', '8000', '&', # '<=', '9000', '|', '<', '100', '&', '>', '110'] elements = [v.strip() for v in re.split( r'([0-9]+)|([A-Z]+)|(\|&\+)|([!=<>]+)', val) if v and v.strip()] elms_iter = iter(elements) for elm in elms_iter: if elm in cls._logical_conditions: # ['&', '|'] operator |= cls._logical_conditions[elm] continue elif elm in cls._comparison_conditions: # ['=', '<', '>', '<=', '>=' ] or ['=', '!='] operator |= cls._comparison_conditions[elm] continue elif elm == '+': # If keyword "+" is used, add the value to the previous rule. # e.g.) 'SYN+ACK' or '!=SYN+ACK' rules[-1].value |= cls._to_value(next(elms_iter)) continue value = cls._to_value(elm) operator = cls.normalize_operator(operator) rules.append(cls(operator, value)) operator = 0 return rules @classmethod def _to_value(cls, value): return value @classmethod def normalize_operator(cls, operator): return operator class _FlowSpecNumeric(_FlowSpecOperatorBase): """ Numeric operator class for Flow Specification NLRI component """ # Numeric operator format # 0 1 2 3 4 5 6 7 # +---+---+---+---+---+---+---+---+ # | e | a | len | 0 |lt |gt |eq | # +---+---+---+---+---+---+---+---+ LT = 1 << 2 # Less than comparison bit GT = 1 << 1 # Greater than comparison bit EQ = 1 << 0 # Equality bit _comparison_conditions = { '==': EQ, '<': LT, '>': GT, '<=': LT | EQ, '>=': GT | EQ } @classmethod def _to_value(cls, value): try: return int(str(value), 0) except ValueError: raise ValueError('Invalid params: %s="%s"' % ( cls.COMPONENT_NAME, value)) def to_str(self): string = "" if self.operator & self.AND: string += "&" operator = self.operator & (self.LT | self.GT | self.EQ) for k, v in self._comparison_conditions.items(): if operator == v: string += k string += str(self.value) return string @classmethod def normalize_operator(cls, operator): if operator & (cls.LT | cls.GT | cls.EQ): return operator else: return operator | cls.EQ class _FlowSpecBitmask(_FlowSpecOperatorBase): """ Bitmask operator class for Flow Specification NLRI component """ # Bitmask operator format # 0 1 2 3 4 5 6 7 # +---+---+---+---+---+---+---+---+ # | e | a | len | 0 | 0 |not| m | # +---+---+---+---+---+---+---+---+ NOT = 1 << 1 # NOT bit MATCH = 1 << 0 # MATCH bit _comparison_conditions = { '!=': NOT, '==': MATCH, } _bitmask_flags = {} @classmethod def _to_value(cls, value): try: return cls.__dict__[value] except KeyError: raise ValueError('Invalid params: %s="%s"' % ( cls.COMPONENT_NAME, value)) def to_str(self): string = "" if self.operator & self.AND: string += "&" operator = self.operator & (self.NOT | self.MATCH) for k, v in self._comparison_conditions.items(): if operator == v: string += k plus = "" for k, v in self._bitmask_flags.items(): if self.value & k: string += plus + v plus = "+" return string @_FlowSpecComponentBase.register_type( _FlowSpecIPv4Component.TYPE_PROTOCOL, addr_family.IP) class FlowSpecIPProtocol(_FlowSpecNumeric): """IP Protocol for Flow Specification NLRI component Set the IP protocol number at value. """ COMPONENT_NAME = 'ip_proto' @_FlowSpecComponentBase.register_type( _FlowSpecIPv6Component.TYPE_NEXT_HEADER, addr_family.IP6) class FlowSpecNextHeader(_FlowSpecNumeric): """Next Header value in IPv6 packets Set the IP protocol number at value """ COMPONENT_NAME = 'next_header' @_FlowSpecComponentBase.register_type( _FlowSpecIPv4Component.TYPE_PORT, addr_family.IP) @_FlowSpecComponentBase.register_type( _FlowSpecIPv6Component.TYPE_PORT, addr_family.IP6) class FlowSpecPort(_FlowSpecNumeric): """Port number for Flow Specification NLRI component Set the source or destination TCP/UDP ports at value. """ COMPONENT_NAME = 'port' @_FlowSpecComponentBase.register_type( _FlowSpecIPv4Component.TYPE_DESTINATION_PORT, addr_family.IP) @_FlowSpecComponentBase.register_type( _FlowSpecIPv6Component.TYPE_DESTINATION_PORT, addr_family.IP6) class FlowSpecDestPort(_FlowSpecNumeric): """Destination port number for Flow Specification NLRI component Set the destination port of a TCP or UDP packet at value. """ COMPONENT_NAME = 'dst_port' @_FlowSpecComponentBase.register_type( _FlowSpecIPv4Component.TYPE_SOURCE_PORT, addr_family.IP) @_FlowSpecComponentBase.register_type( _FlowSpecIPv6Component.TYPE_SOURCE_PORT, addr_family.IP6) class FlowSpecSrcPort(_FlowSpecNumeric): """Source port number for Flow Specification NLRI component Set the source port of a TCP or UDP packet at value. """ COMPONENT_NAME = 'src_port' @_FlowSpecComponentBase.register_type( _FlowSpecIPv4Component.TYPE_ICMP, addr_family.IP) @_FlowSpecComponentBase.register_type( _FlowSpecIPv6Component.TYPE_ICMP, addr_family.IP6) class FlowSpecIcmpType(_FlowSpecNumeric): """ICMP type for Flow Specification NLRI component Set the type field of an ICMP packet at value. """ COMPONENT_NAME = 'icmp_type' @_FlowSpecComponentBase.register_type( _FlowSpecIPv4Component.TYPE_ICMP_CODE, addr_family.IP) @_FlowSpecComponentBase.register_type( _FlowSpecIPv6Component.TYPE_ICMP_CODE, addr_family.IP6) class FlowSpecIcmpCode(_FlowSpecNumeric): """ICMP code Flow Specification NLRI component Set the code field of an ICMP packet at value. """ COMPONENT_NAME = 'icmp_code' @_FlowSpecComponentBase.register_type( _FlowSpecIPv4Component.TYPE_TCP_FLAGS, addr_family.IP) @_FlowSpecComponentBase.register_type( _FlowSpecIPv6Component.TYPE_TCP_FLAGS, addr_family.IP6) class FlowSpecTCPFlags(_FlowSpecBitmask): """TCP flags for Flow Specification NLRI component Supported TCP flags are CWR, ECN, URGENT, ACK, PUSH, RST, SYN and FIN. """ COMPONENT_NAME = 'tcp_flags' # bitmask format # 0 1 2 3 4 5 6 7 # +----+----+----+----+----+----+----+----+ # |CWR |ECN |URG |ACK |PSH |RST |SYN |FIN | # +----+----+----+----+----+----+----+----+ CWR = 1 << 7 ECN = 1 << 6 URGENT = 1 << 5 ACK = 1 << 4 PUSH = 1 << 3 RST = 1 << 2 SYN = 1 << 1 FIN = 1 << 0 _bitmask_flags = collections.OrderedDict() _bitmask_flags[SYN] = 'SYN' _bitmask_flags[ACK] = 'ACK' _bitmask_flags[FIN] = 'FIN' _bitmask_flags[RST] = 'RST' _bitmask_flags[PUSH] = 'PUSH' _bitmask_flags[URGENT] = 'URGENT' _bitmask_flags[ECN] = 'ECN' _bitmask_flags[CWR] = 'CWR' @_FlowSpecComponentBase.register_type( _FlowSpecIPv4Component.TYPE_PACKET_LENGTH, addr_family.IP) @_FlowSpecComponentBase.register_type( _FlowSpecIPv6Component.TYPE_PACKET_LENGTH, addr_family.IP6) class FlowSpecPacketLen(_FlowSpecNumeric): """Packet length for Flow Specification NLRI component Set the total IP packet length at value. """ COMPONENT_NAME = 'packet_len' @_FlowSpecComponentBase.register_type( _FlowSpecIPv4Component.TYPE_DIFFSERV_CODE_POINT, addr_family.IP) @_FlowSpecComponentBase.register_type( _FlowSpecIPv6Component.TYPE_DIFFSERV_CODE_POINT, addr_family.IP6) class FlowSpecDSCP(_FlowSpecNumeric): """Diffserv Code Point for Flow Specification NLRI component Set the 6-bit DSCP field at value. [RFC2474] """ COMPONENT_NAME = 'dscp' @_FlowSpecComponentBase.register_type( _FlowSpecIPv4Component.TYPE_FRAGMENT, addr_family.IP) class FlowSpecFragment(_FlowSpecBitmask): """Fragment for Flow Specification NLRI component Set the bitmask for operand format at value. The following values are supported. ========== =============================================== Attribute Description ========== =============================================== LF Last fragment FF First fragment ISF Is a fragment DF Don't fragment ========== =============================================== """ COMPONENT_NAME = 'fragment' # bitmask format # 0 1 2 3 4 5 6 7 # +---+---+---+---+---+---+---+---+ # | Reserved |LF |FF |IsF|DF | # +---+---+---+---+---+---+---+---+ LF = 1 << 3 FF = 1 << 2 ISF = 1 << 1 DF = 1 << 0 _bitmask_flags = collections.OrderedDict() _bitmask_flags[LF] = 'LF' _bitmask_flags[FF] = 'FF' _bitmask_flags[ISF] = 'ISF' _bitmask_flags[DF] = 'DF' @_FlowSpecComponentBase.register_type( _FlowSpecIPv6Component.TYPE_FRAGMENT, addr_family.IP6) class FlowSpecIPv6Fragment(_FlowSpecBitmask): """Fragment for Flow Specification for IPv6 NLRI component ========== =============================================== Attribute Description ========== =============================================== LF Last fragment FF First fragment ISF Is a fragment ========== =============================================== """ COMPONENT_NAME = 'fragment' # bitmask format # 0 1 2 3 4 5 6 7 # +---+---+---+---+---+---+---+---+ # | Reserved |LF |FF |IsF| 0 | # +---+---+---+---+---+---+---+---+ LF = 1 << 3 FF = 1 << 2 ISF = 1 << 1 _bitmask_flags = collections.OrderedDict() _bitmask_flags[LF] = 'LF' _bitmask_flags[FF] = 'FF' _bitmask_flags[ISF] = 'ISF' @_FlowSpecComponentBase.register_type( _FlowSpecL2VPNComponent.TYPE_ETHER_TYPE, addr_family.L2VPN) class FlowSpecEtherType(_FlowSpecNumeric): """Ethernet Type field in an Ethernet frame. Set the 2 byte value of an Ethernet Type field at value. """ COMPONENT_NAME = 'ether_type' @_FlowSpecComponentBase.register_type( _FlowSpecL2VPNComponent.TYPE_SOURCE_MAC, addr_family.L2VPN) class FlowSpecSourceMac(_FlowSpecL2VPNPrefixBase): """Source Mac Address. Set the Mac Address at value. """ COMPONENT_NAME = 'src_mac' @_FlowSpecComponentBase.register_type( _FlowSpecL2VPNComponent.TYPE_DESTINATION_MAC, addr_family.L2VPN) class FlowSpecDestinationMac(_FlowSpecL2VPNPrefixBase): """Destination Mac Address. Set the Mac Address at value. """ COMPONENT_NAME = 'dst_mac' @_FlowSpecComponentBase.register_type( _FlowSpecL2VPNComponent.TYPE_LLC_DSAP, addr_family.L2VPN) class FlowSpecLLCDSAP(_FlowSpecNumeric): """Destination SAP field in LLC header in an Ethernet frame. Set the 2 byte value of an Destination SAP at value. """ COMPONENT_NAME = 'llc_dsap' @_FlowSpecComponentBase.register_type( _FlowSpecL2VPNComponent.TYPE_LLC_SSAP, addr_family.L2VPN) class FlowSpecLLCSSAP(_FlowSpecNumeric): """Source SAP field in LLC header in an Ethernet frame. Set the 2 byte value of an Source SAP at value. """ COMPONENT_NAME = 'llc_ssap' @_FlowSpecComponentBase.register_type( _FlowSpecL2VPNComponent.TYPE_LLC_CONTROL, addr_family.L2VPN) class FlowSpecLLCControl(_FlowSpecNumeric): """Control field in LLC header in an Ethernet frame. Set the Contorol field at value. """ COMPONENT_NAME = 'llc_control' @_FlowSpecComponentBase.register_type( _FlowSpecL2VPNComponent.TYPE_SNAP, addr_family.L2VPN) class FlowSpecSNAP(_FlowSpecNumeric): """Sub-Network Access Protocol field in an Ethernet frame. Set the 5 byte SNAP field at value. """ COMPONENT_NAME = 'snap' @_FlowSpecComponentBase.register_type( _FlowSpecL2VPNComponent.TYPE_VLAN_ID, addr_family.L2VPN) class FlowSpecVLANID(_FlowSpecNumeric): """VLAN ID. Set VLAN ID at value. """ COMPONENT_NAME = 'vlan_id' @_FlowSpecComponentBase.register_type( _FlowSpecL2VPNComponent.TYPE_VLAN_COS, addr_family.L2VPN) class FlowSpecVLANCoS(_FlowSpecNumeric): """VLAN CoS Fields in an Ethernet frame. Set the 3 bit CoS field at value. """ COMPONENT_NAME = 'vlan_cos' @_FlowSpecComponentBase.register_type( _FlowSpecL2VPNComponent.TYPE_INNER_VLAN_ID, addr_family.L2VPN) class FlowSpecInnerVLANID(_FlowSpecNumeric): """Inner VLAN ID. Set VLAN ID at value. """ COMPONENT_NAME = 'inner_vlan_id' @_FlowSpecComponentBase.register_type( _FlowSpecL2VPNComponent.TYPE_INNER_VLAN_COS, addr_family.L2VPN) class FlowSpecInnerVLANCoS(_FlowSpecNumeric): """VLAN CoS Fields in an Inner Ethernet frame. Set the 3 bit CoS field at value.. """ COMPONENT_NAME = 'inner_vlan_cos' @_FlowSpecComponentBase.register_type( _FlowSpecIPv6Component.TYPE_FLOW_LABEL, addr_family.IP6) class FlowSpecIPv6FlowLabel(_FlowSpecNumeric): COMPONENT_NAME = 'flow_label' @functools.total_ordering class RouteTargetMembershipNLRI(StringifyMixin): """Route Target Membership NLRI. Route Target membership NLRI is advertised in BGP UPDATE messages using the MP_REACH_NLRI and MP_UNREACH_NLRI attributes. """ ROUTE_FAMILY = RF_RTC_UC DEFAULT_AS = '0:0' DEFAULT_RT = '0:0' def __init__(self, origin_as, route_target): # If given is not default_as and default_rt if not (origin_as is self.DEFAULT_AS and route_target is self.DEFAULT_RT): # We validate them if (not self._is_valid_asn(origin_as) or not self._is_valid_ext_comm_attr(route_target)): raise ValueError('Invalid params.') self.origin_as = origin_as self.route_target = route_target def _is_valid_asn(self, asn): """Returns True if the given AS number is Two or Four Octet.""" if isinstance(asn, int) and 0 <= asn <= 0xffffffff: return True else: return False def _is_valid_ext_comm_attr(self, attr): """Validates *attr* as string representation of RT or SOO. Returns True if *attr* is as per our convention of RT or SOO, else False. Our convention is to represent RT/SOO is a string with format: *global_admin_part:local_admin_path* """ is_valid = True if not isinstance(attr, str): is_valid = False else: first, second = attr.split(':') try: if '.' in first: socket.inet_aton(first) else: int(first) int(second) except (ValueError, socket.error): is_valid = False return is_valid @property def formatted_nlri_str(self): return "%s:%s" % (self.origin_as, self.route_target) def is_default_rtnlri(self): if (self._origin_as is self.DEFAULT_AS and self._route_target is self.DEFAULT_RT): return True return False def __lt__(self, other): return ((self.origin_as, self.route_target) < (other.origin_as, other.route_target)) def __eq__(self, other): return ((self.origin_as, self.route_target) == (other.origin_as, other.route_target)) def __hash__(self): return hash((self.origin_as, self.route_target)) @classmethod def parser(cls, buf): idx = 0 # Extract origin AS. origin_as, = struct.unpack_from('!I', buf, idx) idx += 4 # Extract route target. route_target = _ExtendedCommunity(buf[idx:]) return cls(origin_as, route_target) def serialize(self): rt_nlri = b'' if not self.is_default_rtnlri(): rt_nlri += struct.pack('!I', self.origin_as) # Encode route target rt_nlri += self.route_target.serialize() # RT Nlri is 12 octets return struct.pack('B', (8 * 12)) + rt_nlri def _addr_class_key(route_family): return route_family.afi, route_family.safi _ADDR_CLASSES = { _addr_class_key(RF_IPv4_UC): IPAddrPrefix, _addr_class_key(RF_IPv6_UC): IP6AddrPrefix, _addr_class_key(RF_IPv4_MPLS): LabelledIPAddrPrefix, _addr_class_key(RF_IPv6_MPLS): LabelledIP6AddrPrefix, _addr_class_key(RF_IPv4_VPN): LabelledVPNIPAddrPrefix, _addr_class_key(RF_IPv6_VPN): LabelledVPNIP6AddrPrefix, _addr_class_key(RF_L2_EVPN): EvpnNLRI, _addr_class_key(RF_IPv4_FLOWSPEC): FlowSpecIPv4NLRI, _addr_class_key(RF_IPv6_FLOWSPEC): FlowSpecIPv6NLRI, _addr_class_key(RF_VPNv4_FLOWSPEC): FlowSpecVPNv4NLRI, _addr_class_key(RF_VPNv6_FLOWSPEC): FlowSpecVPNv6NLRI, _addr_class_key(RF_L2VPN_FLOWSPEC): FlowSpecL2VPNNLRI, _addr_class_key(RF_RTC_UC): RouteTargetMembershipNLRI, } def _get_addr_class(afi, safi): try: return _ADDR_CLASSES[(afi, safi)] except KeyError: return _BinAddrPrefix class _OptParam(StringifyMixin, TypeDisp, _Value): _PACK_STR = '!BB' # type, length def __init__(self, type_, value=None, length=None): if type_ is None: type_ = self._rev_lookup_type(self.__class__) self.type = type_ self.length = length if value is not None: self.value = value @classmethod def parser(cls, buf): (type_, length) = struct.unpack_from(cls._PACK_STR, bytes(buf)) rest = buf[struct.calcsize(cls._PACK_STR):] value = bytes(rest[:length]) rest = rest[length:] subcls = cls._lookup_type(type_) caps = subcls.parse_value(value) if not isinstance(caps, list): caps = [subcls(type_=type_, length=length, **caps[0])] return caps, rest def serialize(self): # fixup value = self.serialize_value() self.length = len(value) buf = bytearray() msg_pack_into(self._PACK_STR, buf, 0, self.type, self.length) return buf + value @_OptParam.register_unknown_type() class BGPOptParamUnknown(_OptParam): @classmethod def parse_value(cls, buf): return { 'value': buf }, cls def serialize_value(self): return self.value @_OptParam.register_type(BGP_OPT_CAPABILITY) class _OptParamCapability(_OptParam, TypeDisp): _CAP_HDR_PACK_STR = '!BB' def __init__(self, cap_code=None, cap_value=None, cap_length=None, type_=None, length=None): super(_OptParamCapability, self).__init__(type_=BGP_OPT_CAPABILITY, length=length) if cap_code is None: cap_code = self._rev_lookup_type(self.__class__) self.cap_code = cap_code if cap_value is not None: self.cap_value = cap_value if cap_length is not None: self.cap_length = cap_length @classmethod def parse_value(cls, buf): caps = [] while len(buf) > 0: (code, length) = struct.unpack_from(cls._CAP_HDR_PACK_STR, bytes(buf)) value = buf[struct.calcsize(cls._CAP_HDR_PACK_STR):] buf = buf[length + 2:] kwargs = { 'cap_code': code, 'cap_length': length, } subcls = cls._lookup_type(code) kwargs.update(subcls.parse_cap_value(value)) caps.append(subcls(type_=BGP_OPT_CAPABILITY, length=length + 2, **kwargs)) return caps def serialize_value(self): # fixup cap_value = self.serialize_cap_value() self.cap_length = len(cap_value) buf = bytearray() msg_pack_into(self._CAP_HDR_PACK_STR, buf, 0, self.cap_code, self.cap_length) return buf + cap_value class _OptParamEmptyCapability(_OptParamCapability): @classmethod def parse_cap_value(cls, buf): return {} def serialize_cap_value(self): return bytearray() @_OptParamCapability.register_unknown_type() class BGPOptParamCapabilityUnknown(_OptParamCapability): @classmethod def parse_cap_value(cls, buf): return {'cap_value': buf} def serialize_cap_value(self): return self.cap_value @_OptParamCapability.register_type(BGP_CAP_ROUTE_REFRESH) class BGPOptParamCapabilityRouteRefresh(_OptParamEmptyCapability): pass @_OptParamCapability.register_type(BGP_CAP_ROUTE_REFRESH_CISCO) class BGPOptParamCapabilityCiscoRouteRefresh(_OptParamEmptyCapability): pass @_OptParamCapability.register_type(BGP_CAP_ENHANCED_ROUTE_REFRESH) class BGPOptParamCapabilityEnhancedRouteRefresh(_OptParamEmptyCapability): pass @_OptParamCapability.register_type(BGP_CAP_GRACEFUL_RESTART) class BGPOptParamCapabilityGracefulRestart(_OptParamCapability): _CAP_PACK_STR = "!H" def __init__(self, flags, time, tuples, **kwargs): super(BGPOptParamCapabilityGracefulRestart, self).__init__(**kwargs) self.flags = flags self.time = time self.tuples = tuples @classmethod def parse_cap_value(cls, buf): (restart, ) = struct.unpack_from(cls._CAP_PACK_STR, bytes(buf)) buf = buf[2:] l = [] while len(buf) >= 4: l.append(struct.unpack_from("!HBB", buf)) buf = buf[4:] return {'flags': restart >> 12, 'time': restart & 0xfff, 'tuples': l} def serialize_cap_value(self): buf = bytearray() msg_pack_into(self._CAP_PACK_STR, buf, 0, self.flags << 12 | self.time) offset = 2 for i in self.tuples: afi, safi, flags = i msg_pack_into("!HBB", buf, offset, afi, safi, flags) offset += 4 return buf @_OptParamCapability.register_type(BGP_CAP_FOUR_OCTET_AS_NUMBER) class BGPOptParamCapabilityFourOctetAsNumber(_OptParamCapability): _CAP_PACK_STR = '!I' def __init__(self, as_number, **kwargs): super(BGPOptParamCapabilityFourOctetAsNumber, self).__init__(**kwargs) self.as_number = as_number @classmethod def parse_cap_value(cls, buf): (as_number, ) = struct.unpack_from(cls._CAP_PACK_STR, bytes(buf)) return {'as_number': as_number} def serialize_cap_value(self): buf = bytearray() msg_pack_into(self._CAP_PACK_STR, buf, 0, self.as_number) return buf @_OptParamCapability.register_type(BGP_CAP_MULTIPROTOCOL) class BGPOptParamCapabilityMultiprotocol(_OptParamCapability): _CAP_PACK_STR = '!HBB' # afi, reserved, safi def __init__(self, afi, safi, reserved=0, **kwargs): super(BGPOptParamCapabilityMultiprotocol, self).__init__(**kwargs) self.afi = afi self.reserved = reserved self.safi = safi @classmethod def parse_cap_value(cls, buf): (afi, reserved, safi,) = struct.unpack_from(cls._CAP_PACK_STR, bytes(buf)) return { 'afi': afi, 'reserved': reserved, 'safi': safi, } def serialize_cap_value(self): # fixup self.reserved = 0 buf = bytearray() msg_pack_into(self._CAP_PACK_STR, buf, 0, self.afi, self.reserved, self.safi) return buf @_OptParamCapability.register_type(BGP_CAP_CARRYING_LABEL_INFO) class BGPOptParamCapabilityCarryingLabelInfo(_OptParamEmptyCapability): pass class BGPWithdrawnRoute(IPAddrPrefix): pass class _PathAttribute(StringifyMixin, TypeDisp, _Value): _PACK_STR = '!BB' # flags, type _PACK_STR_LEN = '!B' # length _PACK_STR_EXT_LEN = '!H' # length w/ BGP_ATTR_FLAG_EXTENDED_LENGTH _ATTR_FLAGS = None def __init__(self, value=None, flags=0, type_=None, length=None): if type_ is None: type_ = self._rev_lookup_type(self.__class__) self.flags = flags self.type = type_ self.length = length if value is not None: self.value = value @classmethod def parser(cls, buf): (flags, type_) = struct.unpack_from(cls._PACK_STR, bytes(buf)) rest = buf[struct.calcsize(cls._PACK_STR):] if (flags & BGP_ATTR_FLAG_EXTENDED_LENGTH) != 0: len_pack_str = cls._PACK_STR_EXT_LEN else: len_pack_str = cls._PACK_STR_LEN (length,) = struct.unpack_from(len_pack_str, bytes(rest)) rest = rest[struct.calcsize(len_pack_str):] value = bytes(rest[:length]) rest = rest[length:] subcls = cls._lookup_type(type_) return subcls(flags=flags, type_=type_, length=length, **subcls.parse_value(value)), rest def serialize(self): # fixup if self._ATTR_FLAGS is not None: self.flags = ( self.flags & ~(BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANSITIVE) | self._ATTR_FLAGS) value = self.serialize_value() self.length = len(value) if self.flags & BGP_ATTR_FLAG_EXTENDED_LENGTH: len_pack_str = self._PACK_STR_EXT_LEN elif self.length > 255: self.flags |= BGP_ATTR_FLAG_EXTENDED_LENGTH len_pack_str = self._PACK_STR_EXT_LEN else: self.flags &= ~BGP_ATTR_FLAG_EXTENDED_LENGTH len_pack_str = self._PACK_STR_LEN buf = bytearray() msg_pack_into(self._PACK_STR, buf, 0, self.flags, self.type) msg_pack_into(len_pack_str, buf, len(buf), self.length) return buf + value @_PathAttribute.register_unknown_type() class BGPPathAttributeUnknown(_PathAttribute): @classmethod def parse_value(cls, buf): return { 'value': buf } def serialize_value(self): return self.value class _PathAttributeUint32(_PathAttribute): _VALUE_PACK_STR = '!I' @_PathAttribute.register_type(BGP_ATTR_TYPE_ORIGIN) class BGPPathAttributeOrigin(_PathAttribute): _VALUE_PACK_STR = '!B' _ATTR_FLAGS = BGP_ATTR_FLAG_TRANSITIVE class _BGPPathAttributeAsPathCommon(_PathAttribute): _AS_SET = 1 _AS_SEQUENCE = 2 _SEG_HDR_PACK_STR = '!BB' _AS_PACK_STR = None _ATTR_FLAGS = BGP_ATTR_FLAG_TRANSITIVE def __init__(self, value, as_pack_str=None, flags=0, type_=None, length=None): super(_BGPPathAttributeAsPathCommon, self).__init__(value=value, flags=flags, type_=type_, length=length) if as_pack_str: self._AS_PACK_STR = as_pack_str @property def path_seg_list(self): return copy.deepcopy(self.value) def get_as_path_len(self): count = 0 for seg in self.value: if isinstance(seg, list): # Segment type 2 stored in list and all AS counted. count += len(seg) else: # Segment type 1 stored in set and count as one. count += 1 return count def has_local_as(self, local_as, max_count=0): """Check if *local_as* is already present on path list.""" _count = 0 for as_path_seg in self.value: _count += list(as_path_seg).count(local_as) return _count > max_count def has_matching_leftmost(self, remote_as): """Check if leftmost AS matches *remote_as*.""" if not self.value or not remote_as: return False leftmost_seg = self.path_seg_list[0] if leftmost_seg and leftmost_seg[0] == remote_as: return True return False @classmethod def _is_valid_16bit_as_path(cls, buf): two_byte_as_size = struct.calcsize('!H') while buf: (type_, num_as) = struct.unpack_from(cls._SEG_HDR_PACK_STR, bytes(buf)) if type_ is not cls._AS_SET and type_ is not cls._AS_SEQUENCE: return False buf = buf[struct.calcsize(cls._SEG_HDR_PACK_STR):] if len(buf) < num_as * two_byte_as_size: return False buf = buf[num_as * two_byte_as_size:] return True @classmethod def parse_value(cls, buf): result = [] if cls._is_valid_16bit_as_path(buf): as_pack_str = '!H' else: as_pack_str = '!I' while buf: (type_, num_as) = struct.unpack_from(cls._SEG_HDR_PACK_STR, bytes(buf)) buf = buf[struct.calcsize(cls._SEG_HDR_PACK_STR):] l = [] for _ in range(0, num_as): (as_number,) = struct.unpack_from(as_pack_str, bytes(buf)) buf = buf[struct.calcsize(as_pack_str):] l.append(as_number) if type_ == cls._AS_SET: result.append(set(l)) elif type_ == cls._AS_SEQUENCE: result.append(l) else: # protocol error raise struct.error('Unsupported segment type: %s' % type_) return { 'value': result, 'as_pack_str': as_pack_str, } def serialize_value(self): buf = bytearray() offset = 0 for e in self.value: if isinstance(e, set): type_ = self._AS_SET elif isinstance(e, list): type_ = self._AS_SEQUENCE else: raise struct.error( 'Element of %s.value must be of type set or list' % self.__class__.__name__) l = list(e) num_as = len(l) if num_as == 0: continue msg_pack_into(self._SEG_HDR_PACK_STR, buf, offset, type_, num_as) offset += struct.calcsize(self._SEG_HDR_PACK_STR) for i in l: msg_pack_into(self._AS_PACK_STR, buf, offset, i) offset += struct.calcsize(self._AS_PACK_STR) return buf @_PathAttribute.register_type(BGP_ATTR_TYPE_AS_PATH) class BGPPathAttributeAsPath(_BGPPathAttributeAsPathCommon): # XXX depends on negotiated capability, AS numbers can be 32 bit. # while wireshark seems to attempt auto-detect, it seems that # there's no way to detect it reliably. for example, the # following byte sequence can be interpreted in two ways. # 01 02 99 88 77 66 02 01 55 44 # AS_SET num=2 9988 7766 AS_SEQUENCE num=1 5544 # AS_SET num=2 99887766 02015544 # we first check whether AS path can be parsed in 16bit format and if # it fails, we try to parse as 32bit _AS_PACK_STR = '!H' @_PathAttribute.register_type(BGP_ATTR_TYPE_AS4_PATH) class BGPPathAttributeAs4Path(_BGPPathAttributeAsPathCommon): _AS_PACK_STR = '!I' _ATTR_FLAGS = BGP_ATTR_FLAG_TRANSITIVE | BGP_ATTR_FLAG_OPTIONAL @classmethod def _is_valid_16bit_as_path(cls, buf): return False @_PathAttribute.register_type(BGP_ATTR_TYPE_NEXT_HOP) class BGPPathAttributeNextHop(_PathAttribute): _VALUE_PACK_STR = '!4s' _ATTR_FLAGS = BGP_ATTR_FLAG_TRANSITIVE _TYPE = { 'ascii': [ 'value' ] } @classmethod def parse_value(cls, buf): (ip_addr,) = struct.unpack_from(cls._VALUE_PACK_STR, bytes(buf)) return { 'value': addrconv.ipv4.bin_to_text(ip_addr), } def serialize_value(self): buf = bytearray() msg_pack_into(self._VALUE_PACK_STR, buf, 0, addrconv.ipv4.text_to_bin(self.value)) return buf @_PathAttribute.register_type(BGP_ATTR_TYPE_MULTI_EXIT_DISC) class BGPPathAttributeMultiExitDisc(_PathAttributeUint32): _ATTR_FLAGS = BGP_ATTR_FLAG_OPTIONAL @_PathAttribute.register_type(BGP_ATTR_TYPE_LOCAL_PREF) class BGPPathAttributeLocalPref(_PathAttributeUint32): _ATTR_FLAGS = BGP_ATTR_FLAG_TRANSITIVE @_PathAttribute.register_type(BGP_ATTR_TYPE_ATOMIC_AGGREGATE) class BGPPathAttributeAtomicAggregate(_PathAttribute): _ATTR_FLAGS = BGP_ATTR_FLAG_TRANSITIVE @classmethod def parse_value(cls, buf): return {} def serialize_value(self): return b'' class _BGPPathAttributeAggregatorCommon(_PathAttribute): _VALUE_PACK_STR = None _ATTR_FLAGS = BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANSITIVE _TYPE = { 'ascii': [ 'addr' ] } def __init__(self, as_number, addr, flags=0, type_=None, length=None): super(_BGPPathAttributeAggregatorCommon, self).__init__(flags=flags, type_=type_, length=length) self.as_number = as_number self.addr = addr @classmethod def parse_value(cls, buf): (as_number, addr) = struct.unpack_from(cls._VALUE_PACK_STR, bytes(buf)) return { 'as_number': as_number, 'addr': addrconv.ipv4.bin_to_text(addr), } def serialize_value(self): buf = bytearray() msg_pack_into(self._VALUE_PACK_STR, buf, 0, self.as_number, addrconv.ipv4.text_to_bin(self.addr)) return buf @_PathAttribute.register_type(BGP_ATTR_TYPE_AGGREGATOR) class BGPPathAttributeAggregator(_BGPPathAttributeAggregatorCommon): # Note: AS numbers can be Two-Octet or Four-Octet. # This class would detect it by the value length field. # For example, # - if the value field length is 6 (='!H4s'), AS number should # be Two-Octet. # - else if the length is 8 (='!I4s'), AS number should be Four-Octet. _TWO_OCTET_VALUE_PACK_STR = '!H4s' _FOUR_OCTET_VALUE_PACK_STR = '!I4s' _VALUE_PACK_STR = _TWO_OCTET_VALUE_PACK_STR # Two-Octet by default _FOUR_OCTET_VALUE_SIZE = struct.calcsize(_FOUR_OCTET_VALUE_PACK_STR) @classmethod def parse_value(cls, buf): if len(buf) == cls._FOUR_OCTET_VALUE_SIZE: cls._VALUE_PACK_STR = cls._FOUR_OCTET_VALUE_PACK_STR return super(BGPPathAttributeAggregator, cls).parse_value(buf) def serialize_value(self): if self.as_number > 0xffff: self._VALUE_PACK_STR = self._FOUR_OCTET_VALUE_PACK_STR return super(BGPPathAttributeAggregator, self).serialize_value() @_PathAttribute.register_type(BGP_ATTR_TYPE_AS4_AGGREGATOR) class BGPPathAttributeAs4Aggregator(_BGPPathAttributeAggregatorCommon): _VALUE_PACK_STR = '!I4s' @_PathAttribute.register_type(BGP_ATTR_TYPE_COMMUNITIES) class BGPPathAttributeCommunities(_PathAttribute): _VALUE_PACK_STR = '!I' _ATTR_FLAGS = BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANSITIVE # String constants of well-known-communities NO_EXPORT = int('0xFFFFFF01', 16) NO_ADVERTISE = int('0xFFFFFF02', 16) NO_EXPORT_SUBCONFED = int('0xFFFFFF03', 16) WELL_KNOW_COMMUNITIES = (NO_EXPORT, NO_ADVERTISE, NO_EXPORT_SUBCONFED) def __init__(self, communities, flags=0, type_=None, length=None): super(BGPPathAttributeCommunities, self).__init__(flags=flags, type_=type_, length=length) self.communities = communities @classmethod def parse_value(cls, buf): rest = buf communities = [] elem_size = struct.calcsize(cls._VALUE_PACK_STR) while len(rest) >= elem_size: (comm, ) = struct.unpack_from(cls._VALUE_PACK_STR, bytes(rest)) communities.append(comm) rest = rest[elem_size:] return { 'communities': communities, } def serialize_value(self): buf = bytearray() for comm in self.communities: bincomm = bytearray() msg_pack_into(self._VALUE_PACK_STR, bincomm, 0, comm) buf += bincomm return buf @staticmethod def is_no_export(comm_attr): """Returns True if given value matches well-known community NO_EXPORT attribute value. """ return comm_attr == BGPPathAttributeCommunities.NO_EXPORT @staticmethod def is_no_advertise(comm_attr): """Returns True if given value matches well-known community NO_ADVERTISE attribute value. """ return comm_attr == BGPPathAttributeCommunities.NO_ADVERTISE @staticmethod def is_no_export_subconfed(comm_attr): """Returns True if given value matches well-known community NO_EXPORT_SUBCONFED attribute value. """ return comm_attr == BGPPathAttributeCommunities.NO_EXPORT_SUBCONFED def has_comm_attr(self, attr): """Returns True if given community attribute is present.""" for comm_attr in self.communities: if comm_attr == attr: return True return False @_PathAttribute.register_type(BGP_ATTR_TYPE_ORIGINATOR_ID) class BGPPathAttributeOriginatorId(_PathAttribute): # ORIGINATOR_ID is a new optional, non-transitive BGP attribute of Type # code 9. This attribute is 4 bytes long and it will be created by an # RR in reflecting a route. _VALUE_PACK_STR = '!4s' _ATTR_FLAGS = BGP_ATTR_FLAG_OPTIONAL _TYPE = { 'asciilist': [ 'value' ] } @classmethod def parse_value(cls, buf): (originator_id,) = struct.unpack_from(cls._VALUE_PACK_STR, bytes(buf)) return { 'value': addrconv.ipv4.bin_to_text(originator_id), } def serialize_value(self): buf = bytearray() msg_pack_into(self._VALUE_PACK_STR, buf, 0, addrconv.ipv4.text_to_bin(self.value)) return buf @_PathAttribute.register_type(BGP_ATTR_TYPE_CLUSTER_LIST) class BGPPathAttributeClusterList(_PathAttribute): # CLUSTER_LIST is a new, optional, non-transitive BGP attribute of Type # code 10. It is a sequence of CLUSTER_ID values representing the # reflection path that the route has passed. _VALUE_PACK_STR = '!4s' _ATTR_FLAGS = BGP_ATTR_FLAG_OPTIONAL _TYPE = { 'ascii': [ 'value' ] } @classmethod def parse_value(cls, buf): rest = buf cluster_list = [] elem_size = struct.calcsize(cls._VALUE_PACK_STR) while len(rest) >= elem_size: (cluster_id, ) = struct.unpack_from( cls._VALUE_PACK_STR, bytes(rest)) cluster_list.append(addrconv.ipv4.bin_to_text(cluster_id)) rest = rest[elem_size:] return { 'value': cluster_list, } def serialize_value(self): buf = bytearray() offset = 0 for cluster_id in self.value: msg_pack_into( self._VALUE_PACK_STR, buf, offset, addrconv.ipv4.text_to_bin(cluster_id)) offset += struct.calcsize(self._VALUE_PACK_STR) return buf # Extended Communities # RFC 4360 # RFC 5668 # IANA registry: # https://www.iana.org/assignments/bgp-extended-communities/ # bgp-extended-communities.xml # # type # high low # 00 sub-type Two-Octet AS Specific Extended Community (transitive) # 40 sub-type Two-Octet AS Specific Extended Community # payload: # 2 byte Global Administrator (AS number) # 4 byte Local Administrator (defined by sub-type) # 01 sub-type IPv4 Address Specific Extended Community (transitive) # 41 sub-type IPv4 Address Specific Extended Community # payload: # 4 byte Global Administrator (IPv4 address) # 2 byte Local Administrator (defined by sub-type) # 03 sub-type Opaque Extended Community (transitive) # 43 sub-type Opaque Extended Community # payload: # 6 byte opaque value (defined by sub-type) # # 00 02 Route Target Community (two-octet AS specific) # 01 02 Route Target Community (IPv4 address specific) # 02 02 Route Target Community (four-octet AS specific, RFC 5668) # 00 03 Route Origin Community (two-octet AS specific) # 01 03 Route Origin Community (IPv4 address specific) # 02 03 Route Origin Community (four-octet AS specific, RFC 5668) # 06 sub-type Ethernet VPN Extended Community (RFC 7432) # 80 sub-type Flow Specification Extended Community (RFC 5575) @_PathAttribute.register_type(BGP_ATTR_TYPE_EXTENDED_COMMUNITIES) class BGPPathAttributeExtendedCommunities(_PathAttribute): _ATTR_FLAGS = BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANSITIVE _class_prefixes = ['BGP'] def __init__(self, communities, flags=0, type_=None, length=None): super(BGPPathAttributeExtendedCommunities, self).__init__(flags=flags, type_=type_, length=length) self.communities = communities @classmethod def parse_value(cls, buf): rest = buf communities = [] while rest: comm, rest = _ExtendedCommunity.parse(rest) communities.append(comm) return { 'communities': communities, } def serialize_value(self): buf = bytearray() for comm in self.communities: buf += comm.serialize() return buf def _community_list(self, subtype): _list = [] for comm in (c for c in self.communities if hasattr(c, "subtype") and c.subtype == subtype): if comm.type == 0 or comm.type == 2: _list.append('%d:%d' % (comm.as_number, comm.local_administrator)) elif comm.type == 1: _list.append('%s:%d' % (comm.ipv4_address, comm.local_administrator)) return _list @property def rt_list(self): return self._community_list(2) @property def soo_list(self): return self._community_list(3) class _ExtendedCommunity(StringifyMixin, TypeDisp, _Value): _PACK_STR = '!B7s' # type high (+ type low), value _PACK_STR_SIZE = struct.calcsize(_PACK_STR) _SUBTYPE_PACK_STR = '!B' # subtype IANA_AUTHORITY = 0x80 TRANSITIVE = 0x40 _TYPE_HIGH_MASK = ~TRANSITIVE TWO_OCTET_AS_SPECIFIC = 0x00 IPV4_ADDRESS_SPECIFIC = 0x01 FOUR_OCTET_AS_SPECIFIC = 0x02 OPAQUE = 0x03 SUBTYPE_ENCAPSULATION = 0x0c ENCAPSULATION = (OPAQUE, SUBTYPE_ENCAPSULATION) EVPN = 0x06 SUBTYPE_EVPN_MAC_MOBILITY = 0x00 SUBTYPE_EVPN_ESI_LABEL = 0x01 SUBTYPE_EVPN_ES_IMPORT_RT = 0x02 EVPN_MAC_MOBILITY = (EVPN, SUBTYPE_EVPN_MAC_MOBILITY) EVPN_ESI_LABEL = (EVPN, SUBTYPE_EVPN_ESI_LABEL) EVPN_ES_IMPORT_RT = (EVPN, SUBTYPE_EVPN_ES_IMPORT_RT) FLOWSPEC = 0x80 FLOWSPEC_L2VPN = 0x08 SUBTYPE_FLOWSPEC_TRAFFIC_RATE = 0x06 SUBTYPE_FLOWSPEC_TRAFFIC_ACTION = 0x07 SUBTYPE_FLOWSPEC_REDIRECT = 0x08 SUBTYPE_FLOWSPEC_TRAFFIC_REMARKING = 0x09 SUBTYPE_FLOWSPEC_VLAN_ACTION = 0x0a SUBTYPE_FLOWSPEC_TPID_ACTION = 0x0b FLOWSPEC_TRAFFIC_RATE = (FLOWSPEC, SUBTYPE_FLOWSPEC_TRAFFIC_RATE) FLOWSPEC_TRAFFIC_ACTION = (FLOWSPEC, SUBTYPE_FLOWSPEC_TRAFFIC_ACTION) FLOWSPEC_REDIRECT = (FLOWSPEC, SUBTYPE_FLOWSPEC_REDIRECT) FLOWSPEC_TRAFFIC_REMARKING = (FLOWSPEC, SUBTYPE_FLOWSPEC_TRAFFIC_REMARKING) FLOWSPEC_VLAN_ACTION = (FLOWSPEC_L2VPN, SUBTYPE_FLOWSPEC_VLAN_ACTION) FLOWSPEC_TPID_ACTION = (FLOWSPEC_L2VPN, SUBTYPE_FLOWSPEC_TPID_ACTION) def __init__(self, type_=None): if type_ is None: type_ = self._rev_lookup_type(self.__class__) if isinstance(type_, (tuple, list)): type_ = type_[0] self.type = type_ @classmethod def parse_subtype(cls, buf): (subtype,) = struct.unpack_from(cls._SUBTYPE_PACK_STR, buf) return subtype @classmethod def parse(cls, buf): (type_, value) = struct.unpack_from(cls._PACK_STR, buf) rest = buf[cls._PACK_STR_SIZE:] type_low = type_ & cls._TYPE_HIGH_MASK subtype = cls.parse_subtype(value) subcls = cls._lookup_type((type_low, subtype)) if subcls == cls._UNKNOWN_TYPE: subcls = cls._lookup_type(type_low) return subcls(type_=type_, **subcls.parse_value(value)), rest def serialize(self): return struct.pack(self._PACK_STR, self.type, self.serialize_value()) @_ExtendedCommunity.register_type(_ExtendedCommunity.TWO_OCTET_AS_SPECIFIC) class BGPTwoOctetAsSpecificExtendedCommunity(_ExtendedCommunity): _VALUE_PACK_STR = '!BHI' # sub type, as number, local adm _VALUE_FIELDS = ['subtype', 'as_number', 'local_administrator'] def __init__(self, **kwargs): super(BGPTwoOctetAsSpecificExtendedCommunity, self).__init__() self.do_init(BGPTwoOctetAsSpecificExtendedCommunity, self, kwargs) @_ExtendedCommunity.register_type(_ExtendedCommunity.IPV4_ADDRESS_SPECIFIC) class BGPIPv4AddressSpecificExtendedCommunity(_ExtendedCommunity): _VALUE_PACK_STR = '!B4sH' # sub type, IPv4 address, local adm _VALUE_FIELDS = ['subtype', 'ipv4_address', 'local_administrator'] _TYPE = { 'ascii': [ 'ipv4_address' ] } def __init__(self, **kwargs): super(BGPIPv4AddressSpecificExtendedCommunity, self).__init__() self.do_init(BGPIPv4AddressSpecificExtendedCommunity, self, kwargs) @classmethod def parse_value(cls, buf): d_ = super(BGPIPv4AddressSpecificExtendedCommunity, cls).parse_value(buf) d_['ipv4_address'] = addrconv.ipv4.bin_to_text(d_['ipv4_address']) return d_ def serialize_value(self): return struct.pack(self._VALUE_PACK_STR, self.subtype, addrconv.ipv4.text_to_bin(self.ipv4_address), self.local_administrator) @_ExtendedCommunity.register_type(_ExtendedCommunity.FOUR_OCTET_AS_SPECIFIC) class BGPFourOctetAsSpecificExtendedCommunity(_ExtendedCommunity): _VALUE_PACK_STR = '!BIH' # sub type, as number, local adm _VALUE_FIELDS = ['subtype', 'as_number', 'local_administrator'] def __init__(self, **kwargs): super(BGPFourOctetAsSpecificExtendedCommunity, self).__init__() self.do_init(BGPFourOctetAsSpecificExtendedCommunity, self, kwargs) @_ExtendedCommunity.register_type(_ExtendedCommunity.OPAQUE) class BGPOpaqueExtendedCommunity(_ExtendedCommunity): _VALUE_PACK_STR = '!B6s' _VALUE_FIELDS = ['subtype', 'opaque'] def __init__(self, **kwargs): super(BGPOpaqueExtendedCommunity, self).__init__() self.do_init(BGPOpaqueExtendedCommunity, self, kwargs) @_ExtendedCommunity.register_type(_ExtendedCommunity.ENCAPSULATION) class BGPEncapsulationExtendedCommunity(_ExtendedCommunity): _VALUE_PACK_STR = '!B4xH' _VALUE_FIELDS = ['subtype', 'tunnel_type'] # BGP Tunnel Encapsulation Attribute Tunnel Types # http://www.iana.org/assignments/bgp-parameters/bgp-parameters.xhtml#tunnel-types TUNNEL_TYPE_L2TPV3 = 1 TUNNEL_TYPE_GRE = 2 TUNNEL_TYPE_IP_IN_IP = 7 TUNNEL_TYPE_VXLAN = 8 TUNNEL_TYPE_NVGRE = 9 TUNNEL_TYPE_MPLS = 10 TUNNEL_TYPE_MPLS_IN_GRE = 11 TUNNEL_TYPE_VXLAN_GRE = 12 TUNNEL_TYPE_MPLS_IN_UDP = 13 def __init__(self, **kwargs): super(BGPEncapsulationExtendedCommunity, self).__init__() self.do_init(BGPEncapsulationExtendedCommunity, self, kwargs) @classmethod def from_str(cls, tunnel_type): """ Returns an instance identified with the given `tunnel_type`. `tunnel_type` should be a str type value and corresponding to BGP Tunnel Encapsulation Attribute Tunnel Type constants name omitting `TUNNEL_TYPE_` prefix. Example: - `gre` means TUNNEL_TYPE_GRE - `vxlan` means TUNNEL_TYPE_VXLAN And raises AttributeError when the corresponding Tunnel Type is not found to the given `tunnel_type`. """ return cls(subtype=_ExtendedCommunity.SUBTYPE_ENCAPSULATION, tunnel_type=getattr(cls, 'TUNNEL_TYPE_' + tunnel_type.upper())) @_ExtendedCommunity.register_type(_ExtendedCommunity.EVPN_MAC_MOBILITY) class BGPEvpnMacMobilityExtendedCommunity(_ExtendedCommunity): """ MAC Mobility Extended Community """ # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Type=0x06 | Sub-Type=0x00 |Flags(1 octet)| Reserved=0 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Sequence Number | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ _VALUE_PACK_STR = '!BBxI' _VALUE_FIELDS = ['subtype', 'flags', 'sequence_number'] def __init__(self, **kwargs): super(BGPEvpnMacMobilityExtendedCommunity, self).__init__() self.do_init(BGPEvpnMacMobilityExtendedCommunity, self, kwargs) @_ExtendedCommunity.register_type(_ExtendedCommunity.EVPN_ESI_LABEL) class BGPEvpnEsiLabelExtendedCommunity(_ExtendedCommunity): """ ESI Label Extended Community """ # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Type=0x06 | Sub-Type=0x01 | Flags(1 octet)| Reserved=0 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Reserved=0 | ESI Label | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ _VALUE_PACK_STR = '!BB2x3s' _VALUE_FIELDS = ['subtype', 'flags'] # Classification for Flags. SINGLE_ACTIVE_BIT = 1 << 0 def __init__(self, label=None, mpls_label=None, vni=None, **kwargs): super(BGPEvpnEsiLabelExtendedCommunity, self).__init__() self.do_init(BGPEvpnEsiLabelExtendedCommunity, self, kwargs) if label: # If binary type label field value is specified, stores it # and decodes as MPLS label and VNI. self._label = label self._mpls_label, _ = mpls.label_from_bin(label) self._vni = vxlan.vni_from_bin(label) else: # If either MPLS label or VNI is specified, stores it # and encodes into binary type label field value. self._label = self._serialize_label(mpls_label, vni) self._mpls_label = mpls_label self._vni = vni def _serialize_label(self, mpls_label, vni): if mpls_label: return mpls.label_to_bin(mpls_label, is_bos=True) elif vni: return vxlan.vni_to_bin(vni) else: return b'\x00' * 3 @classmethod def parse_value(cls, buf): (subtype, flags, label) = struct.unpack_from(cls._VALUE_PACK_STR, buf) return { 'subtype': subtype, 'flags': flags, 'label': label, } def serialize_value(self): return struct.pack(self._VALUE_PACK_STR, self.subtype, self.flags, self._label) @property def mpls_label(self): return self._mpls_label @mpls_label.setter def mpls_label(self, mpls_label): self._label = mpls.label_to_bin(mpls_label, is_bos=True) self._mpls_label = mpls_label self._vni = None # disables VNI @property def vni(self): return self._vni @vni.setter def vni(self, vni): self._label = vxlan.vni_to_bin(vni) self._mpls_label = None # disables ESI label self._vni = vni @_ExtendedCommunity.register_type(_ExtendedCommunity.EVPN_ES_IMPORT_RT) class BGPEvpnEsImportRTExtendedCommunity(_ExtendedCommunity): """ ES-Import Route Target Extended Community """ # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Type=0x06 | Sub-Type=0x02 | ES-Import | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | ES-Import Cont'd | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ _VALUE_PACK_STR = '!B6s' _VALUE_FIELDS = ['subtype', 'es_import'] _TYPE = { 'ascii': [ 'es_import' ] } def __init__(self, **kwargs): super(BGPEvpnEsImportRTExtendedCommunity, self).__init__() self.do_init(BGPEvpnEsImportRTExtendedCommunity, self, kwargs) @classmethod def parse_value(cls, buf): (subtype, es_import) = struct.unpack_from(cls._VALUE_PACK_STR, buf) return { 'subtype': subtype, 'es_import': addrconv.mac.bin_to_text(es_import), } def serialize_value(self): return struct.pack(self._VALUE_PACK_STR, self.subtype, addrconv.mac.text_to_bin(self.es_import)) @_ExtendedCommunity.register_type(_ExtendedCommunity.FLOWSPEC_TRAFFIC_RATE) class BGPFlowSpecTrafficRateCommunity(_ExtendedCommunity): """ Flow Specification Traffic Filtering Actions for Traffic Rate. ========================== =============================================== Attribute Description ========================== =============================================== as_number Autonomous System number. rate_info rate information. ========================== =============================================== """ # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Type=0x80 | Sub-Type=0x06 | AS number | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Rate information | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ _VALUE_PACK_STR = '!BHf' _VALUE_FIELDS = ['subtype', 'as_number', 'rate_info'] ACTION_NAME = 'traffic_rate' def __init__(self, **kwargs): super(BGPFlowSpecTrafficRateCommunity, self).__init__() kwargs['subtype'] = self.SUBTYPE_FLOWSPEC_TRAFFIC_RATE self.do_init(BGPFlowSpecTrafficRateCommunity, self, kwargs) @classmethod def parse_value(cls, buf): (subtype, as_number, rate_info) = struct.unpack_from(cls._VALUE_PACK_STR, buf) return { 'subtype': subtype, 'as_number': as_number, 'rate_info': rate_info, } def serialize_value(self): return struct.pack(self._VALUE_PACK_STR, self.subtype, self.as_number, self.rate_info) @_ExtendedCommunity.register_type(_ExtendedCommunity.FLOWSPEC_TRAFFIC_ACTION) class BGPFlowSpecTrafficActionCommunity(_ExtendedCommunity): """ Flow Specification Traffic Filtering Actions for Traffic Action. ========================== =============================================== Attribute Description ========================== =============================================== action Apply action. The supported action are ``SAMPLE`` and ``TERMINAL``. ========================== =============================================== """ # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Type=0x80 | Sub-Type=0x07 | Traffic-action | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Traffic-action Cont'd | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # Traffic-action format # 40 41 42 43 44 45 46 47 # +---+---+---+---+---+---+---+---+ # | reserved | S | T | # +---+---+---+---+---+---+---+---+ _VALUE_PACK_STR = '!B5xB' _VALUE_FIELDS = ['subtype', 'action'] ACTION_NAME = 'traffic_action' SAMPLE = 1 << 1 TERMINAL = 1 << 0 def __init__(self, **kwargs): super(BGPFlowSpecTrafficActionCommunity, self).__init__() kwargs['subtype'] = self.SUBTYPE_FLOWSPEC_TRAFFIC_ACTION self.do_init(BGPFlowSpecTrafficActionCommunity, self, kwargs) @_ExtendedCommunity.register_type(_ExtendedCommunity.FLOWSPEC_REDIRECT) class BGPFlowSpecRedirectCommunity(BGPTwoOctetAsSpecificExtendedCommunity): """ Flow Specification Traffic Filtering Actions for Redirect. ========================== =============================================== Attribute Description ========================== =============================================== as_number Autonomous System number. local_administrator Local Administrator. ========================== =============================================== """ ACTION_NAME = 'redirect' def __init__(self, **kwargs): super(BGPTwoOctetAsSpecificExtendedCommunity, self).__init__() kwargs['subtype'] = self.SUBTYPE_FLOWSPEC_REDIRECT self.do_init(BGPTwoOctetAsSpecificExtendedCommunity, self, kwargs) @_ExtendedCommunity.register_type( _ExtendedCommunity.FLOWSPEC_TRAFFIC_REMARKING) class BGPFlowSpecTrafficMarkingCommunity(_ExtendedCommunity): """ Flow Specification Traffic Filtering Actions for Traffic Marking. ========================== =============================================== Attribute Description ========================== =============================================== dscp Differentiated Services Code Point. ========================== =============================================== """ # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Type=0x80 | Sub-Type=0x09 | Reserved=0 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Reserved=0 | Dscp | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ _VALUE_PACK_STR = '!B5xB' _VALUE_FIELDS = ['subtype', 'dscp'] ACTION_NAME = 'traffic_marking' def __init__(self, **kwargs): super(BGPFlowSpecTrafficMarkingCommunity, self).__init__() kwargs['subtype'] = self.SUBTYPE_FLOWSPEC_TRAFFIC_REMARKING self.do_init(BGPFlowSpecTrafficMarkingCommunity, self, kwargs) @classmethod def parse_value(cls, buf): (subtype, dscp) = struct.unpack_from(cls._VALUE_PACK_STR, buf) return { 'subtype': subtype, 'dscp': dscp, } def serialize_value(self): return struct.pack(self._VALUE_PACK_STR, self.subtype, self.dscp) # TODO # Implement "Redirect-IPv6" [draft-ietf-idr-flow-spec-v6-08] @_ExtendedCommunity.register_type( _ExtendedCommunity.FLOWSPEC_VLAN_ACTION) class BGPFlowSpecVlanActionCommunity(_ExtendedCommunity): """ Flow Specification Vlan Actions. ========= =============================================== Attribute Description ========= =============================================== actions_1 Bit representation of actions. Supported actions are ``POP``, ``PUSH``, ``SWAP``, ``REWRITE_INNER``, ``REWRITE_OUTER``. actions_2 Same as ``actions_1``. vlan_1 VLAN ID used by ``actions_1``. cos_1 Class of Service used by ``actions_1``. vlan_2 VLAN ID used by ``actions_2``. cos_2 Class of Service used by ``actions_2``. ========= =============================================== """ # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Type=0x08 | Sub-Type=0x0a |PO1|PU1|SW1|RT1|RO1|...|PO2|...| # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | VLAN ID1 | COS1 |0| VLAN ID2 | COS2 |0| # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ _VALUE_PACK_STR = '!BBBHH' _VALUE_FIELDS = [ 'subtype', 'actions_1', 'actions_2', 'vlan_1', 'vlan_2', 'cos_1', 'cos_2'] ACTION_NAME = 'vlan_action' _COS_MASK = 0x07 POP = 1 << 7 PUSH = 1 << 6 SWAP = 1 << 5 REWRITE_INNER = 1 << 4 REWRITE_OUTER = 1 << 3 def __init__(self, **kwargs): super(BGPFlowSpecVlanActionCommunity, self).__init__() kwargs['subtype'] = self.SUBTYPE_FLOWSPEC_VLAN_ACTION self.do_init(BGPFlowSpecVlanActionCommunity, self, kwargs) @classmethod def parse_value(cls, buf): (subtype, actions_1, actions_2, vlan_cos_1, vlan_cos_2) = struct.unpack_from(cls._VALUE_PACK_STR, buf) return { 'subtype': subtype, 'actions_1': actions_1, 'vlan_1': int(vlan_cos_1 >> 4), 'cos_1': int((vlan_cos_1 >> 1) & cls._COS_MASK), 'actions_2': actions_2, 'vlan_2': int(vlan_cos_2 >> 4), 'cos_2': int((vlan_cos_2 >> 1) & cls._COS_MASK) } def serialize_value(self): return struct.pack( self._VALUE_PACK_STR, self.subtype, self.actions_1, self.actions_2, (self.vlan_1 << 4) + (self.cos_1 << 1), (self.vlan_2 << 4) + (self.cos_2 << 1), ) @_ExtendedCommunity.register_type( _ExtendedCommunity.FLOWSPEC_TPID_ACTION) class BGPFlowSpecTPIDActionCommunity(_ExtendedCommunity): """ Flow Specification TPID Actions. ========= ========================================================= Attribute Description ========= ========================================================= actions Bit representation of actions. Supported actions are ``TI(inner TPID action)`` and ``TO(outer TPID action)``. tpid_1 TPID used by ``TI``. tpid_2 TPID used by ``TO``. ========= ========================================================= """ # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Type=0x08 | Sub-Type=0x0b |TI|TO| Reserved=0 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | TPID1 | TPID2 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ _VALUE_PACK_STR = '!BHHH' _VALUE_FIELDS = ['subtype', 'actions', 'tpid_1', 'tpid_2'] ACTION_NAME = 'tpid_action' TI = 1 << 15 TO = 1 << 14 def __init__(self, **kwargs): super(BGPFlowSpecTPIDActionCommunity, self).__init__() kwargs['subtype'] = self.SUBTYPE_FLOWSPEC_TPID_ACTION self.do_init(BGPFlowSpecTPIDActionCommunity, self, kwargs) @classmethod def parse_value(cls, buf): (subtype, actions, tpid_1, tpid_2) = struct.unpack_from( cls._VALUE_PACK_STR, buf) return { 'subtype': subtype, 'actions': actions, 'tpid_1': tpid_1, 'tpid_2': tpid_2, } def serialize_value(self): return struct.pack( self._VALUE_PACK_STR, self.subtype, self.actions, self.tpid_1, self.tpid_2, ) @_ExtendedCommunity.register_unknown_type() class BGPUnknownExtendedCommunity(_ExtendedCommunity): _VALUE_PACK_STR = '!7s' # opaque value def __init__(self, type_, **kwargs): super(BGPUnknownExtendedCommunity, self).__init__(type_=type_) self.do_init(BGPUnknownExtendedCommunity, self, kwargs, type_=type_) @_PathAttribute.register_type(BGP_ATTR_TYPE_MP_REACH_NLRI) class BGPPathAttributeMpReachNLRI(_PathAttribute): _VALUE_PACK_STR = '!HBB' # afi, safi, next_hop_len _VALUE_PACK_SIZE = struct.calcsize(_VALUE_PACK_STR) _RD_LENGTH = 8 _RESERVED_LENGTH = 1 _ATTR_FLAGS = BGP_ATTR_FLAG_OPTIONAL _class_suffixes = ['AddrPrefix'] _opt_attributes = ['next_hop'] _TYPE = { 'ascii': [ 'next_hop' ] } def __init__(self, afi, safi, next_hop, nlri, flags=0, type_=None, length=None): super(BGPPathAttributeMpReachNLRI, self).__init__( flags=flags, type_=type_, length=length) self.afi = afi self.safi = safi if not isinstance(next_hop, (list, tuple)): next_hop = [next_hop] for n in next_hop: if not ip.valid_ipv4(n) and not ip.valid_ipv6(n): raise ValueError('Invalid address for next_hop: %s' % n) # Note: For the backward compatibility, stores the first next_hop # address and all next_hop addresses separately. if next_hop: self._next_hop = next_hop[0] else: self._next_hop = None self._next_hop_list = next_hop self.nlri = nlri addr_cls = _get_addr_class(afi, safi) for i in nlri: if not isinstance(i, addr_cls): raise ValueError('Invalid NRLI class for afi=%d and safi=%d' % (self.afi, self.safi)) @staticmethod def split_bin_with_len(buf, unit_len): f = io.BytesIO(buf) return [f.read(unit_len) for _ in range(0, len(buf), unit_len)] @classmethod def parse_next_hop_ipv4(cls, buf, unit_len): next_hop = [] for next_hop_bin in cls.split_bin_with_len(buf, unit_len): next_hop.append(addrconv.ipv4.bin_to_text(next_hop_bin[-4:])) return next_hop @classmethod def parse_next_hop_ipv6(cls, buf, unit_len): next_hop = [] for next_hop_bin in cls.split_bin_with_len(buf, unit_len): next_hop.append(addrconv.ipv6.bin_to_text(next_hop_bin[-16:])) return next_hop @classmethod def parse_value(cls, buf): (afi, safi, next_hop_len,) = struct.unpack_from( cls._VALUE_PACK_STR, bytes(buf)) rest = buf[cls._VALUE_PACK_SIZE:] next_hop_bin = rest[:next_hop_len] rest = rest[next_hop_len:] reserved = rest[:cls._RESERVED_LENGTH] assert reserved == b'\0' nlri_bin = rest[cls._RESERVED_LENGTH:] addr_cls = _get_addr_class(afi, safi) nlri = [] while nlri_bin: n, nlri_bin = addr_cls.parser(nlri_bin) nlri.append(n) rf = RouteFamily(afi, safi) if rf == RF_IPv4_VPN: next_hop = cls.parse_next_hop_ipv4(next_hop_bin, cls._RD_LENGTH + 4) next_hop_len -= cls._RD_LENGTH * len(next_hop) elif rf == RF_IPv6_VPN: next_hop = cls.parse_next_hop_ipv6(next_hop_bin, cls._RD_LENGTH + 16) next_hop_len -= cls._RD_LENGTH * len(next_hop) elif (afi == addr_family.IP or (rf == RF_L2_EVPN and next_hop_len < 16)): next_hop = cls.parse_next_hop_ipv4(next_hop_bin, 4) elif (afi == addr_family.IP6 or (rf == RF_L2_EVPN and next_hop_len >= 16)): next_hop = cls.parse_next_hop_ipv6(next_hop_bin, 16) elif rf == RF_L2VPN_FLOWSPEC: next_hop = [] else: raise ValueError('Invalid address family: afi=%d, safi=%d' % (afi, safi)) return { 'afi': afi, 'safi': safi, 'next_hop': next_hop, 'nlri': nlri, } def serialize_next_hop(self): buf = bytearray() for next_hop in self.next_hop_list: if self.afi == addr_family.IP6: next_hop = str(netaddr.IPAddress(next_hop).ipv6()) next_hop_bin = ip.text_to_bin(next_hop) if RouteFamily(self.afi, self.safi) in (RF_IPv4_VPN, RF_IPv6_VPN): # Empty label stack(RD=0:0) + IP address next_hop_bin = b'\x00' * self._RD_LENGTH + next_hop_bin buf += next_hop_bin return buf def serialize_value(self): next_hop_bin = self.serialize_next_hop() # fixup next_hop_len = len(next_hop_bin) buf = bytearray() msg_pack_into(self._VALUE_PACK_STR, buf, 0, self.afi, self.safi, next_hop_len) buf += next_hop_bin buf += b'\0' # reserved nlri_bin = bytearray() for n in self.nlri: nlri_bin += n.serialize() buf += nlri_bin return buf @property def next_hop(self): return self._next_hop @next_hop.setter def next_hop(self, addr): if not ip.valid_ipv4(addr) and not ip.valid_ipv6(addr): raise ValueError('Invalid address for next_hop: %s' % addr) self._next_hop = addr self.next_hop_list[0] = addr @property def next_hop_list(self): return self._next_hop_list @next_hop_list.setter def next_hop_list(self, addr_list): if not isinstance(addr_list, (list, tuple)): addr_list = [addr_list] for addr in addr_list: if not ip.valid_ipv4(addr) and not ip.valid_ipv6(addr): raise ValueError('Invalid address for next_hop: %s' % addr) self._next_hop = addr_list[0] self._next_hop_list = addr_list @property def route_family(self): return _rf_map[(self.afi, self.safi)] @_PathAttribute.register_type(BGP_ATTR_TYPE_MP_UNREACH_NLRI) class BGPPathAttributeMpUnreachNLRI(_PathAttribute): _VALUE_PACK_STR = '!HB' # afi, safi _ATTR_FLAGS = BGP_ATTR_FLAG_OPTIONAL _class_suffixes = ['AddrPrefix'] def __init__(self, afi, safi, withdrawn_routes, flags=0, type_=None, length=None): super(BGPPathAttributeMpUnreachNLRI, self).__init__( flags=flags, type_=type_, length=length) self.afi = afi self.safi = safi self.withdrawn_routes = withdrawn_routes addr_cls = _get_addr_class(afi, safi) for i in withdrawn_routes: if not isinstance(i, addr_cls): raise ValueError('Invalid NRLI class for afi=%d and safi=%d' % (self.afi, self.safi)) @classmethod def parse_value(cls, buf): (afi, safi,) = struct.unpack_from( cls._VALUE_PACK_STR, bytes(buf)) nlri_bin = buf[struct.calcsize(cls._VALUE_PACK_STR):] addr_cls = _get_addr_class(afi, safi) nlri = [] while nlri_bin: n, nlri_bin = addr_cls.parser(nlri_bin) nlri.append(n) return { 'afi': afi, 'safi': safi, 'withdrawn_routes': nlri, } def serialize_value(self): buf = bytearray() msg_pack_into(self._VALUE_PACK_STR, buf, 0, self.afi, self.safi) nlri_bin = bytearray() for n in self.withdrawn_routes: nlri_bin += n.serialize() buf += nlri_bin return buf @property def route_family(self): return _rf_map[(self.afi, self.safi)] @_PathAttribute.register_type(BGP_ATTR_TYEP_PMSI_TUNNEL_ATTRIBUTE) class BGPPathAttributePmsiTunnel(_PathAttribute): """ P-Multicast Service Interface Tunnel (PMSI Tunnel) attribute """ # pmsi_flags, tunnel_type, mpls_label _VALUE_PACK_STR = '!BB3s' _PACK_STR_SIZE = struct.calcsize(_VALUE_PACK_STR) _ATTR_FLAGS = BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANSITIVE # RFC 6514 # +--------------------------------+ # | Flags (1 octet) | # +--------------------------------+ # | Tunnel Type (1 octets) | # +--------------------------------+ # | MPLS Label (3 octets) | # +--------------------------------+ # | Tunnel Identifier (variable) | # +--------------------------------+ # The Flags field has the following format: # 0 1 2 3 4 5 6 7 # +-+-+-+-+-+-+-+-+ # | reserved |L| # +-+-+-+-+-+-+-+-+ # `L` refers to the Leaf Information Required. # Current, Tunnel Type supports following. # + 0 - No tunnel information present # + 6 - Ingress Replication TYPE_NO_TUNNEL_INFORMATION_PRESENT = 0 TYPE_INGRESS_REPLICATION = 6 # TODO: # The following Tunnel Type are not supported. # Therefore, we will need to support in the future. # + 1 - RSVP-TE P2MP LSP # + 2 - mLDP P2MP LSP # + 3 - PIM-SSM Tree # + 4 - PIM-SM Tree # + 5 - BIDIR-PIM Tree # + 7 - mLDP MP2MP LSP def __init__(self, pmsi_flags, tunnel_type, mpls_label=None, label=None, vni=None, tunnel_id=None, flags=0, type_=None, length=None): super(BGPPathAttributePmsiTunnel, self).__init__(flags=flags, type_=type_, length=length) self.pmsi_flags = pmsi_flags self.tunnel_type = tunnel_type self.tunnel_id = tunnel_id if label: # If binary type label field value is specified, stores it # and decodes as MPLS label and VNI. self._label = label self._mpls_label, _ = mpls.label_from_bin(label) self._vni = vxlan.vni_from_bin(label) else: # If either MPLS label or VNI is specified, stores it # and encodes into binary type label field value. self._label = self._serialize_label(mpls_label, vni) self._mpls_label = mpls_label self._vni = vni @classmethod def parse_value(cls, buf): (pmsi_flags, tunnel_type, label) = struct.unpack_from(cls._VALUE_PACK_STR, buf) value = buf[cls._PACK_STR_SIZE:] return { 'pmsi_flags': pmsi_flags, 'tunnel_type': tunnel_type, 'label': label, 'tunnel_id': _PmsiTunnelId.parse(tunnel_type, value) } def serialize_value(self): buf = bytearray() msg_pack_into(self._VALUE_PACK_STR, buf, 0, self.pmsi_flags, self.tunnel_type, self._label) if self.tunnel_id is not None: buf += self.tunnel_id.serialize() return buf def _serialize_label(self, mpls_label, vni): if mpls_label: return mpls.label_to_bin(mpls_label, is_bos=True) elif vni: return vxlan.vni_to_bin(vni) else: return b'\x00' * 3 @property def mpls_label(self): return self._mpls_label @mpls_label.setter def mpls_label(self, mpls_label): self._label = mpls.label_to_bin(mpls_label, is_bos=True) self._mpls_label = mpls_label self._vni = None # disables VNI @property def vni(self): return self._vni @vni.setter def vni(self, vni): self._label = vxlan.vni_to_bin(vni) self._mpls_label = None # disables MPLS label self._vni = vni @classmethod def from_jsondict(cls, dict_, decode_string=base64.b64decode, **additional_args): if isinstance(dict_['tunnel_id'], dict): tunnel_id = dict_.pop('tunnel_id') ins = super(BGPPathAttributePmsiTunnel, cls).from_jsondict(dict_, decode_string, **additional_args) mod = import_module(cls.__module__) for key, value in tunnel_id.items(): tunnel_id_cls = getattr(mod, key) ins.tunnel_id = tunnel_id_cls.from_jsondict(value, decode_string, **additional_args) else: ins = super(BGPPathAttributePmsiTunnel, cls).from_jsondict(dict_, decode_string, **additional_args) return ins class _PmsiTunnelId(StringifyMixin, TypeDisp): @classmethod def parse(cls, tunnel_type, buf): subcls = cls._lookup_type(tunnel_type) return subcls.parser(buf) @_PmsiTunnelId.register_unknown_type() class PmsiTunnelIdUnknown(_PmsiTunnelId): """ Unknown route type specific _PmsiTunnelId """ def __init__(self, value): super(PmsiTunnelIdUnknown, self).__init__() self.value = value @classmethod def parser(cls, buf): return cls(value=buf) def serialize(self): return self.value @_PmsiTunnelId.register_type( BGPPathAttributePmsiTunnel.TYPE_NO_TUNNEL_INFORMATION_PRESENT) class _PmsiTunnelIdNoInformationPresent(_PmsiTunnelId): @classmethod def parser(cls, buf): return None @_PmsiTunnelId.register_type( BGPPathAttributePmsiTunnel.TYPE_INGRESS_REPLICATION) class PmsiTunnelIdIngressReplication(_PmsiTunnelId): # tunnel_endpoint_ip _VALUE_PACK_STR = '!%ds' _TYPE = { 'ascii': [ 'tunnel_endpoint_ip' ] } def __init__(self, tunnel_endpoint_ip): super(PmsiTunnelIdIngressReplication, self).__init__() self.tunnel_endpoint_ip = tunnel_endpoint_ip @classmethod def parser(cls, buf): (tunnel_endpoint_ip, ) = struct.unpack_from( cls._VALUE_PACK_STR % len(buf), bytes(buf)) return cls(tunnel_endpoint_ip=ip.bin_to_text(tunnel_endpoint_ip)) def serialize(self): ip_bin = ip.text_to_bin(self.tunnel_endpoint_ip) return struct.pack(self._VALUE_PACK_STR % len(ip_bin), ip.text_to_bin(self.tunnel_endpoint_ip)) class BGPNLRI(IPAddrPrefix): pass class BGPMessage(packet_base.PacketBase, TypeDisp): """Base class for BGP-4 messages. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. ========================== =============================================== Attribute Description ========================== =============================================== marker Marker field. Ignored when encoding. len Length field. Ignored when encoding. type Type field. one of ``BGP_MSG_*`` constants. ========================== =============================================== """ _HDR_PACK_STR = '!16sHB' # marker, len, type _HDR_LEN = struct.calcsize(_HDR_PACK_STR) _class_prefixes = ['BGP'] def __init__(self, marker=None, len_=None, type_=None): super(BGPMessage, self).__init__() if marker is None: self._marker = _MARKER else: self._marker = marker self.len = len_ if type_ is None: type_ = self._rev_lookup_type(self.__class__) self.type = type_ @classmethod def parser(cls, buf): if len(buf) < cls._HDR_LEN: raise stream_parser.StreamParser.TooSmallException( '%d < %d' % (len(buf), cls._HDR_LEN)) (marker, len_, type_) = struct.unpack_from(cls._HDR_PACK_STR, bytes(buf)) msglen = len_ if len(buf) < msglen: raise stream_parser.StreamParser.TooSmallException( '%d < %d' % (len(buf), msglen)) binmsg = buf[cls._HDR_LEN:msglen] rest = buf[msglen:] subcls = cls._lookup_type(type_) kwargs = subcls.parser(binmsg) return subcls(marker=marker, len_=len_, type_=type_, **kwargs), cls, rest def serialize(self, payload=None, prev=None): # fixup self._marker = _MARKER tail = self.serialize_tail() self.len = self._HDR_LEN + len(tail) hdr = bytearray(struct.pack(self._HDR_PACK_STR, self._marker, self.len, self.type)) return hdr + tail def __len__(self): # XXX destructive buf = self.serialize() return len(buf) @BGPMessage.register_type(BGP_MSG_OPEN) class BGPOpen(BGPMessage): """BGP-4 OPEN Message encoder/decoder class. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. ========================== =============================================== Attribute Description ========================== =============================================== marker Marker field. Ignored when encoding. len Length field. Ignored when encoding. type Type field. version Version field. my_as My Autonomous System field. 2 octet unsigned integer. hold_time Hold Time field. 2 octet unsigned integer. bgp_identifier BGP Identifier field. An IPv4 address. For example, '192.0.2.1' opt_param_len Optional Parameters Length field. Ignored when encoding. opt_param Optional Parameters field. A list of BGPOptParam instances. The default is []. ========================== =============================================== """ _PACK_STR = '!BHH4sB' _MIN_LEN = BGPMessage._HDR_LEN + struct.calcsize(_PACK_STR) _TYPE = { 'ascii': [ 'bgp_identifier' ] } def __init__(self, my_as, bgp_identifier, type_=BGP_MSG_OPEN, opt_param_len=0, opt_param=None, version=_VERSION, hold_time=0, len_=None, marker=None): opt_param = opt_param if opt_param else [] super(BGPOpen, self).__init__(marker=marker, len_=len_, type_=type_) self.version = version self.my_as = my_as self.bgp_identifier = bgp_identifier self.hold_time = hold_time self.opt_param_len = opt_param_len self.opt_param = opt_param @property def opt_param_cap_map(self): cap_map = {} for param in self.opt_param: if param.type == BGP_OPT_CAPABILITY: cap_map[param.cap_code] = param return cap_map def get_opt_param_cap(self, cap_code): return self.opt_param_cap_map.get(cap_code) @classmethod def parser(cls, buf): (version, my_as, hold_time, bgp_identifier, opt_param_len) = struct.unpack_from(cls._PACK_STR, bytes(buf)) rest = buf[struct.calcsize(cls._PACK_STR):] binopts = rest[:opt_param_len] opt_param = [] while binopts: opt, binopts = _OptParam.parser(binopts) opt_param.extend(opt) return { "version": version, "my_as": my_as, "hold_time": hold_time, "bgp_identifier": addrconv.ipv4.bin_to_text(bgp_identifier), "opt_param_len": opt_param_len, "opt_param": opt_param, } def serialize_tail(self): # fixup self.version = _VERSION binopts = bytearray() for opt in self.opt_param: binopts += opt.serialize() self.opt_param_len = len(binopts) msg = bytearray(struct.pack(self._PACK_STR, self.version, self.my_as, self.hold_time, addrconv.ipv4.text_to_bin( self.bgp_identifier), self.opt_param_len)) msg += binopts return msg @BGPMessage.register_type(BGP_MSG_UPDATE) class BGPUpdate(BGPMessage): """BGP-4 UPDATE Message encoder/decoder class. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ========================== =============================================== Attribute Description ========================== =============================================== marker Marker field. Ignored when encoding. len Length field. Ignored when encoding. type Type field. withdrawn_routes_len Withdrawn Routes Length field. Ignored when encoding. withdrawn_routes Withdrawn Routes field. A list of BGPWithdrawnRoute instances. The default is []. total_path_attribute_len Total Path Attribute Length field. Ignored when encoding. path_attributes Path Attributes field. A list of BGPPathAttribute instances. The default is []. nlri Network Layer Reachability Information field. A list of BGPNLRI instances. The default is []. ========================== =============================================== """ _MIN_LEN = BGPMessage._HDR_LEN def __init__(self, type_=BGP_MSG_UPDATE, withdrawn_routes_len=None, withdrawn_routes=None, total_path_attribute_len=None, path_attributes=None, nlri=None, len_=None, marker=None): withdrawn_routes = withdrawn_routes if withdrawn_routes else [] path_attributes = path_attributes if path_attributes else [] nlri = nlri if nlri else [] super(BGPUpdate, self).__init__(marker=marker, len_=len_, type_=type_) self.withdrawn_routes_len = withdrawn_routes_len self.withdrawn_routes = withdrawn_routes self.total_path_attribute_len = total_path_attribute_len self.path_attributes = path_attributes self.nlri = nlri @property def pathattr_map(self): passattr_map = {} for attr in self.path_attributes: passattr_map[attr.type] = attr return passattr_map def get_path_attr(self, attr_name): return self.pathattr_map.get(attr_name) @classmethod def parser(cls, buf): offset = 0 buf = bytes(buf) (withdrawn_routes_len,) = struct.unpack_from('!H', buf, offset) binroutes = buf[offset + 2: offset + 2 + withdrawn_routes_len] offset += 2 + withdrawn_routes_len (total_path_attribute_len,) = struct.unpack_from('!H', buf, offset) binpathattrs = buf[offset + 2: offset + 2 + total_path_attribute_len] binnlri = buf[offset + 2 + total_path_attribute_len:] withdrawn_routes = [] while binroutes: r, binroutes = BGPWithdrawnRoute.parser(binroutes) withdrawn_routes.append(r) path_attributes = [] while binpathattrs: pa, binpathattrs = _PathAttribute.parser(binpathattrs) path_attributes.append(pa) offset += 2 + total_path_attribute_len nlri = [] while binnlri: n, binnlri = BGPNLRI.parser(binnlri) nlri.append(n) return { "withdrawn_routes_len": withdrawn_routes_len, "withdrawn_routes": withdrawn_routes, "total_path_attribute_len": total_path_attribute_len, "path_attributes": path_attributes, "nlri": nlri, } def serialize_tail(self): # fixup binroutes = bytearray() for r in self.withdrawn_routes: binroutes += r.serialize() self.withdrawn_routes_len = len(binroutes) binpathattrs = bytearray() for pa in self.path_attributes: binpathattrs += pa.serialize() self.total_path_attribute_len = len(binpathattrs) binnlri = bytearray() for n in self.nlri: binnlri += n.serialize() msg = bytearray() offset = 0 msg_pack_into('!H', msg, offset, self.withdrawn_routes_len) msg += binroutes offset += 2 + self.withdrawn_routes_len msg_pack_into('!H', msg, offset, self.total_path_attribute_len) msg += binpathattrs offset += 2 + self.total_path_attribute_len msg += binnlri return msg @BGPMessage.register_type(BGP_MSG_KEEPALIVE) class BGPKeepAlive(BGPMessage): """BGP-4 KEEPALIVE Message encoder/decoder class. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. ========================== =============================================== Attribute Description ========================== =============================================== marker Marker field. Ignored when encoding. len Length field. Ignored when encoding. type Type field. ========================== =============================================== """ _MIN_LEN = BGPMessage._HDR_LEN def __init__(self, type_=BGP_MSG_KEEPALIVE, len_=None, marker=None): super(BGPKeepAlive, self).__init__(marker=marker, len_=len_, type_=type_) @classmethod def parser(cls, buf): return {} def serialize_tail(self): return bytearray() @BGPMessage.register_type(BGP_MSG_NOTIFICATION) class BGPNotification(BGPMessage): """BGP-4 NOTIFICATION Message encoder/decoder class. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. ========================== =============================================== Attribute Description ========================== =============================================== marker Marker field. Ignored when encoding. len Length field. Ignored when encoding. type Type field. error_code Error code field. error_subcode Error subcode field. data Data field. ========================== =============================================== """ _PACK_STR = '!BB' _MIN_LEN = BGPMessage._HDR_LEN + struct.calcsize(_PACK_STR) _REASONS = { (1, 1): 'Message Header Error: not synchronised', (1, 2): 'Message Header Error: bad message len', (1, 3): 'Message Header Error: bad message type', (2, 1): 'Open Message Error: unsupported version', (2, 2): 'Open Message Error: bad peer AS', (2, 3): 'Open Message Error: bad BGP identifier', (2, 4): 'Open Message Error: unsupported optional param', (2, 5): 'Open Message Error: authentication failure', (2, 6): 'Open Message Error: unacceptable hold time', (2, 7): 'Open Message Error: Unsupported Capability', (2, 8): 'Open Message Error: Unassigned', (3, 1): 'Update Message Error: malformed attribute list', (3, 2): 'Update Message Error: unrecognized well-known attr', (3, 3): 'Update Message Error: missing well-known attr', (3, 4): 'Update Message Error: attribute flags error', (3, 5): 'Update Message Error: attribute length error', (3, 6): 'Update Message Error: invalid origin attr', (3, 7): 'Update Message Error: as routing loop', (3, 8): 'Update Message Error: invalid next hop attr', (3, 9): 'Update Message Error: optional attribute error', (3, 10): 'Update Message Error: invalid network field', (3, 11): 'Update Message Error: malformed AS_PATH', (4, 1): 'Hold Timer Expired', (5, 1): 'Finite State Machine Error', (6, 1): 'Cease: Maximum Number of Prefixes Reached', (6, 2): 'Cease: Administrative Shutdown', (6, 3): 'Cease: Peer De-configured', (6, 4): 'Cease: Administrative Reset', (6, 5): 'Cease: Connection Rejected', (6, 6): 'Cease: Other Configuration Change', (6, 7): 'Cease: Connection Collision Resolution', (6, 8): 'Cease: Out of Resources', } def __init__(self, error_code, error_subcode, data=b'', type_=BGP_MSG_NOTIFICATION, len_=None, marker=None): super(BGPNotification, self).__init__(marker=marker, len_=len_, type_=type_) self.error_code = error_code self.error_subcode = error_subcode self.data = data @classmethod def parser(cls, buf): (error_code, error_subcode,) = struct.unpack_from(cls._PACK_STR, bytes(buf)) data = bytes(buf[2:]) return { "error_code": error_code, "error_subcode": error_subcode, "data": data, } def serialize_tail(self): msg = bytearray(struct.pack(self._PACK_STR, self.error_code, self.error_subcode)) msg += self.data return msg @property def reason(self): return self._REASONS.get((self.error_code, self.error_subcode)) @BGPMessage.register_type(BGP_MSG_ROUTE_REFRESH) class BGPRouteRefresh(BGPMessage): """BGP-4 ROUTE REFRESH Message (RFC 2918) encoder/decoder class. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. ========================== =============================================== Attribute Description ========================== =============================================== marker Marker field. Ignored when encoding. len Length field. Ignored when encoding. type Type field. afi Address Family Identifier safi Subsequent Address Family Identifier ========================== =============================================== """ _PACK_STR = '!HBB' _MIN_LEN = BGPMessage._HDR_LEN + struct.calcsize(_PACK_STR) def __init__(self, afi, safi, demarcation=0, type_=BGP_MSG_ROUTE_REFRESH, len_=None, marker=None): super(BGPRouteRefresh, self).__init__(marker=marker, len_=len_, type_=type_) self.afi = afi self.safi = safi self.demarcation = demarcation self.eor_sent = False @classmethod def parser(cls, buf): (afi, demarcation, safi,) = struct.unpack_from(cls._PACK_STR, bytes(buf)) return { "afi": afi, "safi": safi, "demarcation": demarcation, } def serialize_tail(self): return bytearray(struct.pack(self._PACK_STR, self.afi, self.demarcation, self.safi)) class StreamParser(stream_parser.StreamParser): """Streaming parser for BGP-4 messages. This is a subclass of os_ken.lib.packet.stream_parser.StreamParser. Its parse method returns a list of BGPMessage subclass instances. """ def try_parse(self, data): msg, _, rest = BGPMessage.parser(data) return msg, rest ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/packet/bmp.py0000664000175000017500000007175200000000000017450 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone 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. """ BGP Monitoring Protocol draft-ietf-grow-bmp-07 """ import struct from os_ken.lib import addrconv from os_ken.lib.packet import packet_base from os_ken.lib.packet import stream_parser from os_ken.lib.packet.bgp import BGPMessage from os_ken.lib.type_desc import TypeDisp VERSION = 3 BMP_MSG_ROUTE_MONITORING = 0 BMP_MSG_STATISTICS_REPORT = 1 BMP_MSG_PEER_DOWN_NOTIFICATION = 2 BMP_MSG_PEER_UP_NOTIFICATION = 3 BMP_MSG_INITIATION = 4 BMP_MSG_TERMINATION = 5 BMP_PEER_TYPE_GLOBAL = 0 BMP_PEER_TYPE_L3VPN = 1 BMP_INIT_TYPE_STRING = 0 BMP_INIT_TYPE_SYSDESCR = 1 BMP_INIT_TYPE_SYSNAME = 2 BMP_TERM_TYPE_STRING = 0 BMP_TERM_TYPE_REASON = 1 BMP_TERM_REASON_ADMIN = 0 BMP_TERM_REASON_UNSPEC = 1 BMP_TERM_REASON_OUT_OF_RESOURCE = 2 BMP_TERM_REASON_REDUNDANT_CONNECTION = 3 BMP_STAT_TYPE_REJECTED = 0 BMP_STAT_TYPE_DUPLICATE_PREFIX = 1 BMP_STAT_TYPE_DUPLICATE_WITHDRAW = 2 BMP_STAT_TYPE_INV_UPDATE_DUE_TO_CLUSTER_LIST_LOOP = 3 BMP_STAT_TYPE_INV_UPDATE_DUE_TO_AS_PATH_LOOP = 4 BMP_STAT_TYPE_INV_UPDATE_DUE_TO_ORIGINATOR_ID = 5 BMP_STAT_TYPE_INV_UPDATE_DUE_TO_AS_CONFED_LOOP = 6 BMP_STAT_TYPE_ADJ_RIB_IN = 7 BMP_STAT_TYPE_LOC_RIB = 8 BMP_STAT_TYPE_ADJ_RIB_OUT = 14 BMP_STAT_TYPE_EXPORT_RIB = 15 BMP_PEER_DOWN_REASON_UNKNOWN = 0 BMP_PEER_DOWN_REASON_LOCAL_BGP_NOTIFICATION = 1 BMP_PEER_DOWN_REASON_LOCAL_NO_NOTIFICATION = 2 BMP_PEER_DOWN_REASON_REMOTE_BGP_NOTIFICATION = 3 BMP_PEER_DOWN_REASON_REMOTE_NO_NOTIFICATION = 4 class BMPMessage(packet_base.PacketBase, TypeDisp): r"""Base class for BGP Monitoring Protocol messages. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. ========================== =============================================== Attribute Description ========================== =============================================== version Version. this packet lib defines BMP ver. 3 len Length field. Ignored when encoding. type Type field. one of BMP\_MSG\_ constants. ========================== =============================================== """ _HDR_PACK_STR = '!BIB' # version, padding, len, type, padding _HDR_LEN = struct.calcsize(_HDR_PACK_STR) def __init__(self, type_, len_=None, version=VERSION): self.version = version self.len = len_ self.type = type_ @classmethod def parse_header(cls, buf): if len(buf) < cls._HDR_LEN: raise stream_parser.StreamParser.TooSmallException( '%d < %d' % (len(buf), cls._HDR_LEN)) (version, len_, type_) = struct.unpack_from(cls._HDR_PACK_STR, bytes(buf)) return version, len_, type_ @classmethod def parser(cls, buf): version, msglen, type_ = cls.parse_header(buf) if version != VERSION: raise ValueError("not supportted bmp version: %d" % version) if len(buf) < msglen: raise stream_parser.StreamParser.TooSmallException( '%d < %d' % (len(buf), msglen)) binmsg = buf[cls._HDR_LEN:msglen] rest = buf[msglen:] subcls = cls._lookup_type(type_) if subcls == cls._UNKNOWN_TYPE: raise ValueError("unknown bmp type: %d" % type_) kwargs = subcls.parser(binmsg) return subcls(len_=msglen, type_=type_, version=version, **kwargs), rest def serialize(self): # fixup tail = self.serialize_tail() self.len = self._HDR_LEN + len(tail) hdr = bytearray(struct.pack(self._HDR_PACK_STR, self.version, self.len, self.type)) return hdr + tail def __len__(self): # XXX destructive buf = self.serialize() return len(buf) class BMPPeerMessage(BMPMessage): r"""BMP Message with Per Peer Header Following BMP Messages contain Per Peer Header after Common BMP Header. - BMP_MSG_TYPE_ROUTE_MONITRING - BMP_MSG_TYPE_STATISTICS_REPORT - BMP_MSG_PEER_UP_NOTIFICATION ========================== =============================================== Attribute Description ========================== =============================================== version Version. this packet lib defines BMP ver. 3 len Length field. Ignored when encoding. type Type field. one of BMP\_MSG\_ constants. peer_type The type of the peer. is_post_policy Indicate the message reflects the post-policy is_adj_rib_out Indicate the message reflects Adj-RIB-Out (defaults to Adj-RIB-In) peer_distinguisher Use for L3VPN router which can have multiple instance. peer_address The remote IP address associated with the TCP session. peer_as The Autonomous System number of the peer. peer_bgp_id The BGP Identifier of the peer timestamp The time when the encapsulated routes were received. ========================== =============================================== """ _PEER_HDR_PACK_STR = '!BBQ16sI4sII' _TYPE = { 'ascii': [ 'peer_address', 'peer_bgp_id' ] } def __init__(self, peer_type, is_post_policy, peer_distinguisher, peer_address, peer_as, peer_bgp_id, timestamp, version=VERSION, type_=None, len_=None, is_adj_rib_out=False): super(BMPPeerMessage, self).__init__(version=version, len_=len_, type_=type_) self.peer_type = peer_type self.is_post_policy = is_post_policy self.is_adj_rib_out = is_adj_rib_out self.peer_distinguisher = peer_distinguisher self.peer_address = peer_address self.peer_as = peer_as self.peer_bgp_id = peer_bgp_id self.timestamp = timestamp @classmethod def parser(cls, buf): (peer_type, peer_flags, peer_distinguisher, peer_address, peer_as, peer_bgp_id, timestamp1, timestamp2) = struct.unpack_from(cls._PEER_HDR_PACK_STR, bytes(buf)) rest = buf[struct.calcsize(cls._PEER_HDR_PACK_STR):] if peer_flags & (1 << 4): is_adj_rib_out = True else: is_adj_rib_out = False if peer_flags & (1 << 6): is_post_policy = True else: is_post_policy = False if peer_flags & (1 << 7): peer_address = addrconv.ipv6.bin_to_text(peer_address) else: peer_address = addrconv.ipv4.bin_to_text(peer_address[-4:]) peer_bgp_id = addrconv.ipv4.bin_to_text(peer_bgp_id) timestamp = float(timestamp1) + timestamp2 * (10 ** -6) return { "peer_type": peer_type, "is_post_policy": is_post_policy, "peer_distinguisher": peer_distinguisher, "peer_address": peer_address, "peer_as": peer_as, "peer_bgp_id": peer_bgp_id, "timestamp": timestamp, "is_adj_rib_out": is_adj_rib_out, }, rest def serialize_tail(self): flags = 0 if self.is_adj_rib_out: flags |= (1 << 4) if self.is_post_policy: flags |= (1 << 6) if ':' in self.peer_address: flags |= (1 << 7) peer_address = addrconv.ipv6.text_to_bin(self.peer_address) else: peer_address = struct.pack( '!12x4s', addrconv.ipv4.text_to_bin(self.peer_address)) peer_bgp_id = addrconv.ipv4.text_to_bin(self.peer_bgp_id) t1, t2 = [int(t) for t in ("%.6f" % self.timestamp).split('.')] msg = bytearray(struct.pack(self._PEER_HDR_PACK_STR, self.peer_type, flags, self.peer_distinguisher, peer_address, self.peer_as, peer_bgp_id, t1, t2)) return msg @BMPMessage.register_type(BMP_MSG_ROUTE_MONITORING) class BMPRouteMonitoring(BMPPeerMessage): r"""BMP Route Monitoring Message ========================== =============================================== Attribute Description ========================== =============================================== version Version. this packet lib defines BMP ver. 3 len Length field. Ignored when encoding. type Type field. one of BMP\_MSG\_ constants. peer_type The type of the peer. peer_flags Provide more information about the peer. peer_distinguisher Use for L3VPN router which can have multiple instance. peer_address The remote IP address associated with the TCP session. peer_as The Autonomous System number of the peer. peer_bgp_id The BGP Identifier of the peer timestamp The time when the encapsulated routes were received. bgp_update BGP Update PDU ========================== =============================================== """ def __init__(self, bgp_update, peer_type, is_post_policy, peer_distinguisher, peer_address, peer_as, peer_bgp_id, timestamp, version=VERSION, type_=BMP_MSG_ROUTE_MONITORING, len_=None, is_adj_rib_out=False): super(BMPRouteMonitoring, self).__init__(peer_type=peer_type, is_post_policy=is_post_policy, peer_distinguisher=peer_distinguisher, peer_address=peer_address, peer_as=peer_as, peer_bgp_id=peer_bgp_id, timestamp=timestamp, len_=len_, type_=type_, version=version, is_adj_rib_out=is_adj_rib_out) self.bgp_update = bgp_update @classmethod def parser(cls, buf): kwargs, buf = super(BMPRouteMonitoring, cls).parser(buf) bgp_update, _, buf = BGPMessage.parser(buf) kwargs['bgp_update'] = bgp_update return kwargs def serialize_tail(self): msg = super(BMPRouteMonitoring, self).serialize_tail() msg += self.bgp_update.serialize() return msg @BMPMessage.register_type(BMP_MSG_STATISTICS_REPORT) class BMPStatisticsReport(BMPPeerMessage): r"""BMP Statistics Report Message ========================== =============================================== Attribute Description ========================== =============================================== version Version. this packet lib defines BMP ver. 3 len Length field. Ignored when encoding. type Type field. one of BMP\_MSG\_ constants. peer_type The type of the peer. peer_flags Provide more information about the peer. peer_distinguisher Use for L3VPN router which can have multiple instance. peer_address The remote IP address associated with the TCP session. peer_as The Autonomous System number of the peer. peer_bgp_id The BGP Identifier of the peer timestamp The time when the encapsulated routes were received. stats Statistics (one or more stats encoded as a TLV) ========================== =============================================== """ _TLV_PACK_STR = '!HH' _MIN_LEN = struct.calcsize(_TLV_PACK_STR) def __init__(self, stats, peer_type, is_post_policy, peer_distinguisher, peer_address, peer_as, peer_bgp_id, timestamp, version=VERSION, type_=BMP_MSG_STATISTICS_REPORT, len_=None, is_adj_rib_out=False): super(BMPStatisticsReport, self).__init__(peer_type=peer_type, is_post_policy=is_post_policy, peer_distinguisher=peer_distinguisher, peer_address=peer_address, peer_as=peer_as, peer_bgp_id=peer_bgp_id, timestamp=timestamp, len_=len_, type_=type_, version=version, is_adj_rib_out=is_adj_rib_out) self.stats = stats @classmethod def parser(cls, buf): kwargs, rest = super(BMPStatisticsReport, cls).parser(buf) stats_count, = struct.unpack_from('!I', bytes(rest)) buf = rest[struct.calcsize('!I'):] stats = [] while len(buf): if len(buf) < cls._MIN_LEN: raise stream_parser.StreamParser.TooSmallException( '%d < %d' % (len(buf), cls._MIN_LEN)) (type_, len_) = struct.unpack_from(cls._TLV_PACK_STR, bytes(buf)) if len(buf) < (cls._MIN_LEN + len_): raise stream_parser.StreamParser.TooSmallException( '%d < %d' % (len(buf), cls._MIN_LEN + len_)) value = buf[cls._MIN_LEN:cls._MIN_LEN + len_] if type_ == BMP_STAT_TYPE_REJECTED or \ type_ == BMP_STAT_TYPE_DUPLICATE_PREFIX or \ type_ == BMP_STAT_TYPE_DUPLICATE_WITHDRAW or \ type_ == BMP_STAT_TYPE_INV_UPDATE_DUE_TO_CLUSTER_LIST_LOOP or \ type_ == BMP_STAT_TYPE_INV_UPDATE_DUE_TO_AS_PATH_LOOP or \ type_ == BMP_STAT_TYPE_INV_UPDATE_DUE_TO_ORIGINATOR_ID or \ type_ == BMP_STAT_TYPE_INV_UPDATE_DUE_TO_AS_CONFED_LOOP: value, = struct.unpack_from('!I', bytes(value)) elif type_ == BMP_STAT_TYPE_ADJ_RIB_IN or \ type_ == BMP_STAT_TYPE_LOC_RIB or \ type_ == BMP_STAT_TYPE_ADJ_RIB_OUT or \ type_ == BMP_STAT_TYPE_EXPORT_RIB: value, = struct.unpack_from('!Q', bytes(value)) buf = buf[cls._MIN_LEN + len_:] stats.append({'type': type_, 'len': len_, 'value': value}) kwargs['stats'] = stats return kwargs def serialize_tail(self): msg = super(BMPStatisticsReport, self).serialize_tail() stats_count = len(self.stats) msg += bytearray(struct.pack('!I', stats_count)) for v in self.stats: t = v['type'] if t == BMP_STAT_TYPE_REJECTED or \ t == BMP_STAT_TYPE_DUPLICATE_PREFIX or \ t == BMP_STAT_TYPE_DUPLICATE_WITHDRAW or \ t == BMP_STAT_TYPE_INV_UPDATE_DUE_TO_CLUSTER_LIST_LOOP or \ t == BMP_STAT_TYPE_INV_UPDATE_DUE_TO_AS_PATH_LOOP or \ t == BMP_STAT_TYPE_INV_UPDATE_DUE_TO_ORIGINATOR_ID or \ t == BMP_STAT_TYPE_INV_UPDATE_DUE_TO_AS_CONFED_LOOP: valuepackstr = 'I' elif t == BMP_STAT_TYPE_ADJ_RIB_IN or \ t == BMP_STAT_TYPE_LOC_RIB or \ t == BMP_STAT_TYPE_ADJ_RIB_OUT or \ t == BMP_STAT_TYPE_EXPORT_RIB: valuepackstr = 'Q' else: continue v['len'] = struct.calcsize(valuepackstr) msg += bytearray(struct.pack(self._TLV_PACK_STR + valuepackstr, t, v['len'], v['value'])) return msg @BMPMessage.register_type(BMP_MSG_PEER_DOWN_NOTIFICATION) class BMPPeerDownNotification(BMPPeerMessage): r"""BMP Peer Down Notification Message ========================== =============================================== Attribute Description ========================== =============================================== version Version. this packet lib defines BMP ver. 3 len Length field. Ignored when encoding. type Type field. one of BMP\_MSG\_ constants. reason Reason indicates why the session was closed. data vary by the reason. ========================== =============================================== """ def __init__(self, reason, data, peer_type, is_post_policy, peer_distinguisher, peer_address, peer_as, peer_bgp_id, timestamp, version=VERSION, type_=BMP_MSG_PEER_DOWN_NOTIFICATION, len_=None, is_adj_rib_out=False): super(BMPPeerDownNotification, self).__init__(peer_type=peer_type, is_post_policy=is_post_policy, peer_distinguisher=peer_distinguisher, peer_address=peer_address, peer_as=peer_as, peer_bgp_id=peer_bgp_id, timestamp=timestamp, len_=len_, type_=type_, version=version, is_adj_rib_out=is_adj_rib_out) self.reason = reason self.data = data @classmethod def parser(cls, buf): kwargs, buf = super(BMPPeerDownNotification, cls).parser(buf) reason, = struct.unpack_from('!B', bytes(buf)) buf = buf[struct.calcsize('!B'):] if reason == BMP_PEER_DOWN_REASON_LOCAL_BGP_NOTIFICATION: data, _, rest = BGPMessage.parser(buf) elif reason == BMP_PEER_DOWN_REASON_LOCAL_NO_NOTIFICATION: data = struct.unpack_from('!H', bytes(buf)) elif reason == BMP_PEER_DOWN_REASON_REMOTE_BGP_NOTIFICATION: data, _, rest = BGPMessage.parser(buf) elif reason == BMP_PEER_DOWN_REASON_REMOTE_NO_NOTIFICATION: data = None else: reason = BMP_PEER_DOWN_REASON_UNKNOWN data = buf kwargs['reason'] = reason kwargs['data'] = data return kwargs def serialize_tail(self): msg = super(BMPPeerDownNotification, self).serialize_tail() msg += struct.pack('!B', self.reason) if self.reason == BMP_PEER_DOWN_REASON_LOCAL_BGP_NOTIFICATION: msg += self.data.serialize() elif self.reason == BMP_PEER_DOWN_REASON_LOCAL_NO_NOTIFICATION: msg += struct.pack('!H', self.data) elif self.reason == BMP_PEER_DOWN_REASON_REMOTE_BGP_NOTIFICATION: msg += self.data.serialize() elif self.reason == BMP_PEER_DOWN_REASON_UNKNOWN: msg += str(self.data) return msg @BMPMessage.register_type(BMP_MSG_PEER_UP_NOTIFICATION) class BMPPeerUpNotification(BMPPeerMessage): r"""BMP Peer Up Notification Message ========================== =============================================== Attribute Description ========================== =============================================== version Version. this packet lib defines BMP ver. 3 len Length field. Ignored when encoding. type Type field. one of BMP\_MSG\_ constants. peer_type The type of the peer. peer_flags Provide more information about the peer. peer_distinguisher Use for L3VPN router which can have multiple instance. peer_address The remote IP address associated with the TCP session. peer_as The Autonomous System number of the peer. peer_bgp_id The BGP Identifier of the peer timestamp The time when the encapsulated routes were received. local_address The local IP address associated with the peering TCP session. local_port The local port number associated with the peering TCP session. remote_port The remote port number associated with the peering TCP session. sent_open_message The full OPEN message transmitted by the monitored router to its peer. received_open_message The full OPEN message received by the monitored router from its peer. ========================== =============================================== """ _PACK_STR = '!16sHH' _MIN_LEN = struct.calcsize(_PACK_STR) def __init__(self, local_address, local_port, remote_port, sent_open_message, received_open_message, peer_type, is_post_policy, peer_distinguisher, peer_address, peer_as, peer_bgp_id, timestamp, version=VERSION, type_=BMP_MSG_PEER_UP_NOTIFICATION, len_=None, is_adj_rib_out=False): super(BMPPeerUpNotification, self).__init__(peer_type=peer_type, is_post_policy=is_post_policy, peer_distinguisher=peer_distinguisher, peer_address=peer_address, peer_as=peer_as, peer_bgp_id=peer_bgp_id, timestamp=timestamp, len_=len_, type_=type_, version=version, is_adj_rib_out=is_adj_rib_out) self.local_address = local_address self.local_port = local_port self.remote_port = remote_port self.sent_open_message = sent_open_message self.received_open_message = received_open_message @classmethod def parser(cls, buf): kwargs, rest = super(BMPPeerUpNotification, cls).parser(buf) (local_address, local_port, remote_port) = struct.unpack_from(cls._PACK_STR, bytes(rest)) if '.' in kwargs['peer_address']: local_address = addrconv.ipv4.bin_to_text(local_address[-4:]) elif ':' in kwargs['peer_address']: local_address = addrconv.ipv6.bin_to_text(local_address) else: raise ValueError("invalid local_address: %s" % local_address) kwargs['local_address'] = local_address kwargs['local_port'] = local_port kwargs['remote_port'] = remote_port rest = rest[cls._MIN_LEN:] sent_open_msg, _, rest = BGPMessage.parser(rest) received_open_msg, _, rest = BGPMessage.parser(rest) kwargs['sent_open_message'] = sent_open_msg kwargs['received_open_message'] = received_open_msg return kwargs def serialize_tail(self): msg = super(BMPPeerUpNotification, self).serialize_tail() if '.' in self.local_address: local_address = struct.pack( '!12x4s', addrconv.ipv4.text_to_bin(self.local_address)) elif ':' in self.local_address: local_address = addrconv.ipv6.text_to_bin(self.local_address) else: raise ValueError("invalid local_address: %s" % self.local_address) msg += struct.pack(self._PACK_STR, local_address, self.local_port, self.remote_port) msg += self.sent_open_message.serialize() msg += self.received_open_message.serialize() return msg @BMPMessage.register_type(BMP_MSG_INITIATION) class BMPInitiation(BMPMessage): r"""BMP Initiation Message ========================== =============================================== Attribute Description ========================== =============================================== version Version. this packet lib defines BMP ver. 3 len Length field. Ignored when encoding. type Type field. one of BMP\_MSG\_ constants. info One or more piece of information encoded as a TLV ========================== =============================================== """ _TLV_PACK_STR = '!HH' _MIN_LEN = struct.calcsize(_TLV_PACK_STR) def __init__(self, info, type_=BMP_MSG_INITIATION, len_=None, version=VERSION): super(BMPInitiation, self).__init__(type_, len_, version) self.info = info @classmethod def parser(cls, buf): info = [] while len(buf): if len(buf) < cls._MIN_LEN: raise stream_parser.StreamParser.TooSmallException( '%d < %d' % (len(buf), cls._MIN_LEN)) (type_, len_) = struct.unpack_from(cls._TLV_PACK_STR, bytes(buf)) if len(buf) < (cls._MIN_LEN + len_): raise stream_parser.StreamParser.TooSmallException( '%d < %d' % (len(buf), cls._MIN_LEN + len_)) value = buf[cls._MIN_LEN:cls._MIN_LEN + len_] if type_ == BMP_INIT_TYPE_STRING: value = value.decode('utf-8') buf = buf[cls._MIN_LEN + len_:] info.append({'type': type_, 'len': len_, 'value': value}) return {'info': info} def serialize_tail(self): msg = bytearray() for v in self.info: if v['type'] == BMP_INIT_TYPE_STRING: value = v['value'].encode('utf-8') else: value = v['value'] v['len'] = len(value) msg += struct.pack(self._TLV_PACK_STR, v['type'], v['len']) msg += value return msg @BMPMessage.register_type(BMP_MSG_TERMINATION) class BMPTermination(BMPMessage): r"""BMP Termination Message ========================== =============================================== Attribute Description ========================== =============================================== version Version. this packet lib defines BMP ver. 3 len Length field. Ignored when encoding. type Type field. one of BMP\_MSG\_ constants. info One or more piece of information encoded as a TLV ========================== =============================================== """ _TLV_PACK_STR = '!HH' _MIN_LEN = struct.calcsize(_TLV_PACK_STR) def __init__(self, info, type_=BMP_MSG_TERMINATION, len_=None, version=VERSION): super(BMPTermination, self).__init__(type_, len_, version) self.info = info @classmethod def parser(cls, buf): info = [] while len(buf): if len(buf) < cls._MIN_LEN: raise stream_parser.StreamParser.TooSmallException( '%d < %d' % (len(buf), cls._MIN_LEN)) (type_, len_) = struct.unpack_from(cls._TLV_PACK_STR, bytes(buf)) if len(buf) < (cls._MIN_LEN + len_): raise stream_parser.StreamParser.TooSmallException( '%d < %d' % (len(buf), cls._MIN_LEN + len_)) value = buf[cls._MIN_LEN:cls._MIN_LEN + len_] if type_ == BMP_TERM_TYPE_STRING: value = value.decode('utf-8') elif type_ == BMP_TERM_TYPE_REASON: value, = struct.unpack_from('!H', bytes(value)) buf = buf[cls._MIN_LEN + len_:] info.append({'type': type_, 'len': len_, 'value': value}) return {'info': info} def serialize_tail(self): msg = bytearray() for v in self.info: if v['type'] == BMP_TERM_TYPE_STRING: value = v['value'].encode('utf-8') elif v['type'] == BMP_TERM_TYPE_REASON: value = struct.pack('!H', v['value']) v['len'] = len(value) msg += struct.pack(self._TLV_PACK_STR, v['type'], v['len']) msg += value return msg ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/packet/bpdu.py0000664000175000017500000005131300000000000017613 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone 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. """ Bridge Protocol Data Unit(BPDU, IEEE 802.1D) parser/serializer http://standards.ieee.org/getieee802/download/802.1D-2004.pdf Configuration BPDUs format +----------------------------------------------+---------+ | Structure | Octet | +==============================================+=========+ | Protocol Identifier = 0000 0000 0000 0000 | 1 - 2 | | | | +----------------------------------------------+---------+ | Protocol Version Identifier = 0000 0000 | 3 | +----------------------------------------------+---------+ | BPDU Type = 0000 0000 | 4 | +----------------------------------------------+---------+ | Flags | 5 | +----------------------------------------------+---------+ | Root Identifier | 6 - 13 | | include - priority | | | system ID extension | | | MAC address | | +----------------------------------------------+---------+ | Root Path Cost | 14 - 17 | | | | +----------------------------------------------+---------+ | Bridge Identifier | 18 - 25 | | include - priority | | | system ID extension | | | MAC address | | +----------------------------------------------+---------+ | Port Identifier | 26 - 27 | | include - priority | | | port number | | +----------------------------------------------+---------+ | Message Age | 28 - 29 | | | | +----------------------------------------------+---------+ | Max Age | 30 - 31 | | | | +----------------------------------------------+---------+ | Hello Time | 32 - 33 | | | | +----------------------------------------------+---------+ | Forward Delay | 34 - 35 | | | | +----------------------------------------------+---------+ Topology Change NotificationBPDUs format +----------------------------------------------+---------+ | Structure | Octet | +==============================================+=========+ | Protocol Identifier = 0000 0000 0000 0000 | 1 - 2 | | | | +----------------------------------------------+---------+ | Protocol Version Identifier = 0000 0000 | 3 | +----------------------------------------------+---------+ | BPDU Type = 1000 0000 | 4 | +----------------------------------------------+---------+ Rapid Spanning Tree BPDUs(RST BPDUs) format +----------------------------------------------+---------+ | Structure | Octet | +==============================================+=========+ | Protocol Identifier = 0000 0000 0000 0000 | 1 - 2 | | | | +----------------------------------------------+---------+ | Protocol Version Identifier = 0000 0010 | 3 | +----------------------------------------------+---------+ | BPDU Type = 0000 0010 | 4 | +----------------------------------------------+---------+ | Flags | 5 | +----------------------------------------------+---------+ | Root Identifier | 6 - 13 | | include - priority | | | system ID extension | | | MAC address | | +----------------------------------------------+---------+ | Root Path Cost | 14 - 17 | | | | +----------------------------------------------+---------+ | Bridge Identifier | 18 - 25 | | include - priority | | | system ID extension | | | MAC address | | +----------------------------------------------+---------+ | Port Identifier | 26 - 27 | | include - priority | | | port number | | +----------------------------------------------+---------+ | Message Age | 28 - 29 | | | | +----------------------------------------------+---------+ | Max Age | 30 - 31 | | | | +----------------------------------------------+---------+ | Hello Time | 32 - 33 | | | | +----------------------------------------------+---------+ | Forward Delay | 34 - 35 | | | | +----------------------------------------------+---------+ | Version 1 Length = 0000 0000 | 36 | +----------------------------------------------+---------+ """ import binascii import struct from . import packet_base from os_ken.lib import addrconv # BPDU destination BRIDGE_GROUP_ADDRESS = '01:80:c2:00:00:00' PROTOCOL_IDENTIFIER = 0 PROTOCOLVERSION_ID_BPDU = 0 PROTOCOLVERSION_ID_RSTBPDU = 2 TYPE_CONFIG_BPDU = 0 TYPE_TOPOLOGY_CHANGE_BPDU = 128 TYPE_RSTBPDU = 2 DEFAULT_BRIDGE_PRIORITY = 32768 DEFAULT_PORT_PRIORITY = 128 PORT_PATH_COST_100KB = 200000000 PORT_PATH_COST_1MB = 20000000 PORT_PATH_COST_10MB = 2000000 PORT_PATH_COST_100MB = 200000 PORT_PATH_COST_1GB = 20000 PORT_PATH_COST_10GB = 2000 PORT_PATH_COST_100GB = 200 PORT_PATH_COST_1TB = 20 PORT_PATH_COST_10TB = 2 DEFAULT_MAX_AGE = 20 DEFAULT_HELLO_TIME = 2 DEFAULT_FORWARD_DELAY = 15 VERSION_1_LENGTH = 0 class bpdu(packet_base.PacketBase): """Bridge Protocol Data Unit(BPDU) header encoder/decoder base class. """ _PACK_STR = '!HBB' _PACK_LEN = struct.calcsize(_PACK_STR) _BPDU_TYPES = {} _MIN_LEN = _PACK_LEN @staticmethod def register_bpdu_type(sub_cls): bpdu._BPDU_TYPES.setdefault(sub_cls.VERSION_ID, {}) bpdu._BPDU_TYPES[sub_cls.VERSION_ID][sub_cls.BPDU_TYPE] = sub_cls return sub_cls def __init__(self): super(bpdu, self).__init__() assert hasattr(self, 'VERSION_ID') assert hasattr(self, 'BPDU_TYPE') self._protocol_id = PROTOCOL_IDENTIFIER self._version_id = self.VERSION_ID self._bpdu_type = self.BPDU_TYPE if hasattr(self, 'check_parameters'): self.check_parameters() @classmethod def parser(cls, buf): assert len(buf) >= cls._PACK_LEN (protocol_id, version_id, bpdu_type) = struct.unpack_from(cls._PACK_STR, buf) assert protocol_id == PROTOCOL_IDENTIFIER if (version_id in cls._BPDU_TYPES and bpdu_type in cls._BPDU_TYPES[version_id]): bpdu_cls = cls._BPDU_TYPES[version_id][bpdu_type] assert len(buf[cls._PACK_LEN:]) >= bpdu_cls.PACK_LEN return bpdu_cls.parser(buf[cls._PACK_LEN:]) else: # Unknown bpdu version/type. return buf, None, None def serialize(self, payload, prev): return struct.pack(bpdu._PACK_STR, self._protocol_id, self._version_id, self._bpdu_type) @bpdu.register_bpdu_type class ConfigurationBPDUs(bpdu): """Configuration BPDUs(IEEE 802.1D) header encoder/decoder class. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. ========================== =============================================== Attribute Description ========================== =============================================== flags | Bit 1: Topology Change flag | Bits 2 through 7: unused and take the value 0 | Bit 8: Topology Change Acknowledgment flag root_priority Root Identifier priority \ set 0-61440 in steps of 4096 root_system_id_extension Root Identifier system ID extension root_mac_address Root Identifier MAC address root_path_cost Root Path Cost bridge_priority Bridge Identifier priority \ set 0-61440 in steps of 4096 bridge_system_id_extension Bridge Identifier system ID extension bridge_mac_address Bridge Identifier MAC address port_priority Port Identifier priority \ set 0-240 in steps of 16 port_number Port Identifier number message_age Message Age timer value max_age Max Age timer value hello_time Hello Time timer value forward_delay Forward Delay timer value ========================== =============================================== """ VERSION_ID = PROTOCOLVERSION_ID_BPDU BPDU_TYPE = TYPE_CONFIG_BPDU _PACK_STR = '!BQIQHHHHH' PACK_LEN = struct.calcsize(_PACK_STR) _TYPE = { 'ascii': [ 'root_mac_address', "bridge_mac_address" ] } _BRIDGE_PRIORITY_STEP = 4096 _PORT_PRIORITY_STEP = 16 _TIMER_STEP = float(1) / 256 def __init__(self, flags=0, root_priority=DEFAULT_BRIDGE_PRIORITY, root_system_id_extension=0, root_mac_address='00:00:00:00:00:00', root_path_cost=0, bridge_priority=DEFAULT_BRIDGE_PRIORITY, bridge_system_id_extension=0, bridge_mac_address='00:00:00:00:00:00', port_priority=DEFAULT_PORT_PRIORITY, port_number=0, message_age=0, max_age=DEFAULT_MAX_AGE, hello_time=DEFAULT_HELLO_TIME, forward_delay=DEFAULT_FORWARD_DELAY): self.flags = flags self.root_priority = root_priority self.root_system_id_extension = root_system_id_extension self.root_mac_address = root_mac_address self.root_path_cost = root_path_cost self.bridge_priority = bridge_priority self.bridge_system_id_extension = bridge_system_id_extension self.bridge_mac_address = bridge_mac_address self.port_priority = port_priority self.port_number = port_number self.message_age = message_age self.max_age = max_age self.hello_time = hello_time self.forward_delay = forward_delay super(ConfigurationBPDUs, self).__init__() def check_parameters(self): assert (self.flags >> 1 & 0b111111) == 0 assert self.root_priority % self._BRIDGE_PRIORITY_STEP == 0 assert self.bridge_priority % self._BRIDGE_PRIORITY_STEP == 0 assert self.port_priority % self._PORT_PRIORITY_STEP == 0 assert self.message_age % self._TIMER_STEP == 0 assert self.max_age % self._TIMER_STEP == 0 assert self.hello_time % self._TIMER_STEP == 0 assert self.forward_delay % self._TIMER_STEP == 0 @classmethod def parser(cls, buf): (flags, root_id, root_path_cost, bridge_id, port_id, message_age, max_age, hello_time, forward_delay) = struct.unpack_from(ConfigurationBPDUs._PACK_STR, buf) (root_priority, root_system_id_extension, root_mac_address) = cls._decode_bridge_id(root_id) (bridge_priority, bridge_system_id_extension, bridge_mac_address) = cls._decode_bridge_id(bridge_id) (port_priority, port_number) = cls._decode_port_id(port_id) return (cls(flags, root_priority, root_system_id_extension, root_mac_address, root_path_cost, bridge_priority, bridge_system_id_extension, bridge_mac_address, port_priority, port_number, cls._decode_timer(message_age), cls._decode_timer(max_age), cls._decode_timer(hello_time), cls._decode_timer(forward_delay)), None, buf[ConfigurationBPDUs.PACK_LEN:]) def serialize(self, payload, prev): base = super(ConfigurationBPDUs, self).serialize(payload, prev) root_id = self.encode_bridge_id(self.root_priority, self.root_system_id_extension, self.root_mac_address) bridge_id = self.encode_bridge_id(self.bridge_priority, self.bridge_system_id_extension, self.bridge_mac_address) port_id = self.encode_port_id(self.port_priority, self.port_number) sub = struct.pack(ConfigurationBPDUs._PACK_STR, self.flags, root_id, self.root_path_cost, bridge_id, port_id, self._encode_timer(self.message_age), self._encode_timer(self.max_age), self._encode_timer(self.hello_time), self._encode_timer(self.forward_delay)) return base + sub @staticmethod def _decode_bridge_id(bridge_id): priority = (bridge_id >> 48) & 0xf000 system_id_extension = (bridge_id >> 48) & 0xfff mac_addr = bridge_id & 0xffffffffffff mac_addr_list = [format((mac_addr >> (8 * i)) & 0xff, '02x') for i in range(0, 6)] mac_addr_list.reverse() mac_address_bin = binascii.a2b_hex(''.join(mac_addr_list)) mac_address = addrconv.mac.bin_to_text(mac_address_bin) return priority, system_id_extension, mac_address @staticmethod def encode_bridge_id(priority, system_id_extension, mac_address): mac_addr = int(binascii.hexlify(addrconv.mac.text_to_bin(mac_address)), 16) return ((priority + system_id_extension) << 48) + mac_addr @staticmethod def _decode_port_id(port_id): priority = port_id >> 8 & 0xf0 port_number = port_id & 0xfff return priority, port_number @staticmethod def encode_port_id(priority, port_number): return (priority << 8) + port_number @staticmethod def _decode_timer(timer): return timer / float(0x100) @staticmethod def _encode_timer(timer): return int(timer) * 0x100 @bpdu.register_bpdu_type class TopologyChangeNotificationBPDUs(bpdu): """Topology Change Notification BPDUs(IEEE 802.1D) header encoder/decoder class. """ VERSION_ID = PROTOCOLVERSION_ID_BPDU BPDU_TYPE = TYPE_TOPOLOGY_CHANGE_BPDU _PACK_STR = '' PACK_LEN = struct.calcsize(_PACK_STR) def __init__(self): super(TopologyChangeNotificationBPDUs, self).__init__() @classmethod def parser(cls, buf): return cls(), None, buf[bpdu._PACK_LEN:] @bpdu.register_bpdu_type class RstBPDUs(ConfigurationBPDUs): """Rapid Spanning Tree BPDUs(RST BPDUs, IEEE 802.1D) header encoder/decoder class. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. ========================== =========================================== Attribute Description ========================== =========================================== flags | Bit 1: Topology Change flag | Bit 2: Proposal flag | Bits 3 and 4: Port Role | Bit 5: Learning flag | Bit 6: Forwarding flag | Bit 7: Agreement flag | Bit 8: Topology Change Acknowledgment flag root_priority Root Identifier priority \ set 0-61440 in steps of 4096 root_system_id_extension Root Identifier system ID extension root_mac_address Root Identifier MAC address root_path_cost Root Path Cost bridge_priority Bridge Identifier priority \ set 0-61440 in steps of 4096 bridge_system_id_extension Bridge Identifier system ID extension bridge_mac_address Bridge Identifier MAC address port_priority Port Identifier priority \ set 0-240 in steps of 16 port_number Port Identifier number message_age Message Age timer value max_age Max Age timer value hello_time Hello Time timer value forward_delay Forward Delay timer value ========================== =========================================== """ VERSION_ID = PROTOCOLVERSION_ID_RSTBPDU BPDU_TYPE = TYPE_RSTBPDU _PACK_STR = '!B' PACK_LEN = struct.calcsize(_PACK_STR) def __init__(self, flags=0, root_priority=DEFAULT_BRIDGE_PRIORITY, root_system_id_extension=0, root_mac_address='00:00:00:00:00:00', root_path_cost=0, bridge_priority=DEFAULT_BRIDGE_PRIORITY, bridge_system_id_extension=0, bridge_mac_address='00:00:00:00:00:00', port_priority=DEFAULT_PORT_PRIORITY, port_number=0, message_age=0, max_age=DEFAULT_MAX_AGE, hello_time=DEFAULT_HELLO_TIME, forward_delay=DEFAULT_FORWARD_DELAY): self._version_1_length = VERSION_1_LENGTH super(RstBPDUs, self).__init__(flags, root_priority, root_system_id_extension, root_mac_address, root_path_cost, bridge_priority, bridge_system_id_extension, bridge_mac_address, port_priority, port_number, message_age, max_age, hello_time, forward_delay) def check_parameters(self): assert self.root_priority % self._BRIDGE_PRIORITY_STEP == 0 assert self.bridge_priority % self._BRIDGE_PRIORITY_STEP == 0 assert self.port_priority % self._PORT_PRIORITY_STEP == 0 assert self.message_age % self._TIMER_STEP == 0 assert self.max_age % self._TIMER_STEP == 0 assert self.hello_time % self._TIMER_STEP == 0 assert self.forward_delay % self._TIMER_STEP == 0 @classmethod def parser(cls, buf): get_cls, next_type, buf = super(RstBPDUs, cls).parser(buf) (version_1_length,) = struct.unpack_from(RstBPDUs._PACK_STR, buf) assert version_1_length == VERSION_1_LENGTH return get_cls, next_type, buf[RstBPDUs.PACK_LEN:] def serialize(self, payload, prev): base = super(RstBPDUs, self).serialize(payload, prev) sub = struct.pack(RstBPDUs._PACK_STR, self._version_1_length) return base + sub ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/packet/cfm.py0000664000175000017500000014145200000000000017432 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone 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. import abc import struct from os_ken.lib import addrconv from os_ken.lib import stringify from os_ken.lib.packet import packet_base # IEEE 802.1ag OpCode CFM_CC_MESSAGE = 0x01 CFM_LOOPBACK_REPLY = 0x02 CFM_LOOPBACK_MESSAGE = 0x03 CFM_LINK_TRACE_REPLY = 0x04 CFM_LINK_TRACE_MESSAGE = 0x05 # IEEE 802.1ag TLV type CFM_END_TLV = 0x00 CFM_SENDER_ID_TLV = 0x01 CFM_PORT_STATUS_TLV = 0x02 CFM_DATA_TLV = 0x03 CFM_INTERFACE_STATUS_TLV = 0x04 CFM_REPLY_INGRESS_TLV = 0x05 CFM_REPLY_EGRESS_TLV = 0x06 CFM_LTM_EGRESS_IDENTIFIER_TLV = 0x07 CFM_LTR_EGRESS_IDENTIFIER_TLV = 0x08 CFM_ORGANIZATION_SPECIFIC_TLV = 0x1f # IEEE 802.1ag CFM version CFM_VERSION = 0 class cfm(packet_base.PacketBase): """CFM (Connectivity Fault Management) Protocol header class. http://standards.ieee.org/getieee802/download/802.1ag-2007.pdf OpCode Field range assignments +---------------+--------------------------------------------------+ | OpCode range | CFM PDU or organization | +===============+==================================================+ | 0 | Reserved for IEEE 802.1 | +---------------+--------------------------------------------------+ | 1 | Continuity Check Message (CCM) | +---------------+--------------------------------------------------+ | 2 | Loopback Reply (LBR) | +---------------+--------------------------------------------------+ | 3 | Loopback Message (LBM) | +---------------+--------------------------------------------------+ | 4 | Linktrace Reply (LTR) | +---------------+--------------------------------------------------+ | 5 | Linktrace Message (LTM) | +---------------+--------------------------------------------------+ | 06 - 31 | Reserved for IEEE 802.1 | +---------------+--------------------------------------------------+ | 32 - 63 | Defined by ITU-T Y.1731 | +---------------+--------------------------------------------------+ | 64 - 255 | Reserved for IEEE 802.1. | +---------------+--------------------------------------------------+ An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============== ======================================== Attribute Description ============== ======================================== op CFM PDU ============== ======================================== """ _PACK_STR = '!B' _MIN_LEN = struct.calcsize(_PACK_STR) _CFM_OPCODE = {} _TYPE = { 'ascii': [ 'ltm_orig_addr', 'ltm_targ_addr' ] } @staticmethod def register_cfm_opcode(type_): def _register_cfm_opcode(cls): cfm._CFM_OPCODE[type_] = cls return cls return _register_cfm_opcode def __init__(self, op=None): super(cfm, self).__init__() assert isinstance(op, operation) self.op = op @classmethod def parser(cls, buf): (opcode, ) = struct.unpack_from(cls._PACK_STR, buf, cls._MIN_LEN) cls_ = cls._CFM_OPCODE.get(opcode) op = cls_.parser(buf) instance = cls(op) rest = buf[len(instance):] return instance, None, rest def serialize(self, payload, prev): buf = self.op.serialize() return buf def __len__(self): return len(self.op) class operation(stringify.StringifyMixin, metaclass=abc.ABCMeta): _TLV_TYPES = {} _END_TLV_LEN = 1 @staticmethod def register_tlv_types(type_): def _register_tlv_types(cls): operation._TLV_TYPES[type_] = cls return cls return _register_tlv_types def __init__(self, md_lv, version, tlvs): self.md_lv = md_lv self.version = version tlvs = tlvs or [] assert isinstance(tlvs, list) for tlv_ in tlvs: assert isinstance(tlv_, tlv) self.tlvs = tlvs @classmethod @abc.abstractmethod def parser(cls, buf): pass @abc.abstractmethod def serialize(self): pass @abc.abstractmethod def __len__(self): pass @classmethod def _parser_tlvs(cls, buf): offset = 0 tlvs = [] while True: (type_, ) = struct.unpack_from('!B', buf, offset) cls_ = cls._TLV_TYPES.get(type_) if not cls_: assert type_ is CFM_END_TLV break tlv_ = cls_.parser(buf[offset:]) tlvs.append(tlv_) offset += len(tlv_) return tlvs @staticmethod def _serialize_tlvs(tlvs): buf = bytearray() for tlv_ in tlvs: buf.extend(tlv_.serialize()) return buf def _calc_len(self, len_): for tlv_ in self.tlvs: len_ += len(tlv_) len_ += self._END_TLV_LEN return len_ @cfm.register_cfm_opcode(CFM_CC_MESSAGE) class cc_message(operation): """CFM (IEEE Std 802.1ag-2007) Continuity Check Message (CCM) encoder/decoder class. This is used with os_ken.lib.packet.cfm.cfm. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ==================== ======================================= Attribute Description ==================== ======================================= md_lv Maintenance Domain Level. version The protocol version number. rdi RDI bit. interval CCM Interval.The default is 4 (1 frame/s) seq_num Sequence Number. mep_id Maintenance association End Point Identifier. md_name_format Maintenance Domain Name Format. The default is 4 (Character string) md_name_length Maintenance Domain Name Length. (0 means automatically-calculate when encoding.) md_name Maintenance Domain Name. short_ma_name_format Short MA Name Format. The default is 2 (Character string) short_ma_name_length Short MA Name Format Length. (0 means automatically-calculate when encoding.) short_ma_name Short MA Name. tlvs TLVs. ==================== ======================================= """ _PACK_STR = '!4BIHB' _MIN_LEN = struct.calcsize(_PACK_STR) _TLV_OFFSET = 70 _MD_NAME_FORMAT_LEN = 1 _MD_NAME_LENGTH_LEN = 1 _SHORT_MA_NAME_FORMAT_LEN = 1 _SHORT_MA_NAME_LENGTH_LEN = 1 _MA_ID_LEN = 64 # Maintenance Domain Name Format _MD_FMT_NO_MD_NAME_PRESENT = 1 _MD_FMT_DOMAIN_NAME_BASED_STRING = 2 _MD_FMT_MAC_ADDRESS_TWO_OCTET_INTEGER = 3 _MD_FMT_CHARACTER_STRING = 4 # Short MA Name Format _SHORT_MA_FMT_PRIMARY_VID = 1 _SHORT_MA_FMT_CHARACTER_STRING = 2 _SHORT_MA_FMT_TWO_OCTET_INTEGER = 3 _SHORT_MA_FMT_RFC_2685_VPN_ID = 4 # CCM Transmission Interval _INTERVAL_300_HZ = 1 _INTERVAL_10_MSEC = 2 _INTERVAL_100_MSEC = 3 _INTERVAL_1_SEC = 4 _INTERVAL_10_SEC = 5 _INTERVAL_1_MIN = 6 _INTERVAL_10_MIN = 6 def __init__(self, md_lv=0, version=CFM_VERSION, rdi=0, interval=_INTERVAL_1_SEC, seq_num=0, mep_id=1, md_name_format=_MD_FMT_CHARACTER_STRING, md_name_length=0, md_name=b"0", short_ma_name_format=_SHORT_MA_FMT_CHARACTER_STRING, short_ma_name_length=0, short_ma_name=b"1", tlvs=None): super(cc_message, self).__init__(md_lv, version, tlvs) self._opcode = CFM_CC_MESSAGE assert rdi in [0, 1] self.rdi = rdi assert interval != 0 self.interval = interval self.seq_num = seq_num assert 1 <= mep_id <= 8191 self.mep_id = mep_id self.md_name_format = md_name_format self.md_name_length = md_name_length self.md_name = md_name self.short_ma_name_format = short_ma_name_format self.short_ma_name_length = short_ma_name_length self.short_ma_name = short_ma_name @classmethod def parser(cls, buf): (md_lv_version, opcode, flags, tlv_offset, seq_num, mep_id, md_name_format) = struct.unpack_from(cls._PACK_STR, buf) md_name_length = 0 md_name = b"" md_lv = int(md_lv_version >> 5) version = int(md_lv_version & 0x1f) rdi = int(flags >> 7) interval = int(flags & 0x07) offset = cls._MIN_LEN # parse md_name if md_name_format != cls._MD_FMT_NO_MD_NAME_PRESENT: (md_name_length, ) = struct.unpack_from("!B", buf, offset) offset += cls._MD_NAME_LENGTH_LEN form = "%dB" % md_name_length md_name = struct.unpack_from(form, buf, offset) offset += md_name_length # parse short_ma_name (short_ma_name_format, short_ma_name_length) = struct.unpack_from("!2B", buf, offset) offset += (cls._SHORT_MA_NAME_FORMAT_LEN + cls._SHORT_MA_NAME_LENGTH_LEN) form = "%dB" % short_ma_name_length short_ma_name = struct.unpack_from(form, buf, offset) offset = cls._MIN_LEN + (cls._MA_ID_LEN - cls._MD_NAME_FORMAT_LEN) tlvs = cls._parser_tlvs(buf[offset:]) # ascii to text if md_name_format == cls._MD_FMT_DOMAIN_NAME_BASED_STRING or \ md_name_format == cls._MD_FMT_CHARACTER_STRING: md_name = b"".join(map(struct.Struct(">B").pack, md_name)) if short_ma_name_format == cls._SHORT_MA_FMT_CHARACTER_STRING: short_ma_name = b"".join(map(struct.Struct(">B").pack, short_ma_name)) return cls(md_lv, version, rdi, interval, seq_num, mep_id, md_name_format, md_name_length, md_name, short_ma_name_format, short_ma_name_length, short_ma_name, tlvs) def serialize(self): buf = struct.pack(self._PACK_STR, (self.md_lv << 5) | self.version, self._opcode, (self.rdi << 7) | self.interval, self._TLV_OFFSET, self.seq_num, self.mep_id, self.md_name_format) buf = bytearray(buf) # Maintenance Domain Name if self.md_name_format != self._MD_FMT_NO_MD_NAME_PRESENT: if self.md_name_length == 0: self.md_name_length = len(self.md_name) buf.extend(struct.pack('!B%ds' % self.md_name_length, self.md_name_length, self.md_name)) # Short MA Name if self.short_ma_name_length == 0: self.short_ma_name_length = len(self.short_ma_name) buf.extend(struct.pack('!2B%ds' % self.short_ma_name_length, self.short_ma_name_format, self.short_ma_name_length, self.short_ma_name )) # 0 pad maid_length = (self._MD_NAME_FORMAT_LEN + self._SHORT_MA_NAME_FORMAT_LEN + self._SHORT_MA_NAME_LENGTH_LEN + self.short_ma_name_length) if self.md_name_format != self._MD_FMT_NO_MD_NAME_PRESENT: maid_length += self._MD_NAME_LENGTH_LEN + self.md_name_length buf.extend(bytearray(self._MA_ID_LEN - maid_length)) # tlvs if self.tlvs: buf.extend(self._serialize_tlvs(self.tlvs)) buf.extend(struct.pack("!B", CFM_END_TLV)) return buf def __len__(self): return self._calc_len( (self._MIN_LEN - self._MD_NAME_FORMAT_LEN) + self._MA_ID_LEN) class loopback(operation): _PACK_STR = '!4BI' _MIN_LEN = struct.calcsize(_PACK_STR) _TLV_OFFSET = 4 @abc.abstractmethod def __init__(self, md_lv, version, transaction_id, tlvs): super(loopback, self).__init__(md_lv, version, tlvs) self._flags = 0 self.transaction_id = transaction_id @classmethod def parser(cls, buf): (md_lv_version, opcode, flags, tlv_offset, transaction_id) = struct.unpack_from(cls._PACK_STR, buf) md_lv = int(md_lv_version >> 5) version = int(md_lv_version & 0x1f) tlvs = cls._parser_tlvs(buf[cls._MIN_LEN:]) return cls(md_lv, version, transaction_id, tlvs) def serialize(self): buf = struct.pack(self._PACK_STR, (self.md_lv << 5) | self.version, self._opcode, self._flags, self._TLV_OFFSET, self.transaction_id, ) buf = bytearray(buf) # tlvs if self.tlvs: buf.extend(self._serialize_tlvs(self.tlvs)) buf.extend(struct.pack("!B", CFM_END_TLV)) return buf def __len__(self): return self._calc_len(self._MIN_LEN) @cfm.register_cfm_opcode(CFM_LOOPBACK_MESSAGE) class loopback_message(loopback): """CFM (IEEE Std 802.1ag-2007) Loopback Message (LBM) encoder/decoder class. This is used with os_ken.lib.packet.cfm.cfm. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ================= ======================================= Attribute Description ================= ======================================= md_lv Maintenance Domain Level. version The protocol version number. transaction_id Loopback Transaction Identifier. tlvs TLVs. ================= ======================================= """ def __init__(self, md_lv=0, version=CFM_VERSION, transaction_id=0, tlvs=None, ): super(loopback_message, self).__init__(md_lv, version, transaction_id, tlvs) self._opcode = CFM_LOOPBACK_MESSAGE @cfm.register_cfm_opcode(CFM_LOOPBACK_REPLY) class loopback_reply(loopback): """CFM (IEEE Std 802.1ag-2007) Loopback Reply (LBR) encoder/decoder class. This is used with os_ken.lib.packet.cfm.cfm. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ==================== ======================================= Attribute Description ==================== ======================================= md_lv Maintenance Domain Level. version The protocol version number. transaction_id Loopback Transaction Identifier. tlvs TLVs. ==================== ======================================= """ def __init__(self, md_lv=0, version=CFM_VERSION, transaction_id=0, tlvs=None, ): super(loopback_reply, self).__init__(md_lv, version, transaction_id, tlvs) self._opcode = CFM_LOOPBACK_REPLY class link_trace(operation): @abc.abstractmethod def __init__(self, md_lv, version, use_fdb_only, transaction_id, ttl, tlvs): super(link_trace, self).__init__(md_lv, version, tlvs) assert use_fdb_only in [0, 1] self.use_fdb_only = use_fdb_only self.transaction_id = transaction_id self.ttl = ttl @classmethod @abc.abstractmethod def parser(cls, buf): pass @abc.abstractmethod def serialize(self): pass def __len__(self): return self._calc_len(self._MIN_LEN) @cfm.register_cfm_opcode(CFM_LINK_TRACE_MESSAGE) class link_trace_message(link_trace): """CFM (IEEE Std 802.1ag-2007) Linktrace Message (LTM) encoder/decoder class. This is used with os_ken.lib.packet.cfm.cfm. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ==================== ======================================= Attribute Description ==================== ======================================= md_lv Maintenance Domain Level. version The protocol version number. use_fdb_only UseFDBonly bit. transaction_id LTM Transaction Identifier. ttl LTM TTL. ltm_orig_addr Original MAC Address. ltm_targ_addr Target MAC Address. tlvs TLVs. ==================== ======================================= """ _PACK_STR = '!4BIB6s6s' _ALL_PACK_LEN = struct.calcsize(_PACK_STR) _MIN_LEN = _ALL_PACK_LEN _TLV_OFFSET = 17 _TYPE = { 'ascii': [ 'ltm_orig_addr', 'ltm_targ_addr' ] } def __init__(self, md_lv=0, version=CFM_VERSION, use_fdb_only=1, transaction_id=0, ttl=64, ltm_orig_addr='00:00:00:00:00:00', ltm_targ_addr='00:00:00:00:00:00', tlvs=None ): super(link_trace_message, self).__init__(md_lv, version, use_fdb_only, transaction_id, ttl, tlvs) self._opcode = CFM_LINK_TRACE_MESSAGE self.ltm_orig_addr = ltm_orig_addr self.ltm_targ_addr = ltm_targ_addr @classmethod def parser(cls, buf): (md_lv_version, opcode, flags, tlv_offset, transaction_id, ttl, ltm_orig_addr, ltm_targ_addr) = struct.unpack_from(cls._PACK_STR, buf) md_lv = int(md_lv_version >> 5) version = int(md_lv_version & 0x1f) use_fdb_only = int(flags >> 7) tlvs = cls._parser_tlvs(buf[cls._MIN_LEN:]) return cls(md_lv, version, use_fdb_only, transaction_id, ttl, addrconv.mac.bin_to_text(ltm_orig_addr), addrconv.mac.bin_to_text(ltm_targ_addr), tlvs) def serialize(self): buf = struct.pack(self._PACK_STR, (self.md_lv << 5) | self.version, self._opcode, self.use_fdb_only << 7, self._TLV_OFFSET, self.transaction_id, self.ttl, addrconv.mac.text_to_bin(self.ltm_orig_addr), addrconv.mac.text_to_bin(self.ltm_targ_addr), ) buf = bytearray(buf) if self.tlvs: buf.extend(self._serialize_tlvs(self.tlvs)) buf.extend(struct.pack("!B", CFM_END_TLV)) return buf @cfm.register_cfm_opcode(CFM_LINK_TRACE_REPLY) class link_trace_reply(link_trace): """CFM (IEEE Std 802.1ag-2007) Linktrace Reply (LTR) encoder/decoder class. This is used with os_ken.lib.packet.cfm.cfm. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ==================== ======================================= Attribute Description ==================== ======================================= version The protocol version number. use_fdb_only UseFDBonly bit. fwd_yes FwdYes bit. terminal_mep TerminalMep bit. transaction_id LTR Transaction Identifier. ttl Reply TTL. relay_action Relay Action.The default is 1 (RlyHit) tlvs TLVs. ==================== ======================================= """ _PACK_STR = '!4BIBB' _ALL_PACK_LEN = struct.calcsize(_PACK_STR) _MIN_LEN = _ALL_PACK_LEN _TLV_OFFSET = 6 # Relay Action field values _RLY_HIT = 1 _RLY_FDB = 2 _RLY_MPDB = 3 def __init__(self, md_lv=0, version=CFM_VERSION, use_fdb_only=1, fwd_yes=0, terminal_mep=1, transaction_id=0, ttl=64, relay_action=_RLY_HIT, tlvs=None ): super(link_trace_reply, self).__init__(md_lv, version, use_fdb_only, transaction_id, ttl, tlvs) self._opcode = CFM_LINK_TRACE_REPLY assert fwd_yes in [0, 1] self.fwd_yes = fwd_yes assert terminal_mep in [0, 1] self.terminal_mep = terminal_mep assert relay_action in [self._RLY_HIT, self._RLY_FDB, self._RLY_MPDB] self.relay_action = relay_action @classmethod def parser(cls, buf): (md_lv_version, opcode, flags, tlv_offset, transaction_id, ttl, relay_action) = struct.unpack_from(cls._PACK_STR, buf) md_lv = int(md_lv_version >> 5) version = int(md_lv_version & 0x1f) use_fdb_only = int(flags >> 7) fwd_yes = int(flags >> 6 & 0x01) terminal_mep = int(flags >> 5 & 0x01) tlvs = cls._parser_tlvs(buf[cls._MIN_LEN:]) return cls(md_lv, version, use_fdb_only, fwd_yes, terminal_mep, transaction_id, ttl, relay_action, tlvs) def serialize(self): buf = struct.pack(self._PACK_STR, (self.md_lv << 5) | self.version, self._opcode, (self.use_fdb_only << 7) | (self.fwd_yes << 6) | (self.terminal_mep << 5), self._TLV_OFFSET, self.transaction_id, self.ttl, self.relay_action, ) buf = bytearray(buf) if self.tlvs: buf.extend(self._serialize_tlvs(self.tlvs)) buf.extend(struct.pack("!B", CFM_END_TLV)) return buf cfm.set_classes(cfm._CFM_OPCODE) class tlv(stringify.StringifyMixin, metaclass=abc.ABCMeta): _TYPE_LEN = 1 _LENGTH_LEN = 2 _TYPE = { 'ascii': [ 'egress_id_mac', 'last_egress_id_mac', 'next_egress_id_mac', 'mac_address' ] } def __init__(self, length): self.length = length @classmethod @abc.abstractmethod def parser(cls, buf): pass @abc.abstractmethod def serialize(self): pass def __len__(self): return self.length + self._TYPE_LEN + self._LENGTH_LEN @operation.register_tlv_types(CFM_SENDER_ID_TLV) class sender_id_tlv(tlv): """CFM (IEEE Std 802.1ag-2007) Sender ID TLV encoder/decoder class. This is used with os_ken.lib.packet.cfm.cfm. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ==================== ======================================= Attribute Description ==================== ======================================= length Length of Value field. (0 means automatically-calculate when encoding.) chassis_id_length Chassis ID Length. (0 means automatically-calculate when encoding.) chassis_id_subtype Chassis ID Subtype. The default is 4 (Mac Address) chassis_id Chassis ID. ma_domain_length Management Address Domain Length. (0 means automatically-calculate when encoding.) ma_domain Management Address Domain. ma_length Management Address Length. (0 means automatically-calculate when encoding.) ma Management Address. ==================== ======================================= """ _PACK_STR = '!BHB' _MIN_LEN = struct.calcsize(_PACK_STR) _CHASSIS_ID_LENGTH_LEN = 1 _CHASSIS_ID_SUBTYPE_LEN = 1 _MA_DOMAIN_LENGTH_LEN = 1 _MA_LENGTH_LEN = 1 # Chassis ID subtype enumeration _CHASSIS_ID_CHASSIS_COMPONENT = 1 _CHASSIS_ID_INTERFACE_ALIAS = 2 _CHASSIS_ID_PORT_COMPONENT = 3 _CHASSIS_ID_MAC_ADDRESS = 4 _CHASSIS_ID_NETWORK_ADDRESS = 5 _CHASSIS_ID_INTERFACE_NAME = 6 _CHASSIS_ID_LOCALLY_ASSIGNED = 7 def __init__(self, length=0, chassis_id_length=0, chassis_id_subtype=_CHASSIS_ID_MAC_ADDRESS, chassis_id=b'', ma_domain_length=0, ma_domain=b'', ma_length=0, ma=b'' ): super(sender_id_tlv, self).__init__(length) self._type = CFM_SENDER_ID_TLV self.chassis_id_length = chassis_id_length assert chassis_id_subtype in [ self._CHASSIS_ID_CHASSIS_COMPONENT, self._CHASSIS_ID_INTERFACE_ALIAS, self._CHASSIS_ID_PORT_COMPONENT, self._CHASSIS_ID_MAC_ADDRESS, self._CHASSIS_ID_NETWORK_ADDRESS, self._CHASSIS_ID_INTERFACE_NAME, self._CHASSIS_ID_LOCALLY_ASSIGNED] self.chassis_id_subtype = chassis_id_subtype self.chassis_id = chassis_id self.ma_domain_length = ma_domain_length self.ma_domain = ma_domain self.ma_length = ma_length self.ma = ma @classmethod def parser(cls, buf): (type_, length, chassis_id_length) = struct.unpack_from(cls._PACK_STR, buf) chassis_id_subtype = 4 chassis_id = b'' ma_domain_length = 0 ma_domain = b'' ma_length = 0 ma = b'' offset = cls._MIN_LEN if chassis_id_length != 0: (chassis_id_subtype, ) = struct.unpack_from("!B", buf, offset) offset += cls._CHASSIS_ID_SUBTYPE_LEN form = "%ds" % chassis_id_length (chassis_id,) = struct.unpack_from(form, buf, offset) offset += chassis_id_length if length + (cls._TYPE_LEN + cls._LENGTH_LEN) > offset: (ma_domain_length, ) = struct.unpack_from("!B", buf, offset) offset += cls._MA_DOMAIN_LENGTH_LEN form = "%ds" % ma_domain_length (ma_domain, ) = struct.unpack_from(form, buf, offset) offset += ma_domain_length if length + (cls._TYPE_LEN + cls._LENGTH_LEN) > offset: (ma_length, ) = struct.unpack_from("!B", buf, offset) offset += cls._MA_LENGTH_LEN form = "%ds" % ma_length (ma, ) = struct.unpack_from(form, buf, offset) return cls(length, chassis_id_length, chassis_id_subtype, chassis_id, ma_domain_length, ma_domain, ma_length, ma) def serialize(self): # calculate length when it contains 0 if self.chassis_id_length == 0: self.chassis_id_length = len(self.chassis_id) if self.ma_domain_length == 0: self.ma_domain_length = len(self.ma_domain) if self.ma_length == 0: self.ma_length = len(self.ma) if self.length == 0: self.length += self._CHASSIS_ID_LENGTH_LEN if self.chassis_id_length != 0: self.length += (self._CHASSIS_ID_SUBTYPE_LEN + self.chassis_id_length) if self.chassis_id_length != 0 or self.ma_domain_length != 0: self.length += self._MA_DOMAIN_LENGTH_LEN if self.ma_domain_length != 0: self.length += (self.ma_domain_length + self._MA_LENGTH_LEN + self.ma_length) # start serialize buf = struct.pack(self._PACK_STR, self._type, self.length, self.chassis_id_length ) buf = bytearray(buf) # Chassis ID Subtype and Chassis ID present # if the Chassis ID Length field contains not 0. if self.chassis_id_length != 0: buf.extend(struct.pack("!B", self.chassis_id_subtype)) form = "%ds" % self.chassis_id_length buf.extend(struct.pack(form, self.chassis_id)) # Management Address Domain Length present # if the Chassis ID Length field or Management Address Length field # contains not 0. if self.chassis_id_length != 0 or self.ma_domain_length != 0: buf.extend(struct.pack("!B", self.ma_domain_length)) # Management Address Domain present # Management Address Domain Length field contains not 0. if self.ma_domain_length != 0: form = "%ds" % self.ma_domain_length buf.extend(struct.pack(form, self.ma_domain)) buf.extend(struct.pack("!B", self.ma_length)) # Management Address present # Management Address Length field contains not 0. if self.ma_length != 0: form = "%ds" % self.ma_length buf.extend(struct.pack(form, self.ma)) return buf @operation.register_tlv_types(CFM_PORT_STATUS_TLV) class port_status_tlv(tlv): """CFM (IEEE Std 802.1ag-2007) Port Status TLV encoder/decoder class. This is used with os_ken.lib.packet.cfm.cfm. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ==================== ======================================= Attribute Description ==================== ======================================= length Length of Value field. (0 means automatically-calculate when encoding.) port_status Port Status.The default is 1 (psUp) ==================== ======================================= """ _PACK_STR = '!BHB' _MIN_LEN = struct.calcsize(_PACK_STR) # Port Status TLV values _PS_BLOCKED = 1 _PS_UP = 2 def __init__(self, length=0, port_status=_PS_UP): super(port_status_tlv, self).__init__(length) self._type = CFM_PORT_STATUS_TLV assert port_status in [self._PS_BLOCKED, self._PS_UP] self.port_status = port_status @classmethod def parser(cls, buf): (type_, length, port_status) = struct.unpack_from(cls._PACK_STR, buf) return cls(length, port_status) def serialize(self): # calculate length when it contains 0 if self.length == 0: self.length = 1 # start serialize buf = struct.pack(self._PACK_STR, self._type, self.length, self.port_status) return bytearray(buf) @operation.register_tlv_types(CFM_DATA_TLV) class data_tlv(tlv): """CFM (IEEE Std 802.1ag-2007) Data TLV encoder/decoder class. This is used with os_ken.lib.packet.cfm.cfm. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============== ======================================= Attribute Description ============== ======================================= length Length of Value field. (0 means automatically-calculate when encoding) data_value Bit pattern of any of n octets.(n = length) ============== ======================================= """ _PACK_STR = '!BH' _MIN_LEN = struct.calcsize(_PACK_STR) def __init__(self, length=0, data_value=b"" ): super(data_tlv, self).__init__(length) self._type = CFM_DATA_TLV self.data_value = data_value @classmethod def parser(cls, buf): (type_, length) = struct.unpack_from(cls._PACK_STR, buf) form = "%ds" % length (data_value, ) = struct.unpack_from(form, buf, cls._MIN_LEN) return cls(length, data_value) def serialize(self): # calculate length when it contains 0 if self.length == 0: self.length = len(self.data_value) # start serialize buf = struct.pack(self._PACK_STR, self._type, self.length) buf = bytearray(buf) form = "%ds" % self.length buf.extend(struct.pack(form, self.data_value)) return buf @operation.register_tlv_types(CFM_INTERFACE_STATUS_TLV) class interface_status_tlv(tlv): """CFM (IEEE Std 802.1ag-2007) Interface Status TLV encoder/decoder class. This is used with os_ken.lib.packet.cfm.cfm. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ==================== ======================================= Attribute Description ==================== ======================================= length Length of Value field. (0 means automatically-calculate when encoding.) interface_status Interface Status.The default is 1 (isUp) ==================== ======================================= """ _PACK_STR = '!BHB' _MIN_LEN = struct.calcsize(_PACK_STR) # Interface Status TLV values _IS_UP = 1 _IS_DOWN = 2 _IS_TESTING = 3 _IS_UNKNOWN = 4 _IS_DORMANT = 5 _IS_NOT_PRESENT = 6 _IS_LOWER_LAYER_DOWN = 7 def __init__(self, length=0, interface_status=_IS_UP): super(interface_status_tlv, self).__init__(length) self._type = CFM_INTERFACE_STATUS_TLV assert interface_status in [ self._IS_UP, self._IS_DOWN, self._IS_TESTING, self._IS_UNKNOWN, self._IS_DORMANT, self._IS_NOT_PRESENT, self._IS_LOWER_LAYER_DOWN] self.interface_status = interface_status @classmethod def parser(cls, buf): (type_, length, interface_status) = struct.unpack_from(cls._PACK_STR, buf) return cls(length, interface_status) def serialize(self): # calculate length when it contains 0 if self.length == 0: self.length = 1 # start serialize buf = struct.pack(self._PACK_STR, self._type, self.length, self.interface_status) return bytearray(buf) @operation.register_tlv_types(CFM_LTM_EGRESS_IDENTIFIER_TLV) class ltm_egress_identifier_tlv(tlv): """CFM (IEEE Std 802.1ag-2007) LTM EGRESS TLV encoder/decoder class. This is used with os_ken.lib.packet.cfm.cfm. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============== ======================================= Attribute Description ============== ======================================= length Length of Value field. (0 means automatically-calculate when encoding.) egress_id_ui Egress Identifier of Unique ID. egress_id_mac Egress Identifier of MAC address. ============== ======================================= """ _PACK_STR = '!BHH6s' _MIN_LEN = struct.calcsize(_PACK_STR) def __init__(self, length=0, egress_id_ui=0, egress_id_mac='00:00:00:00:00:00' ): super(ltm_egress_identifier_tlv, self).__init__(length) self._type = CFM_LTM_EGRESS_IDENTIFIER_TLV self.egress_id_ui = egress_id_ui self.egress_id_mac = egress_id_mac @classmethod def parser(cls, buf): (type_, length, egress_id_ui, egress_id_mac) = struct.unpack_from(cls._PACK_STR, buf) return cls(length, egress_id_ui, addrconv.mac.bin_to_text(egress_id_mac)) def serialize(self): # calculate length when it contains 0 if self.length == 0: self.length = 8 # start serialize buf = struct.pack(self._PACK_STR, self._type, self.length, self.egress_id_ui, addrconv.mac.text_to_bin(self.egress_id_mac) ) return bytearray(buf) @operation.register_tlv_types(CFM_LTR_EGRESS_IDENTIFIER_TLV) class ltr_egress_identifier_tlv(tlv): """CFM (IEEE Std 802.1ag-2007) LTR EGRESS TLV encoder/decoder class. This is used with os_ken.lib.packet.cfm.cfm. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ==================== ======================================= Attribute Description ==================== ======================================= length Length of Value field. (0 means automatically-calculate when encoding.) last_egress_id_ui Last Egress Identifier of Unique ID. last_egress_id_mac Last Egress Identifier of MAC address. next_egress_id_ui Next Egress Identifier of Unique ID. next_egress_id_mac Next Egress Identifier of MAC address. ==================== ======================================= """ _PACK_STR = '!BHH6sH6s' _MIN_LEN = struct.calcsize(_PACK_STR) def __init__(self, length=0, last_egress_id_ui=0, last_egress_id_mac='00:00:00:00:00:00', next_egress_id_ui=0, next_egress_id_mac='00:00:00:00:00:00' ): super(ltr_egress_identifier_tlv, self).__init__(length) self._type = CFM_LTR_EGRESS_IDENTIFIER_TLV self.last_egress_id_ui = last_egress_id_ui self.last_egress_id_mac = last_egress_id_mac self.next_egress_id_ui = next_egress_id_ui self.next_egress_id_mac = next_egress_id_mac @classmethod def parser(cls, buf): (type_, length, last_egress_id_ui, last_egress_id_mac, next_egress_id_ui, next_egress_id_mac ) = struct.unpack_from(cls._PACK_STR, buf) return cls(length, last_egress_id_ui, addrconv.mac.bin_to_text(last_egress_id_mac), next_egress_id_ui, addrconv.mac.bin_to_text(next_egress_id_mac)) def serialize(self): # calculate length when it contains 0 if self.length == 0: self.length = 16 # start serialize buf = struct.pack(self._PACK_STR, self._type, self.length, self.last_egress_id_ui, addrconv.mac.text_to_bin(self.last_egress_id_mac), self.next_egress_id_ui, addrconv.mac.text_to_bin(self.next_egress_id_mac) ) return bytearray(buf) @operation.register_tlv_types(CFM_ORGANIZATION_SPECIFIC_TLV) class organization_specific_tlv(tlv): """CFM (IEEE Std 802.1ag-2007) Organization Specific TLV encoder/decoder class. This is used with os_ken.lib.packet.cfm.cfm. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============== ======================================= Attribute Description ============== ======================================= length Length of Value field. (0 means automatically-calculate when encoding.) oui Organizationally Unique Identifier. subtype Subtype. value Value.(optional) ============== ======================================= """ _PACK_STR = '!BH3sB' _MIN_LEN = struct.calcsize(_PACK_STR) _OUI_AND_SUBTYPE_LEN = 4 def __init__(self, length=0, oui=b"\x00\x00\x00", subtype=0, value=b"" ): super(organization_specific_tlv, self).__init__(length) self._type = CFM_ORGANIZATION_SPECIFIC_TLV self.oui = oui self.subtype = subtype self.value = value @classmethod def parser(cls, buf): (type_, length, oui, subtype) = struct.unpack_from(cls._PACK_STR, buf) value = b"" if length > cls._OUI_AND_SUBTYPE_LEN: form = "%ds" % (length - cls._OUI_AND_SUBTYPE_LEN) (value,) = struct.unpack_from(form, buf, cls._MIN_LEN) return cls(length, oui, subtype, value) def serialize(self): # calculate length when it contains 0 if self.length == 0: self.length = len(self.value) + self._OUI_AND_SUBTYPE_LEN # start serialize buf = struct.pack(self._PACK_STR, self._type, self.length, self.oui, self.subtype, ) buf = bytearray(buf) form = "%ds" % (self.length - self._OUI_AND_SUBTYPE_LEN) buf.extend(struct.pack(form, self.value)) return buf class reply_tlv(tlv): _PACK_STR = '!BHB6s' _MIN_LEN = struct.calcsize(_PACK_STR) _MIN_VALUE_LEN = _MIN_LEN - struct.calcsize('!BH') _PORT_ID_LENGTH_LEN = 1 _PORT_ID_SUBTYPE_LEN = 1 def __init__(self, length, action, mac_address, port_id_length, port_id_subtype, port_id): super(reply_tlv, self).__init__(length) self.action = action self.mac_address = mac_address self.port_id_length = port_id_length self.port_id_subtype = port_id_subtype self.port_id = port_id @classmethod def parser(cls, buf): (type_, length, action, mac_address) = struct.unpack_from(cls._PACK_STR, buf) port_id_length = 0 port_id_subtype = 0 port_id = b'' if length > cls._MIN_VALUE_LEN: (port_id_length, port_id_subtype) = struct.unpack_from('!2B', buf, cls._MIN_LEN) form = "%ds" % port_id_length (port_id,) = struct.unpack_from(form, buf, cls._MIN_LEN + cls._PORT_ID_LENGTH_LEN + cls._PORT_ID_SUBTYPE_LEN) return cls(length, action, addrconv.mac.bin_to_text(mac_address), port_id_length, port_id_subtype, port_id) def serialize(self): # calculate length when it contains 0 if self.port_id_length == 0: self.port_id_length = len(self.port_id) if self.length == 0: self.length = self._MIN_VALUE_LEN if self.port_id_length != 0: self.length += (self.port_id_length + self._PORT_ID_LENGTH_LEN + self._PORT_ID_SUBTYPE_LEN) # start serialize buf = struct.pack(self._PACK_STR, self._type, self.length, self.action, addrconv.mac.text_to_bin(self.mac_address), ) buf = bytearray(buf) if self.port_id_length != 0: buf.extend(struct.pack("!BB", self.port_id_length, self.port_id_subtype)) form = "%ds" % self.port_id_length buf.extend(struct.pack(form, self.port_id)) return buf @operation.register_tlv_types(CFM_REPLY_INGRESS_TLV) class reply_ingress_tlv(reply_tlv): """CFM (IEEE Std 802.1ag-2007) Reply Ingress TLV encoder/decoder class. This is used with os_ken.lib.packet.cfm.cfm. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ================= ======================================= Attribute Description ================= ======================================= length Length of Value field. (0 means automatically-calculate when encoding.) action Ingress Action.The default is 1 (IngOK) mac_address Ingress MAC Address. port_id_length Ingress PortID Length. (0 means automatically-calculate when encoding.) port_id_subtype Ingress PortID Subtype. port_id Ingress PortID. ================= ======================================= """ # Ingress Action field values _ING_OK = 1 _ING_DOWN = 2 _ING_BLOCKED = 3 _ING_VID = 4 def __init__(self, length=0, action=_ING_OK, mac_address='00:00:00:00:00:00', port_id_length=0, port_id_subtype=0, port_id=b'' ): super(reply_ingress_tlv, self).__init__(length, action, mac_address, port_id_length, port_id_subtype, port_id) assert action in [self._ING_OK, self._ING_DOWN, self._ING_BLOCKED, self._ING_VID] self._type = CFM_REPLY_INGRESS_TLV @operation.register_tlv_types(CFM_REPLY_EGRESS_TLV) class reply_egress_tlv(reply_tlv): """CFM (IEEE Std 802.1ag-2007) Reply Egress TLV encoder/decoder class. This is used with os_ken.lib.packet.cfm.cfm. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ================= ======================================= Attribute Description ================= ======================================= length Length of Value field. (0 means automatically-calculate when encoding.) action Egress Action.The default is 1 (EgrOK) mac_address Egress MAC Address. port_id_length Egress PortID Length. (0 means automatically-calculate when encoding.) port_id_subtype Egress PortID Subtype. port_id Egress PortID. ================= ======================================= """ # Egress Action field values _EGR_OK = 1 _EGR_DOWN = 2 _EGR_BLOCKED = 3 _EGR_VID = 4 def __init__(self, length=0, action=_EGR_OK, mac_address='00:00:00:00:00:00', port_id_length=0, port_id_subtype=0, port_id=b'' ): super(reply_egress_tlv, self).__init__(length, action, mac_address, port_id_length, port_id_subtype, port_id) assert action in [self._EGR_OK, self._EGR_DOWN, self._EGR_BLOCKED, self._EGR_VID] self._type = CFM_REPLY_EGRESS_TLV operation.set_classes(operation._TLV_TYPES) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/packet/dhcp.py0000664000175000017500000003147500000000000017606 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone 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. """ DHCP packet parser/serializer """ # RFC 2131 # DHCP packet format # 0 1 2 3 # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | op (1) | htype (1) | hlen (1) | hops (1) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | xid (4) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | secs (2) | flags (2) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | ciaddr (4) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | yiaddr (4) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | siaddr (4) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | giaddr (4) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | | # | chaddr (16) | # | | # | | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | | # | sname (64) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | | # | file (128) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | | # | options (variable) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ import random import struct import netaddr from os_ken.lib import addrconv from os_ken.lib import stringify from . import packet_base DHCP_BOOT_REQUEST = 1 DHCP_BOOT_REPLY = 2 # DHCP message type code DHCP_DISCOVER = 1 DHCP_OFFER = 2 DHCP_REQUEST = 3 DHCP_ACK = 5 # DHCP options tag code DHCP_PAD_OPT = 0 DHCP_SUBNET_MASK_OPT = 1 DHCP_GATEWAY_ADDR_OPT = 3 DHCP_DNS_SERVER_ADDR_OPT = 6 DHCP_HOST_NAME_OPT = 12 DHCP_DOMAIN_NAME_OPT = 15 DHCP_INTERFACE_MTU_OPT = 26 DHCP_REQUESTED_IP_ADDR_OPT = 50 DHCP_IP_ADDR_LEASE_TIME_OPT = 51 DHCP_MESSAGE_TYPE_OPT = 53 DHCP_SERVER_IDENTIFIER_OPT = 54 DHCP_PARAMETER_REQUEST_LIST_OPT = 55 DHCP_RENEWAL_TIME_OPT = 58 DHCP_REBINDING_TIME_OPT = 59 DHCP_CLASSLESS_ROUTE_OPT = 121 DHCP_END_OPT = 255 class dhcp(packet_base.PacketBase): """DHCP (RFC 2131) header encoder/decoder class. The serialized packet would looks like the ones described in the following sections. * RFC 2131 DHCP packet format An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============== ==================== Attribute Description ============== ==================== op Message op code / message type.\ 1 = BOOTREQUEST, 2 = BOOTREPLY htype Hardware address type (e.g. '1' = 10mb ethernet). hlen Hardware address length (e.g. '6' = 10mb ethernet). hops Client sets to zero, optionally used by relay agent\ when booting via a relay agent. xid Transaction ID, a random number chosen by the client,\ used by the client and serverto associate messages\ and responses between a client and a server. secs Filled in by client, seconds elapsed since client\ began address acquisition or renewal process. flags Flags. ciaddr Client IP address; only filled in if client is in\ BOUND, RENEW or REBINDING state and can respond\ to ARP requests. yiaddr 'your' (client) IP address. siaddr IP address of next server to use in bootstrap;\ returned in DHCPOFFER, DHCPACK by server. giaddr Relay agent IP address, used in booting via a\ relay agent. chaddr Client hardware address. sname Optional server host name, null terminated string. boot_file Boot file name, null terminated string; "generic"\ name or null in DHCPDISCOVER, fully qualified\ directory-path name in DHCPOFFER. options Optional parameters field\ ('DHCP message type' option must be included in\ every DHCP message). ============== ==================== """ _DHCP_PACK_STR = '!BBBBIHH4s4s4s4s16s64s128s' _MIN_LEN = struct.calcsize(_DHCP_PACK_STR) _MAC_ADDRESS_LEN = 6 _HARDWARE_TYPE_ETHERNET = 1 _class_prefixes = ['options'] _TYPE = { 'ascii': [ 'ciaddr', 'yiaddr', 'siaddr', 'giaddr', 'chaddr', 'sname', 'boot_file' ] } def __init__(self, op, chaddr, options=None, htype=_HARDWARE_TYPE_ETHERNET, hlen=0, hops=0, xid=None, secs=0, flags=0, ciaddr='0.0.0.0', yiaddr='0.0.0.0', siaddr='0.0.0.0', giaddr='0.0.0.0', sname='', boot_file=''): super(dhcp, self).__init__() self.op = op self.htype = htype self.hlen = hlen self.hops = hops if xid is None: self.xid = random.randint(0, 0xffffffff) else: self.xid = xid self.secs = secs self.flags = flags self.ciaddr = ciaddr self.yiaddr = yiaddr self.siaddr = siaddr self.giaddr = giaddr self.chaddr = chaddr self.sname = sname self.boot_file = boot_file self.options = options @classmethod def parser(cls, buf): (op, htype, hlen, hops, xid, secs, flags, ciaddr, yiaddr, siaddr, giaddr, chaddr, sname, boot_file) = struct.unpack_from(cls._DHCP_PACK_STR, buf) if hlen == cls._MAC_ADDRESS_LEN: chaddr = addrconv.mac.bin_to_text(chaddr[:cls._MAC_ADDRESS_LEN]) length = cls._MIN_LEN parse_opt = None if len(buf) > length: parse_opt = options.parser(buf[length:]) length += parse_opt.options_len return (cls(op, chaddr, parse_opt, htype, hlen, hops, xid, secs, flags, addrconv.ipv4.bin_to_text(ciaddr), addrconv.ipv4.bin_to_text(yiaddr), addrconv.ipv4.bin_to_text(siaddr), addrconv.ipv4.bin_to_text(giaddr), sname.decode('ascii'), boot_file.decode('ascii')), None, buf[length:]) def serialize(self, _payload=None, _prev=None): opt_buf = bytearray() if self.options is not None: opt_buf = self.options.serialize() if netaddr.valid_mac(self.chaddr): chaddr = addrconv.mac.text_to_bin(self.chaddr) else: chaddr = self.chaddr self.hlen = len(chaddr) return struct.pack(self._DHCP_PACK_STR, self.op, self.htype, self.hlen, self.hops, self.xid, self.secs, self.flags, addrconv.ipv4.text_to_bin(self.ciaddr), addrconv.ipv4.text_to_bin(self.yiaddr), addrconv.ipv4.text_to_bin(self.siaddr), addrconv.ipv4.text_to_bin(self.giaddr), chaddr, self.sname.encode('ascii'), self.boot_file.encode('ascii')) + opt_buf class options(stringify.StringifyMixin): """DHCP (RFC 2132) options encoder/decoder class. This is used with os_ken.lib.packet.dhcp.dhcp. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============== ==================== Attribute Description ============== ==================== option_list 'end option' and 'pad option' are added automatically\ after the option class is stored in array. options_len Option's byte length.\ ('magic cookie', 'end option' and 'pad option'\ length including.) magic_cookie The first four octets contain the decimal values\ 99, 130, 83 and 99. ============== ==================== """ _MAGIC_COOKIE_UNPACK_STR = '!4s' # same magic cookie as is defined in RFC 1497 _MAGIC_COOKIE = '99.130.83.99' _OPT_TAG_LEN_BYTE = 2 _class_prefixes = ['option'] _TYPE = { 'ascii': [ 'magic_cookie' ] } def __init__(self, option_list=None, options_len=0, magic_cookie=_MAGIC_COOKIE): super(options, self).__init__() self.option_list = option_list or [] self.options_len = options_len self.magic_cookie = magic_cookie @classmethod def parser(cls, buf): opt_parse_list = [] offset = struct.calcsize(cls._MAGIC_COOKIE_UNPACK_STR) magic_cookie = struct.unpack_from(cls._MAGIC_COOKIE_UNPACK_STR, buf)[0] while len(buf) > offset: opt_buf = buf[offset:] try: opt = option.parser(opt_buf) except struct.error: opt_parse_list.append(opt_buf) break if opt is None: break opt_parse_list.append(opt) offset += opt.length + cls._OPT_TAG_LEN_BYTE return cls(opt_parse_list, len(buf), addrconv.ipv4.bin_to_text(magic_cookie)) def serialize(self): seri_opt = addrconv.ipv4.text_to_bin(self.magic_cookie) for opt in self.option_list: if isinstance(opt, option): seri_opt += opt.serialize() else: seri_opt += opt if isinstance(self.option_list[-1], option): seri_opt += b'\xff' self.options_len = len(seri_opt) return seri_opt class option(stringify.StringifyMixin): """DHCP (RFC 2132) options encoder/decoder class. This is used with os_ken.lib.packet.dhcp.dhcp.options. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. ============== ==================== Attribute Description ============== ==================== tag Option type.\ (except for the 'magic cookie', 'pad option'\ and 'end option'.) value Option's value.\ (set the value that has been converted to hexadecimal.) length Option's value length.\ (calculated automatically from the length of value.) ============== ==================== """ _UNPACK_STR = '!B' _MIN_LEN = struct.calcsize(_UNPACK_STR) def __init__(self, tag, value, length=0): super(option, self).__init__() self.tag = tag self.value = value self.length = length @classmethod def parser(cls, buf): tag = struct.unpack_from(cls._UNPACK_STR, buf)[0] if tag == DHCP_END_OPT or tag == DHCP_PAD_OPT: return None buf = buf[cls._MIN_LEN:] length = struct.unpack_from(cls._UNPACK_STR, buf)[0] buf = buf[cls._MIN_LEN:] value_unpack_str = '%ds' % length value = struct.unpack_from(value_unpack_str, buf)[0] return cls(tag, value, length) def serialize(self): self.length = len(self.value) options_pack_str = '!BB%ds' % self.length return struct.pack(options_pack_str, self.tag, self.length, self.value) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/packet/dhcp6.py0000664000175000017500000002636200000000000017673 0ustar00zuulzuul00000000000000# Copyright (C) 2016 Bouygues Telecom. # # 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. """ DHCPv6 packet parser/serializer [RFC 3315] DHCPv6 packet format: The following diagram illustrates the format of DHCP messages sent between clients and servers:: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | msg_type | transaction_id | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | . options . . (variable) . | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ There are two relay agent messages, which share the following format:: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | msg_type | hop_count | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | | | link_address | | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-| | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | | | peer_address | | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-| | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | . . . options (variable number and length) .... . | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ """ import random import struct from . import packet_base from os_ken.lib import addrconv from os_ken.lib import stringify # DHCPv6 message types DHCPV6_SOLICIT = 1 DHCPV6_ADVERTISE = 2 DHCPV6_REQUEST = 3 DHCPV6_CONFIRM = 4 DHCPV6_RENEW = 5 DHCPV6_REBIND = 6 DHCPV6_REPLY = 7 DHCPV6_RELEASE = 8 DHCPV6_DECLINE = 9 DHCPV6_RECONFIGURE = 10 DHCPV6_INFORMATION_REQUEST = 11 DHCPV6_RELAY_FORW = 12 DHCPV6_RELAY_REPL = 13 # DHCPv6 option-codes DHCPV6_OPTION_CLIENTID = 1 DHCPV6_OPTION_SERVERID = 2 DHCPV6_OPTION_IA_NA = 3 DHCPV6_OPTION_IA_TA = 4 DHCPV6_OPTION_IAADDR = 5 DHCPV6_OPTION_ORO = 6 DHCPV6_OPTION_PREFERENCE = 7 DHCPV6_OPTION_ELAPSED_TIME = 8 DHCPV6_OPTION_RELAY_MSG = 9 DHCPV6_OPTION_AUTH = 11 DHCPV6_OPTION_UNICAST = 12 DHCPV6_OPTION_STATUS_CODE = 13 DHCPV6_OPTION_RAPID_COMMIT = 14 DHCPV6_OPTION_USER_CLASS = 15 DHCPV6_OPTION_VENDOR_CLASS = 16 DHCPV6_OPTION_VENDOR_OPTS = 17 DHCPV6_OPTION_INTERFACE_ID = 18 DHCPV6_OPTION_RECONF_MSG = 19 DHCPV6_OPTION_RECONF_ACCEPT = 20 class dhcp6(packet_base.PacketBase): """DHCPv6 (RFC 3315) header encoder/decoder class. The serialized packet would looks like the ones described in the following sections. * RFC 3315 DHCP packet format An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. ============== ==================== Attribute Description ============== ==================== msg_type Identifies the DHCP message type transaction_id For unrelayed messages only: the transaction ID for\ this message exchange. hop_count For relayed messages only: number of relay agents that\ have relayed this message. link_address For relayed messages only: a global or site-local address\ that will be used by the server to identify the link on\ which the client is located. peer_address For relayed messages only: the address of the client or\ relay agent from which the message to be relayed was\ received. options Options carried in this message ============== ==================== """ _MIN_LEN = 8 _DHCPV6_UNPACK_STR = '!I' _DHCPV6_RELAY_UNPACK_STR = '!H16s16s' _DHCPV6_UNPACK_STR_LEN = struct.calcsize(_DHCPV6_UNPACK_STR) _DHCPV6_RELAY_UNPACK_STR_LEN = struct.calcsize(_DHCPV6_RELAY_UNPACK_STR) _DHCPV6_PACK_STR = '!I' _DHCPV6_RELAY_PACK_STR = '!H16s16s' def __init__(self, msg_type, options, transaction_id=None, hop_count=0, link_address='::', peer_address='::'): super(dhcp6, self).__init__() self.msg_type = msg_type self.options = options if transaction_id is None: self.transaction_id = random.randint(0, 0xffffff) else: self.transaction_id = transaction_id self.hop_count = hop_count self.link_address = link_address self.peer_address = peer_address @classmethod def parser(cls, buf): (msg_type, ) = struct.unpack_from('!B', buf) buf = b'\x00' + buf[1:] # unpack xid as a 4-byte integer if msg_type == DHCPV6_RELAY_FORW or msg_type == DHCPV6_RELAY_REPL: (hop_count, link_address, peer_address) \ = struct.unpack_from(cls._DHCPV6_RELAY_UNPACK_STR, buf) length = struct.calcsize(cls._DHCPV6_RELAY_UNPACK_STR) else: (transaction_id, ) \ = struct.unpack_from(cls._DHCPV6_UNPACK_STR, buf) length = struct.calcsize(cls._DHCPV6_UNPACK_STR) if len(buf) > length: parse_opt = options.parser(buf[length:]) length += parse_opt.options_len if msg_type == DHCPV6_RELAY_FORW or msg_type == DHCPV6_RELAY_REPL: return (cls(msg_type, parse_opt, 0, hop_count, addrconv.ipv6.bin_to_text(link_address), addrconv.ipv6.bin_to_text(peer_address)), None, buf[length:]) else: return (cls(msg_type, parse_opt, transaction_id), None, buf[length:]) else: return None, None, buf def serialize(self, payload=None, prev=None): seri_opt = self.options.serialize() if (self.msg_type == DHCPV6_RELAY_FORW or self.msg_type == DHCPV6_RELAY_REPL): pack_str = '%s%ds' % (self._DHCPV6_RELAY_PACK_STR, self.options.options_len) buf = struct.pack(pack_str, self.hop_count, addrconv.ipv6.text_to_bin(self.link_address), addrconv.ipv6.text_to_bin(self.peer_address), seri_opt) else: pack_str = '%s%ds' % (self._DHCPV6_PACK_STR, self.options.options_len) buf = struct.pack(pack_str, self.transaction_id, seri_opt) return struct.pack('!B', self.msg_type) + buf[1:] class options(stringify.StringifyMixin): """DHCP (RFC 3315) options encoder/decoder class. This is used with os_ken.lib.packet.dhcp6.dhcp6. """ def __init__(self, option_list=None, options_len=0): super(options, self).__init__() if option_list is None: self.option_list = [] else: self.option_list = option_list self.options_len = options_len @classmethod def parser(cls, buf): opt_parse_list = [] offset = 0 while len(buf) > offset: opt_buf = buf[offset:] opt = option.parser(opt_buf) opt_parse_list.append(opt) offset += opt.length + 4 return cls(opt_parse_list, len(buf)) def serialize(self): seri_opt = bytes() for opt in self.option_list: seri_opt += opt.serialize() if self.options_len == 0: self.options_len = len(seri_opt) return seri_opt class option(stringify.StringifyMixin): """DHCP (RFC 3315) options encoder/decoder class. This is used with os_ken.lib.packet.dhcp6.dhcp6.options. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. The format of DHCP options is:: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | option-code | option-len | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | option-data | | (option-len octets) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ============== ==================== Attribute Description ============== ==================== option-code An unsigned integer identifying the specific option\ type carried in this option. option-len An unsigned integer giving the length of the\ option-data field in this option in octets. option-data The data for the option; the format of this data\ depends on the definition of the option. ============== ==================== """ _UNPACK_STR = '!H' _UNPACK_STR_LEN = struct.calcsize(_UNPACK_STR) _PACK_STR = '!HH%ds' def __init__(self, code, data, length=0): super(option, self).__init__() self.code = code self.data = data self.length = length @classmethod def parser(cls, buf): code = struct.unpack_from(cls._UNPACK_STR, buf)[0] buf = buf[cls._UNPACK_STR_LEN:] length = struct.unpack_from(cls._UNPACK_STR, buf)[0] buf = buf[cls._UNPACK_STR_LEN:] value_unpack_str = '%ds' % length data = struct.unpack_from(value_unpack_str, buf)[0] return cls(code, data, length) def serialize(self): if self.length == 0: self.length = len(self.data) options_pack_str = self._PACK_STR % self.length return struct.pack(options_pack_str, self.code, self.length, self.data) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/packet/ether_types.py0000664000175000017500000000164000000000000021212 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone 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. ETH_TYPE_IP = 0x0800 ETH_TYPE_ARP = 0x0806 ETH_TYPE_TEB = 0x6558 ETH_TYPE_8021Q = 0x8100 ETH_TYPE_IPV6 = 0x86dd ETH_TYPE_SLOW = 0x8809 ETH_TYPE_MPLS = 0x8847 ETH_TYPE_8021AD = 0x88a8 ETH_TYPE_LLDP = 0x88cc ETH_TYPE_8021AH = 0x88e7 ETH_TYPE_IEEE802_3 = 0x05dc ETH_TYPE_CFM = 0x8902 ETH_TYPE_NSH = 0x894f # RFC8300 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/packet/ethernet.py0000664000175000017500000000646700000000000020511 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone 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. import struct from . import packet_base from . import vlan from . import mpls from . import ether_types as ether from os_ken.lib import addrconv from os_ken.lib.pack_utils import msg_pack_into class ethernet(packet_base.PacketBase): """Ethernet header encoder/decoder class. An instance has the following attributes at least. MAC addresses are represented as a string like '08:60:6e:7f:74:e7'. __init__ takes the corresponding args in this order. ============== ==================== ===================== Attribute Description Example ============== ==================== ===================== dst destination address 'ff:ff:ff:ff:ff:ff' src source address '08:60:6e:7f:74:e7' ethertype ether type 0x0800 ============== ==================== ===================== """ _PACK_STR = '!6s6sH' _MIN_LEN = struct.calcsize(_PACK_STR) _MIN_PAYLOAD_LEN = 46 _TYPE = { 'ascii': [ 'src', 'dst' ] } def __init__(self, dst='ff:ff:ff:ff:ff:ff', src='00:00:00:00:00:00', ethertype=ether.ETH_TYPE_IP): super(ethernet, self).__init__() self.dst = dst self.src = src self.ethertype = ethertype @classmethod def parser(cls, buf): dst, src, ethertype = struct.unpack_from(cls._PACK_STR, buf) return (cls(addrconv.mac.bin_to_text(dst), addrconv.mac.bin_to_text(src), ethertype), ethernet.get_packet_type(ethertype), buf[ethernet._MIN_LEN:]) def serialize(self, payload, prev): # Append padding if the payload is less than 46 bytes long pad_len = self._MIN_PAYLOAD_LEN - len(payload) if pad_len > 0: payload.extend(b'\x00' * pad_len) return struct.pack(ethernet._PACK_STR, addrconv.mac.text_to_bin(self.dst), addrconv.mac.text_to_bin(self.src), self.ethertype) @classmethod def get_packet_type(cls, type_): """Override method for the ethernet IEEE802.3 Length/Type field (self.ethertype). If the value of Length/Type field is less than or equal to 1500 decimal(05DC hexadecimal), it means Length interpretation and be passed to the LLC sublayer.""" if type_ <= ether.ETH_TYPE_IEEE802_3: type_ = ether.ETH_TYPE_IEEE802_3 return cls._TYPES.get(type_) # copy vlan _TYPES ethernet._TYPES = vlan.vlan._TYPES ethernet.register_packet_type(vlan.vlan, ether.ETH_TYPE_8021Q) ethernet.register_packet_type(vlan.svlan, ether.ETH_TYPE_8021AD) ethernet.register_packet_type(mpls.mpls, ether.ETH_TYPE_MPLS) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/packet/geneve.py0000664000175000017500000001537700000000000020144 0ustar00zuulzuul00000000000000# Copyright (C) 2016 Nippon Telegraph and Telephone 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. """ Geneve packet parser/serializer """ import struct from os_ken.lib import stringify from os_ken.lib import type_desc from . import packet_base from . import ether_types UDP_DST_PORT = 6081 class geneve(packet_base.PacketBase): """Geneve (RFC draft-ietf-nvo3-geneve-03) header encoder/decoder class. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. ============== ======================================================== Attribute Description ============== ======================================================== version Version. opt_len The length of the options fields. flags Flag field for OAM packet and Critical options present. protocol Protocol Type field. The Protocol Type is defined as "ETHER TYPES". vni Identifier for unique element of virtual network. options List of ``Option*`` instance. ============== ======================================================== """ _HEADER_FMT = "!BBHI" _MIN_LEN = struct.calcsize(_HEADER_FMT) # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # |Ver| Opt Len |O|C| Rsvd. | Protocol Type | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Virtual Network Identifier (VNI) | Reserved | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Variable Length Options | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # Flags OAM_PACKET_FLAG = 1 << 7 CRITICAL_OPTIONS_FLAG = 1 << 6 def __init__(self, version=0, opt_len=0, flags=0, protocol=ether_types.ETH_TYPE_TEB, vni=None, options=None): super(geneve, self).__init__() self.version = version self.opt_len = opt_len assert (flags & 0x3F) == 0 self.flags = flags self.protocol = protocol self.vni = vni for o in options: assert isinstance(o, Option) self.options = options @classmethod def parser(cls, buf): (ver_opt_len, flags, protocol, vni) = struct.unpack_from(cls._HEADER_FMT, buf) version = ver_opt_len >> 6 # The Opt Len field expressed in four byte multiples. opt_len = (ver_opt_len & 0x3F) * 4 opt_bin = buf[cls._MIN_LEN:cls._MIN_LEN + opt_len] options = [] while opt_bin: option, opt_bin = Option.parser(opt_bin) options.append(option) msg = cls(version, opt_len, flags, protocol, vni >> 8, options) from . import ethernet geneve._TYPES = ethernet.ethernet._TYPES geneve.register_packet_type(ethernet.ethernet, ether_types.ETH_TYPE_TEB) return (msg, geneve.get_packet_type(protocol), buf[cls._MIN_LEN + opt_len:]) def serialize(self, payload=None, prev=None): tunnel_options = bytearray() for o in self.options: tunnel_options += o.serialize() self.opt_len = len(tunnel_options) # The Opt Len field expressed in four byte multiples. opt_len = self.opt_len // 4 return (struct.pack(self._HEADER_FMT, (self.version << 6) | opt_len, self.flags, self.protocol, self.vni << 8) + tunnel_options) class Option(stringify.StringifyMixin, type_desc.TypeDisp): """ Tunnel Options """ _OPTION_PACK_STR = "!HBB" _OPTION_LEN = struct.calcsize(_OPTION_PACK_STR) # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Option Class | Type |R|R|R| Length | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Variable Option Data | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ def __init__(self, option_class=None, type_=None, length=0): super(Option, self).__init__() if option_class is None or type_ is None: (option_class, type_) = self._rev_lookup_type(self.__class__) self.option_class = option_class self.type = type_ self.length = length @classmethod def parse_value(cls, buf): # Sub-classes should override this method, if needed. return {} def serialize_value(self): # Sub-classes should override this method, if needed. return b'' @classmethod def parser(cls, buf): (option_class, type_, length) = struct.unpack_from(cls._OPTION_PACK_STR, buf) # The Length field expressed in four byte multiples. length *= 4 subcls = Option._lookup_type((option_class, type_)) return ( subcls(option_class=option_class, type_=type_, length=length, **subcls.parse_value( buf[cls._OPTION_LEN:cls._OPTION_LEN + length])), buf[cls._OPTION_LEN + length:]) def serialize(self, _payload=None, _prev=None): data = self.serialize_value() self.length = len(data) # The Length field expressed in four byte multiples. length = self.length // 4 return (struct.pack(self._OPTION_PACK_STR, int(self.option_class), self.type, length) + data) @Option.register_unknown_type() class OptionDataUnknown(Option): """ Unknown Option Class and Type specific Option """ def __init__(self, buf, option_class=None, type_=None, length=0): super(OptionDataUnknown, self).__init__(option_class=option_class, type_=type_, length=length) self.buf = buf @classmethod def parse_value(cls, buf): return {"buf": buf} def serialize_value(self): return self.buf ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/packet/gre.py0000664000175000017500000001745500000000000017447 0ustar00zuulzuul00000000000000# Copyright (C) 2016 Nippon Telegraph and Telephone 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. import struct from os_ken.lib.pack_utils import msg_pack_into from . import packet_base from . import packet_utils from . import ether_types GRE_CHECKSUM_FLG = 1 << 7 GRE_KEY_FLG = 1 << 5 GRE_SEQUENCE_NUM_FLG = 1 << 4 class gre(packet_base.PacketBase): """GRE (RFC2784,RFC2890) header encoder/decoder class. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. ============== ======================================================== Attribute Description ============== ======================================================== version Version. protocol Protocol Type field. The Protocol Type is defined as "ETHER TYPES". checksum Checksum field(optional). When you set a value other than None, this field will be automatically calculated. key Key field(optional) This field is intended to be used for identifying an individual traffic flow within a tunnel. vsid Virtual Subnet ID field(optional) This field is a 24-bit value that is used to identify the NVGRE-based Virtual Layer 2 Network. flow_id FlowID field(optional) This field is an 8-bit value that is used to provide per-flow entropy for flows in the same VSID. seq_number Sequence Number field(optional) ============== ======================================================== """ _PACK_STR = "!BBH" _CHECKSUM_PACK_STR = "!H2x" _KEY_PACK_STR = "!I" _SEQNUM_PACK_STR = "!I" _MIN_LEN = struct.calcsize(_PACK_STR) _CHECKSUM_LEN = struct.calcsize(_CHECKSUM_PACK_STR) _KEY_LEN = struct.calcsize(_KEY_PACK_STR) _SEQNUM_PACK_LEN = struct.calcsize(_SEQNUM_PACK_STR) # GRE header # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # |C| |K|S| Reserved0 | Ver | Protocol Type | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Checksum (optional) | Reserved1 (Optional) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Key (optional) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Sequence Number (Optional) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ def __init__(self, version=0, protocol=ether_types.ETH_TYPE_IP, checksum=None, key=None, vsid=None, flow_id=None, seq_number=None): super(gre, self).__init__() self.version = version self.protocol = protocol self.checksum = checksum self.seq_number = seq_number if key is not None: self._key = key self._vsid = self._key >> 8 self._flow_id = self._key & 0xff elif (vsid is not None) and (flow_id is not None): self._key = vsid << 8 | flow_id self._vsid = vsid self._flow_id = flow_id else: self._key = None self._vsid = None self._flow_id = None @property def key(self): return self._key @key.setter def key(self, key): if key is not None: self._key = key self._vsid = self._key >> 8 self._flow_id = self._key & 0xff else: self._key = None self._vsid = None self._flow_id = None @property def vsid(self): return self._vsid @vsid.setter def vsid(self, vsid): self._key = vsid << 8 | (self._key & 0xff) self._vsid = vsid @property def flow_id(self): return self._flow_id @flow_id.setter def flow_id(self, flow_id): self._key = (self._key & 0xffffff00) | flow_id self._flow_id = flow_id @classmethod def parser(cls, buf): present, version, protocol = struct.unpack_from(cls._PACK_STR, buf) gre_offset = gre._MIN_LEN checksum = None key = None seq_number = None if present & GRE_CHECKSUM_FLG: checksum, = struct.unpack_from(cls._CHECKSUM_PACK_STR, buf, gre_offset) gre_offset += cls._CHECKSUM_LEN if present & GRE_KEY_FLG: key, = struct.unpack_from(cls._KEY_PACK_STR, buf, gre_offset) gre_offset += cls._KEY_LEN if present & GRE_SEQUENCE_NUM_FLG: seq_number, = struct.unpack_from(cls._SEQNUM_PACK_STR, buf, gre_offset) gre_offset += cls._SEQNUM_PACK_LEN msg = cls(version=version, protocol=protocol, checksum=checksum, key=key, seq_number=seq_number) from . import ethernet gre._TYPES = ethernet.ethernet._TYPES gre.register_packet_type(ethernet.ethernet, ether_types.ETH_TYPE_TEB) return msg, gre.get_packet_type(protocol), buf[gre_offset:] def serialize(self, payload=None, prev=None): present = 0 hdr = bytearray() optional = bytearray() if self.checksum is not None: present |= GRE_CHECKSUM_FLG # For purposes of computing the checksum, # the value of the checksum field is zero. # Also, because Reserved1 is always 0x00 of 2 bytes, # Set in conjunction with checksum. optional += b'\x00' * self._CHECKSUM_LEN if self._key is not None: present |= GRE_KEY_FLG optional += struct.pack(self._KEY_PACK_STR, self._key) if self.seq_number is not None: present |= GRE_SEQUENCE_NUM_FLG optional += struct.pack(self._SEQNUM_PACK_STR, self.seq_number) msg_pack_into(self._PACK_STR, hdr, 0, present, self.version, self.protocol) hdr += optional if self.checksum: self.checksum = packet_utils.checksum(hdr) struct.pack_into(self._CHECKSUM_PACK_STR, hdr, self._MIN_LEN, self.checksum) return hdr def nvgre(version=0, vsid=0, flow_id=0): """ Generate instance of GRE class with information for NVGRE (RFC7637). :param version: Version. :param vsid: Virtual Subnet ID. :param flow_id: FlowID. :return: Instance of GRE class with information for NVGRE. """ # NVGRE header # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # |0| |1|0| Reserved0 | Ver | Protocol Type 0x6558 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Virtual Subnet ID (VSID) | FlowID | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ return gre(version=version, protocol=ether_types.ETH_TYPE_TEB, vsid=vsid, flow_id=flow_id) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/packet/icmp.py0000664000175000017500000002274300000000000017616 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone 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. import abc import struct from . import packet_base from . import packet_utils from os_ken.lib import stringify ICMP_ECHO_REPLY = 0 ICMP_DEST_UNREACH = 3 ICMP_SRC_QUENCH = 4 ICMP_REDIRECT = 5 ICMP_ECHO_REQUEST = 8 ICMP_TIME_EXCEEDED = 11 ICMP_ECHO_REPLY_CODE = 0 ICMP_HOST_UNREACH_CODE = 1 ICMP_PORT_UNREACH_CODE = 3 ICMP_TTL_EXPIRED_CODE = 0 class icmp(packet_base.PacketBase): """ICMP (RFC 792) header encoder/decoder class. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============== ==================== Attribute Description ============== ==================== type Type code Code csum CheckSum \ (0 means automatically-calculate when encoding) data Payload. \ Either a bytearray, or \ os_ken.lib.packet.icmp.echo or \ os_ken.lib.packet.icmp.dest_unreach or \ os_ken.lib.packet.icmp.TimeExceeded object \ NOTE for icmp.echo: \ This includes "unused" 16 bits and the following \ "Internet Header + 64 bits of Original Data Datagram" of \ the ICMP header. \ NOTE for icmp.dest_unreach and icmp.TimeExceeded: \ This includes "unused" 8 or 24 bits and the following \ "Internet Header + leading octets of original datagram" \ of the original packet. ============== ==================== """ _PACK_STR = '!BBH' _MIN_LEN = struct.calcsize(_PACK_STR) _ICMP_TYPES = {} @staticmethod def register_icmp_type(*args): def _register_icmp_type(cls): for type_ in args: icmp._ICMP_TYPES[type_] = cls return cls return _register_icmp_type def __init__(self, type_=ICMP_ECHO_REQUEST, code=0, csum=0, data=b''): super(icmp, self).__init__() self.type = type_ self.code = code self.csum = csum self.data = data @classmethod def parser(cls, buf): (type_, code, csum) = struct.unpack_from(cls._PACK_STR, buf) msg = cls(type_, code, csum) offset = cls._MIN_LEN if len(buf) > offset: cls_ = cls._ICMP_TYPES.get(type_, None) if cls_: msg.data = cls_.parser(buf, offset) else: msg.data = buf[offset:] return msg, None, None def serialize(self, payload, prev): hdr = bytearray(struct.pack(icmp._PACK_STR, self.type, self.code, self.csum)) if self.data: if self.type in icmp._ICMP_TYPES: assert isinstance(self.data, _ICMPv4Payload) hdr += self.data.serialize() else: hdr += self.data else: self.data = echo() hdr += self.data.serialize() if self.csum == 0: self.csum = packet_utils.checksum(hdr) struct.pack_into('!H', hdr, 2, self.csum) return hdr def __len__(self): return self._MIN_LEN + len(self.data) class _ICMPv4Payload(stringify.StringifyMixin, metaclass=abc.ABCMeta): """ Base class for the payload of ICMPv4 packet. """ @icmp.register_icmp_type(ICMP_ECHO_REPLY, ICMP_ECHO_REQUEST) class echo(_ICMPv4Payload): """ICMP sub encoder/decoder class for Echo and Echo Reply messages. This is used with os_ken.lib.packet.icmp.icmp for ICMP Echo and Echo Reply messages. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============== ==================== Attribute Description ============== ==================== id Identifier seq Sequence Number data Internet Header + 64 bits of Original Data Datagram ============== ==================== """ _PACK_STR = '!HH' _MIN_LEN = struct.calcsize(_PACK_STR) def __init__(self, id_=0, seq=0, data=None): super(echo, self).__init__() self.id = id_ self.seq = seq self.data = data @classmethod def parser(cls, buf, offset): (id_, seq) = struct.unpack_from(cls._PACK_STR, buf, offset) msg = cls(id_, seq) offset += cls._MIN_LEN if len(buf) > offset: msg.data = buf[offset:] return msg def serialize(self): hdr = bytearray(struct.pack(echo._PACK_STR, self.id, self.seq)) if self.data is not None: hdr += self.data return hdr def __len__(self): length = self._MIN_LEN if self.data is not None: length += len(self.data) return length @icmp.register_icmp_type(ICMP_DEST_UNREACH) class dest_unreach(_ICMPv4Payload): """ICMP sub encoder/decoder class for Destination Unreachable Message. This is used with os_ken.lib.packet.icmp.icmp for ICMP Destination Unreachable Message. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. [RFC1191] reserves bits for the "Next-Hop MTU" field. [RFC4884] introduced 8-bit data length attribute. .. tabularcolumns:: |l|p{35em}| ============== ===================================================== Attribute Description ============== ===================================================== data_len data length mtu Next-Hop MTU NOTE: This field is required when icmp code is 4 code 4 = fragmentation needed and DF set data Internet Header + leading octets of original datagram ============== ===================================================== """ _PACK_STR = '!xBH' _MIN_LEN = struct.calcsize(_PACK_STR) def __init__(self, data_len=0, mtu=0, data=None): super(dest_unreach, self).__init__() if ((data_len >= 0) and (data_len <= 255)): self.data_len = data_len else: raise ValueError('Specified data length (%d) is invalid.' % data_len) self.mtu = mtu self.data = data @classmethod def parser(cls, buf, offset): (data_len, mtu) = struct.unpack_from(cls._PACK_STR, buf, offset) msg = cls(data_len, mtu) offset += cls._MIN_LEN if len(buf) > offset: msg.data = buf[offset:] return msg def serialize(self): hdr = bytearray(struct.pack(dest_unreach._PACK_STR, self.data_len, self.mtu)) if self.data is not None: hdr += self.data return hdr def __len__(self): length = self._MIN_LEN if self.data is not None: length += len(self.data) return length @icmp.register_icmp_type(ICMP_TIME_EXCEEDED) class TimeExceeded(_ICMPv4Payload): """ICMP sub encoder/decoder class for Time Exceeded Message. This is used with os_ken.lib.packet.icmp.icmp for ICMP Time Exceeded Message. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. [RFC4884] introduced 8-bit data length attribute. .. tabularcolumns:: |l|L| ============== ==================== Attribute Description ============== ==================== data_len data length data Internet Header + leading octets of original datagram ============== ==================== """ _PACK_STR = '!xBxx' _MIN_LEN = struct.calcsize(_PACK_STR) def __init__(self, data_len=0, data=None): if (data_len >= 0) and (data_len <= 255): self.data_len = data_len else: raise ValueError('Specified data length (%d) is invalid.' % data_len) self.data = data @classmethod def parser(cls, buf, offset): (data_len, ) = struct.unpack_from(cls._PACK_STR, buf, offset) msg = cls(data_len) offset += cls._MIN_LEN if len(buf) > offset: msg.data = buf[offset:] return msg def serialize(self): hdr = bytearray(struct.pack(TimeExceeded._PACK_STR, self.data_len)) if self.data is not None: hdr += self.data return hdr def __len__(self): length = self._MIN_LEN if self.data is not None: length += len(self.data) return length icmp.set_classes(icmp._ICMP_TYPES) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/packet/icmpv6.py0000664000175000017500000010203100000000000020057 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone 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. import abc import struct from . import packet_base from . import packet_utils from os_ken.lib import addrconv from os_ken.lib import stringify ICMPV6_DST_UNREACH = 1 # dest unreachable, codes: ICMPV6_PACKET_TOO_BIG = 2 # packet too big ICMPV6_TIME_EXCEEDED = 3 # time exceeded, code: ICMPV6_PARAM_PROB = 4 # ip6 header bad ICMPV6_ECHO_REQUEST = 128 # echo service ICMPV6_ECHO_REPLY = 129 # echo reply MLD_LISTENER_QUERY = 130 # multicast listener query MLD_LISTENER_REPOR = 131 # multicast listener report MLD_LISTENER_DONE = 132 # multicast listener done MLDV2_LISTENER_REPORT = 143 # multicast listern report (v2) # RFC2292 decls ICMPV6_MEMBERSHIP_QUERY = 130 # group membership query ICMPV6_MEMBERSHIP_REPORT = 131 # group membership report ICMPV6_MEMBERSHIP_REDUCTION = 132 # group membership termination ND_ROUTER_SOLICIT = 133 # router solicitation ND_ROUTER_ADVERT = 134 # router advertisment ND_NEIGHBOR_SOLICIT = 135 # neighbor solicitation ND_NEIGHBOR_ADVERT = 136 # neighbor advertisment ND_REDIREC = 137 # redirect ICMPV6_ROUTER_RENUMBERING = 138 # router renumbering ICMPV6_WRUREQUEST = 139 # who are you request ICMPV6_WRUREPLY = 140 # who are you reply ICMPV6_FQDN_QUERY = 139 # FQDN query ICMPV6_FQDN_REPLY = 140 # FQDN reply ICMPV6_NI_QUERY = 139 # node information request ICMPV6_NI_REPLY = 140 # node information reply ICMPV6_MAXTYPE = 201 # ND_OPTIONS from RFC 4861 ND_OPTION_SLA = 1 # Source Link-Layer Address ND_OPTION_TLA = 2 # Target Link-Layer Address ND_OPTION_PI = 3 # Prefix Information ND_OPTION_RH = 4 # Redirected Header ND_OPTION_MTU = 5 # MTU MODE_IS_INCLUDE = 1 MODE_IS_EXCLUDE = 2 CHANGE_TO_INCLUDE_MODE = 3 CHANGE_TO_EXCLUDE_MODE = 4 ALLOW_NEW_SOURCES = 5 BLOCK_OLD_SOURCES = 6 class icmpv6(packet_base.PacketBase): r"""ICMPv6 (RFC 2463) header encoder/decoder class. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|p{35em}| ============== ==================== Attribute Description ============== ==================== type\_ Type code Code csum CheckSum (0 means automatically-calculate when encoding) data Payload. os_ken.lib.packet.icmpv6.echo object, \ os_ken.lib.packet.icmpv6.nd_neighbor object, \ os_ken.lib.packet.icmpv6.nd_router_solicit object, \ os_ken.lib.packet.icmpv6.nd_router_advert object, \ os_ken.lib.packet.icmpv6.mld object, \ or a bytearray. ============== ==================== """ _PACK_STR = '!BBH' _MIN_LEN = struct.calcsize(_PACK_STR) _ICMPV6_TYPES = {} @staticmethod def register_icmpv6_type(*args): def _register_icmpv6_type(cls): for type_ in args: icmpv6._ICMPV6_TYPES[type_] = cls return cls return _register_icmpv6_type def __init__(self, type_=0, code=0, csum=0, data=b''): super(icmpv6, self).__init__() self.type_ = type_ self.code = code self.csum = csum self.data = data @classmethod def parser(cls, buf): (type_, code, csum) = struct.unpack_from(cls._PACK_STR, buf) msg = cls(type_, code, csum) offset = cls._MIN_LEN if len(buf) > offset: cls_ = cls._ICMPV6_TYPES.get(type_, None) if cls_: msg.data = cls_.parser(buf, offset) else: msg.data = buf[offset:] return msg, None, None def serialize(self, payload, prev): hdr = bytearray(struct.pack(icmpv6._PACK_STR, self.type_, self.code, self.csum)) if self.data: if self.type_ in icmpv6._ICMPV6_TYPES: assert isinstance(self.data, _ICMPv6Payload) hdr += self.data.serialize() else: hdr += self.data if self.csum == 0: self.csum = packet_utils.checksum_ip(prev, len(hdr), hdr + payload) struct.pack_into('!H', hdr, 2, self.csum) return hdr def __len__(self): return self._MIN_LEN + len(self.data) class _ICMPv6Payload(stringify.StringifyMixin, metaclass=abc.ABCMeta): """ Base class for the payload of ICMPv6 packet. """ @icmpv6.register_icmpv6_type(ND_NEIGHBOR_SOLICIT, ND_NEIGHBOR_ADVERT) class nd_neighbor(_ICMPv6Payload): """ICMPv6 sub encoder/decoder class for Neighbor Solicitation and Neighbor Advertisement messages. (RFC 4861) This is used with os_ken.lib.packet.icmpv6.icmpv6. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|p{35em}| ============== ==================== Attribute Description ============== ==================== res R,S,O Flags for Neighbor Advertisement. \ The 3 MSBs of "Reserved" field for Neighbor Solicitation. dst Target Address option a derived object of os_ken.lib.packet.icmpv6.nd_option \ or a bytearray. None if no options. ============== ==================== """ _PACK_STR = '!I16s' _MIN_LEN = struct.calcsize(_PACK_STR) _ND_OPTION_TYPES = {} _TYPE = { 'ascii': [ 'dst' ] } @staticmethod def register_nd_option_type(*args): def _register_nd_option_type(cls): nd_neighbor._ND_OPTION_TYPES[cls.option_type()] = cls return cls return _register_nd_option_type(args[0]) def __init__(self, res=0, dst='::', option=None): self.res = res self.dst = dst self.option = option @classmethod def parser(cls, buf, offset): (res, dst) = struct.unpack_from(cls._PACK_STR, buf, offset) offset += cls._MIN_LEN option = None if len(buf) > offset: (type_, length) = struct.unpack_from('!BB', buf, offset) if length == 0: raise struct.error('Invalid length: {len}'.format(len=length)) cls_ = cls._ND_OPTION_TYPES.get(type_) if cls_ is not None: option = cls_.parser(buf, offset) else: option = buf[offset:] msg = cls(res >> 29, addrconv.ipv6.bin_to_text(dst), option) return msg def serialize(self): res = self.res << 29 hdr = bytearray(struct.pack( nd_neighbor._PACK_STR, res, addrconv.ipv6.text_to_bin(self.dst))) if self.option is not None: if isinstance(self.option, nd_option): hdr.extend(self.option.serialize()) else: hdr.extend(self.option) return bytes(hdr) def __len__(self): length = self._MIN_LEN if self.option is not None: length += len(self.option) return length @icmpv6.register_icmpv6_type(ND_ROUTER_SOLICIT) class nd_router_solicit(_ICMPv6Payload): """ICMPv6 sub encoder/decoder class for Router Solicitation messages. (RFC 4861) This is used with os_ken.lib.packet.icmpv6.icmpv6. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|p{35em}| ============== ==================== Attribute Description ============== ==================== res This field is unused. It MUST be initialized to zero. option a derived object of os_ken.lib.packet.icmpv6.nd_option \ or a bytearray. None if no options. ============== ==================== """ _PACK_STR = '!I' _MIN_LEN = struct.calcsize(_PACK_STR) _ND_OPTION_TYPES = {} @staticmethod def register_nd_option_type(*args): def _register_nd_option_type(cls): nd_router_solicit._ND_OPTION_TYPES[cls.option_type()] = cls return cls return _register_nd_option_type(args[0]) def __init__(self, res=0, option=None): self.res = res self.option = option @classmethod def parser(cls, buf, offset): (res, ) = struct.unpack_from(cls._PACK_STR, buf, offset) offset += cls._MIN_LEN option = None if len(buf) > offset: (type_, length) = struct.unpack_from('!BB', buf, offset) if length == 0: raise struct.error('Invalid length: {len}'.format(len=length)) cls_ = cls._ND_OPTION_TYPES.get(type_) if cls_ is not None: option = cls_.parser(buf, offset) else: option = buf[offset:] msg = cls(res, option) return msg def serialize(self): hdr = bytearray(struct.pack( nd_router_solicit._PACK_STR, self.res)) if self.option is not None: if isinstance(self.option, nd_option): hdr.extend(self.option.serialize()) else: hdr.extend(self.option) return bytes(hdr) def __len__(self): length = self._MIN_LEN if self.option is not None: length += len(self.option) return length @icmpv6.register_icmpv6_type(ND_ROUTER_ADVERT) class nd_router_advert(_ICMPv6Payload): """ICMPv6 sub encoder/decoder class for Router Advertisement messages. (RFC 4861) This is used with os_ken.lib.packet.icmpv6.icmpv6. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|p{35em}| ============== ==================== Attribute Description ============== ==================== ch_l Cur Hop Limit. res M,O Flags for Router Advertisement. rou_l Router Lifetime. rea_t Reachable Time. ret_t Retrans Timer. options List of a derived object of \ os_ken.lib.packet.icmpv6.nd_option or a bytearray. \ None if no options. ============== ==================== """ _PACK_STR = '!BBHII' _MIN_LEN = struct.calcsize(_PACK_STR) _ND_OPTION_TYPES = {} @staticmethod def register_nd_option_type(*args): def _register_nd_option_type(cls): nd_router_advert._ND_OPTION_TYPES[cls.option_type()] = cls return cls return _register_nd_option_type(args[0]) def __init__(self, ch_l=0, res=0, rou_l=0, rea_t=0, ret_t=0, options=None): self.ch_l = ch_l self.res = res self.rou_l = rou_l self.rea_t = rea_t self.ret_t = ret_t options = options or [] assert isinstance(options, list) self.options = options @classmethod def parser(cls, buf, offset): (ch_l, res, rou_l, rea_t, ret_t ) = struct.unpack_from(cls._PACK_STR, buf, offset) offset += cls._MIN_LEN options = [] while len(buf) > offset: (type_, length) = struct.unpack_from('!BB', buf, offset) if length == 0: raise struct.error('Invalid length: {len}'.format(len=length)) cls_ = cls._ND_OPTION_TYPES.get(type_) if cls_ is not None: option = cls_.parser(buf, offset) else: option = buf[offset:offset + (length * 8)] options.append(option) offset += len(option) msg = cls(ch_l, res >> 6, rou_l, rea_t, ret_t, options) return msg def serialize(self): res = self.res << 6 hdr = bytearray(struct.pack( nd_router_advert._PACK_STR, self.ch_l, res, self.rou_l, self.rea_t, self.ret_t)) for option in self.options: if isinstance(option, nd_option): hdr.extend(option.serialize()) else: hdr.extend(option) return bytes(hdr) def __len__(self): length = self._MIN_LEN for option in self.options: length += len(option) return length class nd_option(stringify.StringifyMixin, metaclass=abc.ABCMeta): @classmethod @abc.abstractmethod def option_type(cls): pass @abc.abstractmethod def __init__(self, _type, length): self._type = _type self.length = length @classmethod @abc.abstractmethod def parser(cls, buf): pass @abc.abstractmethod def serialize(self): pass def __len__(self): return self._MIN_LEN class nd_option_la(nd_option): _PACK_STR = '!BB6s' _MIN_LEN = struct.calcsize(_PACK_STR) _TYPE = { 'ascii': [ 'hw_src' ] } @abc.abstractmethod def __init__(self, length, hw_src, data): super(nd_option_la, self).__init__(self.option_type(), length) self.hw_src = hw_src self.data = data @classmethod def parser(cls, buf, offset): (_, length, hw_src) = struct.unpack_from(cls._PACK_STR, buf, offset) msg = cls(length, addrconv.mac.bin_to_text(hw_src)) offset += cls._MIN_LEN if len(buf) > offset: msg.data = buf[offset:] return msg def serialize(self): buf = bytearray(struct.pack( self._PACK_STR, self.option_type(), self.length, addrconv.mac.text_to_bin(self.hw_src))) if self.data is not None: buf.extend(self.data) mod = len(buf) % 8 if mod: buf.extend(bytearray(8 - mod)) if 0 == self.length: self.length = len(buf) // 8 struct.pack_into('!B', buf, 1, self.length) return bytes(buf) def __len__(self): length = self._MIN_LEN if self.data is not None: length += len(self.data) return length @nd_neighbor.register_nd_option_type @nd_router_solicit.register_nd_option_type @nd_router_advert.register_nd_option_type class nd_option_sla(nd_option_la): """ICMPv6 sub encoder/decoder class for Neighbor discovery Source Link-Layer Address Option. (RFC 4861) This is used with os_ken.lib.packet.icmpv6.nd_neighbor, os_ken.lib.packet.icmpv6.nd_router_solicit or os_ken.lib.packet.icmpv6.nd_router_advert. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|p{35em}| ============== ==================== Attribute Description ============== ==================== length length of the option. \ (0 means automatically-calculate when encoding) hw_src Link-Layer Address. \ NOTE: If the address is longer than 6 octets this contains \ the first 6 octets in the address. \ This implementation assumes the address has at least \ 6 octets. data A bytearray which contains the rest of Link-Layer Address \ and padding. When encoding a packet, it's user's \ responsibility to provide necessary padding for 8-octets \ alignment required by the protocol. ============== ==================== """ @classmethod def option_type(cls): return ND_OPTION_SLA def __init__(self, length=0, hw_src='00:00:00:00:00:00', data=None): super(nd_option_sla, self).__init__(length, hw_src, data) @nd_neighbor.register_nd_option_type class nd_option_tla(nd_option_la): """ICMPv6 sub encoder/decoder class for Neighbor discovery Target Link-Layer Address Option. (RFC 4861) This is used with os_ken.lib.packet.icmpv6.nd_neighbor. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|p{35em}| ============== ==================== Attribute Description ============== ==================== length length of the option. \ (0 means automatically-calculate when encoding) hw_src Link-Layer Address. \ NOTE: If the address is longer than 6 octets this contains \ the first 6 octets in the address. \ This implementation assumes the address has at least \ 6 octets. data A bytearray which contains the rest of Link-Layer Address \ and padding. When encoding a packet, it's user's \ responsibility to provide necessary padding for 8-octets \ alignment required by the protocol. ============== ==================== """ @classmethod def option_type(cls): return ND_OPTION_TLA def __init__(self, length=0, hw_src='00:00:00:00:00:00', data=None): super(nd_option_tla, self).__init__(length, hw_src, data) @nd_router_advert.register_nd_option_type class nd_option_pi(nd_option): r"""ICMPv6 sub encoder/decoder class for Neighbor discovery Prefix Information Option. (RFC 4861) This is used with os_ken.lib.packet.icmpv6.nd_router_advert. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|p{35em}| ============== ==================== Attribute Description ============== ==================== length length of the option. \ (0 means automatically-calculate when encoding) pl Prefix Length. res1 L,A,R\* Flags for Prefix Information. val_l Valid Lifetime. pre_l Preferred Lifetime. res2 This field is unused. It MUST be initialized to zero. prefix An IP address or a prefix of an IP address. ============== ==================== \*R flag is defined in (RFC 3775) """ _PACK_STR = '!BBBBIII16s' _MIN_LEN = struct.calcsize(_PACK_STR) _TYPE = { 'ascii': [ 'prefix' ] } @classmethod def option_type(cls): return ND_OPTION_PI def __init__(self, length=0, pl=0, res1=0, val_l=0, pre_l=0, res2=0, prefix='::'): super(nd_option_pi, self).__init__(self.option_type(), length) self.pl = pl self.res1 = res1 self.val_l = val_l self.pre_l = pre_l self.res2 = res2 self.prefix = prefix @classmethod def parser(cls, buf, offset): (_, length, pl, res1, val_l, pre_l, res2, prefix ) = struct.unpack_from(cls._PACK_STR, buf, offset) msg = cls(length, pl, res1 >> 5, val_l, pre_l, res2, addrconv.ipv6.bin_to_text(prefix)) return msg def serialize(self): res1 = self.res1 << 5 hdr = bytearray(struct.pack( self._PACK_STR, self.option_type(), self.length, self.pl, res1, self.val_l, self.pre_l, self.res2, addrconv.ipv6.text_to_bin(self.prefix))) if 0 == self.length: self.length = len(hdr) // 8 struct.pack_into('!B', hdr, 1, self.length) return bytes(hdr) @nd_router_advert.register_nd_option_type class nd_option_mtu(nd_option): """ICMPv6 sub encoder/decoder class for Neighbor discovery MTU Option. (RFC 4861) This is used with os_ken.lib.packet.icmpv6.nd_router_advert. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|p{35em}| ============== ==================== Attribute Description ============== ==================== mtu MTU. ============== ==================== """ _PACK_STR = '!BBHI' _LEN = struct.calcsize(_PACK_STR) _OPTION_LEN = _LEN // 8 @classmethod def option_type(cls): return ND_OPTION_MTU def __init__(self, mtu=1500): super(nd_option_mtu, self).__init__(self.option_type(), 0) self.mtu = mtu @classmethod def parser(cls, buf, offset): (_, _, _, mtu) = struct.unpack_from(cls._PACK_STR, buf, offset) msg = cls(mtu) return msg def serialize(self): buf = bytearray(struct.pack( self._PACK_STR, self.option_type(), self._OPTION_LEN, 0, self.mtu)) return bytes(buf) @icmpv6.register_icmpv6_type(ICMPV6_ECHO_REPLY, ICMPV6_ECHO_REQUEST) class echo(_ICMPv6Payload): """ICMPv6 sub encoder/decoder class for Echo Request and Echo Reply messages. This is used with os_ken.lib.packet.icmpv6.icmpv6 for ICMPv6 Echo Request and Echo Reply messages. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. ============== ==================== Attribute Description ============== ==================== id Identifier seq Sequence Number data Data ============== ==================== """ _PACK_STR = '!HH' _MIN_LEN = struct.calcsize(_PACK_STR) def __init__(self, id_=0, seq=0, data=None): self.id = id_ self.seq = seq self.data = data @classmethod def parser(cls, buf, offset): (id_, seq) = struct.unpack_from(cls._PACK_STR, buf, offset) msg = cls(id_, seq) offset += cls._MIN_LEN if len(buf) > offset: msg.data = buf[offset:] return msg def serialize(self): hdr = bytearray(struct.pack(echo._PACK_STR, self.id, self.seq)) if self.data is not None: hdr += bytearray(self.data) return hdr def __len__(self): length = self._MIN_LEN if self.data is not None: length += len(self.data) return length @icmpv6.register_icmpv6_type( MLD_LISTENER_QUERY, MLD_LISTENER_REPOR, MLD_LISTENER_DONE) class mld(_ICMPv6Payload): """ICMPv6 sub encoder/decoder class for MLD Lister Query, MLD Listener Report, and MLD Listener Done messages. (RFC 2710) http://www.ietf.org/rfc/rfc2710.txt This is used with os_ken.lib.packet.icmpv6.icmpv6. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. ============== ========================================= Attribute Description ============== ========================================= maxresp max response time in millisecond. it is meaningful only in Query Message. address a group address value. ============== ========================================= """ _PACK_STR = '!H2x16s' _MIN_LEN = struct.calcsize(_PACK_STR) _TYPE = { 'ascii': [ 'address' ] } def __init__(self, maxresp=0, address='::'): self.maxresp = maxresp self.address = address @classmethod def parser(cls, buf, offset): if cls._MIN_LEN < len(buf[offset:]): msg = mldv2_query.parser(buf[offset:]) else: (maxresp, address) = struct.unpack_from( cls._PACK_STR, buf, offset) msg = cls(maxresp, addrconv.ipv6.bin_to_text(address)) return msg def serialize(self): buf = struct.pack(mld._PACK_STR, self.maxresp, addrconv.ipv6.text_to_bin(self.address)) return buf def __len__(self): return self._MIN_LEN class mldv2_query(mld): """ ICMPv6 sub encoder/decoder class for MLD v2 Lister Query messages. (RFC 3810) http://www.ietf.org/rfc/rfc3810.txt This is used with os_ken.lib.packet.icmpv6.icmpv6. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. ============== ========================================= Attribute Description ============== ========================================= maxresp max response time in millisecond. it is meaningful only in Query Message. address a group address value. s_flg when set to 1, routers suppress the timer process. qrv robustness variable for a querier. qqic an interval time for a querier in unit of seconds. num a number of the multicast servers. srcs a list of IPv6 addresses of the multicast servers. ============== ========================================= """ _PACK_STR = '!H2x16sBBH' _MIN_LEN = struct.calcsize(_PACK_STR) _TYPE = { 'ascii': [ 'address' ], 'asciilist': [ 'srcs' ] } def __init__(self, maxresp=0, address='::', s_flg=0, qrv=2, qqic=0, num=0, srcs=None): super(mldv2_query, self).__init__(maxresp, address) self.s_flg = s_flg self.qrv = qrv self.qqic = qqic self.num = num srcs = srcs or [] assert isinstance(srcs, list) for src in srcs: assert isinstance(src, str) self.srcs = srcs @classmethod def parser(cls, buf): (maxresp, address, s_qrv, qqic, num ) = struct.unpack_from(cls._PACK_STR, buf) s_flg = (s_qrv >> 3) & 0b1 qrv = s_qrv & 0b111 offset = cls._MIN_LEN srcs = [] while 0 < len(buf[offset:]) and num > len(srcs): assert 16 <= len(buf[offset:]) (src, ) = struct.unpack_from('16s', buf, offset) srcs.append(addrconv.ipv6.bin_to_text(src)) offset += 16 assert num == len(srcs) return cls(maxresp, addrconv.ipv6.bin_to_text(address), s_flg, qrv, qqic, num, srcs) def serialize(self): s_qrv = self.s_flg << 3 | self.qrv buf = bytearray(struct.pack(self._PACK_STR, self.maxresp, addrconv.ipv6.text_to_bin(self.address), s_qrv, self.qqic, self.num)) for src in self.srcs: buf.extend(struct.pack('16s', addrconv.ipv6.text_to_bin(src))) if 0 == self.num: self.num = len(self.srcs) struct.pack_into('!H', buf, 22, self.num) return bytes(buf) def __len__(self): return self._MIN_LEN + len(self.srcs) * 16 @icmpv6.register_icmpv6_type(MLDV2_LISTENER_REPORT) class mldv2_report(mld): """ ICMPv6 sub encoder/decoder class for MLD v2 Lister Report messages. (RFC 3810) http://www.ietf.org/rfc/rfc3810.txt This is used with os_ken.lib.packet.icmpv6.icmpv6. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. ============== ========================================= Attribute Description ============== ========================================= record_num a number of the group records. records a list of os_ken.lib.packet.icmpv6.mldv2_report_group. None if no records. ============== ========================================= """ _PACK_STR = '!2xH' _MIN_LEN = struct.calcsize(_PACK_STR) _class_prefixes = ['mldv2_report_group'] def __init__(self, record_num=0, records=None): self.record_num = record_num records = records or [] assert isinstance(records, list) for record in records: assert isinstance(record, mldv2_report_group) self.records = records @classmethod def parser(cls, buf, offset): (record_num, ) = struct.unpack_from(cls._PACK_STR, buf, offset) offset += cls._MIN_LEN records = [] while 0 < len(buf[offset:]) and record_num > len(records): record = mldv2_report_group.parser(buf[offset:]) records.append(record) offset += len(record) assert record_num == len(records) return cls(record_num, records) def serialize(self): buf = bytearray(struct.pack(self._PACK_STR, self.record_num)) for record in self.records: buf.extend(record.serialize()) if 0 == self.record_num: self.record_num = len(self.records) struct.pack_into('!H', buf, 2, self.record_num) return bytes(buf) def __len__(self): records_len = 0 for record in self.records: records_len += len(record) return self._MIN_LEN + records_len class mldv2_report_group(stringify.StringifyMixin): r""" ICMPv6 sub encoder/decoder class for MLD v2 Lister Report Group Record messages. (RFC 3810) This is used with os_ken.lib.packet.icmpv6.mldv2_report. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. =============== ==================================================== Attribute Description =============== ==================================================== type\_ a group record type for v3. aux_len the length of the auxiliary data in 32-bit words. num a number of the multicast servers. address a group address value. srcs a list of IPv6 addresses of the multicast servers. aux the auxiliary data. =============== ==================================================== """ _PACK_STR = '!BBH16s' _MIN_LEN = struct.calcsize(_PACK_STR) _TYPE = { 'ascii': [ 'address' ], 'asciilist': [ 'srcs' ] } def __init__(self, type_=0, aux_len=0, num=0, address='::', srcs=None, aux=None): self.type_ = type_ self.aux_len = aux_len self.num = num self.address = address srcs = srcs or [] assert isinstance(srcs, list) for src in srcs: assert isinstance(src, str) self.srcs = srcs self.aux = aux @classmethod def parser(cls, buf): (type_, aux_len, num, address ) = struct.unpack_from(cls._PACK_STR, buf) offset = cls._MIN_LEN srcs = [] while 0 < len(buf[offset:]) and num > len(srcs): assert 16 <= len(buf[offset:]) (src, ) = struct.unpack_from('16s', buf, offset) srcs.append(addrconv.ipv6.bin_to_text(src)) offset += 16 assert num == len(srcs) aux = None if aux_len: (aux, ) = struct.unpack_from('%ds' % (aux_len * 4), buf, offset) msg = cls(type_, aux_len, num, addrconv.ipv6.bin_to_text(address), srcs, aux) return msg def serialize(self): buf = bytearray(struct.pack(self._PACK_STR, self.type_, self.aux_len, self.num, addrconv.ipv6.text_to_bin(self.address))) for src in self.srcs: buf.extend(struct.pack('16s', addrconv.ipv6.text_to_bin(src))) if 0 == self.num: self.num = len(self.srcs) struct.pack_into('!H', buf, 2, self.num) if self.aux is not None: mod = len(self.aux) % 4 if mod: self.aux += bytearray(4 - mod) self.aux = bytes(self.aux) buf.extend(self.aux) if 0 == self.aux_len: self.aux_len = len(self.aux) // 4 struct.pack_into('!B', buf, 1, self.aux_len) return bytes(buf) def __len__(self): return self._MIN_LEN + len(self.srcs) * 16 + self.aux_len * 4 icmpv6.set_classes(icmpv6._ICMPV6_TYPES) nd_neighbor.set_classes(nd_neighbor._ND_OPTION_TYPES) nd_router_solicit.set_classes(nd_router_solicit._ND_OPTION_TYPES) nd_router_advert.set_classes(nd_router_advert._ND_OPTION_TYPES) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/packet/igmp.py0000664000175000017500000004562500000000000017626 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone 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. """ Internet Group Management Protocol(IGMP) packet parser/serializer [RFC 1112] IGMP v1 format:: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |Version| Type | Unused | Checksum | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Group Address | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ [RFC 2236] IGMP v2 format:: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Type | Max Resp Time | Checksum | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Group Address | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ [RFC 3376] IGMP v3 Membership Query format:: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Type = 0x11 | Max Resp Code | Checksum | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Group Address | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Resv |S| QRV | QQIC | Number of Sources (N) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Source Address [1] | +- -+ | Source Address [2] | +- . -+ . . . . . . +- -+ | Source Address [N] | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ IGMP v3 Membership Report format:: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Type = 0x22 | Reserved | Checksum | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Reserved | Number of Group Records (M) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | . . . Group Record [1] . . . | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | . . . Group Record [2] . . . | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | . | . . . | . | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | . . . Group Record [M] . . . | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Where each Group Record has the following internal format:: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Record Type | Aux Data Len | Number of Sources (N) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Multicast Address | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Source Address [1] | +- -+ | Source Address [2] | +- -+ . . . . . . . . . +- -+ | Source Address [N] | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | . . . Auxiliary Data . . . | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ """ import struct from math import trunc from os_ken.lib import addrconv from os_ken.lib import stringify from os_ken.lib.packet import packet_base from os_ken.lib.packet import packet_utils IGMP_TYPE_QUERY = 0x11 IGMP_TYPE_REPORT_V1 = 0x12 IGMP_TYPE_REPORT_V2 = 0x16 IGMP_TYPE_LEAVE = 0x17 IGMP_TYPE_REPORT_V3 = 0x22 QUERY_RESPONSE_INTERVAL = 10.0 LAST_MEMBER_QUERY_INTERVAL = 1.0 MULTICAST_IP_ALL_HOST = '224.0.0.1' MULTICAST_MAC_ALL_HOST = '01:00:5e:00:00:01' # for types of IGMPv3 Report Group Records MODE_IS_INCLUDE = 1 MODE_IS_EXCLUDE = 2 CHANGE_TO_INCLUDE_MODE = 3 CHANGE_TO_EXCLUDE_MODE = 4 ALLOW_NEW_SOURCES = 5 BLOCK_OLD_SOURCES = 6 class igmp(packet_base.PacketBase): """ Internet Group Management Protocol(IGMP, RFC 1112, RFC 2236) header encoder/decoder class. http://www.ietf.org/rfc/rfc1112.txt http://www.ietf.org/rfc/rfc2236.txt An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. =============== ==================================================== Attribute Description =============== ==================================================== msgtype a message type for v2, or a combination of version and a message type for v1. maxresp max response time in unit of 1/10 second. it is meaningful only in Query Message. csum a check sum value. 0 means automatically-calculate when encoding. address a group address value. =============== ==================================================== """ _PACK_STR = '!BBH4s' _MIN_LEN = struct.calcsize(_PACK_STR) _TYPE = { 'ascii': [ 'address' ] } def __init__(self, msgtype=IGMP_TYPE_QUERY, maxresp=0, csum=0, address='0.0.0.0'): super(igmp, self).__init__() self.msgtype = msgtype self.maxresp = maxresp self.csum = csum self.address = address @classmethod def parser(cls, buf): assert cls._MIN_LEN <= len(buf) (msgtype, ) = struct.unpack_from('!B', buf) if (IGMP_TYPE_QUERY == msgtype and igmpv3_query.MIN_LEN <= len(buf)): (instance, subclass, rest,) = igmpv3_query.parser(buf) elif IGMP_TYPE_REPORT_V3 == msgtype: (instance, subclass, rest,) = igmpv3_report.parser(buf) else: (msgtype, maxresp, csum, address ) = struct.unpack_from(cls._PACK_STR, buf) instance = cls(msgtype, maxresp, csum, addrconv.ipv4.bin_to_text(address)) subclass = None rest = buf[cls._MIN_LEN:] return instance, subclass, rest def serialize(self, payload, prev): hdr = bytearray(struct.pack(self._PACK_STR, self.msgtype, trunc(self.maxresp), self.csum, addrconv.ipv4.text_to_bin(self.address))) if self.csum == 0: self.csum = packet_utils.checksum(hdr) struct.pack_into('!H', hdr, 2, self.csum) return hdr class igmpv3_query(igmp): """ Internet Group Management Protocol(IGMP, RFC 3376) Membership Query message encoder/decoder class. http://www.ietf.org/rfc/rfc3376.txt An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| =============== ==================================================== Attribute Description =============== ==================================================== msgtype a message type for v3. maxresp max response time in unit of 1/10 second. csum a check sum value. 0 means automatically-calculate when encoding. address a group address value. s_flg when set to 1, routers suppress the timer process. qrv robustness variable for a querier. qqic an interval time for a querier in unit of seconds. num a number of the multicast servers. srcs a list of IPv4 addresses of the multicast servers. =============== ==================================================== """ _PACK_STR = '!BBH4sBBH' _MIN_LEN = struct.calcsize(_PACK_STR) MIN_LEN = _MIN_LEN _TYPE = { 'ascii': [ 'address' ], 'asciilist': [ 'srcs' ] } def __init__(self, msgtype=IGMP_TYPE_QUERY, maxresp=100, csum=0, address='0.0.0.0', s_flg=0, qrv=2, qqic=0, num=0, srcs=None): super(igmpv3_query, self).__init__( msgtype, maxresp, csum, address) self.s_flg = s_flg self.qrv = qrv self.qqic = qqic self.num = num srcs = srcs or [] assert isinstance(srcs, list) for src in srcs: assert isinstance(src, str) self.srcs = srcs @classmethod def parser(cls, buf): (msgtype, maxresp, csum, address, s_qrv, qqic, num ) = struct.unpack_from(cls._PACK_STR, buf) s_flg = (s_qrv >> 3) & 0b1 qrv = s_qrv & 0b111 offset = cls._MIN_LEN srcs = [] while 0 < len(buf[offset:]) and num > len(srcs): assert 4 <= len(buf[offset:]) (src, ) = struct.unpack_from('4s', buf, offset) srcs.append(addrconv.ipv4.bin_to_text(src)) offset += 4 assert num == len(srcs) return (cls(msgtype, maxresp, csum, addrconv.ipv4.bin_to_text(address), s_flg, qrv, qqic, num, srcs), None, buf[offset:]) def serialize(self, payload, prev): s_qrv = self.s_flg << 3 | self.qrv buf = bytearray(struct.pack(self._PACK_STR, self.msgtype, trunc(self.maxresp), self.csum, addrconv.ipv4.text_to_bin(self.address), s_qrv, trunc(self.qqic), self.num)) for src in self.srcs: buf.extend(struct.pack('4s', addrconv.ipv4.text_to_bin(src))) if 0 == self.num: self.num = len(self.srcs) struct.pack_into('!H', buf, 10, self.num) if 0 == self.csum: self.csum = packet_utils.checksum(buf) struct.pack_into('!H', buf, 2, self.csum) return bytes(buf) def __len__(self): return self._MIN_LEN + len(self.srcs) * 4 class igmpv3_report(igmp): """ Internet Group Management Protocol(IGMP, RFC 3376) Membership Report message encoder/decoder class. http://www.ietf.org/rfc/rfc3376.txt An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| =============== ==================================================== Attribute Description =============== ==================================================== msgtype a message type for v3. csum a check sum value. 0 means automatically-calculate when encoding. record_num a number of the group records. records a list of os_ken.lib.packet.igmp.igmpv3_report_group. None if no records. =============== ==================================================== """ _PACK_STR = '!BxH2xH' _MIN_LEN = struct.calcsize(_PACK_STR) _class_prefixes = ['igmpv3_report_group'] def __init__(self, msgtype=IGMP_TYPE_REPORT_V3, csum=0, record_num=0, records=None): self.msgtype = msgtype self.csum = csum self.record_num = record_num records = records or [] assert isinstance(records, list) for record in records: assert isinstance(record, igmpv3_report_group) self.records = records @classmethod def parser(cls, buf): (msgtype, csum, record_num ) = struct.unpack_from(cls._PACK_STR, buf) offset = cls._MIN_LEN records = [] while 0 < len(buf[offset:]) and record_num > len(records): record = igmpv3_report_group.parser(buf[offset:]) records.append(record) offset += len(record) assert record_num == len(records) return (cls(msgtype, csum, record_num, records), None, buf[offset:]) def serialize(self, payload, prev): buf = bytearray(struct.pack(self._PACK_STR, self.msgtype, self.csum, self.record_num)) for record in self.records: buf.extend(record.serialize()) if 0 == self.record_num: self.record_num = len(self.records) struct.pack_into('!H', buf, 6, self.record_num) if 0 == self.csum: self.csum = packet_utils.checksum(buf) struct.pack_into('!H', buf, 2, self.csum) return bytes(buf) def __len__(self): records_len = 0 for record in self.records: records_len += len(record) return self._MIN_LEN + records_len class igmpv3_report_group(stringify.StringifyMixin): r""" Internet Group Management Protocol(IGMP, RFC 3376) Membership Report Group Record message encoder/decoder class. http://www.ietf.org/rfc/rfc3376.txt This is used with os_ken.lib.packet.igmp.igmpv3_report. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| =============== ==================================================== Attribute Description =============== ==================================================== type\_ a group record type for v3. aux_len the length of the auxiliary data. num a number of the multicast servers. address a group address value. srcs a list of IPv4 addresses of the multicast servers. aux the auxiliary data. =============== ==================================================== """ _PACK_STR = '!BBH4s' _MIN_LEN = struct.calcsize(_PACK_STR) _TYPE = { 'ascii': [ 'address' ], 'asciilist': [ 'srcs' ] } def __init__(self, type_=0, aux_len=0, num=0, address='0.0.0.0', srcs=None, aux=None): self.type_ = type_ self.aux_len = aux_len self.num = num self.address = address srcs = srcs or [] assert isinstance(srcs, list) for src in srcs: assert isinstance(src, str) self.srcs = srcs self.aux = aux @classmethod def parser(cls, buf): (type_, aux_len, num, address ) = struct.unpack_from(cls._PACK_STR, buf) offset = cls._MIN_LEN srcs = [] while 0 < len(buf[offset:]) and num > len(srcs): assert 4 <= len(buf[offset:]) (src, ) = struct.unpack_from('4s', buf, offset) srcs.append(addrconv.ipv4.bin_to_text(src)) offset += 4 assert num == len(srcs) aux = None if aux_len: (aux, ) = struct.unpack_from('%ds' % (aux_len * 4), buf, offset) return cls(type_, aux_len, num, addrconv.ipv4.bin_to_text(address), srcs, aux) def serialize(self): buf = bytearray(struct.pack(self._PACK_STR, self.type_, self.aux_len, self.num, addrconv.ipv4.text_to_bin(self.address))) for src in self.srcs: buf.extend(struct.pack('4s', addrconv.ipv4.text_to_bin(src))) if 0 == self.num: self.num = len(self.srcs) struct.pack_into('!H', buf, 2, self.num) if self.aux is not None: mod = len(self.aux) % 4 if mod: self.aux += bytearray(4 - mod) self.aux = bytes(self.aux) buf.extend(self.aux) if 0 == self.aux_len: self.aux_len = len(self.aux) // 4 struct.pack_into('!B', buf, 1, self.aux_len) return bytes(buf) def __len__(self): return self._MIN_LEN + len(self.srcs) * 4 + self.aux_len * 4 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/packet/in_proto.py0000664000175000017500000000161300000000000020510 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone 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. IPPROTO_IP = 0 IPPROTO_HOPOPTS = 0 IPPROTO_ICMP = 1 IPPROTO_IGMP = 2 IPPROTO_TCP = 6 IPPROTO_UDP = 17 IPPROTO_ROUTING = 43 IPPROTO_FRAGMENT = 44 IPPROTO_GRE = 47 IPPROTO_AH = 51 IPPROTO_ICMPV6 = 58 IPPROTO_NONE = 59 IPPROTO_DSTOPTS = 60 IPPROTO_OSPF = 89 IPPROTO_VRRP = 112 IPPROTO_SCTP = 132 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/packet/ipv4.py0000664000175000017500000001266400000000000017551 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone 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. import struct from . import packet_base from . import packet_utils from . import icmp from . import igmp from . import udp from . import tcp from . import sctp from . import ospf from . import gre from . import in_proto as inet from os_ken.lib import addrconv IPV4_ADDRESS_PACK_STR = '!I' IPV4_ADDRESS_LEN = struct.calcsize(IPV4_ADDRESS_PACK_STR) IPV4_PSEUDO_HEADER_PACK_STR = '!4s4s2xHH' class ipv4(packet_base.PacketBase): """IPv4 (RFC 791) header encoder/decoder class. NOTE: When decoding, this implementation tries to decode the upper layer protocol even for a fragmented datagram. It isn't likely what a user would want. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. IPv4 addresses are represented as a string like '192.0.2.1'. __init__ takes the corresponding args in this order. ============== ======================================== ================== Attribute Description Example ============== ======================================== ================== version Version header_length IHL tos Type of Service total_length Total Length (0 means automatically-calculate when encoding) identification Identification flags Flags offset Fragment Offset ttl Time to Live proto Protocol csum Header Checksum (Ignored and automatically-calculated when encoding) src Source Address '192.0.2.1' dst Destination Address '192.0.2.2' option A bytearray which contains the entire Options, or None for no Options ============== ======================================== ================== """ _PACK_STR = '!BBHHHBBH4s4s' _MIN_LEN = struct.calcsize(_PACK_STR) _TYPE = { 'ascii': [ 'src', 'dst' ] } def __init__(self, version=4, header_length=5, tos=0, total_length=0, identification=0, flags=0, offset=0, ttl=255, proto=0, csum=0, src='10.0.0.1', dst='10.0.0.2', option=None): super(ipv4, self).__init__() self.version = version self.header_length = header_length self.tos = tos self.total_length = total_length self.identification = identification self.flags = flags self.offset = offset self.ttl = ttl self.proto = proto self.csum = csum self.src = src self.dst = dst self.option = option def __len__(self): return self.header_length * 4 @classmethod def parser(cls, buf): (version, tos, total_length, identification, flags, ttl, proto, csum, src, dst) = struct.unpack_from(cls._PACK_STR, buf) header_length = version & 0xf version = version >> 4 offset = flags & ((1 << 13) - 1) flags = flags >> 13 length = header_length * 4 if length > ipv4._MIN_LEN: option = buf[ipv4._MIN_LEN:length] else: option = None msg = cls(version, header_length, tos, total_length, identification, flags, offset, ttl, proto, csum, addrconv.ipv4.bin_to_text(src), addrconv.ipv4.bin_to_text(dst), option) return msg, ipv4.get_packet_type(proto), buf[length:total_length] def serialize(self, payload, prev): length = len(self) hdr = bytearray(length) version = self.version << 4 | self.header_length flags = self.flags << 13 | self.offset if self.total_length == 0: self.total_length = self.header_length * 4 + len(payload) struct.pack_into(ipv4._PACK_STR, hdr, 0, version, self.tos, self.total_length, self.identification, flags, self.ttl, self.proto, 0, addrconv.ipv4.text_to_bin(self.src), addrconv.ipv4.text_to_bin(self.dst)) if self.option: assert (length - ipv4._MIN_LEN) >= len(self.option) hdr[ipv4._MIN_LEN:ipv4._MIN_LEN + len(self.option)] = self.option self.csum = packet_utils.checksum(hdr) struct.pack_into('!H', hdr, 10, self.csum) return hdr ipv4.register_packet_type(icmp.icmp, inet.IPPROTO_ICMP) ipv4.register_packet_type(igmp.igmp, inet.IPPROTO_IGMP) ipv4.register_packet_type(tcp.tcp, inet.IPPROTO_TCP) ipv4.register_packet_type(udp.udp, inet.IPPROTO_UDP) ipv4.register_packet_type(sctp.sctp, inet.IPPROTO_SCTP) ipv4.register_packet_type(ospf.ospf, inet.IPPROTO_OSPF) ipv4.register_packet_type(gre.gre, inet.IPPROTO_GRE) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/packet/ipv6.py0000664000175000017500000005106600000000000017552 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone 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. import abc import struct from . import packet_base from . import icmpv6 from . import tcp from . import udp from . import sctp from . import gre from . import in_proto as inet from os_ken.lib import addrconv from os_ken.lib import stringify IPV6_ADDRESS_PACK_STR = '!16s' IPV6_ADDRESS_LEN = struct.calcsize(IPV6_ADDRESS_PACK_STR) IPV6_PSEUDO_HEADER_PACK_STR = '!16s16s3xB' class ipv6(packet_base.PacketBase): """IPv6 (RFC 2460) header encoder/decoder class. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. IPv6 addresses are represented as a string like 'ff02::1'. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|p{30em}|l| ============== ======================================== ================== Attribute Description Example ============== ======================================== ================== version Version traffic_class Traffic Class flow_label When decoding, Flow Label. When encoding, the most significant 8 bits of Flow Label. payload_length Payload Length nxt Next Header hop_limit Hop Limit src Source Address 'ff02::1' dst Destination Address '::' ext_hdrs Extension Headers ============== ======================================== ================== """ _PACK_STR = '!IHBB16s16s' _MIN_LEN = struct.calcsize(_PACK_STR) _IPV6_EXT_HEADER_TYPE = {} _TYPE = { 'ascii': [ 'src', 'dst' ] } @staticmethod def register_header_type(type_): def _register_header_type(cls): ipv6._IPV6_EXT_HEADER_TYPE[type_] = cls return cls return _register_header_type def __init__(self, version=6, traffic_class=0, flow_label=0, payload_length=0, nxt=inet.IPPROTO_TCP, hop_limit=255, src='10::10', dst='20::20', ext_hdrs=None): super(ipv6, self).__init__() self.version = version self.traffic_class = traffic_class self.flow_label = flow_label self.payload_length = payload_length self.nxt = nxt self.hop_limit = hop_limit self.src = src self.dst = dst ext_hdrs = ext_hdrs or [] assert isinstance(ext_hdrs, list) for ext_hdr in ext_hdrs: assert isinstance(ext_hdr, header) self.ext_hdrs = ext_hdrs @classmethod def parser(cls, buf): (v_tc_flow, payload_length, nxt, hlim, src, dst) = struct.unpack_from( cls._PACK_STR, buf) version = v_tc_flow >> 28 traffic_class = (v_tc_flow >> 20) & 0xff flow_label = v_tc_flow & 0xfffff hop_limit = hlim offset = cls._MIN_LEN last = nxt ext_hdrs = [] while True: cls_ = cls._IPV6_EXT_HEADER_TYPE.get(last) if not cls_: break hdr = cls_.parser(buf[offset:]) ext_hdrs.append(hdr) offset += len(hdr) last = hdr.nxt msg = cls(version, traffic_class, flow_label, payload_length, nxt, hop_limit, addrconv.ipv6.bin_to_text(src), addrconv.ipv6.bin_to_text(dst), ext_hdrs) return (msg, ipv6.get_packet_type(last), buf[offset:offset + payload_length]) def serialize(self, payload, prev): hdr = bytearray(40) v_tc_flow = (self.version << 28 | self.traffic_class << 20 | self.flow_label) struct.pack_into(ipv6._PACK_STR, hdr, 0, v_tc_flow, self.payload_length, self.nxt, self.hop_limit, addrconv.ipv6.text_to_bin(self.src), addrconv.ipv6.text_to_bin(self.dst)) if self.ext_hdrs: for ext_hdr in self.ext_hdrs: hdr.extend(ext_hdr.serialize()) if 0 == self.payload_length: payload_length = len(payload) for ext_hdr in self.ext_hdrs: payload_length += len(ext_hdr) self.payload_length = payload_length struct.pack_into('!H', hdr, 4, self.payload_length) return hdr def __len__(self): ext_hdrs_len = 0 for ext_hdr in self.ext_hdrs: ext_hdrs_len += len(ext_hdr) return self._MIN_LEN + ext_hdrs_len ipv6.register_packet_type(icmpv6.icmpv6, inet.IPPROTO_ICMPV6) ipv6.register_packet_type(tcp.tcp, inet.IPPROTO_TCP) ipv6.register_packet_type(udp.udp, inet.IPPROTO_UDP) ipv6.register_packet_type(sctp.sctp, inet.IPPROTO_SCTP) ipv6.register_packet_type(gre.gre, inet.IPPROTO_GRE) class header(stringify.StringifyMixin, metaclass=abc.ABCMeta): """extension header abstract class.""" def __init__(self, nxt): self.nxt = nxt @classmethod @abc.abstractmethod def parser(cls, buf): pass @abc.abstractmethod def serialize(self): pass @abc.abstractmethod def __len__(self): pass class opt_header(header): """an abstract class for Hop-by-Hop Options header and destination header.""" _PACK_STR = '!BB' _MIN_LEN = struct.calcsize(_PACK_STR) _FIX_SIZE = 8 _class_prefixes = ['option'] @abc.abstractmethod def __init__(self, nxt, size, data): super(opt_header, self).__init__(nxt) assert not (size % 8) self.size = size self.data = data @classmethod def parser(cls, buf): (nxt, len_) = struct.unpack_from(cls._PACK_STR, buf) data_len = cls._FIX_SIZE + int(len_) data = [] size = cls._MIN_LEN while size < data_len: (type_, ) = struct.unpack_from('!B', buf[size:]) if type_ == 0: opt = option(type_, -1, None) size += 1 else: opt = option.parser(buf[size:]) size += len(opt) data.append(opt) return cls(nxt, len_, data) def serialize(self): buf = struct.pack(self._PACK_STR, self.nxt, self.size) buf = bytearray(buf) if self.data is None: self.data = [option(type_=1, len_=4, data=b'\x00\x00\x00\x00')] for opt in self.data: buf.extend(opt.serialize()) return buf def __len__(self): return self._FIX_SIZE + self.size @ipv6.register_header_type(inet.IPPROTO_HOPOPTS) class hop_opts(opt_header): """IPv6 (RFC 2460) Hop-by-Hop Options header encoder/decoder class. This is used with os_ken.lib.packet.ipv6.ipv6. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============== ======================================= Attribute Description ============== ======================================= nxt Next Header size the length of the Hop-by-Hop Options header, not include the first 8 octet. data IPv6 options. ============== ======================================= """ TYPE = inet.IPPROTO_HOPOPTS def __init__(self, nxt=inet.IPPROTO_TCP, size=0, data=None): super(hop_opts, self).__init__(nxt, size, data) @ipv6.register_header_type(inet.IPPROTO_DSTOPTS) class dst_opts(opt_header): """IPv6 (RFC 2460) destination header encoder/decoder class. This is used with os_ken.lib.packet.ipv6.ipv6. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============== ======================================= Attribute Description ============== ======================================= nxt Next Header size the length of the destination header, not include the first 8 octet. data IPv6 options. ============== ======================================= """ TYPE = inet.IPPROTO_DSTOPTS def __init__(self, nxt=inet.IPPROTO_TCP, size=0, data=None): super(dst_opts, self).__init__(nxt, size, data) class option(stringify.StringifyMixin): r"""IPv6 (RFC 2460) Options header encoder/decoder class. This is used with os_ken.lib.packet.ipv6.hop_opts or os_ken.lib.packet.ipv6.dst_opts. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============== ======================================= Attribute Description ============== ======================================= type\_ option type. len\_ the length of data. -1 if type\_ is 0. data an option value. None if len\_ is 0 or -1. ============== ======================================= """ _PACK_STR = '!BB' _MIN_LEN = struct.calcsize(_PACK_STR) def __init__(self, type_=0, len_=-1, data=None): self.type_ = type_ self.len_ = len_ self.data = data @classmethod def parser(cls, buf): (type_, ) = struct.unpack_from('!B', buf) if not type_: cls_ = cls(type_, -1, None) else: data = None (type_, len_) = struct.unpack_from(cls._PACK_STR, buf) if len_: form = "%ds" % len_ (data, ) = struct.unpack_from(form, buf, cls._MIN_LEN) cls_ = cls(type_, len_, data) return cls_ def serialize(self): data = None if not self.type_: data = struct.pack('!B', self.type_) elif not self.len_: data = struct.pack(self._PACK_STR, self.type_, self.len_) else: form = "%ds" % self.len_ data = struct.pack(self._PACK_STR + form, self.type_, self.len_, self.data) return data def __len__(self): return self._MIN_LEN + self.len_ @ipv6.register_header_type(inet.IPPROTO_ROUTING) class routing(header): """An IPv6 Routing Header decoder class. This class has only the parser method. IPv6 Routing Header types. http://www.iana.org/assignments/ipv6-parameters/ipv6-parameters.xhtml +-----------+----------------------------------+-------------------+ | Value | Description | Reference | +===========+==================================+===================+ | 0 | Source Route (DEPRECATED) | [[IPV6]][RFC5095] | +-----------+----------------------------------+-------------------+ | 1 | Nimrod (DEPRECATED 2009-05-06) | | +-----------+----------------------------------+-------------------+ | 2 | Type 2 Routing Header | [RFC6275] | +-----------+----------------------------------+-------------------+ | 3 | RPL Source Route Header | [RFC6554] | +-----------+----------------------------------+-------------------+ | 4 - 252 | Unassigned | | +-----------+----------------------------------+-------------------+ | 253 | RFC3692-style Experiment 1 [2] | [RFC4727] | +-----------+----------------------------------+-------------------+ | 254 | RFC3692-style Experiment 2 [2] | [RFC4727] | +-----------+----------------------------------+-------------------+ | 255 | Reserved | | +-----------+----------------------------------+-------------------+ """ TYPE = inet.IPPROTO_ROUTING _OFFSET_LEN = struct.calcsize('!2B') # IPv6 Routing Header Type ROUTING_TYPE_2 = 0x02 ROUTING_TYPE_3 = 0x03 @classmethod def parser(cls, buf): (type_, ) = struct.unpack_from('!B', buf, cls._OFFSET_LEN) switch = { # TODO: make parsers of type2. cls.ROUTING_TYPE_2: None, cls.ROUTING_TYPE_3: routing_type3 } cls_ = switch.get(type_) if cls_: return cls_.parser(buf) else: return None class routing_type3(header): """ An IPv6 Routing Header for Source Routes with the RPL (RFC 6554) encoder/decoder class. This is used with os_ken.lib.packet.ipv6.ipv6. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============== ======================================= Attribute Description ============== ======================================= nxt Next Header size The length of the Routing header, not include the first 8 octet. (0 means automatically-calculate when encoding) type Identifies the particular Routing header variant. seg Number of route segments remaining. cmpi Number of prefix octets from segments 1 through n-1. cmpe Number of prefix octets from segment n. pad Number of octets that are used for padding after Address[n] at the end of the SRH. adrs Vector of addresses, numbered 1 to n. ============== ======================================= """ _PACK_STR = '!BBBBBB2x' _MIN_LEN = struct.calcsize(_PACK_STR) _TYPE = { 'asciilist': [ 'adrs' ] } def __init__(self, nxt=inet.IPPROTO_TCP, size=0, type_=3, seg=0, cmpi=0, cmpe=0, adrs=None): super(routing_type3, self).__init__(nxt) self.size = size self.type_ = type_ self.seg = seg self.cmpi = cmpi self.cmpe = cmpe adrs = adrs or [] assert isinstance(adrs, list) self.adrs = adrs self._pad = (8 - ((len(self.adrs) - 1) * (16 - self.cmpi) + (16 - self.cmpe) % 8)) % 8 @classmethod def _get_size(cls, size): return (int(size) + 1) * 8 @classmethod def parser(cls, buf): (nxt, size, type_, seg, cmp_, pad) = struct.unpack_from( cls._PACK_STR, buf) data = cls._MIN_LEN header_len = cls._get_size(size) cmpi = int(cmp_ >> 4) cmpe = int(cmp_ & 0xf) pad = int(pad >> 4) adrs = [] if size: # Address[1..n-1] has size (16 - CmprI) octets adrs_len_i = 16 - cmpi # Address[n] has size (16 - CmprE) octets adrs_len_e = 16 - cmpe form_i = "%ds" % adrs_len_i form_e = "%ds" % adrs_len_e while data < (header_len - (adrs_len_e + pad)): (adr, ) = struct.unpack_from(form_i, buf[data:]) adr = (b'\x00' * cmpi) + adr adrs.append(addrconv.ipv6.bin_to_text(adr)) data += adrs_len_i (adr, ) = struct.unpack_from(form_e, buf[data:]) adr = (b'\x00' * cmpe) + adr adrs.append(addrconv.ipv6.bin_to_text(adr)) return cls(nxt, size, type_, seg, cmpi, cmpe, adrs) def serialize(self): if self.size == 0: self.size = ((len(self.adrs) - 1) * (16 - self.cmpi) + (16 - self.cmpe) + self._pad) // 8 buf = struct.pack(self._PACK_STR, self.nxt, self.size, self.type_, self.seg, (self.cmpi << 4) | self.cmpe, self._pad << 4) buf = bytearray(buf) if self.size: form_i = "%ds" % (16 - self.cmpi) form_e = "%ds" % (16 - self.cmpe) slice_i = slice(self.cmpi, 16) slice_e = slice(self.cmpe, 16) for adr in self.adrs[:-1]: buf.extend( struct.pack( form_i, addrconv.ipv6.text_to_bin(adr)[slice_i])) buf.extend(struct.pack( form_e, addrconv.ipv6.text_to_bin(self.adrs[-1])[slice_e])) return buf def __len__(self): return routing_type3._get_size(self.size) @ipv6.register_header_type(inet.IPPROTO_FRAGMENT) class fragment(header): r"""IPv6 (RFC 2460) fragment header encoder/decoder class. This is used with os_ken.lib.packet.ipv6.ipv6. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============== ======================================= Attribute Description ============== ======================================= nxt Next Header offset offset, in 8-octet units, relative to the start of the fragmentable part of the original packet. more 1 means more fragments follow; 0 means last fragment. id\_ packet identification value. ============== ======================================= """ TYPE = inet.IPPROTO_FRAGMENT _PACK_STR = '!BxHI' _MIN_LEN = struct.calcsize(_PACK_STR) def __init__(self, nxt=inet.IPPROTO_TCP, offset=0, more=0, id_=0): super(fragment, self).__init__(nxt) self.offset = offset self.more = more self.id_ = id_ @classmethod def parser(cls, buf): (nxt, off_m, id_) = struct.unpack_from(cls._PACK_STR, buf) offset = off_m >> 3 more = off_m & 0x1 return cls(nxt, offset, more, id_) def serialize(self): off_m = (self.offset << 3 | self.more) buf = struct.pack(self._PACK_STR, self.nxt, off_m, self.id_) return buf def __len__(self): return self._MIN_LEN @ipv6.register_header_type(inet.IPPROTO_AH) class auth(header): """IP Authentication header (RFC 2402) encoder/decoder class. This is used with os_ken.lib.packet.ipv6.ipv6. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============== ======================================= Attribute Description ============== ======================================= nxt Next Header size the length of the Authentication Header in 64-bit words, subtracting 1. spi security parameters index. seq sequence number. data authentication data. ============== ======================================= """ TYPE = inet.IPPROTO_AH _PACK_STR = '!BB2xII' _MIN_LEN = struct.calcsize(_PACK_STR) def __init__(self, nxt=inet.IPPROTO_TCP, size=2, spi=0, seq=0, data=b'\x00\x00\x00\x00'): super(auth, self).__init__(nxt) assert data is not None self.size = size self.spi = spi self.seq = seq self.data = data @classmethod def _get_size(cls, size): return (int(size) + 2) * 4 @classmethod def parser(cls, buf): (nxt, size, spi, seq) = struct.unpack_from(cls._PACK_STR, buf) form = "%ds" % (cls._get_size(size) - cls._MIN_LEN) (data, ) = struct.unpack_from(form, buf, cls._MIN_LEN) return cls(nxt, size, spi, seq, data) def serialize(self): buf = struct.pack(self._PACK_STR, self.nxt, self.size, self.spi, self.seq) buf = bytearray(buf) form = "%ds" % (auth._get_size(self.size) - self._MIN_LEN) buf.extend(struct.pack(form, self.data)) return buf def __len__(self): return auth._get_size(self.size) ipv6.set_classes(ipv6._IPV6_EXT_HEADER_TYPE) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/packet/linux.py0000664000175000017500000000433300000000000020020 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone 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. import struct from . import packet_base from . import vlan from . import mpls from . import ether_types as ether from os_ken.lib import addrconv class linuxcooked(packet_base.PacketBase): _PACK_STR = '!HHH8sH' _MIN_LEN = struct.calcsize(_PACK_STR) def __init__(self, pkt_type, arphrd_type, address_length, address, proto_type): super(linuxcooked, self).__init__() self.pkt_type = pkt_type self.arphrd_type = arphrd_type self.address_length = address_length self.address = address self.proto_type = proto_type @classmethod def parser(cls, buf): (pkt_type, arphrd_type, address_length, addres, proto_type) = struct.unpack_from(cls._PACK_STR, buf) l = cls(pkt_type, arphrd_type, address_length, addres, proto_type) return (l, linuxcooked.get_packet_type(proto_type), buf[linuxcooked._MIN_LEN:]) @classmethod def get_packet_type(cls, type_): """Override method for the ethernet IEEE802.3 Length/Type field (self.ethertype). If the value of Length/Type field is less than or equal to 1500 decimal(05DC hexadecimal), it means Length interpretation and be passed to the LLC sublayer.""" if type_ <= ether.ETH_TYPE_IEEE802_3: type_ = ether.ETH_TYPE_IEEE802_3 return cls._TYPES.get(type_) # copy vlan _TYPES linuxcooked._TYPES = vlan.vlan._TYPES linuxcooked.register_packet_type(vlan.vlan, ether.ETH_TYPE_8021Q) linuxcooked.register_packet_type(vlan.svlan, ether.ETH_TYPE_8021AD) linuxcooked.register_packet_type(mpls.mpls, ether.ETH_TYPE_MPLS) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/packet/llc.py0000664000175000017500000002461500000000000017440 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone 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. """ Logical Link Control(LLC, IEEE 802.2) parser/serializer http://standards.ieee.org/getieee802/download/802.2-1998.pdf LLC format:: +-----------------+--------------+ | DSAP address | 8 bits | +-----------------+--------------+ | SSAP address | 8 bits | +-----------------+--------------+ | Control | 8 or 16 bits | +-----------------+--------------+ DSAP address field:: LSB +-----+---+---+---+---+---+---+---+ | I/G | D | D | D | D | D | D | D | +-----+---+---+---+---+---+---+---+ I/G bit = 0 : Individual DSAP I/G bit = 1 : Group DSA D : DSAP address SSAP address field:: LSB +-----+---+---+---+---+---+---+---+ | C/R | S | S | S | S | S | S | S | +-----+---+---+---+---+---+---+---+ C/R bit = 0 : Command C/R bit = 1 : Response S : SSAP address Control field: Information transfer command/response (I-format PDU):: 1 2 3 4 5 6 7 8 9 10-16 +---+---+---+---+---+---+---+---+-----+------+ | 0 | N(S) | P/F | N(R) | +---+---+---+---+---+---+---+---+-----+------+ Supervisory commands/responses (S-format PDUs):: 1 2 3 4 5 6 7 8 9 10-16 +---+---+---+---+---+---+---+---+-----+------+ | 1 0 | S S | 0 0 0 0 | P/F | N(R) | +---+---+---+---+---+---+---+---+-----+------+ Unnumbered commands/responses (U-format PDUs):: 1 2 3 4 5 6 7 8 +---+---+----+---+-----+---+----+---+ | 1 1 | M1 M1 | P/F | M2 M2 M2 | +---+---+----+---+-----+---+----+---+ N(S) : sender send sequence number (Bit 2=lower-order-bit) N(R) : sender receive sequence number (Bit 10=lower-order-bit) S : supervisory function bit M1/M2: modifier function bit P/F : poll bit - command LLC PDUs final bit - response LLC PDUs """ import struct from . import bpdu from . import packet_base from os_ken.lib import stringify SAP_BPDU = 0x42 class llc(packet_base.PacketBase): """LLC(IEEE 802.2) header encoder/decoder class. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| =============== =============================================== Attribute Description =============== =============================================== dsap_addr Destination service access point address field \ includes I/G bit at least significant bit. ssap_addr Source service access point address field \ includes C/R bit at least significant bit. control Control field \ [16 bits for formats that include sequence \ numbering, and 8 bits for formats that do not]. \ Either os_ken.lib.packet.llc.ControlFormatI or \ os_ken.lib.packet.llc.ControlFormatS or \ os_ken.lib.packet.llc.ControlFormatU object. =============== =============================================== """ _PACK_STR = '!BB' _PACK_LEN = struct.calcsize(_PACK_STR) _CTR_TYPES = {} _CTR_PACK_STR = '!2xB' _MIN_LEN = _PACK_LEN @staticmethod def register_control_type(register_cls): llc._CTR_TYPES[register_cls.TYPE] = register_cls return register_cls def __init__(self, dsap_addr, ssap_addr, control): super(llc, self).__init__() assert getattr(control, 'TYPE', None) in self._CTR_TYPES self.dsap_addr = dsap_addr self.ssap_addr = ssap_addr self.control = control @classmethod def parser(cls, buf): assert len(buf) >= cls._PACK_LEN (dsap_addr, ssap_addr) = struct.unpack_from(cls._PACK_STR, buf) (control,) = struct.unpack_from(cls._CTR_PACK_STR, buf) ctrl = cls._get_control(control) control, information = ctrl.parser(buf[cls._PACK_LEN:]) return (cls(dsap_addr, ssap_addr, control), cls.get_packet_type(dsap_addr), information) def serialize(self, payload, prev): addr = struct.pack(self._PACK_STR, self.dsap_addr, self.ssap_addr) control = self.control.serialize() return addr + control @classmethod def _get_control(cls, buf): key = buf & 0b1 if buf & 0b1 == ControlFormatI.TYPE else buf & 0b11 return cls._CTR_TYPES[key] @llc.register_control_type class ControlFormatI(stringify.StringifyMixin): """LLC sub encoder/decoder class for control I-format field. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. ======================== =============================== Attribute Description ======================== =============================== send_sequence_number sender send sequence number pf_bit poll/final bit receive_sequence_number sender receive sequence number ======================== =============================== """ TYPE = 0b0 _PACK_STR = '!H' _PACK_LEN = struct.calcsize(_PACK_STR) def __init__(self, send_sequence_number=0, pf_bit=0, receive_sequence_number=0): super(ControlFormatI, self).__init__() self.send_sequence_number = send_sequence_number self.pf_bit = pf_bit self.receive_sequence_number = receive_sequence_number @classmethod def parser(cls, buf): assert len(buf) >= cls._PACK_LEN (control,) = struct.unpack_from(cls._PACK_STR, buf) assert (control >> 8) & 0b1 == cls.TYPE send_sequence_number = (control >> 9) & 0b1111111 pf_bit = (control >> 8) & 0b1 receive_sequence_number = (control >> 1) & 0b1111111 return cls(send_sequence_number, pf_bit, receive_sequence_number), buf[cls._PACK_LEN:] def serialize(self): control = (self.send_sequence_number << 9 | self.TYPE << 8 | self.receive_sequence_number << 1 | self.pf_bit) return struct.pack(self._PACK_STR, control) @llc.register_control_type class ControlFormatS(stringify.StringifyMixin): """LLC sub encoder/decoder class for control S-format field. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. ======================== =============================== Attribute Description ======================== =============================== supervisory_function supervisory function bit pf_bit poll/final bit receive_sequence_number sender receive sequence number ======================== =============================== """ TYPE = 0b01 _PACK_STR = '!H' _PACK_LEN = struct.calcsize(_PACK_STR) def __init__(self, supervisory_function=0, pf_bit=0, receive_sequence_number=0): super(ControlFormatS, self).__init__() self.supervisory_function = supervisory_function self.pf_bit = pf_bit self.receive_sequence_number = receive_sequence_number @classmethod def parser(cls, buf): assert len(buf) >= cls._PACK_LEN (control,) = struct.unpack_from(cls._PACK_STR, buf) assert (control >> 8) & 0b11 == cls.TYPE supervisory_function = (control >> 10) & 0b11 pf_bit = (control >> 8) & 0b1 receive_sequence_number = (control >> 1) & 0b1111111 return cls(supervisory_function, pf_bit, receive_sequence_number), buf[cls._PACK_LEN:] def serialize(self): control = (self.supervisory_function << 10 | self.TYPE << 8 | self.receive_sequence_number << 1 | self.pf_bit) return struct.pack(self._PACK_STR, control) @llc.register_control_type class ControlFormatU(stringify.StringifyMixin): """LLC sub encoder/decoder class for control U-format field. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. ======================== =============================== Attribute Description ======================== =============================== modifier_function1 modifier function bit pf_bit poll/final bit modifier_function2 modifier function bit ======================== =============================== """ TYPE = 0b11 _PACK_STR = '!B' _PACK_LEN = struct.calcsize(_PACK_STR) def __init__(self, modifier_function1=0, pf_bit=0, modifier_function2=0): super(ControlFormatU, self).__init__() self.modifier_function1 = modifier_function1 self.pf_bit = pf_bit self.modifier_function2 = modifier_function2 @classmethod def parser(cls, buf): assert len(buf) >= cls._PACK_LEN (control,) = struct.unpack_from(cls._PACK_STR, buf) assert control & 0b11 == cls.TYPE modifier_function1 = (control >> 2) & 0b11 pf_bit = (control >> 4) & 0b1 modifier_function2 = (control >> 5) & 0b111 return cls(modifier_function1, pf_bit, modifier_function2), buf[cls._PACK_LEN:] def serialize(self): control = (self.modifier_function2 << 5 | self.pf_bit << 4 | self.modifier_function1 << 2 | self.TYPE) return struct.pack(self._PACK_STR, control) llc.register_packet_type(bpdu.bpdu, SAP_BPDU) llc.set_classes(llc._CTR_TYPES) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/packet/lldp.py0000664000175000017500000005172200000000000017620 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2012 Isaku Yamahata # # 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. """ Link Layer Discovery Protocol(LLDP, IEEE 802.1AB) http://standards.ieee.org/getieee802/download/802.1AB-2009.pdf basic TLV format:: octets | 1 | 2 | 3 ... n + 2 | -------------------------------------------------------- | TLV type | TLV information | TLV information string | | (7bits) | string length | (0-507 octets) | | | (9bits) | | -------------------------------------------------------- bits |8 2|1|8 1| Organizationally specific TLV format:: octets | 1 | 2 | 3 ... 5 | 6 | 7 ... n + 6 | --------------------------------------------------------------- | TLV type | Length | OUI | Subtype | Infomation | | (7bits) | (9bits) | (24bits) | (8bits) | (0-507 octets) | --------------------------------------------------------------- bits |8 2|1|8 1| LLDPDU format:: ------------------------------------------------------------------------ | Chassis ID | Port ID | TTL | optional TLV | ... | optional TLV | End | ------------------------------------------------------------------------ Chasis ID, Port ID, TTL, End are mandatory optional TLV may be inserted in any order """ import struct from os_ken.lib import stringify from os_ken.lib.packet import packet_base # LLDP destination MAC address LLDP_MAC_NEAREST_BRIDGE = '01:80:c2:00:00:0e' LLDP_MAC_NEAREST_NON_TPMR_BRIDGE = '01:80:c2:00:00:03' LLDP_MAC_NEAREST_CUSTOMER_BRIDGE = '01:80:c2:00:00:00' LLDP_TLV_TYPELEN_STR = '!H' LLDP_TLV_SIZE = 2 LLDP_TLV_TYPE_MASK = 0xfe00 LLDP_TLV_TYPE_SHIFT = 9 LLDP_TLV_LENGTH_MASK = 0x01ff # LLDP TLV type LLDP_TLV_END = 0 # End of LLDPDU LLDP_TLV_CHASSIS_ID = 1 # Chassis ID LLDP_TLV_PORT_ID = 2 # Port ID LLDP_TLV_TTL = 3 # Time To Live LLDP_TLV_PORT_DESCRIPTION = 4 # Port Description LLDP_TLV_SYSTEM_NAME = 5 # System Name LLDP_TLV_SYSTEM_DESCRIPTION = 6 # System Description LLDP_TLV_SYSTEM_CAPABILITIES = 7 # System Capabilities LLDP_TLV_MANAGEMENT_ADDRESS = 8 # Management Address LLDP_TLV_ORGANIZATIONALLY_SPECIFIC = 127 # organizationally Specific TLVs class LLDPBasicTLV(stringify.StringifyMixin): _LEN_MIN = 0 _LEN_MAX = 511 tlv_type = None def __init__(self, buf=None, *_args, **_kwargs): super(LLDPBasicTLV, self).__init__() if buf: (self.typelen, ) = struct.unpack( LLDP_TLV_TYPELEN_STR, buf[:LLDP_TLV_SIZE]) tlv_type = \ (self.typelen & LLDP_TLV_TYPE_MASK) >> LLDP_TLV_TYPE_SHIFT assert self.tlv_type == tlv_type self.len = self.typelen & LLDP_TLV_LENGTH_MASK assert len(buf) >= self.len + LLDP_TLV_SIZE self.tlv_info = buf[LLDP_TLV_SIZE:] self.tlv_info = self.tlv_info[:self.len] @staticmethod def get_type(buf): (typelen, ) = struct.unpack(LLDP_TLV_TYPELEN_STR, buf[:LLDP_TLV_SIZE]) return (typelen & LLDP_TLV_TYPE_MASK) >> LLDP_TLV_TYPE_SHIFT @staticmethod def set_tlv_type(subcls, tlv_type): assert issubclass(subcls, LLDPBasicTLV) subcls.tlv_type = tlv_type def _len_valid(self): return self._LEN_MIN <= self.len and self.len <= self._LEN_MAX class lldp(packet_base.PacketBase): """LLDPDU encoder/decoder class. An instance has the following attributes at least. ============== ===================================== Attribute Description ============== ===================================== tlvs List of TLV instance. ============== ===================================== """ _tlv_parsers = {} def __init__(self, tlvs): super(lldp, self).__init__() self.tlvs = tlvs # at least it must have chassis id, port id, ttl and end def _tlvs_len_valid(self): return len(self.tlvs) >= 4 # chassis id, port id, ttl and end def _tlvs_valid(self): return (self.tlvs[0].tlv_type == LLDP_TLV_CHASSIS_ID and self.tlvs[1].tlv_type == LLDP_TLV_PORT_ID and self.tlvs[2].tlv_type == LLDP_TLV_TTL and self.tlvs[-1].tlv_type == LLDP_TLV_END) @classmethod def _parser(cls, buf): tlvs = [] while buf: tlv_type = LLDPBasicTLV.get_type(buf) tlv = cls._tlv_parsers[tlv_type](buf) tlvs.append(tlv) offset = LLDP_TLV_SIZE + tlv.len buf = buf[offset:] if tlv.tlv_type == LLDP_TLV_END: break assert len(buf) > 0 lldp_pkt = cls(tlvs) assert lldp_pkt._tlvs_len_valid() assert lldp_pkt._tlvs_valid() return lldp_pkt, None, buf @classmethod def parser(cls, buf): try: return cls._parser(buf) except: return None, None, buf def serialize(self, payload, prev): data = bytearray() for tlv in self.tlvs: data += tlv.serialize() return data @classmethod def set_type(cls, tlv_cls): cls._tlv_parsers[tlv_cls.tlv_type] = tlv_cls @classmethod def get_type(cls, tlv_type): return cls._tlv_parsers[tlv_type] @classmethod def set_tlv_type(cls, tlv_type): def _set_type(tlv_cls): tlv_cls.set_tlv_type(tlv_cls, tlv_type) cls.set_type(tlv_cls) return tlv_cls return _set_type def __len__(self): return sum(LLDP_TLV_SIZE + tlv.len for tlv in self.tlvs) @lldp.set_tlv_type(LLDP_TLV_END) class End(LLDPBasicTLV): """End TLV encoder/decoder class ============== ===================================== Attribute Description ============== ===================================== buf Binary data to parse. ============== ===================================== """ def __init__(self, buf=None, *args, **kwargs): super(End, self).__init__(buf, *args, **kwargs) if buf: pass else: self.len = 0 self.typelen = 0 def serialize(self): return struct.pack('!H', self.typelen) @lldp.set_tlv_type(LLDP_TLV_CHASSIS_ID) class ChassisID(LLDPBasicTLV): """Chassis ID TLV encoder/decoder class ============== ===================================== Attribute Description ============== ===================================== buf Binary data to parse. subtype Subtype. chassis_id Chassis id corresponding to subtype. ============== ===================================== """ _PACK_STR = '!B' _PACK_SIZE = struct.calcsize(_PACK_STR) # subtype id(1 octet) + chassis id length(1 - 255 octet) _LEN_MIN = 2 _LEN_MAX = 256 # Chassis ID subtype SUB_CHASSIS_COMPONENT = 1 # EntPhysicalAlias (IETF RFC 4133) SUB_INTERFACE_ALIAS = 2 # IfAlias (IETF RFC 2863) SUB_PORT_COMPONENT = 3 # EntPhysicalAlias (IETF RFC 4133) SUB_MAC_ADDRESS = 4 # MAC address (IEEE std 802) SUB_NETWORK_ADDRESS = 5 # networkAddress SUB_INTERFACE_NAME = 6 # IfName (IETF RFC 2863) SUB_LOCALLY_ASSIGNED = 7 # local def __init__(self, buf=None, *args, **kwargs): super(ChassisID, self).__init__(buf, *args, **kwargs) if buf: (self.subtype, ) = struct.unpack( self._PACK_STR, self.tlv_info[:self._PACK_SIZE]) self.chassis_id = self.tlv_info[self._PACK_SIZE:] else: self.subtype = kwargs['subtype'] self.chassis_id = kwargs['chassis_id'] self.len = self._PACK_SIZE + len(self.chassis_id) assert self._len_valid() self.typelen = (self.tlv_type << LLDP_TLV_TYPE_SHIFT) | self.len def serialize(self): return struct.pack('!HB', self.typelen, self.subtype) + self.chassis_id @lldp.set_tlv_type(LLDP_TLV_PORT_ID) class PortID(LLDPBasicTLV): """Port ID TLV encoder/decoder class ============== ===================================== Attribute Description ============== ===================================== buf Binary data to parse. subtype Subtype. port_id Port ID corresponding to subtype. ============== ===================================== """ _PACK_STR = '!B' _PACK_SIZE = struct.calcsize(_PACK_STR) # subtype id(1 octet) + port id length(1 - 255 octet) _LEN_MIN = 2 _LEN_MAX = 256 # Port ID subtype SUB_INTERFACE_ALIAS = 1 # ifAlias (IETF RFC 2863) SUB_PORT_COMPONENT = 2 # entPhysicalAlias (IETF RFC 4133) SUB_MAC_ADDRESS = 3 # MAC address (IEEE Std 802) SUB_NETWORK_ADDRESS = 4 # networkAddress SUB_INTERFACE_NAME = 5 # ifName (IETF RFC 2863) SUB_AGENT_CIRCUIT_ID = 6 # agent circuit ID(IETF RFC 3046) SUB_LOCALLY_ASSIGNED = 7 # local def __init__(self, buf=None, *args, **kwargs): super(PortID, self).__init__(buf, *args, **kwargs) if buf: (self.subtype, ) = struct.unpack( self._PACK_STR, self.tlv_info[:self._PACK_SIZE]) self.port_id = self.tlv_info[self._PACK_SIZE:] else: self.subtype = kwargs['subtype'] self.port_id = kwargs['port_id'] self.len = self._PACK_SIZE + len(self.port_id) assert self._len_valid() self.typelen = (self.tlv_type << LLDP_TLV_TYPE_SHIFT) | self.len def serialize(self): return struct.pack('!HB', self.typelen, self.subtype) + self.port_id @lldp.set_tlv_type(LLDP_TLV_TTL) class TTL(LLDPBasicTLV): """Time To Live TLV encoder/decoder class ============== ===================================== Attribute Description ============== ===================================== buf Binary data to parse. ttl Time To Live. ============== ===================================== """ _PACK_STR = '!H' _PACK_SIZE = struct.calcsize(_PACK_STR) _LEN_MIN = _PACK_SIZE _LEN_MAX = _PACK_SIZE def __init__(self, buf=None, *args, **kwargs): super(TTL, self).__init__(buf, *args, **kwargs) if buf: (self.ttl, ) = struct.unpack( self._PACK_STR, self.tlv_info[:self._PACK_SIZE]) else: self.ttl = kwargs['ttl'] self.len = self._PACK_SIZE assert self._len_valid() self.typelen = (self.tlv_type << LLDP_TLV_TYPE_SHIFT) | self.len def serialize(self): return struct.pack('!HH', self.typelen, self.ttl) @lldp.set_tlv_type(LLDP_TLV_PORT_DESCRIPTION) class PortDescription(LLDPBasicTLV): """Port description TLV encoder/decoder class ================= ===================================== Attribute Description ================= ===================================== buf Binary data to parse. port_description Port description. ================= ===================================== """ _LEN_MAX = 255 def __init__(self, buf=None, *args, **kwargs): super(PortDescription, self).__init__(buf, *args, **kwargs) if buf: pass else: self.port_description = kwargs['port_description'] self.len = len(self.port_description) assert self._len_valid() self.typelen = (self.tlv_type << LLDP_TLV_TYPE_SHIFT) | self.len def serialize(self): return struct.pack('!H', self.typelen) + self.port_description @property def port_description(self): return self.tlv_info @port_description.setter def port_description(self, value): self.tlv_info = value @lldp.set_tlv_type(LLDP_TLV_SYSTEM_NAME) class SystemName(LLDPBasicTLV): """System name TLV encoder/decoder class ================= ===================================== Attribute Description ================= ===================================== buf Binary data to parse. system_name System name. ================= ===================================== """ _LEN_MAX = 255 def __init__(self, buf=None, *args, **kwargs): super(SystemName, self).__init__(buf, *args, **kwargs) if buf: pass else: self.system_name = kwargs['system_name'] self.len = len(self.system_name) assert self._len_valid() self.typelen = (self.tlv_type << LLDP_TLV_TYPE_SHIFT) | self.len def serialize(self): return struct.pack('!H', self.typelen) + self.tlv_info @property def system_name(self): return self.tlv_info @system_name.setter def system_name(self, value): self.tlv_info = value @lldp.set_tlv_type(LLDP_TLV_SYSTEM_DESCRIPTION) class SystemDescription(LLDPBasicTLV): """System description TLV encoder/decoder class =================== ===================================== Attribute Description =================== ===================================== buf Binary data to parse. system_description System description. =================== ===================================== """ _LEN_MAX = 255 def __init__(self, buf=None, *args, **kwargs): super(SystemDescription, self).__init__(buf, *args, **kwargs) if buf: pass else: self.system_description = kwargs['system_description'] self.len = len(self.system_description) assert self._len_valid() self.typelen = (self.tlv_type << LLDP_TLV_TYPE_SHIFT) | self.len def serialize(self): return struct.pack('!H', self.typelen) + self.tlv_info @property def system_description(self): return self.tlv_info @system_description.setter def system_description(self, value): self.tlv_info = value @lldp.set_tlv_type(LLDP_TLV_SYSTEM_CAPABILITIES) class SystemCapabilities(LLDPBasicTLV): """System Capabilities TLV encoder/decoder class ================= ===================================== Attribute Description ================= ===================================== buf Binary data to parse. system_cap System Capabilities. enabled_cap Enabled Capabilities. ================= ===================================== """ # system cap(2) + enabled cap(2) _PACK_STR = '!HH' _PACK_SIZE = struct.calcsize(_PACK_STR) _LEN_MIN = _PACK_SIZE _LEN_MAX = _PACK_SIZE # System Capabilities CAP_REPEATER = (1 << 1) # IETF RFC 2108 CAP_MAC_BRIDGE = (1 << 2) # IEEE Std 802.1D CAP_WLAN_ACCESS_POINT = (1 << 3) # IEEE Std 802.11 MIB CAP_ROUTER = (1 << 4) # IETF RFC 1812 CAP_TELEPHONE = (1 << 5) # IETF RFC 4293 CAP_DOCSIS = (1 << 6) # IETF RFC 4639 and IETF RFC 4546 CAP_STATION_ONLY = (1 << 7) # IETF RFC 4293 CAP_CVLAN = (1 << 8) # IEEE Std 802.1Q CAP_SVLAN = (1 << 9) # IEEE Std 802.1Q CAP_TPMR = (1 << 10) # IEEE Std 802.1Q def __init__(self, buf=None, *args, **kwargs): super(SystemCapabilities, self).__init__(buf, *args, **kwargs) if buf: (self.system_cap, self.enabled_cap) = struct.unpack( self._PACK_STR, self.tlv_info[:self._PACK_SIZE]) else: self.system_cap = kwargs['system_cap'] self.enabled_cap = kwargs['enabled_cap'] self.len = self._PACK_SIZE assert self._len_valid() self.typelen = (self.tlv_type << LLDP_TLV_TYPE_SHIFT) | self.len def serialize(self): return struct.pack('!HHH', self.typelen, self.system_cap, self.enabled_cap) @lldp.set_tlv_type(LLDP_TLV_MANAGEMENT_ADDRESS) class ManagementAddress(LLDPBasicTLV): """Management Address TLV encoder/decoder class ================= ===================================== Attribute Description ================= ===================================== buf Binary data to parse. addr_subtype Address type. addr Device address. intf_subtype Interface type. intf_num Interface number. oid Object ID. ================= ===================================== """ _LEN_MIN = 9 _LEN_MAX = 167 _ADDR_PACK_STR = '!BB' # address string length, address subtype _ADDR_PACK_SIZE = struct.calcsize(_ADDR_PACK_STR) _ADDR_LEN_MIN = 1 _ADDR_LEN_MAX = 31 _INTF_PACK_STR = '!BIB' # interface subtype, interface number, oid length _INTF_PACK_SIZE = struct.calcsize(_INTF_PACK_STR) _OID_LEN_MIN = 0 _OID_LEN_MAX = 128 def __init__(self, buf=None, *args, **kwargs): super(ManagementAddress, self).__init__(buf, *args, **kwargs) if buf: (self.addr_len, self.addr_subtype) = struct.unpack( self._ADDR_PACK_STR, self.tlv_info[:self._ADDR_PACK_SIZE]) assert self._addr_len_valid() offset = self._ADDR_PACK_SIZE + self.addr_len - 1 self.addr = self.tlv_info[self._ADDR_PACK_SIZE:offset] (self.intf_subtype, self.intf_num, self.oid_len) = struct.unpack( self._INTF_PACK_STR, self.tlv_info[offset:offset + self._INTF_PACK_SIZE]) assert self._oid_len_valid() offset = offset + self._INTF_PACK_SIZE self.oid = self.tlv_info[offset:] else: self.addr_subtype = kwargs['addr_subtype'] self.addr = kwargs['addr'] self.addr_len = len(self.addr) + 1 # 1 octet subtype assert self._addr_len_valid() self.intf_subtype = kwargs['intf_subtype'] self.intf_num = kwargs['intf_num'] self.oid = kwargs['oid'] self.oid_len = len(self.oid) assert self._oid_len_valid() self.len = self._ADDR_PACK_SIZE + self.addr_len - 1 \ + self._INTF_PACK_SIZE + self.oid_len assert self._len_valid() self.typelen = (self.tlv_type << LLDP_TLV_TYPE_SHIFT) | self.len def serialize(self): tlv_info = struct.pack(self._ADDR_PACK_STR, self.addr_len, self.addr_subtype) tlv_info += self.addr tlv_info += struct.pack(self._INTF_PACK_STR, self.intf_subtype, self.intf_num, self.oid_len) tlv_info += self.oid return struct.pack('!H', self.typelen) + tlv_info def _addr_len_valid(self): return (self._ADDR_LEN_MIN <= self.addr_len or self.addr_len <= self._ADDR_LEN_MAX) def _oid_len_valid(self): return self._OID_LEN_MIN <= self.oid_len <= self._OID_LEN_MAX @lldp.set_tlv_type(LLDP_TLV_ORGANIZATIONALLY_SPECIFIC) class OrganizationallySpecific(LLDPBasicTLV): """Organizationally Specific TLV encoder/decoder class ================= ============================================= Attribute Description ================= ============================================= buf Binary data to parse. oui Organizationally unique ID. subtype Organizationally defined subtype. info Organizationally defined information string. ================= ============================================= """ _PACK_STR = '!3sB' _PACK_SIZE = struct.calcsize(_PACK_STR) _LEN_MIN = _PACK_SIZE _LEN_MAX = 511 def __init__(self, buf=None, *args, **kwargs): super(OrganizationallySpecific, self).__init__(buf, *args, **kwargs) if buf: (self.oui, self.subtype) = struct.unpack( self._PACK_STR, self.tlv_info[:self._PACK_SIZE]) self.info = self.tlv_info[self._PACK_SIZE:] else: self.oui = kwargs['oui'] self.subtype = kwargs['subtype'] self.info = kwargs['info'] self.len = self._PACK_SIZE + len(self.info) assert self._len_valid() self.typelen = (self.tlv_type << LLDP_TLV_TYPE_SHIFT) | self.len def serialize(self): return struct.pack('!H3sB', self.typelen, self.oui, self.subtype) + self.info lldp.set_classes(lldp._tlv_parsers) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/packet/mpls.py0000664000175000017500000000530500000000000017634 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone 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. import struct from . import packet_base from os_ken.lib import type_desc class mpls(packet_base.PacketBase): """MPLS (RFC 3032) header encoder/decoder class. NOTE: When decoding, this implementation assumes that the inner protocol is IPv4. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. ============== ==================== Attribute Description ============== ==================== label Label Value exp Experimental Use bsb Bottom of Stack ttl Time To Live ============== ==================== """ _PACK_STR = '!I' _MIN_LEN = struct.calcsize(_PACK_STR) def __init__(self, label=0, exp=0, bsb=1, ttl=255): super(mpls, self).__init__() self.label = label self.exp = exp self.bsb = bsb self.ttl = ttl @classmethod def parser(cls, buf): (label,) = struct.unpack_from(cls._PACK_STR, buf) ttl = label & 0xff bsb = (label >> 8) & 1 exp = (label >> 9) & 7 label = label >> 12 msg = cls(label, exp, bsb, ttl) if bsb: from . import ipv4 return msg, ipv4.ipv4, buf[msg._MIN_LEN:] else: return msg, mpls, buf[msg._MIN_LEN:] def serialize(self, payload, prev): val = self.label << 12 | self.exp << 9 | self.bsb << 8 | self.ttl return struct.pack(mpls._PACK_STR, val) def label_from_bin(buf): """ Converts binary representation label to integer. :param buf: Binary representation of label. :return: MPLS Label and BoS bit. """ mpls_label = type_desc.Int3.to_user(bytes(buf)) return mpls_label >> 4, mpls_label & 1 def label_to_bin(mpls_label, is_bos=True): """ Converts integer label to binary representation. :param mpls_label: MPLS Label. :param is_bos: BoS bit. :return: Binary representation of label. """ return type_desc.Int3.from_user(mpls_label << 4 | is_bos) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/packet/openflow.py0000664000175000017500000000764200000000000020520 0ustar00zuulzuul00000000000000# Copyright (C) 2017 Nippon Telegraph and Telephone 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. import struct from os_ken.lib import stringify from . import packet_base class openflow(packet_base.PacketBase): """OpenFlow message encoder/decoder class. An instance has the following attributes at least. ============== ========================================================= Attribute Description ============== ========================================================= msg An instance of OpenFlow message (see :ref:`ofproto_ref`) or an instance of OFPUnparseableMsg if failed to parse packet as OpenFlow message. ============== ========================================================= """ PACK_STR = '!BBHI' _MIN_LEN = struct.calcsize(PACK_STR) def __init__(self, msg): super(openflow, self).__init__() self.msg = msg @classmethod def parser(cls, buf): from os_ken.ofproto import ofproto_parser from os_ken.ofproto import ofproto_protocol (version, msg_type, msg_len, xid) = ofproto_parser.header(buf) msg_parser = ofproto_parser._MSG_PARSERS.get(version) if msg_parser is None: msg = OFPUnparseableMsg( None, version, msg_type, msg_len, xid, buf[cls._MIN_LEN:msg_len]) return cls(msg), cls, buf[msg_len:] datapath = ofproto_protocol.ProtocolDesc(version=version) try: msg = msg_parser(datapath, version, msg_type, msg_len, xid, buf[:msg_len]) except: msg = OFPUnparseableMsg( datapath, version, msg_type, msg_len, xid, buf[datapath.ofproto.OFP_HEADER_SIZE:msg_len]) return cls(msg), cls, buf[msg_len:] def serialize(self, _payload, _prev): self.msg.serialize() return self.msg.buf class OFPUnparseableMsg(stringify.StringifyMixin): """Unparseable OpenFlow message encoder class. An instance has the following attributes at least. ============== ====================================================== Attribute Description ============== ====================================================== datapath A os_ken.ofproto.ofproto_protocol.ProtocolDesc instance for this message or None if OpenFlow protocol version is unsupported version. version OpenFlow protocol version msg_type Type of OpenFlow message msg_len Length of the message xid Transaction id body OpenFlow body data ============== ====================================================== .. Note:: "datapath" attribute is different from os_ken.controller.controller.Datapath. So you can not use "datapath" attribute to send OpenFlow messages. For example, "datapath" attribute does not have send_msg method. """ def __init__(self, datapath, version, msg_type, msg_len, xid, body): self.datapath = datapath self.version = version self.msg_type = msg_type self.msg_len = msg_len self.xid = xid self.body = body self.buf = None def serialize(self): self.buf = struct.pack( openflow.PACK_STR, self.version, self.msg_type, self.msg_len, self.xid) self.buf += self.body ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/packet/ospf.py0000664000175000017500000010305000000000000017624 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone 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. """ RFC 2328 OSPF version 2 """ from functools import reduce import logging import struct from os_ken.lib import addrconv from os_ken.lib.packet import packet_base from os_ken.lib.packet import packet_utils from os_ken.lib.packet import stream_parser from os_ken.lib.stringify import StringifyMixin from os_ken.lib import type_desc LOG = logging.getLogger(__name__) _VERSION = 2 OSPF_MSG_UNKNOWN = 0 OSPF_MSG_HELLO = 1 OSPF_MSG_DB_DESC = 2 OSPF_MSG_LS_REQ = 3 OSPF_MSG_LS_UPD = 4 OSPF_MSG_LS_ACK = 5 OSPF_UNKNOWN_LSA = 0 OSPF_ROUTER_LSA = 1 OSPF_NETWORK_LSA = 2 OSPF_SUMMARY_LSA = 3 OSPF_ASBR_SUMMARY_LSA = 4 OSPF_AS_EXTERNAL_LSA = 5 OSPF_AS_NSSA_LSA = 7 # RFC 3101 OSPF_OPAQUE_LINK_LSA = 9 # RFC 5250 OSPF_OPAQUE_AREA_LSA = 10 # RFC 5250 OSPF_OPAQUE_AS_LSA = 11 # RFC 5250 OSPF_OPTION_T = 1 # Obsolete OSPF_OPTION_E = 1 << 1 # RFC 2328 OSPF_OPTION_MC = 1 << 2 # RFC 1584 OSPF_OPTION_NP = 1 << 3 # RFC 3101 OSPF_OPTION_EA = 1 << 4 # Obsolete OSPF_OPTION_DC = 1 << 5 # RFC 2370 OSPF_OPTION_DN = 1 << 7 # RFC 2567 LSA_LINK_TYPE_P2P = 1 LSA_LINK_TYPE_TRANSIT = 2 LSA_LINK_TYPE_STUB = 3 LSA_LINK_TYPE_VL = 4 ROUTER_LSA_BORDER = 0x01 # The router is an ABR ROUTER_LSA_EXTERNAL = 0x02 # The router is an ASBR ROUTER_LSA_VIRTUAL = 0x04 # The router has a VL in this area ROUTER_LSA_NT = 0x10 # The router always translates Type-7 ROUTER_LSA_SHORTCUT = 0x20 # Shortcut-ABR specific flag AS_EXTERNAL_METRIC = 0x80 OSPF_OPAQUE_TYPE_UNKNOWN = 0 OSPF_OPAQUE_TYPE_EXTENDED_PREFIX_LSA = 7 OSPF_OPAQUE_TYPE_EXTENDED_LINK_LSA = 8 OSPF_EXTENDED_PREFIX_TLV = 1 OSPF_EXTENDED_PREFIX_SID_SUBTLV = 2 class InvalidChecksum(Exception): pass class LSAHeader(StringifyMixin): _HDR_PACK_STR = '!HBB4s4sIHH' _HDR_LEN = struct.calcsize(_HDR_PACK_STR) def __init__(self, ls_age=0, options=0, type_=OSPF_UNKNOWN_LSA, id_='0.0.0.0', adv_router='0.0.0.0', ls_seqnum=0, checksum=0, length=0, opaque_type=OSPF_OPAQUE_TYPE_UNKNOWN, opaque_id=0): self.ls_age = ls_age self.options = options self.type_ = type_ if self.type_ < OSPF_OPAQUE_LINK_LSA: self.id_ = id_ else: self.opaque_type = opaque_type self.opaque_id = opaque_id self.adv_router = adv_router self.ls_seqnum = ls_seqnum self.checksum = checksum self.length = length @classmethod def parser(cls, buf): if len(buf) < cls._HDR_LEN: raise stream_parser.StreamParser.TooSmallException( '%d < %d' % (len(buf), cls._HDR_LEN)) (ls_age, options, type_, id_, adv_router, ls_seqnum, checksum, length,) = struct.unpack_from(cls._HDR_PACK_STR, bytes(buf)) adv_router = addrconv.ipv4.bin_to_text(adv_router) rest = buf[cls._HDR_LEN:] lsacls = LSA._lookup_type(type_) value = { "ls_age": ls_age, "options": options, "type_": type_, "adv_router": adv_router, "ls_seqnum": ls_seqnum, "checksum": checksum, "length": length, } if issubclass(lsacls, OpaqueLSA): (id_,) = struct.unpack_from('!I', id_) value['opaque_type'] = (id_ & 0xff000000) >> 24 value['opaque_id'] = (id_ & 0xffffff) else: value['id_'] = addrconv.ipv4.bin_to_text(id_) return value, rest def serialize(self): if self.type_ < OSPF_OPAQUE_LINK_LSA: id_ = addrconv.ipv4.text_to_bin(self.id_) else: id_ = (self.opaque_type << 24) + self.opaque_id (id_,) = struct.unpack_from('4s', struct.pack('!I', id_)) adv_router = addrconv.ipv4.text_to_bin(self.adv_router) return bytearray( struct.pack(self._HDR_PACK_STR, self.ls_age, self.options, self.type_, id_, adv_router, self.ls_seqnum, self.checksum, self.length)) class LSA(type_desc.TypeDisp, StringifyMixin): def __init__(self, ls_age=0, options=0, type_=OSPF_UNKNOWN_LSA, id_='0.0.0.0', adv_router='0.0.0.0', ls_seqnum=0, checksum=0, length=0, opaque_type=OSPF_OPAQUE_TYPE_UNKNOWN, opaque_id=0): if type_ < OSPF_OPAQUE_LINK_LSA: self.header = LSAHeader( ls_age=ls_age, options=options, type_=type_, id_=id_, adv_router=adv_router, ls_seqnum=ls_seqnum) else: self.header = LSAHeader( ls_age=ls_age, options=options, type_=type_, adv_router=adv_router, ls_seqnum=ls_seqnum, opaque_type=opaque_type, opaque_id=opaque_id) if not (checksum or length): tail = self.serialize_tail() length = self.header._HDR_LEN + len(tail) if not checksum: head = self.header.serialize() checksum = packet_utils.fletcher_checksum(head[2:], 14) self.header.length = length self.header.checksum = checksum @classmethod def parser(cls, buf): hdr, rest = LSAHeader.parser(buf) if len(buf) < hdr['length']: raise stream_parser.StreamParser.TooSmallException( '%d < %d' % (len(buf), hdr['length'])) # exclude ls_age for checksum calculation csum = packet_utils.fletcher_checksum(buf[2:hdr['length']], 14) if csum != hdr['checksum']: raise InvalidChecksum("header has %d, but calculated value is %d" % (hdr['checksum'], csum)) subcls = cls._lookup_type(hdr['type_']) body = rest[:hdr['length'] - LSAHeader._HDR_LEN] rest = rest[hdr['length'] - LSAHeader._HDR_LEN:] if issubclass(subcls, OpaqueLSA): kwargs = subcls.parser(body, hdr['opaque_type']) else: kwargs = subcls.parser(body) kwargs.update(hdr) return subcls(**kwargs), subcls, rest def serialize(self): tail = self.serialize_tail() self.header.length = self.header._HDR_LEN + len(tail) head = self.header.serialize() # exclude ls_age for checksum calculation csum = packet_utils.fletcher_checksum(head[2:] + tail, 14) self.header.checksum = csum struct.pack_into("!H", head, 16, csum) return head + tail def serialize_tail(self): # should be implemented in subclass return b'' @LSA.register_type(OSPF_ROUTER_LSA) class RouterLSA(LSA): _PACK_STR = '!BBH' _PACK_LEN = struct.calcsize(_PACK_STR) # 4bytes class Link(StringifyMixin): _PACK_STR = '!4s4sBBH' _PACK_LEN = struct.calcsize(_PACK_STR) # 12bytes def __init__(self, id_='0.0.0.0', data='0.0.0.0', type_=LSA_LINK_TYPE_STUB, tos=0, metric=10): self.id_ = id_ self.data = data self.type_ = type_ self.tos = tos self.metric = metric @classmethod def parser(cls, buf): if len(buf) < cls._PACK_LEN: raise stream_parser.StreamParser.TooSmallException( '%d < %d' % (len(buf), cls._PACK_LEN)) link = buf[:cls._PACK_LEN] rest = buf[cls._PACK_LEN:] (id_, data, type_, tos, metric) = \ struct.unpack_from(cls._PACK_STR, bytes(link)) id_ = addrconv.ipv4.bin_to_text(id_) data = addrconv.ipv4.bin_to_text(data) return cls(id_, data, type_, tos, metric), rest def serialize(self): id_ = addrconv.ipv4.text_to_bin(self.id_) data = addrconv.ipv4.text_to_bin(self.data) return bytearray( struct.pack(self._PACK_STR, id_, data, self.type_, self.tos, self.metric)) def __init__(self, ls_age=0, options=0, type_=OSPF_ROUTER_LSA, id_='0.0.0.0', adv_router='0.0.0.0', ls_seqnum=0, checksum=None, length=None, flags=0, links=None): links = links if links else [] self.flags = flags self.links = links super(RouterLSA, self).__init__(ls_age, options, type_, id_, adv_router, ls_seqnum, checksum, length) @classmethod def parser(cls, buf): links = [] hdr = buf[:cls._PACK_LEN] buf = buf[cls._PACK_LEN:] (flags, _, num) = struct.unpack_from(cls._PACK_STR, bytes(hdr)) while buf: link, buf = cls.Link.parser(buf) links.append(link) assert len(links) == num return { "flags": flags, "links": links, } def serialize_tail(self): head = bytearray( struct.pack(self._PACK_STR, self.flags, 0, len(self.links))) try: return head + reduce(lambda a, b: a + b, (link.serialize() for link in self.links)) except TypeError: return head @LSA.register_type(OSPF_NETWORK_LSA) class NetworkLSA(LSA): _PACK_STR = '!4s' _PACK_LEN = struct.calcsize(_PACK_STR) def __init__(self, ls_age=0, options=0, type_=OSPF_NETWORK_LSA, id_='0.0.0.0', adv_router='0.0.0.0', ls_seqnum=0, checksum=None, length=None, mask='0.0.0.0', routers=None): routers = routers if routers else [] self.mask = mask self.routers = routers super(NetworkLSA, self).__init__(ls_age, options, type_, id_, adv_router, ls_seqnum, checksum, length) @classmethod def parser(cls, buf): if len(buf) < cls._PACK_LEN: raise stream_parser.StreamParser.TooSmallException( '%d < %d' % (len(buf), cls._PACK_LEN)) binmask = buf[:cls._PACK_LEN] (mask,) = struct.unpack_from(cls._PACK_STR, bytes(binmask)) mask = addrconv.ipv4.bin_to_text(mask) buf = buf[cls._PACK_LEN:] routers = [] while buf: binrouter = buf[:cls._PACK_LEN] (router,) = struct.unpack_from(cls._PACK_STR, bytes(binrouter)) router = addrconv.ipv4.bin_to_text(router) routers.append(router) buf = buf[cls._PACK_LEN:] return { "mask": mask, "routers": routers, } def serialize_tail(self): mask = addrconv.ipv4.text_to_bin(self.mask) routers = [addrconv.ipv4.text_to_bin(router) for router in self.routers] return bytearray( struct.pack("!" + "4s" * (1 + len(routers)), mask, *routers)) @LSA.register_type(OSPF_SUMMARY_LSA) class SummaryLSA(LSA): _PACK_STR = '!4sB3s' _PACK_LEN = struct.calcsize(_PACK_STR) def __init__(self, ls_age=0, options=0, type_=OSPF_SUMMARY_LSA, id_='0.0.0.0', adv_router='0.0.0.0', ls_seqnum=0, checksum=None, length=None, mask='0.0.0.0', tos=0, metric=0): self.mask = mask self.tos = tos self.metric = metric super(SummaryLSA, self).__init__(ls_age, options, type_, id_, adv_router, ls_seqnum, checksum, length) @classmethod def parser(cls, buf): if len(buf) < cls._PACK_LEN: raise stream_parser.StreamParser.TooSmallException( '%d < %d' % (len(buf), cls._PACK_LEN)) buf = buf[:cls._PACK_LEN] (mask, tos, metric) = struct.unpack_from( cls._PACK_STR, bytes(buf)) mask = addrconv.ipv4.bin_to_text(mask) metric = type_desc.Int3.to_user(metric) return { "mask": mask, "tos": tos, "metric": metric, } def serialize_tail(self): mask = addrconv.ipv4.text_to_bin(self.mask) metric = type_desc.Int3.from_user(self.metric) return bytearray(struct.pack(self._PACK_STR, mask, self.tos, metric)) @LSA.register_type(OSPF_ASBR_SUMMARY_LSA) class ASBRSummaryLSA(LSA): pass @LSA.register_type(OSPF_AS_EXTERNAL_LSA) class ASExternalLSA(LSA): class ExternalNetwork(StringifyMixin): _PACK_STR = '!4sB3s4sI' _PACK_LEN = struct.calcsize(_PACK_STR) def __init__(self, mask='0.0.0.0', flags=0, metric=0, fwd_addr='0.0.0.0', tag=0): self.mask = mask self.flags = flags self.metric = metric self.fwd_addr = fwd_addr self.tag = tag @classmethod def parser(cls, buf): if len(buf) < cls._PACK_LEN: raise stream_parser.StreamParser.TooSmallException( '%d < %d' % (len(buf), cls._PACK_LEN)) ext_nw = buf[:cls._PACK_LEN] rest = buf[cls._PACK_LEN:] (mask, flags, metric, fwd_addr, tag) = struct.unpack_from(cls._PACK_STR, bytes(ext_nw)) mask = addrconv.ipv4.bin_to_text(mask) metric = type_desc.Int3.to_user(metric) fwd_addr = addrconv.ipv4.bin_to_text(fwd_addr) return cls(mask, flags, metric, fwd_addr, tag), rest def serialize(self): mask = addrconv.ipv4.text_to_bin(self.mask) metric = type_desc.Int3.from_user(self.metric) fwd_addr = addrconv.ipv4.text_to_bin(self.fwd_addr) return bytearray( struct.pack(self._PACK_STR, mask, self.flags, metric, fwd_addr, self.tag)) def __init__(self, ls_age=0, options=0, type_=OSPF_AS_EXTERNAL_LSA, id_='0.0.0.0', adv_router='0.0.0.0', ls_seqnum=0, checksum=None, length=None, extnws=None): extnws = extnws if extnws else [] self.extnws = extnws super(ASExternalLSA, self).__init__(ls_age, options, type_, id_, adv_router, ls_seqnum, checksum, length) @classmethod def parser(cls, buf): extnws = [] while buf: extnw, buf = cls.ExternalNetwork.parser(buf) extnws.append(extnw) return { "extnws": extnws, } def serialize_tail(self): return reduce(lambda a, b: a + b, (extnw.serialize() for extnw in self.extnws)) @LSA.register_type(OSPF_AS_NSSA_LSA) class NSSAExternalLSA(LSA): pass class ExtendedPrefixTLV(StringifyMixin, type_desc.TypeDisp): pass @ExtendedPrefixTLV.register_type(OSPF_EXTENDED_PREFIX_TLV) class ExtendedPrefixTLV(ExtendedPrefixTLV): _VALUE_PACK_STR = '!HHBBBB4s' _VALUE_PACK_LEN = struct.calcsize(_VALUE_PACK_STR) _VALUE_FIELDS = ['route_type', 'prefix_length', 'address_family', '_pad' 'prefix'] def __init__(self, type_=OSPF_EXTENDED_PREFIX_TLV, length=0, route_type=0, address_family=0, prefix='0.0.0.0/0'): self.type_ = type_ self.length = length self.route_type = route_type self.address_family = address_family self.prefix = prefix @classmethod def parser(cls, buf): rest = buf[cls._VALUE_PACK_LEN:] buf = buf[:cls._VALUE_PACK_LEN] (type_, length, route_type, prefix_length, address_family, _pad, prefix) = struct.unpack_from(cls._VALUE_PACK_STR, buf) prefix = addrconv.ipv4.bin_to_text(prefix) prefix = "%s/%d" % (prefix, prefix_length) return cls(type_, length, route_type, address_family, prefix), rest def serialize(self): prefix, prefix_length = self.prefix.split('/') prefix = addrconv.ipv4.text_to_bin(prefix) prefix_length = int(prefix_length) return struct.pack(self._VALUE_PACK_STR, OSPF_EXTENDED_PREFIX_TLV, self._VALUE_PACK_LEN - 4, self.route_type, prefix_length, self.address_family, 0, prefix) @ExtendedPrefixTLV.register_type(OSPF_EXTENDED_PREFIX_SID_SUBTLV) class PrefixSIDSubTLV(ExtendedPrefixTLV): _VALUE_PACK_STR = '!HHBBBBHHI' _VALUE_PACK_LEN = struct.calcsize(_VALUE_PACK_STR) _VALUE_FIELDS = ['flags', 'mt_id', 'algorithm', '_pad', 'range_size', '_pad', 'index'] def __init__(self, type_=OSPF_EXTENDED_PREFIX_SID_SUBTLV, length=0, flags=0, mt_id=0, algorithm=0, range_size=0, index=0): super(PrefixSIDSubTLV, self).__init__() self.type_ = type_ self.length = length self.flags = flags self.mt_id = mt_id self.algorithm = algorithm self.range_size = range_size self.index = index @classmethod def parser(cls, buf): rest = buf[cls._VALUE_PACK_LEN:] buf = buf[:cls._VALUE_PACK_LEN] (type_, length, flags, mt_id, algorithm, _pad, range_size, _pad, index) = struct.unpack_from(cls._VALUE_PACK_STR, buf) return cls(type_, length, flags, mt_id, algorithm, range_size, index), rest def serialize(self): return struct.pack(self._VALUE_PACK_STR, OSPF_EXTENDED_PREFIX_SID_SUBTLV, self._VALUE_PACK_LEN - 4, self.flags, self.mt_id, self.algorithm, 0, self.range_size, 0, self.index) class ExtendedLinkTLV(StringifyMixin, type_desc.TypeDisp): pass class OpaqueBody(StringifyMixin, type_desc.TypeDisp): def __init__(self, tlvs=None): tlvs = tlvs if tlvs else [] self.tlvs = tlvs def serialize(self): return reduce(lambda a, b: a + b, (tlv.serialize() for tlv in self.tlvs)) @OpaqueBody.register_type(OSPF_OPAQUE_TYPE_EXTENDED_PREFIX_LSA) class ExtendedPrefixOpaqueBody(OpaqueBody): @classmethod def parser(cls, buf): buf = bytes(buf) tlvs = [] while buf: (type_, length) = struct.unpack_from('!HH', buf) if len(buf[struct.calcsize('!HH'):]) < length: raise stream_parser.StreamParser.TooSmallException( '%d < %d' % (len(buf), length)) tlvcls = ExtendedPrefixTLV._lookup_type(type_) if tlvcls: tlv, buf = tlvcls.parser(buf) tlvs.append(tlv) return cls(tlvs) @OpaqueBody.register_type(OSPF_OPAQUE_TYPE_EXTENDED_LINK_LSA) class ExtendedLinkOpaqueBody(OpaqueBody): @classmethod def parser(cls, buf): buf = bytes(buf) tlvs = [] while buf: (type_, length) = struct.unpack_from('!HH', buf) if len(buf[struct.calcsize('!HH'):]) < length: raise stream_parser.StreamParser.TooSmallException( '%d < %d' % (len(buf), length)) tlvcls = ExtendedLinkTLV._lookup_type(type_) if tlvcls: tlv, buf = tlvcls.parser(buf) tlvs.append(tlv) return cls(tlvs) class OpaqueLSA(LSA): def __init__(self, data, *args, **kwargs): super(OpaqueLSA, self).__init__(*args, **kwargs) self.data = data @classmethod def parser(cls, buf, opaque_type=OSPF_OPAQUE_TYPE_UNKNOWN): opaquecls = OpaqueBody._lookup_type(opaque_type) if opaquecls: data = opaquecls.parser(buf) else: data = buf return {'data': data} def serialize_tail(self): if isinstance(self.data, OpaqueBody): return self.data.serialize() else: return self.data @LSA.register_type(OSPF_OPAQUE_LINK_LSA) class LocalOpaqueLSA(OpaqueLSA): def __init__(self, ls_age=0, options=0, type_=OSPF_OPAQUE_LINK_LSA, adv_router='0.0.0.0', ls_seqnum=0, checksum=0, length=0, opaque_type=OSPF_OPAQUE_TYPE_UNKNOWN, opaque_id=0, data=None): self.data = data super(LocalOpaqueLSA, self).__init__(ls_age, options, type_, 0, adv_router, ls_seqnum, checksum, length, opaque_type, opaque_id) @LSA.register_type(OSPF_OPAQUE_AREA_LSA) class AreaOpaqueLSA(OpaqueLSA): def __init__(self, ls_age=0, options=0, type_=OSPF_OPAQUE_AREA_LSA, adv_router='0.0.0.0', ls_seqnum=0, checksum=0, length=0, opaque_type=OSPF_OPAQUE_TYPE_UNKNOWN, opaque_id=0, data=None): self.data = data super(AreaOpaqueLSA, self).__init__(ls_age, options, type_, 0, adv_router, ls_seqnum, checksum, length, opaque_type, opaque_id) @LSA.register_type(OSPF_OPAQUE_AS_LSA) class ASOpaqueLSA(OpaqueLSA): def __init__(self, ls_age=0, options=0, type_=OSPF_OPAQUE_AS_LSA, adv_router='0.0.0.0', ls_seqnum=0, checksum=0, length=0, opaque_type=OSPF_OPAQUE_TYPE_UNKNOWN, opaque_id=0, data=None): self.data = data super(ASOpaqueLSA, self).__init__(ls_age, options, type_, 0, adv_router, ls_seqnum, checksum, length, opaque_type, opaque_id) class OSPFMessage(packet_base.PacketBase, type_desc.TypeDisp): """Base class for OSPF version 2 messages. """ _HDR_PACK_STR = '!BBH4s4sHHQ' _HDR_LEN = struct.calcsize(_HDR_PACK_STR) def __init__(self, type_, length=None, router_id='0.0.0.0', area_id='0.0.0.0', au_type=1, authentication=0, checksum=None, version=_VERSION): super(OSPFMessage, self).__init__() self.version = version self.type_ = type_ self.length = length self.router_id = router_id self.area_id = area_id self.checksum = checksum self.au_type = au_type self.authentication = authentication @classmethod def _parser(cls, buf): if len(buf) < cls._HDR_LEN: raise stream_parser.StreamParser.TooSmallException( '%d < %d' % (len(buf), cls._HDR_LEN)) (version, type_, length, router_id, area_id, checksum, au_type, authentication) = struct.unpack_from(cls._HDR_PACK_STR, bytes(buf)) # Exclude checksum and authentication field for checksum validation. if packet_utils.checksum(buf[:12] + buf[14:16] + buf[cls._HDR_LEN:]) \ != checksum: raise InvalidChecksum if len(buf) < length: raise stream_parser.StreamParser.TooSmallException( '%d < %d' % (len(buf), length)) router_id = addrconv.ipv4.bin_to_text(router_id) area_id = addrconv.ipv4.bin_to_text(area_id) binmsg = buf[cls._HDR_LEN:length] rest = buf[length:] subcls = cls._lookup_type(type_) kwargs = subcls.parser(binmsg) return subcls(length, router_id, area_id, au_type, int(authentication), checksum, version, **kwargs), None, rest @classmethod def parser(cls, buf): try: return cls._parser(buf) except: return None, None, buf def serialize(self, payload=None, prev=None): tail = self.serialize_tail() self.length = self._HDR_LEN + len(tail) head = bytearray( struct.pack(self._HDR_PACK_STR, self.version, self.type_, self.length, addrconv.ipv4.text_to_bin(self.router_id), addrconv.ipv4.text_to_bin(self.area_id), 0, self.au_type, self.authentication)) buf = head + tail csum = packet_utils.checksum(buf[:12] + buf[14:16] + buf[self._HDR_LEN:]) self.checksum = csum struct.pack_into("!H", buf, 12, csum) return buf # alias ospf = OSPFMessage @OSPFMessage.register_type(OSPF_MSG_HELLO) class OSPFHello(OSPFMessage): _PACK_STR = '!4sHBBI4s4s' # + neighbors _PACK_LEN = struct.calcsize(_PACK_STR) _MIN_LEN = OSPFMessage._HDR_LEN + _PACK_LEN def __init__(self, length=None, router_id='0.0.0.0', area_id='0.0.0.0', au_type=1, authentication=0, checksum=None, version=_VERSION, mask='0.0.0.0', hello_interval=10, options=0, priority=1, dead_interval=40, designated_router='0.0.0.0', backup_router='0.0.0.0', neighbors=None): neighbors = neighbors if neighbors else [] super(OSPFHello, self).__init__(OSPF_MSG_HELLO, length, router_id, area_id, au_type, authentication, checksum, version) self.mask = mask self.hello_interval = hello_interval self.options = options self.priority = priority self.dead_interval = dead_interval self.designated_router = designated_router self.backup_router = backup_router self.neighbors = neighbors @classmethod def parser(cls, buf): (mask, hello_interval, options, priority, dead_interval, designated_router, backup_router) = struct.unpack_from(cls._PACK_STR, bytes(buf)) mask = addrconv.ipv4.bin_to_text(mask) designated_router = addrconv.ipv4.bin_to_text(designated_router) backup_router = addrconv.ipv4.bin_to_text(backup_router) neighbors = [] binneighbors = buf[cls._PACK_LEN:len(buf)] while binneighbors: n = binneighbors[:4] n = addrconv.ipv4.bin_to_text(bytes(n)) binneighbors = binneighbors[4:] neighbors.append(n) return { "mask": mask, "hello_interval": hello_interval, "options": options, "priority": priority, "dead_interval": dead_interval, "designated_router": designated_router, "backup_router": backup_router, "neighbors": neighbors, } def serialize_tail(self): head = bytearray( struct.pack(self._PACK_STR, addrconv.ipv4.text_to_bin(self.mask), self.hello_interval, self.options, self.priority, self.dead_interval, addrconv.ipv4.text_to_bin(self.designated_router), addrconv.ipv4.text_to_bin(self.backup_router))) try: return head + reduce(lambda a, b: a + b, (addrconv.ipv4.text_to_bin(n) for n in self.neighbors)) except TypeError: return head @OSPFMessage.register_type(OSPF_MSG_DB_DESC) class OSPFDBDesc(OSPFMessage): _PACK_STR = '!HBBI' # + LSA_HEADERS _PACK_LEN = struct.calcsize(_PACK_STR) _MIN_LEN = OSPFMessage._HDR_LEN + _PACK_LEN def __init__(self, length=None, router_id='0.0.0.0', area_id='0.0.0.0', au_type=1, authentication=0, checksum=None, version=_VERSION, mtu=1500, options=0, i_flag=0, m_flag=0, ms_flag=0, sequence_number=0, lsa_headers=None): lsa_headers = lsa_headers if lsa_headers else [] super(OSPFDBDesc, self).__init__(OSPF_MSG_DB_DESC, length, router_id, area_id, au_type, authentication, checksum, version) self.mtu = mtu self.options = options self.i_flag = i_flag self.m_flag = m_flag self.ms_flag = ms_flag self.sequence_number = sequence_number self.lsa_headers = lsa_headers @classmethod def parser(cls, buf): (mtu, options, flags, sequence_number) = struct.unpack_from(cls._PACK_STR, bytes(buf)) i_flag = (flags >> 2) & 0x1 m_flag = (flags >> 1) & 0x1 ms_flag = flags & 0x1 lsahdrs = [] buf = buf[cls._PACK_LEN:] while buf: kwargs, buf = LSAHeader.parser(buf) lsahdrs.append(LSAHeader(**kwargs)) return { "mtu": mtu, "options": options, "i_flag": i_flag, "m_flag": m_flag, "ms_flag": ms_flag, "sequence_number": sequence_number, "lsa_headers": lsahdrs, } def serialize_tail(self): flags = ((self.i_flag & 0x1) << 2) ^ \ ((self.m_flag & 0x1) << 1) ^ \ (self.ms_flag & 0x1) head = bytearray( struct.pack(self._PACK_STR, self.mtu, self.options, flags, self.sequence_number)) try: return head + reduce(lambda a, b: a + b, (hdr.serialize() for hdr in self.lsa_headers)) except TypeError: return head @OSPFMessage.register_type(OSPF_MSG_LS_REQ) class OSPFLSReq(OSPFMessage): _MIN_LEN = OSPFMessage._HDR_LEN class Request(StringifyMixin): _PACK_STR = '!I4s4s' _PACK_LEN = struct.calcsize(_PACK_STR) def __init__(self, type_=OSPF_UNKNOWN_LSA, id_='0.0.0.0', adv_router='0.0.0.0'): self.type_ = type_ self.id = id_ self.adv_router = adv_router @classmethod def parser(cls, buf): if len(buf) < cls._PACK_LEN: raise stream_parser.StreamParser.TooSmallException( '%d < %d' % (len(buf), cls._PACK_LEN)) link = buf[:cls._PACK_LEN] rest = buf[cls._PACK_LEN:] (type_, id_, adv_router) = struct.unpack_from(cls._PACK_STR, bytes(link)) id_ = addrconv.ipv4.bin_to_text(id_) adv_router = addrconv.ipv4.bin_to_text(adv_router) return cls(type_, id_, adv_router), rest def serialize(self): id_ = addrconv.ipv4.text_to_bin(self.id) adv_router = addrconv.ipv4.text_to_bin(self.adv_router) return struct.pack(self._PACK_STR, self.type_, id_, adv_router) def __init__(self, length=None, router_id='0.0.0.0', area_id='0.0.0.0', au_type=1, authentication=0, checksum=None, version=_VERSION, lsa_requests=None): lsa_requests = lsa_requests if lsa_requests else [] super(OSPFLSReq, self).__init__(OSPF_MSG_LS_REQ, length, router_id, area_id, au_type, authentication, checksum, version) self.lsa_requests = lsa_requests @classmethod def parser(cls, buf): reqs = [] while buf: req, buf = cls.Request.parser(buf) reqs.append(req) return { "lsa_requests": reqs, } def serialize_tail(self): return reduce(lambda a, b: a + b, (req.serialize() for req in self.lsa_requests)) @OSPFMessage.register_type(OSPF_MSG_LS_UPD) class OSPFLSUpd(OSPFMessage): _PACK_STR = '!I' _PACK_LEN = struct.calcsize(_PACK_STR) _MIN_LEN = OSPFMessage._HDR_LEN + _PACK_LEN def __init__(self, length=None, router_id='0.0.0.0', area_id='0.0.0.0', au_type=1, authentication=0, checksum=None, version=_VERSION, lsas=None): lsas = lsas if lsas else [] super(OSPFLSUpd, self).__init__(OSPF_MSG_LS_UPD, length, router_id, area_id, au_type, authentication, checksum, version) self.lsas = lsas @classmethod def parser(cls, buf): binnum = buf[:cls._PACK_LEN] (num,) = struct.unpack_from(cls._PACK_STR, bytes(binnum)) buf = buf[cls._PACK_LEN:] lsas = [] while buf: lsa, _cls, buf = LSA.parser(buf) lsas.append(lsa) assert len(lsas) == num return { "lsas": lsas, } def serialize_tail(self): head = bytearray(struct.pack(self._PACK_STR, len(self.lsas))) try: return head + reduce(lambda a, b: a + b, (lsa.serialize() for lsa in self.lsas)) except TypeError: return head @OSPFMessage.register_type(OSPF_MSG_LS_ACK) class OSPFLSAck(OSPFMessage): _MIN_LEN = OSPFMessage._HDR_LEN def __init__(self, length=None, router_id='0.0.0.0', area_id='0.0.0.0', au_type=1, authentication=0, checksum=None, version=_VERSION, lsa_headers=None): lsa_headers = lsa_headers if lsa_headers else [] super(OSPFLSAck, self).__init__(OSPF_MSG_LS_ACK, length, router_id, area_id, au_type, authentication, checksum, version) self.lsa_headers = lsa_headers @classmethod def parser(cls, buf): lsahdrs = [] while buf: kwargs, buf = LSAHeader.parser(buf) lsahdrs.append(LSAHeader(**kwargs)) return { "lsa_headers": lsahdrs, } def serialize_tail(self): return reduce(lambda a, b: a + b, (hdr.serialize() for hdr in self.lsa_headers)) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/packet/packet.py0000664000175000017500000001373100000000000020132 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone 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. import inspect import struct import base64 from . import packet_base from . import ethernet from os_ken import utils from os_ken.lib.stringify import StringifyMixin # Packet class dictionary mod = inspect.getmembers(utils.import_module("os_ken.lib.packet"), lambda cls: (inspect.ismodule(cls))) cls_list = [] for _, m in mod: cl = inspect.getmembers(m, lambda cls: ( inspect.isclass(cls) and issubclass(cls, packet_base.PacketBase))) cls_list.extend(list(cl)) PKT_CLS_DICT = dict(cls_list) class Packet(StringifyMixin): """A packet decoder/encoder class. An instance is used to either decode or encode a single packet. *data* is a bytearray to describe a raw datagram to decode. When decoding, a Packet object is iteratable. Iterated values are protocol (ethernet, ipv4, ...) headers and the payload. Protocol headers are instances of subclass of packet_base.PacketBase. The payload is a bytearray. They are iterated in on-wire order. *data* should be omitted when encoding a packet. """ # Ignore data field when outputting json representation. _base_attributes = ['data'] def __init__(self, data=None, protocols=None, parse_cls=ethernet.ethernet): super(Packet, self).__init__() self.data = data if protocols is None: self.protocols = [] else: self.protocols = protocols if self.data: self._parser(parse_cls) def _parser(self, cls): rest_data = self.data while cls: # Ignores an empty buffer if not bytes(rest_data).strip(b'\x00'): break try: proto, cls, rest_data = cls.parser(rest_data) except struct.error: break if proto: self.protocols.append(proto) # If rest_data is all padding, we ignore rest_data if rest_data and bytes(rest_data).strip(b'\x00'): self.protocols.append(rest_data) def serialize(self): """Encode a packet and store the resulted bytearray in self.data. This method is legal only when encoding a packet. """ self.data = bytearray() r = self.protocols[::-1] for i, p in enumerate(r): if isinstance(p, packet_base.PacketBase): if i == len(r) - 1: prev = None else: prev = r[i + 1] data = p.serialize(self.data, prev) else: data = bytes(p) self.data = bytearray(data + self.data) @classmethod def from_jsondict(cls, dict_, decode_string=base64.b64decode, **additional_args): protocols = [] for proto in dict_['protocols']: for key, value in proto.items(): if key in PKT_CLS_DICT: pkt_cls = PKT_CLS_DICT[key] protocols.append(pkt_cls.from_jsondict(value)) else: raise ValueError('unknown protocol name %s' % key) return cls(protocols=protocols) def add_protocol(self, proto): """Register a protocol *proto* for this packet. This method is legal only when encoding a packet. When encoding a packet, register a protocol (ethernet, ipv4, ...) header to add to this packet. Protocol headers should be registered in on-wire order before calling self.serialize. """ self.protocols.append(proto) def get_protocols(self, protocol): """Returns a list of protocols that matches to the specified protocol. """ if isinstance(protocol, packet_base.PacketBase): protocol = protocol.__class__ assert issubclass(protocol, packet_base.PacketBase) return [p for p in self.protocols if isinstance(p, protocol)] def get_protocol(self, protocol): """Returns the firstly found protocol that matches to the specified protocol. """ result = self.get_protocols(protocol) if len(result) > 0: return result[0] return None def __div__(self, trailer): self.add_protocol(trailer) return self def __truediv__(self, trailer): return self.__div__(trailer) def __iter__(self): return iter(self.protocols) def __getitem__(self, idx): return self.protocols[idx] def __setitem__(self, idx, item): self.protocols[idx] = item def __delitem__(self, idx): del self.protocols[idx] def __len__(self): return len(self.protocols) def __contains__(self, protocol): if (inspect.isclass(protocol) and issubclass(protocol, packet_base.PacketBase)): return protocol in [p.__class__ for p in self.protocols] return protocol in self.protocols def __str__(self): return ', '.join(repr(protocol) for protocol in self.protocols) __repr__ = __str__ # note: str(list) uses __repr__ for elements # XXX: Hack for preventing recursive import def _PacketBase__div__(self, trailer): pkt = Packet() pkt.add_protocol(self) pkt.add_protocol(trailer) return pkt packet_base.PacketBase.__div__ = _PacketBase__div__ packet_base.PacketBase.__truediv__ = _PacketBase__div__ ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/packet/packet_base.py0000664000175000017500000000504400000000000021122 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone 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. import abc from os_ken.lib import stringify class PacketBase(stringify.StringifyMixin, metaclass=abc.ABCMeta): """A base class for a protocol (ethernet, ipv4, ...) header.""" _TYPES = {} @classmethod def get_packet_type(cls, type_): """Per-protocol dict-like get method. Provided for convenience of protocol implementers. Internal use only.""" return cls._TYPES.get(type_) @classmethod def register_packet_type(cls, cls_, type_): """Per-protocol dict-like set method. Provided for convenience of protocol implementers. Internal use only.""" cls._TYPES[type_] = cls_ def __init__(self): super(PacketBase, self).__init__() def __len__(self): return self._MIN_LEN @property def protocol_name(self): return self.__class__.__name__ @classmethod @abc.abstractmethod def parser(cls, buf): """Decode a protocol header. This method is used only when decoding a packet. Decode a protocol header at offset 0 in bytearray *buf*. Returns the following three objects. * An object to describe the decoded header. * A packet_base.PacketBase subclass appropriate for the rest of the packet. None when the rest of the packet should be considered as raw payload. * The rest of packet. """ pass def serialize(self, payload, prev): """Encode a protocol header. This method is used only when encoding a packet. Encode a protocol header. Returns a bytearray which contains the header. *payload* is the rest of the packet which will immediately follow this header. *prev* is a packet_base.PacketBase subclass for the outer protocol header. *prev* is None if the current header is the outer-most. For example, *prev* is ipv4 or ipv6 for tcp.serialize. """ pass ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/packet/packet_utils.py0000664000175000017500000001075200000000000021352 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone 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. import array import socket import struct from os_ken.lib import addrconv def carry_around_add(a, b): c = a + b return (c & 0xffff) + (c >> 16) def checksum(data): data = bytes(data) # input can be bytearray. if len(data) % 2: data += b'\x00' s = sum(array.array('H', data)) s = (s & 0xffff) + (s >> 16) s += (s >> 16) return socket.ntohs(~s & 0xffff) # avoid circular import _IPV4_PSEUDO_HEADER_PACK_STR = '!4s4sxBH' _IPV6_PSEUDO_HEADER_PACK_STR = '!16s16sI3xB' def checksum_ip(ipvx, length, payload): """ calculate checksum of IP pseudo header IPv4 pseudo header UDP RFC768 TCP RFC793 3.1 0 7 8 15 16 23 24 31 +--------+--------+--------+--------+ | source address | +--------+--------+--------+--------+ | destination address | +--------+--------+--------+--------+ | zero |protocol| length | +--------+--------+--------+--------+ IPv6 pseudo header RFC2460 8.1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | + + | | + Source Address + | | + + | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | + + | | + Destination Address + | | + + | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Upper-Layer Packet Length | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | zero | Next Header | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ """ if ipvx.version == 4: header = struct.pack(_IPV4_PSEUDO_HEADER_PACK_STR, addrconv.ipv4.text_to_bin(ipvx.src), addrconv.ipv4.text_to_bin(ipvx.dst), ipvx.proto, length) elif ipvx.version == 6: header = struct.pack(_IPV6_PSEUDO_HEADER_PACK_STR, addrconv.ipv6.text_to_bin(ipvx.src), addrconv.ipv6.text_to_bin(ipvx.dst), length, ipvx.nxt) else: raise ValueError('Unknown IP version %d' % ipvx.version) buf = header + payload return checksum(buf) _MODX = 4102 def fletcher_checksum(data, offset): """ Fletcher Checksum -- Refer to RFC1008 calling with offset == _FLETCHER_CHECKSUM_VALIDATE will validate the checksum without modifying the buffer; a valid checksum returns 0. """ c0 = 0 c1 = 0 pos = 0 length = len(data) data = bytearray(data) data[offset:offset + 2] = [0] * 2 while pos < length: tlen = min(length - pos, _MODX) for d in data[pos:pos + tlen]: c0 += d c1 += c0 c0 %= 255 c1 %= 255 pos += tlen x = ((length - offset - 1) * c0 - c1) % 255 if x <= 0: x += 255 y = 510 - c0 - x if y > 255: y -= 255 data[offset] = x data[offset + 1] = y return (x << 8) | (y & 0xff) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/packet/pbb.py0000664000175000017500000000407100000000000017423 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone 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. import struct from os_ken.lib.packet import packet_base class itag(packet_base.PacketBase): """I-TAG (IEEE 802.1ah-2008) header encoder/decoder class. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. ============== ==================== Attribute Description ============== ==================== pcp Priority Code Point dei Drop Eligible Indication uca Use Customer Address sid Service Instance ID ============== ==================== """ _PACK_STR = "!I" _MIN_LEN = struct.calcsize(_PACK_STR) def __init__(self, pcp=0, dei=0, uca=0, sid=0): super(itag, self).__init__() self.pcp = pcp self.dei = dei self.uca = uca self.sid = sid @classmethod def parser(cls, buf): (data, ) = struct.unpack_from(cls._PACK_STR, buf) pcp = data >> 29 dei = data >> 28 & 1 uca = data >> 27 & 1 sid = data & 0x00ffffff # circular import: ethernet -> vlan -> pbb from os_ken.lib.packet import ethernet return (cls(pcp, dei, uca, sid), ethernet.ethernet, buf[cls._MIN_LEN:]) def serialize(self, payload, prev): data = self.pcp << 29 | self.dei << 28 | self.uca << 27 | self.sid return struct.pack(self._PACK_STR, data) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/packet/safi.py0000664000175000017500000000177600000000000017613 0ustar00zuulzuul00000000000000# Copyright (C) 2013,2014 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013,2014 YAMAMOTO Takashi # # 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. """ Subsequent Address Family Idenitifier (SAFI) http://www.iana.org/assignments/safi-namespace/safi-namespace.xhtml """ UNICAST = 1 MULTICAST = 2 MPLS_LABEL = 4 # RFC 3107 EVPN = 70 # RFC 7432 MPLS_VPN = 128 # RFC 4364 ROUTE_TARGET_CONSTRAINTS = 132 # RFC 4684 IP_FLOWSPEC = 133 # RFC 5575 VPN_FLOWSPEC = 134 # RFC 5575 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/packet/sctp.py0000664000175000017500000022735700000000000017647 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone 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. import abc import struct from os_ken.lib import addrconv from os_ken.lib import stringify from os_ken.lib.packet import packet_base # Chunk Types TYPE_DATA = 0 TYPE_INIT = 1 TYPE_INIT_ACK = 2 TYPE_SACK = 3 TYPE_HEARTBEAT = 4 TYPE_HEARTBEAT_ACK = 5 TYPE_ABORT = 6 TYPE_SHUTDOWN = 7 TYPE_SHUTDOWN_ACK = 8 TYPE_ERROR = 9 TYPE_COOKIE_ECHO = 10 TYPE_COOKIE_ACK = 11 TYPE_ECN_ECHO = 12 TYPE_CWR = 13 TYPE_SHUTDOWN_COMPLETE = 14 # Cause Code CCODE_INVALID_STREAM_ID = 1 CCODE_MISSING_PARAM = 2 CCODE_STALE_COOKIE = 3 CCODE_OUT_OF_RESOURCE = 4 CCODE_UNRESOLVABLE_ADDR = 5 CCODE_UNRECOGNIZED_CHUNK = 6 CCODE_INVALID_PARAM = 7 CCODE_UNRECOGNIZED_PARAM = 8 CCODE_NO_USERDATA = 9 CCODE_COOKIE_WHILE_SHUTDOWN = 10 CCODE_RESTART_WITH_NEW_ADDR = 11 CCODE_USER_INITIATED_ABORT = 12 CCODE_PROTOCOL_VIOLATION = 13 # Chunk Parameter Types PTYPE_HEARTBEAT = 1 PTYPE_IPV4 = 5 PTYPE_IPV6 = 6 PTYPE_STATE_COOKIE = 7 PTYPE_UNRECOGNIZED_PARAM = 8 PTYPE_COOKIE_PRESERVE = 9 PTYPE_HOST_ADDR = 11 PTYPE_SUPPORTED_ADDR = 12 PTYPE_ECN = 32768 class sctp(packet_base.PacketBase): """Stream Control Transmission Protocol (SCTP) header encoder/decoder class (RFC 4960). An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============== ===================================================== Attribute Description ============== ===================================================== src_port Source Port dst_port Destination Port vtag Verification Tag csum Checksum (0 means automatically-calculate when encoding) chunks a list of derived classes of os_ken.lib.packet.sctp.chunk. ============== ===================================================== """ _PACK_STR = '!HHII' _MIN_LEN = struct.calcsize(_PACK_STR) _SCTP_CHUNK_TYPE = {} _class_prefixes = ['chunk_'] @staticmethod def register_chunk_type(*args): def _register_chunk_type(cls): sctp._SCTP_CHUNK_TYPE[cls.chunk_type()] = cls return cls return _register_chunk_type(args[0]) def __init__(self, src_port=1, dst_port=1, vtag=0, csum=0, chunks=None): super(sctp, self).__init__() self.src_port = src_port self.dst_port = dst_port self.vtag = vtag self.csum = csum chunks = chunks or [] assert isinstance(chunks, list) for one in chunks: assert isinstance(one, chunk) self.chunks = chunks @classmethod def parser(cls, buf): (src_port, dst_port, vtag, csum) = struct.unpack_from( cls._PACK_STR, buf) chunks = [] offset = cls._MIN_LEN while offset < len(buf): (type_, ) = struct.unpack_from('!B', buf, offset) cls_ = cls._SCTP_CHUNK_TYPE.get(type_) if not cls_: break ins = cls_.parser(buf[offset:]) chunks.append(ins) offset += len(ins) msg = cls(src_port, dst_port, vtag, csum, chunks) return msg, None, buf[offset:] def serialize(self, payload, prev): buf = bytearray(struct.pack( self._PACK_STR, self.src_port, self.dst_port, self.vtag, self.csum)) if self.chunks: for one in self.chunks: buf.extend(one.serialize()) if self.csum == 0: self.csum = self._checksum(buf) struct.pack_into('!I', buf, 8, self.csum) return bytes(buf) def __len__(self): length = self._MIN_LEN if self.chunks is not None: for one in self.chunks: length += len(one) return length def _checksum(self, data): # from RFC 3309 crc_c = [ 0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4, 0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB, 0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B, 0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24, 0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B, 0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384, 0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54, 0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B, 0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A, 0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35, 0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5, 0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA, 0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45, 0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A, 0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A, 0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595, 0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48, 0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957, 0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687, 0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198, 0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927, 0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38, 0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8, 0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7, 0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096, 0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789, 0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859, 0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46, 0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9, 0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6, 0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36, 0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829, 0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C, 0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93, 0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043, 0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C, 0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3, 0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC, 0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C, 0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033, 0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652, 0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D, 0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D, 0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982, 0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D, 0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622, 0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2, 0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED, 0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530, 0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F, 0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF, 0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0, 0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F, 0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540, 0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90, 0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F, 0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE, 0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1, 0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321, 0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E, 0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81, 0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E, 0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E, 0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351, ] crc32 = 0xffffffff for c in str(data): crc32 = (crc32 >> 8) ^ crc_c[(crc32 ^ (ord(c))) & 0xFF] crc32 = (~crc32) & 0xffffffff return struct.unpack(">I", struct.pack("> 2) & 1 begin = (flags >> 1) & 1 end = (flags >> 0) & 1 fmt = '!%ds' % (length - cls._MIN_LEN) (payload_data, ) = struct.unpack_from(fmt, buf, cls._MIN_LEN) return cls(unordered, begin, end, length, tsn, sid, seq, payload_id, payload_data) def serialize(self): flags = ( (self.unordered << 2) | (self.begin << 1) | (self.end << 0)) buf = bytearray(struct.pack( self._PACK_STR, self.chunk_type(), flags, self.length, self.tsn, self.sid, self.seq, self.payload_id)) buf.extend(self.payload_data) if 0 == self.length: self.length = len(buf) struct.pack_into('!H', buf, 2, self.length) return bytes(buf) @sctp.register_chunk_type class chunk_init(chunk_init_base): """Stream Control Transmission Protocol (SCTP) sub encoder/decoder class for Initiation (INIT) chunk (RFC 4960). This class is used with the following. - os_ken.lib.packet.sctp.sctp An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============== ===================================================== Attribute Description ============== ===================================================== flags set to '0'. this field will be ignored. length length of this chunk containing this header. (0 means automatically-calculate when encoding) init_tag the tag that be used as Verification Tag. a_rwnd Advertised Receiver Window Credit. os number of outbound streams. mis number of inbound streams. i_tsn Transmission Sequence Number that the sender will use. params Optional/Variable-Length Parameters. a list of derived classes of os_ken.lib.packet.sctp.param. ============== ===================================================== """ _RECOGNIZED_PARAMS = {} @staticmethod def register_param_type(*args): def _register_param_type(cls): chunk_init._RECOGNIZED_PARAMS[cls.param_type()] = cls return cls return _register_param_type(args[0]) @classmethod def chunk_type(cls): return TYPE_INIT @classmethod def parser(cls, buf): return super(chunk_init, cls).parser_base( buf, cls._RECOGNIZED_PARAMS) @sctp.register_chunk_type class chunk_init_ack(chunk_init_base): """Stream Control Transmission Protocol (SCTP) sub encoder/decoder class for Initiation Acknowledgement (INIT ACK) chunk (RFC 4960). This class is used with the following. - os_ken.lib.packet.sctp.sctp An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============== ===================================================== Attribute Description ============== ===================================================== flags set to '0'. this field will be ignored. length length of this chunk containing this header. (0 means automatically-calculate when encoding) init_tag the tag that be used as Verification Tag. a_rwnd Advertised Receiver Window Credit. os number of outbound streams. mis number of inbound streams. i_tsn Transmission Sequence Number that the sender will use. params Optional/Variable-Length Parameters. a list of derived classes of os_ken.lib.packet.sctp.param. ============== ===================================================== """ _RECOGNIZED_PARAMS = {} @staticmethod def register_param_type(*args): def _register_param_type(cls): chunk_init_ack._RECOGNIZED_PARAMS[cls.param_type()] = cls return cls return _register_param_type(args[0]) @classmethod def chunk_type(cls): return TYPE_INIT_ACK @classmethod def parser(cls, buf): return super(chunk_init_ack, cls).parser_base( buf, cls._RECOGNIZED_PARAMS) @sctp.register_chunk_type class chunk_sack(chunk): """Stream Control Transmission Protocol (SCTP) sub encoder/decoder class for Selective Acknowledgement (SACK) chunk (RFC 4960). This class is used with the following. - os_ken.lib.packet.sctp.sctp An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============== ===================================================== Attribute Description ============== ===================================================== flags set to '0'. this field will be ignored. length length of this chunk containing this header. (0 means automatically-calculate when encoding) tsn_ack TSN of the last DATA chunk received in sequence before a gap. a_rwnd Advertised Receiver Window Credit. gapack_num number of Gap Ack blocks. duptsn_num number of duplicate TSNs. gapacks a list of Gap Ack blocks. one block is made of a list with the start offset and the end offset from tsn_ack. e.g.) gapacks = [[2, 3], [10, 12], [19, 21]] duptsns a list of duplicate TSN. ============== ===================================================== """ _PACK_STR = '!BBHIIHH' _MIN_LEN = struct.calcsize(_PACK_STR) _GAPACK_STR = '!HH' _GAPACK_LEN = struct.calcsize(_GAPACK_STR) _DUPTSN_STR = '!I' _DUPTSN_LEN = struct.calcsize(_DUPTSN_STR) @classmethod def chunk_type(cls): return TYPE_SACK def __init__(self, flags=0, length=0, tsn_ack=0, a_rwnd=0, gapack_num=0, duptsn_num=0, gapacks=None, duptsns=None): super(chunk_sack, self).__init__(self.chunk_type(), length) self.flags = flags self.tsn_ack = tsn_ack self.a_rwnd = a_rwnd self.gapack_num = gapack_num self.duptsn_num = duptsn_num gapacks = gapacks or [] assert isinstance(gapacks, list) for one in gapacks: assert isinstance(one, list) assert 2 == len(one) self.gapacks = gapacks duptsns = duptsns or [] assert isinstance(duptsns, list) self.duptsns = duptsns @classmethod def parser(cls, buf): (_, flags, length, tsn_ack, a_rwnd, gapack_num, duptsn_num ) = struct.unpack_from(cls._PACK_STR, buf) gapacks = [] offset = cls._MIN_LEN for _ in range(gapack_num): (gapack_start, gapack_end) = struct.unpack_from( cls._GAPACK_STR, buf, offset) gapacks.append([gapack_start, gapack_end]) offset += cls._GAPACK_LEN duptsns = [] for _ in range(duptsn_num): (duptsn, ) = struct.unpack_from(cls._DUPTSN_STR, buf, offset) duptsns.append(duptsn) offset += cls._DUPTSN_LEN return cls(flags, length, tsn_ack, a_rwnd, gapack_num, duptsn_num, gapacks, duptsns) def serialize(self): buf = bytearray(struct.pack( self._PACK_STR, self.chunk_type(), self.flags, self.length, self.tsn_ack, self.a_rwnd, self.gapack_num, self.duptsn_num)) for one in self.gapacks: buf.extend(struct.pack(chunk_sack._GAPACK_STR, one[0], one[1])) for one in self.duptsns: buf.extend(struct.pack(chunk_sack._DUPTSN_STR, one)) if 0 == self.length: self.length = len(buf) struct.pack_into('!H', buf, 2, self.length) return bytes(buf) @sctp.register_chunk_type class chunk_heartbeat(chunk_heartbeat_base): """Stream Control Transmission Protocol (SCTP) sub encoder/decoder class for Heartbeat Request (HEARTBEAT) chunk (RFC 4960). This class is used with the following. - os_ken.lib.packet.sctp.sctp An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============== ===================================================== Attribute Description ============== ===================================================== flags set to '0'. this field will be ignored. length length of this chunk containing this header. (0 means automatically-calculate when encoding) info os_ken.lib.packet.sctp.param_heartbeat. ============== ===================================================== """ _RECOGNIZED_PARAMS = {} @staticmethod def register_param_type(*args): def _register_param_type(cls): chunk_heartbeat._RECOGNIZED_PARAMS[cls.param_type()] = cls return cls return _register_param_type(args[0]) @classmethod def chunk_type(cls): return TYPE_HEARTBEAT @classmethod def parser(cls, buf): return super(chunk_heartbeat, cls).parser_base( buf, cls._RECOGNIZED_PARAMS) @sctp.register_chunk_type class chunk_heartbeat_ack(chunk_heartbeat_base): """Stream Control Transmission Protocol (SCTP) sub encoder/decoder class for Heartbeat Acknowledgement (HEARTBEAT ACK) chunk (RFC 4960). This class is used with the following. - os_ken.lib.packet.sctp.sctp An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============== ===================================================== Attribute Description ============== ===================================================== flags set to '0'. this field will be ignored. length length of this chunk containing this header. (0 means automatically-calculate when encoding) info os_ken.lib.packet.sctp.param_heartbeat. ============== ===================================================== """ _RECOGNIZED_PARAMS = {} @staticmethod def register_param_type(*args): def _register_param_type(cls): chunk_heartbeat_ack._RECOGNIZED_PARAMS[cls.param_type()] = cls return cls return _register_param_type(args[0]) @classmethod def chunk_type(cls): return TYPE_HEARTBEAT_ACK @classmethod def parser(cls, buf): return super(chunk_heartbeat_ack, cls).parser_base( buf, cls._RECOGNIZED_PARAMS) @sctp.register_chunk_type class chunk_abort(chunk): """Stream Control Transmission Protocol (SCTP) sub encoder/decoder class for Abort Association (ABORT) chunk (RFC 4960). This class is used with the following. - os_ken.lib.packet.sctp.sctp An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============== ===================================================== Attribute Description ============== ===================================================== tflag '0' means the Verification tag is normal. '1' means the Verification tag is copy of the sender. length length of this chunk containing this header. (0 means automatically-calculate when encoding) causes a list of derived classes of os_ken.lib.packet.sctp.causes. ============== ===================================================== """ _class_prefixes = ['cause_'] _RECOGNIZED_CAUSES = {} @staticmethod def register_cause_code(*args): def _register_cause_code(cls): chunk_abort._RECOGNIZED_CAUSES[cls.cause_code()] = cls return cls return _register_cause_code(args[0]) @classmethod def chunk_type(cls): return TYPE_ABORT def __init__(self, tflag=0, length=0, causes=None): super(chunk_abort, self).__init__(self.chunk_type(), length) assert (1 == tflag | 1) self.tflag = tflag causes = causes or [] assert isinstance(causes, list) for one in causes: assert isinstance(one, cause) self.causes = causes @classmethod def parser(cls, buf): (_, flags, length) = struct.unpack_from(cls._PACK_STR, buf) tflag = (flags >> 0) & 1 causes = [] offset = cls._MIN_LEN while offset < length: (ccode, ) = struct.unpack_from('!H', buf, offset) cls_ = cls._RECOGNIZED_CAUSES.get(ccode) if not cls_: break ins = cls_.parser(buf[offset:]) causes.append(ins) offset += len(ins) return cls(tflag, length, causes) def serialize(self): flags = (self.tflag << 0) buf = bytearray(struct.pack( self._PACK_STR, self.chunk_type(), flags, self.length)) for one in self.causes: buf.extend(one.serialize()) if 0 == self.length: self.length = len(buf) struct.pack_into('!H', buf, 2, self.length) return bytes(buf) @sctp.register_chunk_type class chunk_shutdown(chunk): """Stream Control Transmission Protocol (SCTP) sub encoder/decoder class for Shutdown Association (SHUTDOWN) chunk (RFC 4960). This class is used with the following. - os_ken.lib.packet.sctp.sctp An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============== ===================================================== Attribute Description ============== ===================================================== flags set to '0'. this field will be ignored. length length of this chunk containing this header. (0 means automatically-calculate when encoding) tsn_ack TSN of the last DATA chunk received in sequence before a gap. ============== ===================================================== """ _PACK_STR = '!BBHI' _MIN_LEN = struct.calcsize(_PACK_STR) @classmethod def chunk_type(cls): return TYPE_SHUTDOWN def __init__(self, flags=0, length=0, tsn_ack=0): super(chunk_shutdown, self).__init__(self.chunk_type(), length) self.flags = flags self.tsn_ack = tsn_ack @classmethod def parser(cls, buf): (_, flags, length, tsn_ack ) = struct.unpack_from(cls._PACK_STR, buf) msg = cls(flags, length, tsn_ack) return msg def serialize(self): if 0 == self.length: self.length = self._MIN_LEN buf = struct.pack( self._PACK_STR, self.chunk_type(), self.flags, self.length, self.tsn_ack) return buf @sctp.register_chunk_type class chunk_shutdown_ack(chunk_ack_base): """Stream Control Transmission Protocol (SCTP) sub encoder/decoder class for Shutdown Acknowledgement (SHUTDOWN ACK) chunk (RFC 4960). This class is used with the following. - os_ken.lib.packet.sctp.sctp An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============== ===================================================== Attribute Description ============== ===================================================== flags set to '0'. this field will be ignored. length length of this chunk containing this header. (0 means automatically-calculate when encoding) ============== ===================================================== """ @classmethod def chunk_type(cls): return TYPE_SHUTDOWN_ACK @sctp.register_chunk_type class chunk_error(chunk): """Stream Control Transmission Protocol (SCTP) sub encoder/decoder class for Operation Error (ERROR) chunk (RFC 4960). This class is used with the following. - os_ken.lib.packet.sctp.sctp An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============== ===================================================== Attribute Description ============== ===================================================== flags set to '0'. this field will be ignored. length length of this chunk containing this header. (0 means automatically-calculate when encoding) causes a list of derived classes of os_ken.lib.packet.sctp.causes. ============== ===================================================== """ _class_prefixes = ['cause_'] _RECOGNIZED_CAUSES = {} @staticmethod def register_cause_code(*args): def _register_cause_code(cls): chunk_error._RECOGNIZED_CAUSES[cls.cause_code()] = cls return cls return _register_cause_code(args[0]) @classmethod def chunk_type(cls): return TYPE_ERROR def __init__(self, flags=0, length=0, causes=None): super(chunk_error, self).__init__(self.chunk_type(), length) self.flags = flags causes = causes or [] assert isinstance(causes, list) for one in causes: assert isinstance(one, cause) self.causes = causes @classmethod def parser(cls, buf): (_, flags, length) = struct.unpack_from(cls._PACK_STR, buf) causes = [] offset = cls._MIN_LEN while offset < length: (ccode, ) = struct.unpack_from('!H', buf, offset) cls_ = cls._RECOGNIZED_CAUSES.get(ccode) if not cls_: break ins = cls_.parser(buf[offset:]) causes.append(ins) offset += len(ins) return cls(flags, length, causes) def serialize(self): buf = bytearray(struct.pack( self._PACK_STR, self.chunk_type(), self.flags, self.length)) for one in self.causes: buf.extend(one.serialize()) if 0 == self.length: self.length = len(buf) struct.pack_into('!H', buf, 2, self.length) return bytes(buf) @sctp.register_chunk_type class chunk_cookie_echo(chunk): """Stream Control Transmission Protocol (SCTP) sub encoder/decoder class for Cookie Echo (COOKIE ECHO) chunk (RFC 4960). This class is used with the following. - os_ken.lib.packet.sctp.sctp An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============== ===================================================== Attribute Description ============== ===================================================== flags set to '0'. this field will be ignored. length length of this chunk containing this header. (0 means automatically-calculate when encoding) cookie cookie data. ============== ===================================================== """ _PACK_STR = '!BBH' _MIN_LEN = struct.calcsize(_PACK_STR) @classmethod def chunk_type(cls): return TYPE_COOKIE_ECHO def __init__(self, flags=0, length=0, cookie=None): super(chunk_cookie_echo, self).__init__(self.chunk_type(), length) self.flags = flags self.cookie = cookie @classmethod def parser(cls, buf): (_, flags, length) = struct.unpack_from(cls._PACK_STR, buf) _len = length - cls._MIN_LEN cookie = None if _len: fmt = '%ds' % _len (cookie, ) = struct.unpack_from(fmt, buf, cls._MIN_LEN) return cls(flags, length, cookie) def serialize(self): buf = bytearray(struct.pack( self._PACK_STR, self.chunk_type(), self.flags, self.length)) if self.cookie is not None: buf.extend(self.cookie) if 0 == self.length: self.length = len(buf) struct.pack_into('!H', buf, 2, self.length) mod = len(buf) % 4 if mod: buf.extend(bytearray(4 - mod)) return bytes(buf) @sctp.register_chunk_type class chunk_cookie_ack(chunk_ack_base): """Stream Control Transmission Protocol (SCTP) sub encoder/decoder class for Cookie Acknowledgement (COOKIE ACK) chunk (RFC 4960). This class is used with the following. - os_ken.lib.packet.sctp.sctp An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============== ===================================================== Attribute Description ============== ===================================================== flags set to '0'. this field will be ignored. length length of this chunk containing this header. (0 means automatically-calculate when encoding) ============== ===================================================== """ @classmethod def chunk_type(cls): return TYPE_COOKIE_ACK @sctp.register_chunk_type class chunk_ecn_echo(chunk_ecn_base): """Stream Control Transmission Protocol (SCTP) sub encoder/decoder class for ECN-Echo chunk (RFC 4960 Appendix A.). This class is used with the following. - os_ken.lib.packet.sctp.sctp An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============== ===================================================== Attribute Description ============== ===================================================== flags set to '0'. this field will be ignored. length length of this chunk containing this header. (0 means automatically-calculate when encoding) low_tsn the lowest TSN. ============== ===================================================== """ @classmethod def chunk_type(cls): return TYPE_ECN_ECHO @sctp.register_chunk_type class chunk_cwr(chunk_ecn_base): """Stream Control Transmission Protocol (SCTP) sub encoder/decoder class for CWR chunk (RFC 4960 Appendix A.). This class is used with the following. - os_ken.lib.packet.sctp.sctp An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============== ===================================================== Attribute Description ============== ===================================================== flags set to '0'. this field will be ignored. length length of this chunk containing this header. (0 means automatically-calculate when encoding) low_tsn the lowest TSN. ============== ===================================================== """ @classmethod def chunk_type(cls): return TYPE_CWR @sctp.register_chunk_type class chunk_shutdown_complete(chunk): """Stream Control Transmission Protocol (SCTP) sub encoder/decoder class for Shutdown Complete (SHUTDOWN COMPLETE) chunk (RFC 4960). This class is used with the following. - os_ken.lib.packet.sctp.sctp An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============== ===================================================== Attribute Description ============== ===================================================== tflag '0' means the Verification tag is normal. '1' means the Verification tag is copy of the sender. length length of this chunk containing this header. (0 means automatically-calculate when encoding) ============== ===================================================== """ _PACK_STR = '!BBH' _MIN_LEN = struct.calcsize(_PACK_STR) @classmethod def chunk_type(cls): return TYPE_SHUTDOWN_COMPLETE def __init__(self, tflag=0, length=0): assert (1 == tflag | 1) super(chunk_shutdown_complete, self).__init__( self.chunk_type(), length) self.tflag = tflag @classmethod def parser(cls, buf): (_, flags, length) = struct.unpack_from(cls._PACK_STR, buf) tflag = flags & 1 msg = cls(tflag, length) return msg def serialize(self): if 0 == self.length: self.length = self._MIN_LEN buf = struct.pack( self._PACK_STR, self.chunk_type(), self.tflag, self.length) return buf # ======================================================================= # # Cause Code # # ======================================================================= class cause(stringify.StringifyMixin, metaclass=abc.ABCMeta): _PACK_STR = '!HH' _MIN_LEN = struct.calcsize(_PACK_STR) @classmethod @abc.abstractmethod def cause_code(cls): pass def __init__(self, length=0): self.length = length @classmethod @abc.abstractmethod def parser(cls, buf): pass def serialize(self): if 0 == self.length: self.length = self._MIN_LEN buf = struct.pack( self._PACK_STR, self.cause_code(), self.length) return buf def __len__(self): length = self.length mod = length % 4 if mod: length += 4 - mod return length class cause_with_value(cause, metaclass=abc.ABCMeta): def __init__(self, value=None, length=0): super(cause_with_value, self).__init__(length) self.value = value @classmethod def parser(cls, buf): (_, length) = struct.unpack_from(cls._PACK_STR, buf) value = None if (cls._MIN_LEN < length): fmt = '%ds' % (length - cls._MIN_LEN) (value, ) = struct.unpack_from(fmt, buf, cls._MIN_LEN) return cls(value, length) def serialize(self): buf = bytearray(struct.pack( self._PACK_STR, self.cause_code(), self.length)) if self.value is not None: buf.extend(self.value) if 0 == self.length: self.length = len(buf) struct.pack_into('!H', buf, 2, self.length) mod = len(buf) % 4 if mod: buf.extend(bytearray(4 - mod)) return bytes(buf) @chunk_abort.register_cause_code @chunk_error.register_cause_code class cause_invalid_stream_id(cause_with_value): """Stream Control Transmission Protocol (SCTP) sub encoder/decoder class for Invalid Stream Identifier (RFC 4960). This class is used with the following. - os_ken.lib.packet.sctp.chunk_abort - os_ken.lib.packet.sctp.chunk_error An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============== ===================================================== Attribute Description ============== ===================================================== value stream id. length length of this cause containing this header. (0 means automatically-calculate when encoding) ============== ===================================================== """ _PACK_STR = '!HHH2x' _MIN_LEN = struct.calcsize(_PACK_STR) @classmethod def cause_code(cls): return CCODE_INVALID_STREAM_ID def __init__(self, value=0, length=0): super(cause_invalid_stream_id, self).__init__(value, length) @classmethod def parser(cls, buf): (_, length, value) = struct.unpack_from(cls._PACK_STR, buf) return cls(value, length) def serialize(self): if 0 == self.length: self.length = self._MIN_LEN buf = struct.pack( self._PACK_STR, self.cause_code(), self.length, self.value) return buf @chunk_abort.register_cause_code @chunk_error.register_cause_code class cause_missing_param(cause): """Stream Control Transmission Protocol (SCTP) sub encoder/decoder class for Missing Mandatory Parameter (RFC 4960). This class is used with the following. - os_ken.lib.packet.sctp.chunk_abort - os_ken.lib.packet.sctp.chunk_error An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============== ===================================================== Attribute Description ============== ===================================================== types a list of missing params. num Number of missing params. (0 means automatically-calculate when encoding) length length of this cause containing this header. (0 means automatically-calculate when encoding) ============== ===================================================== """ _PACK_STR = '!HHI' _MIN_LEN = struct.calcsize(_PACK_STR) @classmethod def cause_code(cls): return CCODE_MISSING_PARAM def __init__(self, types=None, num=0, length=0): super(cause_missing_param, self).__init__(length) types = types or [] assert isinstance(types, list) for one in types: assert isinstance(one, int) self.types = types self.num = num @classmethod def parser(cls, buf): (_, length, num) = struct.unpack_from(cls._PACK_STR, buf) types = [] offset = cls._MIN_LEN for count in range(num): offset = cls._MIN_LEN + (struct.calcsize('!H') * count) (one, ) = struct.unpack_from('!H', buf, offset) types.append(one) return cls(types, num, length) def serialize(self): buf = bytearray(struct.pack( self._PACK_STR, self.cause_code(), self.length, self.num)) for one in self.types: buf.extend(struct.pack('!H', one)) if 0 == self.num: self.num = len(self.types) struct.pack_into('!I', buf, 4, self.num) if 0 == self.length: self.length = len(buf) struct.pack_into('!H', buf, 2, self.length) mod = len(buf) % 4 if mod: buf.extend(bytearray(4 - mod)) return bytes(buf) @chunk_abort.register_cause_code @chunk_error.register_cause_code class cause_stale_cookie(cause_with_value): """Stream Control Transmission Protocol (SCTP) sub encoder/decoder class for Stale Cookie Error (RFC 4960). This class is used with the following. - os_ken.lib.packet.sctp.chunk_abort - os_ken.lib.packet.sctp.chunk_error An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============== ===================================================== Attribute Description ============== ===================================================== value Measure of Staleness. length length of this cause containing this header. (0 means automatically-calculate when encoding) ============== ===================================================== """ @classmethod def cause_code(cls): return CCODE_STALE_COOKIE @chunk_abort.register_cause_code @chunk_error.register_cause_code class cause_out_of_resource(cause): """Stream Control Transmission Protocol (SCTP) sub encoder/decoder class for Out of Resource (RFC 4960). This class is used with the following. - os_ken.lib.packet.sctp.chunk_abort - os_ken.lib.packet.sctp.chunk_error An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============== ===================================================== Attribute Description ============== ===================================================== length length of this cause containing this header. (0 means automatically-calculate when encoding) ============== ===================================================== """ @classmethod def cause_code(cls): return CCODE_OUT_OF_RESOURCE @classmethod def parser(cls, buf): (_, length) = struct.unpack_from(cls._PACK_STR, buf) return cls(length) @chunk_abort.register_cause_code @chunk_error.register_cause_code class cause_unresolvable_addr(cause_with_value): """Stream Control Transmission Protocol (SCTP) sub encoder/decoder class for Unresolvable Address (RFC 4960). This class is used with the following. - os_ken.lib.packet.sctp.chunk_abort - os_ken.lib.packet.sctp.chunk_error An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============== ===================================================== Attribute Description ============== ===================================================== value Unresolvable Address. one of follows: os_ken.lib.packet.sctp.param_host_addr, os_ken.lib.packet.sctp.param_ipv4, or os_ken.lib.packet.sctp.param_ipv6. length length of this cause containing this header. (0 means automatically-calculate when encoding) ============== ===================================================== """ _class_prefixes = ['param_'] _RECOGNIZED_PARAMS = {} @staticmethod def register_param_type(*args): def _register_param_type(cls): cause_unresolvable_addr._RECOGNIZED_PARAMS[cls.param_type()] = cls return cls return _register_param_type(args[0]) @classmethod def cause_code(cls): return CCODE_UNRESOLVABLE_ADDR @classmethod def parser(cls, buf): (_, length) = struct.unpack_from(cls._PACK_STR, buf) (ptype, ) = struct.unpack_from('!H', buf, cls._MIN_LEN) cls_ = cls._RECOGNIZED_PARAMS.get(ptype) value = cls_.parser(buf[cls._MIN_LEN:]) return cls(value, length) def serialize(self): buf = bytearray(struct.pack( self._PACK_STR, self.cause_code(), self.length)) buf.extend(self.value.serialize()) if 0 == self.length: self.length = len(buf) struct.pack_into('!H', buf, 2, self.length) mod = len(buf) % 4 if mod: buf.extend(bytearray(4 - mod)) return bytes(buf) @chunk_abort.register_cause_code @chunk_error.register_cause_code class cause_unrecognized_chunk(cause_with_value): """Stream Control Transmission Protocol (SCTP) sub encoder/decoder class for Unrecognized Chunk Type (RFC 4960). This class is used with the following. - os_ken.lib.packet.sctp.chunk_abort - os_ken.lib.packet.sctp.chunk_error An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============== ===================================================== Attribute Description ============== ===================================================== value Unrecognized Chunk. length length of this cause containing this header. (0 means automatically-calculate when encoding) ============== ===================================================== """ @classmethod def cause_code(cls): return CCODE_UNRECOGNIZED_CHUNK @chunk_abort.register_cause_code @chunk_error.register_cause_code class cause_invalid_param(cause): """Stream Control Transmission Protocol (SCTP) sub encoder/decoder class for Invalid Mandatory Parameter (RFC 4960). This class is used with the following. - os_ken.lib.packet.sctp.chunk_abort - os_ken.lib.packet.sctp.chunk_error An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============== ===================================================== Attribute Description ============== ===================================================== length length of this cause containing this header. (0 means automatically-calculate when encoding) ============== ===================================================== """ @classmethod def cause_code(cls): return CCODE_INVALID_PARAM @classmethod def parser(cls, buf): (_, length) = struct.unpack_from(cls._PACK_STR, buf) return cls(length) @chunk_abort.register_cause_code @chunk_error.register_cause_code class cause_unrecognized_param(cause_with_value): """Stream Control Transmission Protocol (SCTP) sub encoder/decoder class for Unrecognized Parameters (RFC 4960). This class is used with the following. - os_ken.lib.packet.sctp.chunk_abort - os_ken.lib.packet.sctp.chunk_error An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============== ===================================================== Attribute Description ============== ===================================================== value Unrecognized Parameter. length length of this cause containing this header. (0 means automatically-calculate when encoding) ============== ===================================================== """ @classmethod def cause_code(cls): return CCODE_UNRECOGNIZED_PARAM @chunk_abort.register_cause_code @chunk_error.register_cause_code class cause_no_userdata(cause_with_value): """Stream Control Transmission Protocol (SCTP) sub encoder/decoder class for No User Data (RFC 4960). This class is used with the following. - os_ken.lib.packet.sctp.chunk_abort - os_ken.lib.packet.sctp.chunk_error An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============== ===================================================== Attribute Description ============== ===================================================== value the TSN of the DATA chunk received with no user data field. length length of this cause containing this header. (0 means automatically-calculate when encoding) ============== ===================================================== """ @classmethod def cause_code(cls): return CCODE_NO_USERDATA @chunk_abort.register_cause_code @chunk_error.register_cause_code class cause_cookie_while_shutdown(cause): """Stream Control Transmission Protocol (SCTP) sub encoder/decoder class for Cookie Received While Shutting Down (RFC 4960). This class is used with the following. - os_ken.lib.packet.sctp.chunk_abort - os_ken.lib.packet.sctp.chunk_error An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============== ===================================================== Attribute Description ============== ===================================================== length length of this cause containing this header. (0 means automatically-calculate when encoding) ============== ===================================================== """ @classmethod def cause_code(cls): return CCODE_COOKIE_WHILE_SHUTDOWN @classmethod def parser(cls, buf): (_, length) = struct.unpack_from(cls._PACK_STR, buf) return cls(length) @chunk_abort.register_cause_code @chunk_error.register_cause_code class cause_restart_with_new_addr(cause_with_value): """Stream Control Transmission Protocol (SCTP) sub encoder/decoder class for Restart of an Association with New Addresses (RFC 4960). This class is used with the following. - os_ken.lib.packet.sctp.chunk_abort - os_ken.lib.packet.sctp.chunk_error An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============== ===================================================== Attribute Description ============== ===================================================== value New Address TLVs. length length of this cause containing this header. (0 means automatically-calculate when encoding) ============== ===================================================== """ _class_prefixes = ['param_'] _RECOGNIZED_PARAMS = {} @staticmethod def register_param_type(*args): def _register_param_type(cls): cause_restart_with_new_addr._RECOGNIZED_PARAMS[ cls.param_type()] = cls return cls return _register_param_type(args[0]) @classmethod def cause_code(cls): return CCODE_RESTART_WITH_NEW_ADDR def __init__(self, value=None, length=0): if not isinstance(value, list): value = [value] super(cause_restart_with_new_addr, self).__init__(value, length) @classmethod def parser(cls, buf): (_, length) = struct.unpack_from(cls._PACK_STR, buf) value = [] offset = cls._MIN_LEN while offset < length: (ptype, ) = struct.unpack_from('!H', buf, offset) cls_ = cls._RECOGNIZED_PARAMS.get(ptype) if not cls_: break ins = cls_.parser(buf[offset:]) value.append(ins) offset += len(ins) return cls(value, length) def serialize(self): buf = bytearray(struct.pack( self._PACK_STR, self.cause_code(), self.length)) for one in self.value: buf.extend(one.serialize()) if 0 == self.length: self.length = len(buf) struct.pack_into('!H', buf, 2, self.length) mod = len(buf) % 4 if mod: buf.extend(bytearray(4 - mod)) return bytes(buf) @chunk_abort.register_cause_code @chunk_error.register_cause_code class cause_user_initiated_abort(cause_with_value): """Stream Control Transmission Protocol (SCTP) sub encoder/decoder class for User-Initiated Abort (RFC 4960). This class is used with the following. - os_ken.lib.packet.sctp.chunk_abort - os_ken.lib.packet.sctp.chunk_error An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============== ===================================================== Attribute Description ============== ===================================================== value Upper Layer Abort Reason. length length of this cause containing this header. (0 means automatically-calculate when encoding) ============== ===================================================== """ @classmethod def cause_code(cls): return CCODE_USER_INITIATED_ABORT @chunk_abort.register_cause_code @chunk_error.register_cause_code class cause_protocol_violation(cause_with_value): """Stream Control Transmission Protocol (SCTP) sub encoder/decoder class for Protocol Violation (RFC 4960). This class is used with the following. - os_ken.lib.packet.sctp.chunk_abort - os_ken.lib.packet.sctp.chunk_error An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============== ===================================================== Attribute Description ============== ===================================================== value Additional Information. length length of this cause containing this header. (0 means automatically-calculate when encoding) ============== ===================================================== """ @classmethod def cause_code(cls): return CCODE_PROTOCOL_VIOLATION # ======================================================================= # # Chunk Parameter Types # # ======================================================================= class param(stringify.StringifyMixin, metaclass=abc.ABCMeta): _PACK_STR = '!HH' _MIN_LEN = struct.calcsize(_PACK_STR) @classmethod @abc.abstractmethod def param_type(cls): pass def __init__(self, value=None, length=0): self.length = length self.value = value @classmethod def parser(cls, buf): (_, length) = struct.unpack_from(cls._PACK_STR, buf) value = None if (cls._MIN_LEN < length): fmt = '%ds' % (length - cls._MIN_LEN) (value, ) = struct.unpack_from(fmt, buf, cls._MIN_LEN) return cls(value, length) def serialize(self): buf = bytearray(struct.pack( self._PACK_STR, self.param_type(), self.length)) if self.value: buf.extend(self.value) if 0 == self.length: self.length = len(buf) struct.pack_into('!H', buf, 2, self.length) mod = len(buf) % 4 if mod: buf.extend(bytearray(4 - mod)) return bytes(buf) def __len__(self): length = self.length mod = length % 4 if mod: length += 4 - mod return length @chunk_heartbeat.register_param_type @chunk_heartbeat_ack.register_param_type class param_heartbeat(param): """Stream Control Transmission Protocol (SCTP) sub encoder/decoder class for Heartbeat Info Parameter (RFC 4960). This class is used with the following. - os_ken.lib.packet.sctp.chunk_heartbeat - os_ken.lib.packet.sctp.chunk_heartbeat_ack An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============== ===================================================== Attribute Description ============== ===================================================== value the sender-specific heartbeat information. length length of this param containing this header. (0 means automatically-calculate when encoding) ============== ===================================================== """ @classmethod def param_type(cls): return PTYPE_HEARTBEAT @chunk_init_ack.register_param_type class param_state_cookie(param): """Stream Control Transmission Protocol (SCTP) sub encoder/decoder class for State Cookie Parameter (RFC 4960). This class is used with the following. - os_ken.lib.packet.sctp.chunk_init_ack An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============== ===================================================== Attribute Description ============== ===================================================== value the state cookie. see Section 5.1.3 in RFC 4960. length length of this param containing this header. (0 means automatically-calculate when encoding) ============== ===================================================== """ @classmethod def param_type(cls): return PTYPE_STATE_COOKIE @chunk_init_ack.register_param_type class param_unrecognized_param(param): """Stream Control Transmission Protocol (SCTP) sub encoder/decoder class for Unrecognized Parameter (RFC 4960). This class is used with the following. - os_ken.lib.packet.sctp.chunk_init_ack An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============== ===================================================== Attribute Description ============== ===================================================== value the unrecognized parameter in the INIT chunk. length length of this param containing this header. (0 means automatically-calculate when encoding) ============== ===================================================== """ @classmethod def param_type(cls): return PTYPE_UNRECOGNIZED_PARAM @chunk_init.register_param_type class param_cookie_preserve(param): """Stream Control Transmission Protocol (SCTP) sub encoder/decoder class for Cookie Preservative Parameter (RFC 4960). This class is used with the following. - os_ken.lib.packet.sctp.chunk_init An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============== ===================================================== Attribute Description ============== ===================================================== value Suggested Cookie Life-Span Increment (msec). length length of this param containing this header. (0 means automatically-calculate when encoding) ============== ===================================================== """ _PACK_STR = '!HHI' _MIN_LEN = struct.calcsize(_PACK_STR) @classmethod def param_type(cls): return PTYPE_COOKIE_PRESERVE def __init__(self, value=0, length=0): super(param_cookie_preserve, self).__init__(value, length) @classmethod def parser(cls, buf): (_, length, value) = struct.unpack_from(cls._PACK_STR, buf) return cls(value, length) def serialize(self): if 0 == self.length: self.length = self._MIN_LEN buf = struct.pack( self._PACK_STR, self.param_type(), self.length, self.value) return buf @chunk_init.register_param_type @chunk_init_ack.register_param_type class param_ecn(param): """Stream Control Transmission Protocol (SCTP) sub encoder/decoder class for ECN Parameter (RFC 4960 Appendix A.). This class is used with the following. - os_ken.lib.packet.sctp.chunk_init - os_ken.lib.packet.sctp.chunk_init_ack An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============== ===================================================== Attribute Description ============== ===================================================== value set to None. length length of this param containing this header. (0 means automatically-calculate when encoding) ============== ===================================================== """ @classmethod def param_type(cls): return PTYPE_ECN def __init__(self, value=None, length=0): super(param_ecn, self).__init__(value, length) assert 4 == length or 0 == length assert None is value @chunk_init.register_param_type @chunk_init_ack.register_param_type @cause_unresolvable_addr.register_param_type @cause_restart_with_new_addr.register_param_type class param_host_addr(param): """Stream Control Transmission Protocol (SCTP) sub encoder/decoder class for Host Name Address Parameter (RFC 4960). This class is used with the following. - os_ken.lib.packet.sctp.chunk_init - os_ken.lib.packet.sctp.chunk_init_ack An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============== ===================================================== Attribute Description ============== ===================================================== value a host name that ends with null terminator. length length of this param containing this header. (0 means automatically-calculate when encoding) ============== ===================================================== """ @classmethod def param_type(cls): return PTYPE_HOST_ADDR @chunk_init.register_param_type class param_supported_addr(param): """Stream Control Transmission Protocol (SCTP) sub encoder/decoder class for Supported Address Types Parameter (RFC 4960). This class is used with the following. - os_ken.lib.packet.sctp.chunk_init An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============== ===================================================== Attribute Description ============== ===================================================== value a list of parameter types. odd cases pad with 0x0000. length length of this param containing this header. (0 means automatically-calculate when encoding) ============== ===================================================== """ _VALUE_STR = '!H' _VALUE_LEN = struct.calcsize(_VALUE_STR) @classmethod def param_type(cls): return PTYPE_SUPPORTED_ADDR def __init__(self, value=None, length=0): if not isinstance(value, list): value = [value] for one in value: assert isinstance(one, int) super(param_supported_addr, self).__init__(value, length) @classmethod def parser(cls, buf): (_, length) = struct.unpack_from(cls._PACK_STR, buf) value = [] offset = cls._MIN_LEN while offset < length: (one, ) = struct.unpack_from(cls._VALUE_STR, buf, offset) value.append(one) offset += cls._VALUE_LEN return cls(value, length) def serialize(self): buf = bytearray(struct.pack( self._PACK_STR, self.param_type(), self.length)) for one in self.value: buf.extend(struct.pack(param_supported_addr._VALUE_STR, one)) if 0 == self.length: self.length = len(buf) struct.pack_into('!H', buf, 2, self.length) mod = len(buf) % 4 if mod: buf.extend(bytearray(4 - mod)) return bytes(buf) @chunk_init.register_param_type @chunk_init_ack.register_param_type @cause_unresolvable_addr.register_param_type @cause_restart_with_new_addr.register_param_type class param_ipv4(param): """Stream Control Transmission Protocol (SCTP) sub encoder/decoder class for IPv4 Address Parameter (RFC 4960). This class is used with the following. - os_ken.lib.packet.sctp.chunk_init - os_ken.lib.packet.sctp.chunk_init_ack An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============== ===================================================== Attribute Description ============== ===================================================== value IPv4 address of the sending endpoint. length length of this param containing this header. (0 means automatically-calculate when encoding) ============== ===================================================== """ _TYPE = {'ascii': ['value']} @classmethod def param_type(cls): return PTYPE_IPV4 def __init__(self, value='127.0.0.1', length=0): super(param_ipv4, self).__init__(value, length) @classmethod def parser(cls, buf): (_, length) = struct.unpack_from(cls._PACK_STR, buf) value = None if (cls._MIN_LEN < length): fmt = '%ds' % (length - cls._MIN_LEN) (value, ) = struct.unpack_from(fmt, buf, cls._MIN_LEN) return cls(addrconv.ipv4.bin_to_text(value), length) def serialize(self): buf = bytearray(struct.pack( self._PACK_STR, self.param_type(), self.length)) if self.value: buf.extend(addrconv.ipv4.text_to_bin(self.value)) if 0 == self.length: self.length = len(buf) struct.pack_into('!H', buf, 2, self.length) return bytes(buf) @chunk_init.register_param_type @chunk_init_ack.register_param_type @cause_unresolvable_addr.register_param_type @cause_restart_with_new_addr.register_param_type class param_ipv6(param): """Stream Control Transmission Protocol (SCTP) sub encoder/decoder class for IPv6 Address Parameter (RFC 4960). This class is used with the following. - os_ken.lib.packet.sctp.chunk_init - os_ken.lib.packet.sctp.chunk_init_ack An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============== ===================================================== Attribute Description ============== ===================================================== value IPv6 address of the sending endpoint. length length of this param containing this header. (0 means automatically-calculate when encoding) ============== ===================================================== """ _TYPE = {'ascii': ['value']} @classmethod def param_type(cls): return PTYPE_IPV6 def __init__(self, value='::1', length=0): super(param_ipv6, self).__init__(value, length) @classmethod def parser(cls, buf): (_, length) = struct.unpack_from(cls._PACK_STR, buf) value = None if (cls._MIN_LEN < length): fmt = '%ds' % (length - cls._MIN_LEN) (value, ) = struct.unpack_from(fmt, buf, cls._MIN_LEN) return cls(addrconv.ipv6.bin_to_text(value), length) def serialize(self): buf = bytearray(struct.pack( self._PACK_STR, self.param_type(), self.length)) if self.value: buf.extend(addrconv.ipv6.text_to_bin(self.value)) if 0 == self.length: self.length = len(buf) struct.pack_into('!H', buf, 2, self.length) return bytes(buf) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/packet/slow.py0000664000175000017500000006446000000000000017654 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone 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. import struct from . import packet_base from os_ken.lib import addrconv # Slow Protocol Multicast destination SLOW_PROTOCOL_MULTICAST = '01:80:c2:00:00:02' # Slow Protocol SubType SLOW_SUBTYPE_LACP = 0x01 SLOW_SUBTYPE_MARKER = 0x02 SLOW_SUBTYPE_OAM = 0x03 SLOW_SUBTYPE_OSSP = 0x0a class slow(packet_base.PacketBase): """Slow Protocol header decoder class. This class has only the parser method. http://standards.ieee.org/getieee802/download/802.3-2012_section5.pdf Slow Protocols Subtypes +---------------+--------------------------------------------------+ | Subtype Value | Protocol Name | +===============+==================================================+ | 0 | Unused - Illegal Value | +---------------+--------------------------------------------------+ | 1 | Link Aggregation Control Protocol(LACP) | +---------------+--------------------------------------------------+ | 2 | Link Aggregation - Marker Protocol | +---------------+--------------------------------------------------+ | 3 | Operations, Administration, and Maintenance(OAM) | +---------------+--------------------------------------------------+ | 4 - 9 | Reserved for future use | +---------------+--------------------------------------------------+ | 10 | Organization Specific Slow Protocol(OSSP) | +---------------+--------------------------------------------------+ | 11 - 255 | Unused - Illegal values | +---------------+--------------------------------------------------+ """ _PACK_STR = '!B' @classmethod def parser(cls, buf): (subtype, ) = struct.unpack_from(cls._PACK_STR, buf) switch = { SLOW_SUBTYPE_LACP: lacp, # TODO: make parsers of other subtypes. SLOW_SUBTYPE_MARKER: None, SLOW_SUBTYPE_OAM: None, SLOW_SUBTYPE_OSSP: None, } cls_ = switch.get(subtype) if cls_: return cls_.parser(buf) else: return None, None, buf class lacp(packet_base.PacketBase): """Link Aggregation Control Protocol(LACP, IEEE 802.1AX) header encoder/decoder class. http://standards.ieee.org/getieee802/download/802.1AX-2008.pdf LACPDU format +------------------------------------------------+--------+ | LACPDU structure | Octets | +================================================+========+ | Subtype = LACP | 1 | +------------------------------------------------+--------+ | Version Number | 1 | +------------+-----------------------------------+--------+ | TLV | TLV_type = Actor Information | 1 | | Actor | | | +------------+-----------------------------------+--------+ | | Actor_Information_Length = 20 | 1 | +------------+-----------------------------------+--------+ | | Actor_System_Priority | 2 | +------------+-----------------------------------+--------+ | | Actor_System | 6 | +------------+-----------------------------------+--------+ | | Actor_Key | 2 | +------------+-----------------------------------+--------+ | | Actor_Port_Priority | 2 | +------------+-----------------------------------+--------+ | | Actor_Port | 2 | +------------+-----------------------------------+--------+ | | Actor_State | 1 | +------------+-----------------------------------+--------+ | | Reserved | 3 | +------------+-----------------------------------+--------+ | TLV | TLV_type = Partner Information | 1 | | Partner | | | +------------+-----------------------------------+--------+ | | Partner_Information_Length = 20 | 1 | +------------+-----------------------------------+--------+ | | Partner_System_Priority | 2 | +------------+-----------------------------------+--------+ | | Partner_System | 6 | +------------+-----------------------------------+--------+ | | Partner_Key | 2 | +------------+-----------------------------------+--------+ | | Partner_Port_Priority | 2 | +------------+-----------------------------------+--------+ | | Partner_Port | 2 | +------------+-----------------------------------+--------+ | | Partner_State | 1 | +------------+-----------------------------------+--------+ | | Reserved | 3 | +------------+-----------------------------------+--------+ | TLV | TLV_type = Collector Information | 1 | | Collector | | | +------------+-----------------------------------+--------+ | | Collector_Information_Length = 16 | 1 | +------------+-----------------------------------+--------+ | | Collector_Max_Delay | 2 | +------------+-----------------------------------+--------+ | | Reserved | 12 | +------------+-----------------------------------+--------+ | TLV | TLV_type = Terminator | 1 | | Terminator | | | +------------+-----------------------------------+--------+ | | Terminator_Length = 0 | 1 | +------------+-----------------------------------+--------+ | | Reserved | 50 | +------------+-----------------------------------+--------+ Terminator information uses a length value of 0 (0x00). NOTE--The use of a Terminator_Length of 0 is intentional. In TLV encoding schemes it is common practice for the terminator encoding to be 0 both for the type and the length. Actor_State and Partner_State encoded as individual bits within a single octet as follows: +------+------+------+------+------+------+------+------+ | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | +======+======+======+======+======+======+======+======+ | EXPR | DFLT | DIST | CLCT | SYNC | AGGR | TMO | ACT | +------+------+------+------+------+------+------+------+ ACT bit 0. about the activity control value with regard to this link. TMO bit 1. about the timeout control value with regard to this link. AGGR bit 2. about how the system regards this link from the point of view of the aggregation. SYNC bit 3. about how the system regards this link from the point of view of the synchronization. CLCT bit 4. about collecting of incoming frames. DIST bit 5. about distributing of outgoing frames. DFLT bit 6. about the opposite system information which the system use. EXPR bit 7. about the expire state of the system. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| =============================== ==================================== Attribute Description =============================== ==================================== version LACP version. This parameter must be set to LACP_VERSION_NUMBER(i.e. 1). actor_system_priority The priority assigned to this System. actor_system The Actor's System ID, encoded as a MAC address. actor_key The operational Key value assigned to the port by the Actor. actor_port_priority The priority assigned to this port. actor_port The port number assigned to the port by the Actor. actor_state_activity .. _lacp_activity: about the activity control value with regard to this link. LACP_STATE_ACTIVE(1) LACP_STATE_PASSIVE(0) actor_state_timeout .. _lacp_timeout: about the timeout control value with regard to this link. LACP_STATE_SHORT_TIMEOUT(1) LACP_STATE_LONG_TIMEOUT(0) actor_state_aggregation .. _lacp_aggregation: about how the system regards this link from the point of view of the aggregation. LACP_STATE_AGGREGATEABLE(1) LACP_STATE_INDIVIDUAL(0) actor_state_synchronization .. _lacp_synchronization: about how the system regards this link from the point of view of the synchronization. LACP_STATE_IN_SYNC(1) LACP_STATE_OUT_OF_SYNC(0) actor_state_collecting .. _lacp_collecting: about collecting of incoming frames. LACP_STATE_COLLECTING_ENABLED(1) LACP_STATE_COLLECTING_DISABLED(0) actor_state_distributing .. _lacp_distributing: about distributing of outgoing frames. LACP_STATE_DISTRIBUTING_ENABLED(1) LACP_STATE_DISTRIBUTING_DISABLED(0) actor_state_defaulted .. _lacp_defaulted: about the Partner information which the the Actor use. LACP_STATE_DEFAULTED_PARTNER(1) LACP_STATE_OPERATIONAL_PARTNER(0) actor_state_expired .. _lacp_expired: about the state of the Actor. LACP_STATE_EXPIRED(1) LACP_STATE_NOT_EXPIRED(0) partner_system_priority The priority assigned to the Partner System. partner_system The Partner's System ID, encoded as a MAC address. partner_key The operational Key value assigned to the port by the Partner. partner_port_priority The priority assigned to this port by the Partner. partner_port The port number assigned to the port by the Partner. partner_state_activity See :ref:`actor_state_activity\ `. partner_state_timeout See :ref:`actor_state_timeout\ `. partner_state_aggregation See :ref:`actor_state_aggregation\ `. partner_state_synchronization See :ref:`actor_state_synchronization\ `. partner_state_collecting See :ref:`actor_state_collecting\ `. partner_state_distributing See :ref:`actor_state_distributing\ `. partner_state_defaulted See :ref:`actor_state_defaulted\ `. partner_state_expired See :ref:`actor_state_expired\ `. collector_max_delay the maximum time that the Frame Collector may delay. =============================== ==================================== """ LACP_VERSION_NUMBER = 1 # LACP TLV type LACP_TLV_TYPE_ACTOR = 1 LACP_TLV_TYPE_PARTNER = 2 LACP_TLV_TYPE_COLLECTOR = 3 LACP_TLV_TYPE_TERMINATOR = 0 # LACP state(LACP_Activity) LACP_STATE_ACTIVE = 1 LACP_STATE_PASSIVE = 0 # LACP state(LACP_Timeout) LACP_STATE_SHORT_TIMEOUT = 1 LACP_STATE_LONG_TIMEOUT = 0 # LACP state(Aggregation) LACP_STATE_AGGREGATEABLE = 1 LACP_STATE_INDIVIDUAL = 0 # LACP state(Synchronization) LACP_STATE_IN_SYNC = 1 LACP_STATE_OUT_OF_SYNC = 0 # LACP state(Collecting) LACP_STATE_COLLECTING_ENABLED = 1 LACP_STATE_COLELCTING_DISABLED = 0 # LACP state(Distributing) LACP_STATE_DISTRIBUTING_ENABLED = 1 LACP_STATE_DISTRIBUTING_DISABLED = 0 # LACP state(Defaulted) LACP_STATE_DEFAULED_PARTNER = 1 LACP_STATE_OPERATIONAL_PARTNER = 0 # LACP state(Expired) LACP_STATE_EXPIRED = 1 LACP_STATE_NOT_EXPIRED = 0 # The number of seconds between periodic transmissions using # Short Timeouts. FAST_PERIODIC_TIME = 1 # The number of seconds between periodic transmissions using # Long Timeouts. SLOW_PERIODIC_TIME = 30 # The number of seconds before invalidating received LACPDU # information when using Short Timeouts(3 x Fast_Periodic_Time). SHORT_TIMEOUT_TIME = 3 * FAST_PERIODIC_TIME # The number of seconds before invalidating received LACPDU # information when using Long Timeouts (3 x Slow_Periodic_Time). LONG_TIMEOUT_TIME = 3 * SLOW_PERIODIC_TIME _HLEN_PACK_STR = '!BB' _HLEN_PACK_LEN = struct.calcsize(_HLEN_PACK_STR) _ACTPRT_INFO_PACK_STR = '!BBH6sHHHB3x' _ACTPRT_INFO_PACK_LEN = struct.calcsize(_ACTPRT_INFO_PACK_STR) _COL_INFO_PACK_STR = '!BBH12x' _COL_INFO_PACK_LEN = struct.calcsize(_COL_INFO_PACK_STR) _TRM_PACK_STR = '!BB50x' _TRM_PACK_LEN = struct.calcsize(_TRM_PACK_STR) _ALL_PACK_LEN = _HLEN_PACK_LEN + _ACTPRT_INFO_PACK_LEN * 2 + \ _COL_INFO_PACK_LEN + _TRM_PACK_LEN _MIN_LEN = _ALL_PACK_LEN _TYPE = { 'ascii': [ 'actor_system', 'partner_system' ] } def __init__(self, version=LACP_VERSION_NUMBER, actor_system_priority=0, actor_system='00:00:00:00:00:00', actor_key=0, actor_port_priority=0, actor_port=0, actor_state_activity=0, actor_state_timeout=0, actor_state_aggregation=0, actor_state_synchronization=0, actor_state_collecting=0, actor_state_distributing=0, actor_state_defaulted=0, actor_state_expired=0, partner_system_priority=0, partner_system='00:00:00:00:00:00', partner_key=0, partner_port_priority=0, partner_port=0, partner_state_activity=0, partner_state_timeout=0, partner_state_aggregation=0, partner_state_synchronization=0, partner_state_collecting=0, partner_state_distributing=0, partner_state_defaulted=0, partner_state_expired=0, collector_max_delay=0): super(lacp, self).__init__() # parameter check assert (1 == actor_state_activity | 1) assert (1 == actor_state_timeout | 1) assert (1 == actor_state_aggregation | 1) assert (1 == actor_state_synchronization | 1) assert (1 == actor_state_collecting | 1) assert (1 == actor_state_distributing | 1) assert (1 == actor_state_defaulted | 1) assert (1 == actor_state_expired | 1) assert (1 == partner_state_activity | 1) assert (1 == partner_state_timeout | 1) assert (1 == partner_state_aggregation | 1) assert (1 == partner_state_synchronization | 1) assert (1 == partner_state_collecting | 1) assert (1 == partner_state_distributing | 1) assert (1 == partner_state_defaulted | 1) assert (1 == partner_state_expired | 1) # ------------------------------ # Header # ------------------------------ self._subtype = SLOW_SUBTYPE_LACP self.version = version # ------------------------------ # Actor Information # ------------------------------ self._actor_tag = self.LACP_TLV_TYPE_ACTOR self._actor_length = self._ACTPRT_INFO_PACK_LEN self.actor_system_priority = actor_system_priority self.actor_system = actor_system self.actor_key = actor_key self.actor_port_priority = actor_port_priority self.actor_port = actor_port self.actor_state_activity = actor_state_activity self.actor_state_timeout = actor_state_timeout self.actor_state_aggregation = actor_state_aggregation self.actor_state_synchronization = actor_state_synchronization self.actor_state_collecting = actor_state_collecting self.actor_state_distributing = actor_state_distributing self.actor_state_defaulted = actor_state_defaulted self.actor_state_expired = actor_state_expired self._actor_state = ( (self.actor_state_activity << 0) | (self.actor_state_timeout << 1) | (self.actor_state_aggregation << 2) | (self.actor_state_synchronization << 3) | (self.actor_state_collecting << 4) | (self.actor_state_distributing << 5) | (self.actor_state_defaulted << 6) | (self.actor_state_expired << 7)) # ------------------------------ # Partner Information # ------------------------------ self._partner_tag = self.LACP_TLV_TYPE_PARTNER self._partner_length = self._ACTPRT_INFO_PACK_LEN self.partner_system_priority = partner_system_priority self.partner_system = partner_system self.partner_key = partner_key self.partner_port_priority = partner_port_priority self.partner_port = partner_port self.partner_state_activity = partner_state_activity self.partner_state_timeout = partner_state_timeout self.partner_state_aggregation = partner_state_aggregation self.partner_state_synchronization = \ partner_state_synchronization self.partner_state_collecting = partner_state_collecting self.partner_state_distributing = partner_state_distributing self.partner_state_defaulted = partner_state_defaulted self.partner_state_expired = partner_state_expired self._partner_state = ( (self.partner_state_activity << 0) | (self.partner_state_timeout << 1) | (self.partner_state_aggregation << 2) | (self.partner_state_synchronization << 3) | (self.partner_state_collecting << 4) | (self.partner_state_distributing << 5) | (self.partner_state_defaulted << 6) | (self.partner_state_expired << 7)) # ------------------------------ # Collector Information # ------------------------------ self._collector_tag = self.LACP_TLV_TYPE_COLLECTOR self._collector_length = self._COL_INFO_PACK_LEN self.collector_max_delay = collector_max_delay # ------------------------------ # Terminator # ------------------------------ self._terminator_tag = self.LACP_TLV_TYPE_TERMINATOR self._terminator_length = 0 @classmethod def parser(cls, buf): assert cls._ALL_PACK_LEN == len(buf) offset = 0 # ------------------------------ # Header # ------------------------------ (subtype, version ) = struct.unpack_from(cls._HLEN_PACK_STR, buf, offset) assert SLOW_SUBTYPE_LACP == subtype assert cls.LACP_VERSION_NUMBER == version offset += cls._HLEN_PACK_LEN # ------------------------------ # Actor Information # ------------------------------ (actor_tag, actor_length, actor_system_priority, actor_system, actor_key, actor_port_priority, actor_port, actor_state ) = struct.unpack_from(cls._ACTPRT_INFO_PACK_STR, buf, offset) assert cls.LACP_TLV_TYPE_ACTOR == actor_tag assert cls._ACTPRT_INFO_PACK_LEN == actor_length offset += cls._ACTPRT_INFO_PACK_LEN actor_state_activity = (actor_state >> 0) & 1 actor_state_timeout = (actor_state >> 1) & 1 actor_state_aggregation = (actor_state >> 2) & 1 actor_state_synchronization = (actor_state >> 3) & 1 actor_state_collecting = (actor_state >> 4) & 1 actor_state_distributing = (actor_state >> 5) & 1 actor_state_defaulted = (actor_state >> 6) & 1 actor_state_expired = (actor_state >> 7) & 1 # ------------------------------ # Partner Information # ------------------------------ (partner_tag, partner_length, partner_system_priority, partner_system, partner_key, partner_port_priority, partner_port, partner_state ) = struct.unpack_from(cls._ACTPRT_INFO_PACK_STR, buf, offset) assert cls.LACP_TLV_TYPE_PARTNER == partner_tag assert cls._ACTPRT_INFO_PACK_LEN == partner_length offset += cls._ACTPRT_INFO_PACK_LEN partner_state_activity = (partner_state >> 0) & 1 partner_state_timeout = (partner_state >> 1) & 1 partner_state_aggregation = (partner_state >> 2) & 1 partner_state_synchronization = (partner_state >> 3) & 1 partner_state_collecting = (partner_state >> 4) & 1 partner_state_distributing = (partner_state >> 5) & 1 partner_state_defaulted = (partner_state >> 6) & 1 partner_state_expired = (partner_state >> 7) & 1 # ------------------------------ # Collector Information # ------------------------------ (collector_tag, collector_length, collector_max_delay ) = struct.unpack_from(cls._COL_INFO_PACK_STR, buf, offset) assert cls.LACP_TLV_TYPE_COLLECTOR == collector_tag assert cls._COL_INFO_PACK_LEN == collector_length offset += cls._COL_INFO_PACK_LEN # ------------------------------ # Terminator Information # ------------------------------ (terminator_tag, terminator_length ) = struct.unpack_from(cls._TRM_PACK_STR, buf, offset) assert cls.LACP_TLV_TYPE_TERMINATOR == terminator_tag assert 0 == terminator_length return cls(version, actor_system_priority, addrconv.mac.bin_to_text(actor_system), actor_key, actor_port_priority, actor_port, actor_state_activity, actor_state_timeout, actor_state_aggregation, actor_state_synchronization, actor_state_collecting, actor_state_distributing, actor_state_defaulted, actor_state_expired, partner_system_priority, addrconv.mac.bin_to_text(partner_system), partner_key, partner_port_priority, partner_port, partner_state_activity, partner_state_timeout, partner_state_aggregation, partner_state_synchronization, partner_state_collecting, partner_state_distributing, partner_state_defaulted, partner_state_expired, collector_max_delay), None, buf[lacp._ALL_PACK_LEN:] def serialize(self, payload, prev): header = struct.pack(self._HLEN_PACK_STR, self._subtype, self.version) actor = struct.pack(self._ACTPRT_INFO_PACK_STR, self._actor_tag, self._actor_length, self.actor_system_priority, addrconv.mac.text_to_bin(self.actor_system), self.actor_key, self.actor_port_priority, self.actor_port, self._actor_state) partner = struct.pack(self._ACTPRT_INFO_PACK_STR, self._partner_tag, self._partner_length, self.partner_system_priority, addrconv.mac.text_to_bin(self.partner_system), self.partner_key, self.partner_port_priority, self.partner_port, self._partner_state) collector = struct.pack(self._COL_INFO_PACK_STR, self._collector_tag, self._collector_length, self.collector_max_delay) terminator = struct.pack(self._TRM_PACK_STR, self._terminator_tag, self._terminator_length) return header + actor + partner + collector + terminator ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/packet/stream_parser.py0000664000175000017500000000444600000000000021535 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013 YAMAMOTO Takashi # # 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. import abc class StreamParser(object, metaclass=abc.ABCMeta): """Streaming parser base class. An instance of a subclass of this class is used to extract messages from a raw byte stream. It's designed to be used for data read from a transport which doesn't preserve message boundaries. A typical example of such a transport is TCP. """ class TooSmallException(Exception): pass def __init__(self): self._q = bytearray() def parse(self, data): """Tries to extract messages from a raw byte stream. The data argument would be python bytes newly read from the input stream. Returns an ordered list of extracted messages. It can be an empty list. The rest of data which doesn't produce a complete message is kept internally and will be used when more data is come. I.e. next time this method is called again. """ self._q.append(data) msgs = [] while True: try: msg, self._q = self.try_parse(self._q) except self.TooSmallException: break msgs.append(msg) return msgs @abc.abstractmethod def try_parse(self, q): """Try to extract a message from the given bytes. This is an override point for subclasses. This method tries to extract a message from bytes given by the argument. Raises TooSmallException if the given data is not enough to extract a complete message but there's still a chance to extract a message if more data is come later. """ pass ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/packet/tcp.py0000664000175000017500000003323000000000000017445 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone 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. import struct import logging from os_ken.lib import stringify from . import packet_base from . import packet_utils from . import bgp from . import openflow from . import zebra LOG = logging.getLogger(__name__) # TCP Option Kind Numbers TCP_OPTION_KIND_END_OF_OPTION_LIST = 0 # End of Option List TCP_OPTION_KIND_NO_OPERATION = 1 # No-Operation TCP_OPTION_KIND_MAXIMUM_SEGMENT_SIZE = 2 # Maximum Segment Size TCP_OPTION_KIND_WINDOW_SCALE = 3 # Window Scale TCP_OPTION_KIND_SACK_PERMITTED = 4 # SACK Permitted TCP_OPTION_KIND_SACK = 5 # SACK TCP_OPTION_KIND_TIMESTAMPS = 8 # Timestamps TCP_OPTION_KIND_USER_TIMEOUT = 28 # User Timeout Option TCP_OPTION_KIND_AUTHENTICATION = 29 # TCP Authentication Option (TCP-AO) TCP_FIN = 0x001 TCP_SYN = 0x002 TCP_RST = 0x004 TCP_PSH = 0x008 TCP_ACK = 0x010 TCP_URG = 0x020 TCP_ECE = 0x040 TCP_CWR = 0x080 TCP_NS = 0x100 class tcp(packet_base.PacketBase): """TCP (RFC 793) header encoder/decoder class. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. ============== ==================== Attribute Description ============== ==================== src_port Source Port dst_port Destination Port seq Sequence Number ack Acknowledgement Number offset Data Offset \ (0 means automatically-calculate when encoding) bits Control Bits window_size Window csum Checksum \ (0 means automatically-calculate when encoding) urgent Urgent Pointer option List of ``TCPOption`` sub-classes or an bytearray containing options. \ None if no options. ============== ==================== """ _PACK_STR = '!HHIIBBHHH' _MIN_LEN = struct.calcsize(_PACK_STR) def __init__(self, src_port=1, dst_port=1, seq=0, ack=0, offset=0, bits=0, window_size=0, csum=0, urgent=0, option=None): super(tcp, self).__init__() self.src_port = src_port self.dst_port = dst_port self.seq = seq self.ack = ack self.offset = offset self.bits = bits self.window_size = window_size self.csum = csum self.urgent = urgent self.option = option def __len__(self): return self.offset * 4 def has_flags(self, *flags): """Check if flags are set on this packet. returns boolean if all passed flags is set Example:: >>> pkt = tcp.tcp(bits=(tcp.TCP_SYN | tcp.TCP_ACK)) >>> pkt.has_flags(tcp.TCP_SYN, tcp.TCP_ACK) True """ mask = sum(flags) return (self.bits & mask) == mask @staticmethod def get_payload_type(src_port, dst_port): from os_ken.ofproto.ofproto_common import OFP_TCP_PORT, OFP_SSL_PORT_OLD if bgp.TCP_SERVER_PORT in [src_port, dst_port]: return bgp.BGPMessage elif(src_port in [OFP_TCP_PORT, OFP_SSL_PORT_OLD] or dst_port in [OFP_TCP_PORT, OFP_SSL_PORT_OLD]): return openflow.openflow elif src_port == zebra.ZEBRA_PORT: return zebra._ZebraMessageFromZebra elif dst_port == zebra.ZEBRA_PORT: return zebra.ZebraMessage else: return None @classmethod def parser(cls, buf): (src_port, dst_port, seq, ack, offset, bits, window_size, csum, urgent) = struct.unpack_from(cls._PACK_STR, buf) offset >>= 4 bits &= 0x3f length = offset * 4 if length > tcp._MIN_LEN: option_buf = buf[tcp._MIN_LEN:length] try: option = [] while option_buf: opt, option_buf = TCPOption.parser(option_buf) option.append(opt) except struct.error: LOG.warning( 'Encounter an error during parsing TCP option field.' 'Skip parsing TCP option.') option = buf[tcp._MIN_LEN:length] else: option = None msg = cls(src_port, dst_port, seq, ack, offset, bits, window_size, csum, urgent, option) return msg, cls.get_payload_type(src_port, dst_port), buf[length:] def serialize(self, payload, prev): offset = self.offset << 4 h = bytearray(struct.pack( tcp._PACK_STR, self.src_port, self.dst_port, self.seq, self.ack, offset, self.bits, self.window_size, self.csum, self.urgent)) if self.option: if isinstance(self.option, (list, tuple)): option_buf = bytearray() for opt in self.option: option_buf.extend(opt.serialize()) h.extend(option_buf) mod = len(option_buf) % 4 else: h.extend(self.option) mod = len(self.option) % 4 if mod: h.extend(bytearray(4 - mod)) if self.offset: offset = self.offset << 2 if len(h) < offset: h.extend(bytearray(offset - len(h))) if self.offset == 0: self.offset = len(h) >> 2 offset = self.offset << 4 struct.pack_into('!B', h, 12, offset) if self.csum == 0: total_length = len(h) + len(payload) self.csum = packet_utils.checksum_ip(prev, total_length, h + payload) struct.pack_into('!H', h, 16, self.csum) return bytes(h) class TCPOption(stringify.StringifyMixin): _KINDS = {} _KIND_PACK_STR = '!B' # kind NO_BODY_OFFSET = 1 # kind(1 byte) WITH_BODY_OFFSET = 2 # kind(1 byte) + length(1 byte) cls_kind = None cls_length = None def __init__(self, kind=None, length=None): self.kind = self.cls_kind if kind is None else kind self.length = self.cls_length if length is None else length @classmethod def register(cls, kind, length): def _register(subcls): subcls.cls_kind = kind subcls.cls_length = length cls._KINDS[kind] = subcls return subcls return _register @classmethod def parse(cls, buf): # For no body TCP Options return cls(cls.cls_kind, cls.cls_length), buf[cls.cls_length:] @classmethod def parser(cls, buf): (kind,) = struct.unpack_from(cls._KIND_PACK_STR, buf) subcls = cls._KINDS.get(kind) if not subcls: subcls = TCPOptionUnknown return subcls.parse(buf) def serialize(self): # For no body TCP Options return struct.pack(self._KIND_PACK_STR, self.cls_kind) class TCPOptionUnknown(TCPOption): _PACK_STR = '!BB' # kind, length def __init__(self, value, kind, length): super(TCPOptionUnknown, self).__init__(kind, length) self.value = value if value is not None else b'' @classmethod def parse(cls, buf): (kind, length) = struct.unpack_from(cls._PACK_STR, buf) value = buf[2:length] return cls(value, kind, length), buf[length:] def serialize(self): self.length = self.WITH_BODY_OFFSET + len(self.value) return struct.pack(self._PACK_STR, self.kind, self.length) + self.value @TCPOption.register(TCP_OPTION_KIND_END_OF_OPTION_LIST, TCPOption.NO_BODY_OFFSET) class TCPOptionEndOfOptionList(TCPOption): pass @TCPOption.register(TCP_OPTION_KIND_NO_OPERATION, TCPOption.NO_BODY_OFFSET) class TCPOptionNoOperation(TCPOption): pass @TCPOption.register(TCP_OPTION_KIND_MAXIMUM_SEGMENT_SIZE, 4) class TCPOptionMaximumSegmentSize(TCPOption): _PACK_STR = '!BBH' # kind, length, max_seg_size def __init__(self, max_seg_size, kind=None, length=None): super(TCPOptionMaximumSegmentSize, self).__init__(kind, length) self.max_seg_size = max_seg_size @classmethod def parse(cls, buf): (_, _, max_seg_size) = struct.unpack_from(cls._PACK_STR, buf) return cls(max_seg_size, cls.cls_kind, cls.cls_length), buf[cls.cls_length:] def serialize(self): return struct.pack(self._PACK_STR, self.kind, self.length, self.max_seg_size) @TCPOption.register(TCP_OPTION_KIND_WINDOW_SCALE, 3) class TCPOptionWindowScale(TCPOption): _PACK_STR = '!BBB' # kind, length, shift_cnt def __init__(self, shift_cnt, kind=None, length=None): super(TCPOptionWindowScale, self).__init__(kind, length) self.shift_cnt = shift_cnt @classmethod def parse(cls, buf): (_, _, shift_cnt) = struct.unpack_from(cls._PACK_STR, buf) return cls(shift_cnt, cls.cls_kind, cls.cls_length), buf[cls.cls_length:] def serialize(self): return struct.pack(self._PACK_STR, self.kind, self.length, self.shift_cnt) @TCPOption.register(TCP_OPTION_KIND_SACK_PERMITTED, 2) class TCPOptionSACKPermitted(TCPOption): _PACK_STR = '!BB' # kind, length def serialize(self): return struct.pack(self._PACK_STR, self.kind, self.length) @TCPOption.register(TCP_OPTION_KIND_SACK, 2) # variable length. 2 is the length except blocks. class TCPOptionSACK(TCPOption): _PACK_STR = '!BB' # kind, length _BLOCK_PACK_STR = '!II' # Left Edge of Block, Right Edge of Block def __init__(self, blocks, kind=None, length=None): super(TCPOptionSACK, self).__init__(kind, length) # blocks is a list of tuple as followings. # self.blocks = [ # ('Left Edge of 1st Block', 'Right Edge of 1st Block'), # ... # ('Left Edge of nth Block', 'Right Edge of nth Block') # ] self.blocks = blocks @classmethod def parse(cls, buf): (_, length) = struct.unpack_from(cls._PACK_STR, buf) blocks_buf = buf[2:length] blocks = [] while blocks_buf: lr_block = struct.unpack_from(cls._BLOCK_PACK_STR, blocks_buf) blocks.append(lr_block) # (left, right) blocks_buf = blocks_buf[8:] return cls(blocks, cls.cls_kind, length), buf[length:] def serialize(self): buf = bytearray() for left, right in self.blocks: buf += struct.pack(self._BLOCK_PACK_STR, left, right) self.length = self.cls_length + len(buf) return struct.pack(self._PACK_STR, self.kind, self.length) + buf @TCPOption.register(TCP_OPTION_KIND_TIMESTAMPS, 10) class TCPOptionTimestamps(TCPOption): _PACK_STR = '!BBII' # kind, length, ts_val, ts_ecr def __init__(self, ts_val, ts_ecr, kind=None, length=None): super(TCPOptionTimestamps, self).__init__(kind, length) self.ts_val = ts_val self.ts_ecr = ts_ecr @classmethod def parse(cls, buf): (_, _, ts_val, ts_ecr) = struct.unpack_from(cls._PACK_STR, buf) return cls(ts_val, ts_ecr, cls.cls_kind, cls.cls_length), buf[cls.cls_length:] def serialize(self): return struct.pack(self._PACK_STR, self.kind, self.length, self.ts_val, self.ts_ecr) @TCPOption.register(TCP_OPTION_KIND_USER_TIMEOUT, 4) class TCPOptionUserTimeout(TCPOption): _PACK_STR = '!BBH' # kind, length, granularity(1bit)|user_timeout(15bit) def __init__(self, granularity, user_timeout, kind=None, length=None): super(TCPOptionUserTimeout, self).__init__(kind, length) self.granularity = granularity self.user_timeout = user_timeout @classmethod def parse(cls, buf): (_, _, body) = struct.unpack_from(cls._PACK_STR, buf) granularity = body >> 15 user_timeout = body & 0x7fff return cls(granularity, user_timeout, cls.cls_kind, cls.cls_length), buf[cls.cls_length:] def serialize(self): body = (self.granularity << 15) | self.user_timeout return struct.pack(self._PACK_STR, self.kind, self.length, body) @TCPOption.register(TCP_OPTION_KIND_AUTHENTICATION, 4) # variable length. 4 is the length except MAC. class TCPOptionAuthentication(TCPOption): _PACK_STR = '!BBBB' # kind, length, key_id, r_next_key_id def __init__(self, key_id, r_next_key_id, mac, kind=None, length=None): super(TCPOptionAuthentication, self).__init__(kind, length) self.key_id = key_id self.r_next_key_id = r_next_key_id self.mac = mac @classmethod def parse(cls, buf): (_, length, key_id, r_next_key_id) = struct.unpack_from(cls._PACK_STR, buf) mac = buf[4:length] return cls(key_id, r_next_key_id, mac, cls.cls_kind, length), buf[length:] def serialize(self): self.length = self.cls_length + len(self.mac) return struct.pack(self._PACK_STR, self.kind, self.length, self.key_id, self.r_next_key_id) + self.mac ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/packet/udp.py0000664000175000017500000000617100000000000017453 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone 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. import struct from . import packet_base from . import packet_utils from . import dhcp from . import dhcp6 from . import vxlan from . import geneve class udp(packet_base.PacketBase): """UDP (RFC 768) header encoder/decoder class. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. ============== ==================== Attribute Description ============== ==================== src_port Source Port dst_port Destination Port total_length Length \ (0 means automatically-calculate when encoding) csum Checksum \ (0 means automatically-calculate when encoding) ============== ==================== """ _PACK_STR = '!HHHH' _MIN_LEN = struct.calcsize(_PACK_STR) def __init__(self, src_port=1, dst_port=1, total_length=0, csum=0): super(udp, self).__init__() self.src_port = src_port self.dst_port = dst_port self.total_length = total_length self.csum = csum @staticmethod def get_packet_type(src_port, dst_port): if ((src_port in [67, 68] and dst_port == 67) or (dst_port in [67, 68] and src_port == 67)): return dhcp.dhcp if ((src_port in [546, 547] and dst_port == 547) or (dst_port in [546, 547] and src_port == 547)): return dhcp6.dhcp6 if (dst_port == vxlan.UDP_DST_PORT or dst_port == vxlan.UDP_DST_PORT_OLD): return vxlan.vxlan if dst_port == geneve.UDP_DST_PORT: return geneve.geneve return None @classmethod def parser(cls, buf): (src_port, dst_port, total_length, csum) = struct.unpack_from( cls._PACK_STR, buf) msg = cls(src_port, dst_port, total_length, csum) return msg, cls.get_packet_type(src_port, dst_port), buf[msg._MIN_LEN:total_length] def serialize(self, payload, prev): if self.total_length == 0: self.total_length = udp._MIN_LEN + len(payload) h = struct.pack(udp._PACK_STR, self.src_port, self.dst_port, self.total_length, self.csum) if self.csum == 0: self.csum = packet_utils.checksum_ip( prev, self.total_length, h + payload) h = struct.pack(udp._PACK_STR, self.src_port, self.dst_port, self.total_length, self.csum) return h ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/packet/vlan.py0000664000175000017500000001046300000000000017622 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone 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. import abc import struct from . import packet_base from . import arp from . import ipv4 from . import ipv6 from . import lldp from . import slow from . import llc from . import pbb from . import cfm from . import ether_types as ether class _vlan(packet_base.PacketBase, metaclass=abc.ABCMeta): _PACK_STR = "!HH" _MIN_LEN = struct.calcsize(_PACK_STR) @abc.abstractmethod def __init__(self, pcp, cfi, vid, ethertype): super(_vlan, self).__init__() self.pcp = pcp self.cfi = cfi self.vid = vid self.ethertype = ethertype @classmethod def parser(cls, buf): tci, ethertype = struct.unpack_from(cls._PACK_STR, buf) pcp = tci >> 13 cfi = (tci >> 12) & 1 vid = tci & ((1 << 12) - 1) return (cls(pcp, cfi, vid, ethertype), vlan.get_packet_type(ethertype), buf[vlan._MIN_LEN:]) def serialize(self, payload, prev): tci = self.pcp << 13 | self.cfi << 12 | self.vid return struct.pack(vlan._PACK_STR, tci, self.ethertype) class vlan(_vlan): """VLAN (IEEE 802.1Q) header encoder/decoder class. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. ============== ==================== Attribute Description ============== ==================== pcp Priority Code Point cfi Canonical Format Indicator vid VLAN Identifier ethertype EtherType ============== ==================== """ def __init__(self, pcp=0, cfi=0, vid=0, ethertype=ether.ETH_TYPE_IP): super(vlan, self).__init__(pcp, cfi, vid, ethertype) @classmethod def get_packet_type(cls, type_): """Override method for the Length/Type field (self.ethertype). The Length/Type field means Length or Type interpretation, same as ethernet IEEE802.3. If the value of Length/Type field is less than or equal to 1500 decimal(05DC hexadecimal), it means Length interpretation and be passed to the LLC sublayer.""" if type_ <= ether.ETH_TYPE_IEEE802_3: type_ = ether.ETH_TYPE_IEEE802_3 return cls._TYPES.get(type_) class svlan(_vlan): """S-VLAN (IEEE 802.1ad) header encoder/decoder class. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. .. tabularcolumns:: |l|L| ============== ==================== Attribute Description ============== ==================== pcp Priority Code Point cfi Canonical Format Indicator. In a case to be used as B-TAG, this field means DEI(Drop Eligible Indication). vid VLAN Identifier ethertype EtherType ============== ==================== """ def __init__(self, pcp=0, cfi=0, vid=0, ethertype=ether.ETH_TYPE_8021Q): super(svlan, self).__init__(pcp, cfi, vid, ethertype) @classmethod def get_packet_type(cls, type_): return cls._TYPES.get(type_) vlan.register_packet_type(arp.arp, ether.ETH_TYPE_ARP) vlan.register_packet_type(ipv4.ipv4, ether.ETH_TYPE_IP) vlan.register_packet_type(ipv6.ipv6, ether.ETH_TYPE_IPV6) vlan.register_packet_type(lldp.lldp, ether.ETH_TYPE_LLDP) vlan.register_packet_type(slow.slow, ether.ETH_TYPE_SLOW) vlan.register_packet_type(llc.llc, ether.ETH_TYPE_IEEE802_3) vlan.register_packet_type(cfm.cfm, ether.ETH_TYPE_CFM) svlan.register_packet_type(vlan, ether.ETH_TYPE_8021Q) svlan.register_packet_type(pbb.itag, ether.ETH_TYPE_8021AH) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/packet/vrrp.py0000664000175000017500000006055000000000000017655 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013 Isaku Yamahata # # 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. """ VRRP packet parser/serializer [RFC 3768] VRRP v2 packet format:: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |Version| Type | Virtual Rtr ID| Priority | Count IP Addrs| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Auth Type | Adver Int | Checksum | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | IP Address (1) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | . | | . | | . | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | IP Address (n) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Authentication Data (1) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Authentication Data (2) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ [RFC 5798] VRRP v3 packet format:: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | IPv4 Fields or IPv6 Fields | ... ... | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |Version| Type | Virtual Rtr ID| Priority |Count IPvX Addr| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |(rsvd) | Max Adver Int | Checksum | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | + + | IPvX Address(es) | + + + + + + + + | | + + | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ """ import struct from os_ken.lib.packet import ethernet from os_ken.lib.packet import ether_types as ether from os_ken.lib.packet import in_proto as inet from os_ken.lib.packet import ipv4 from os_ken.lib.packet import ipv6 from os_ken.lib.packet import packet from os_ken.lib.packet import packet_base from os_ken.lib.packet import packet_utils from os_ken.lib.packet import vlan from os_ken.lib import addrconv # IPv4 # the LSB 8 bits is used for VRID VRRP_IPV4_SRC_MAC_ADDRESS_FMT = '00:00:5E:00:01:%02x' VRRP_IPV4_DST_MAC_ADDRESS = '01:00:5E:00:00:12' VRRP_IPV4_DST_ADDRESS = '224.0.0.18' VRRP_IPV4_TTL = 255 def vrrp_ipv4_src_mac_address(vrid): return VRRP_IPV4_SRC_MAC_ADDRESS_FMT % vrid # IPv6 # the LSB 8 bits is used for VRID VRRP_IPV6_SRC_MAC_ADDRESS_FMT = '00:00:5E:00:02:%02x' VRRP_IPV6_DST_MAC_ADDRESS = '33:33:00:00:00:12' VRRP_IPV6_DST_ADDRESS = 'ff02::12' VRRP_IPV6_HOP_LIMIT = 255 def vrrp_ipv6_src_mac_address(vrid): return VRRP_IPV6_SRC_MAC_ADDRESS_FMT % vrid VRRP_VERSION_SHIFT = 4 VRRP_TYPE_MASK = 0xf def vrrp_from_version_type(version_type): return (version_type >> VRRP_VERSION_SHIFT, version_type & VRRP_TYPE_MASK) def vrrp_to_version_type(version, type_): return (version << VRRP_VERSION_SHIFT) | type_ # VRRP version VRRP_VERSION_V2 = 2 VRRP_VERSION_V3 = 3 # VRRP type VRRP_TYPE_ADVERTISEMENT = 1 # VRRP VRID: 0 isn't used VRRP_VRID_MIN = 1 VRRP_VRID_MAX = 255 # VRRP priority VRRP_PRIORITY_MIN = 0 VRRP_PRIORITY_MAX = 255 VRRP_PRIORITY_RELEASE_RESPONSIBILITY = 0 VRRP_PRIORITY_BACKUP_MIN = 1 VRRP_PRIORITY_BACKUP_DEFAULT = 100 VRRP_PRIORITY_BACKUP_MAX = 254 VRRP_PRIORITY_ADDRESS_OWNER = 255 # VRRP auth type (VRRP v2 only) VRRP_AUTH_NO_AUTH = 0 VRRP_AUTH_RESERVED1 = 1 VRRP_AUTH_RESERVED2 = 2 VRRP_AUTH_DATA1 = 0 VRRP_AUTH_DATA2 = 0 VRRP_AUTH_DATA = (VRRP_AUTH_DATA1, VRRP_AUTH_DATA2) # VRRP Max advertisement interval VRRP_MAX_ADVER_INT_DEFAULT_IN_SEC = 1 # 1 second VRRP_V3_MAX_ADVER_INT_MASK = 0xfff # in centiseconds VRRP_V3_MAX_ADVER_INT_DEFAULT = 100 # = 1 second VRRP_V3_MAX_ADVER_INT_MIN = 1 # don't allow 0 VRRP_V3_MAX_ADVER_INT_MAX = 0xfff VRRP_V2_MAX_ADVER_INT_MASK = 0xff # in seconds VRRP_V2_MAX_ADVER_INT_DEFAULT = 1 # 1 second VRRP_V2_MAX_ADVER_INT_MIN = 1 # don't allow 0 VRRP_V2_MAX_ADVER_INT_MAX = 0xff def is_ipv6(ip_address): assert type(ip_address) == str try: addrconv.ipv4.text_to_bin(ip_address) except: addrconv.ipv6.text_to_bin(ip_address) # sanity return True return False def ip_text_to_bin(ip_text): if is_ipv6(ip_text): return addrconv.ipv6.text_to_bin(ip_text) else: return addrconv.ipv4.text_to_bin(ip_text) # This is used for master selection def ip_address_lt(ip1, ip2): return ip_text_to_bin(ip1) < ip_text_to_bin(ip2) class vrrp(packet_base.PacketBase): """The base class for VRRPv2 (RFC 3768) and VRRPv3 (RFC 5798) header encoder/decoder classes. Unlike other os_ken.lib.packet.packet_base.PacketBase derived classes, This class should not be directly instantiated by user. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. ============== ==================== Attribute Description ============== ==================== version Version type Type vrid Virtual Rtr ID (VRID) priority Priority count_ip Count IPvX Addr. \ Calculated automatically when encoding. max_adver_int Maximum Advertisement Interval (Max Adver Int) checksum Checksum. \ Calculated automatically when encoding. ip_addresses IPvX Address(es). A python list of IP addresses. auth_type Authentication Type (only for VRRPv2) auth_data Authentication Data (only for VRRPv2) ============== ==================== """ _VERSION_PACK_STR = '!B' _IPV4_ADDRESS_PACK_STR_RAW = '4s' _IPV4_ADDRESS_PACK_STR = '!' + _IPV4_ADDRESS_PACK_STR_RAW _IPV4_ADDRESS_LEN = struct.calcsize(_IPV4_ADDRESS_PACK_STR) _IPV6_ADDRESS_LEN = 16 _IPV6_ADDRESS_PACK_STR_RAW = '%ds' % _IPV6_ADDRESS_LEN _IPV6_ADDRESS_PACK_STR = '!' + _IPV6_ADDRESS_PACK_STR_RAW _IPV6_ADDRESS_LEN = struct.calcsize(_IPV6_ADDRESS_PACK_STR) _VRRP_VERSIONS = {} _SEC_IN_MAX_ADVER_INT_UNIT = {} @staticmethod def get_payload(packet_): may_ip = None may_vrrp = None idx = 0 for protocol in packet_: if isinstance(protocol, ipv4.ipv4) or isinstance(protocol, ipv6.ipv6): may_ip = protocol try: if isinstance(packet_.protocols[idx + 1], vrrp): may_vrrp = packet_.protocols[idx + 1] finally: break idx += 1 if may_ip and may_vrrp: return may_ip, may_vrrp else: return None, None @classmethod def register_vrrp_version(cls, version, sec_in_max_adver_int_unit): def _register_vrrp_version(cls_): cls._VRRP_VERSIONS[version] = cls_ cls._SEC_IN_MAX_ADVER_INT_UNIT[version] = sec_in_max_adver_int_unit return cls_ return _register_vrrp_version @staticmethod def sec_to_max_adver_int(version, seconds): return int(seconds * vrrp._SEC_IN_MAX_ADVER_INT_UNIT[version]) @staticmethod def max_adver_int_to_sec(version, max_adver_int): return float(max_adver_int) / vrrp._SEC_IN_MAX_ADVER_INT_UNIT[version] def __init__(self, version, type_, vrid, priority, count_ip, max_adver_int, checksum, ip_addresses, # auth_type/auth_data is for vrrp v2 auth_type=None, auth_data=None): super(vrrp, self).__init__() self.version = version self.type = type_ self.vrid = vrid self.priority = priority self.count_ip = count_ip self.max_adver_int = max_adver_int self.checksum = checksum self.ip_addresses = ip_addresses assert len(list(ip_addresses)) == self.count_ip self.auth_type = auth_type self.auth_data = auth_data self._is_ipv6 = is_ipv6(list(self.ip_addresses)[0]) self.identification = 0 # used for ipv4 identification def checksum_ok(self, ipvx, vrrp_buf): cls_ = self._VRRP_VERSIONS[self.version] return cls_.checksum_ok(self, ipvx, vrrp_buf) @property def max_adver_int_in_sec(self): # return seconds of float as time.sleep() accepts such type. return self.max_adver_int_to_sec(self.version, self.max_adver_int) @property def is_ipv6(self): return self._is_ipv6 def __len__(self): cls_ = self._VRRP_VERSIONS[self.version] return cls_.__len__(self) @staticmethod def create_version(version, type_, vrid, priority, max_adver_int, ip_addresses, auth_type=None, auth_data=None): cls_ = vrrp._VRRP_VERSIONS.get(version, None) if not cls_: raise ValueError('unknown VRRP version %d' % version) if priority is None: priority = VRRP_PRIORITY_BACKUP_DEFAULT count_ip = len(ip_addresses) if max_adver_int is None: max_adver_int = cls_.sec_to_max_adver_int( VRRP_MAX_ADVER_INT_DEFAULT_IN_SEC) return cls_(version, type_, vrid, priority, count_ip, max_adver_int, None, ip_addresses, auth_type=auth_type, auth_data=auth_data) def get_identification(self): self.identification += 1 self.identification &= 0xffff if self.identification == 0: self.identification += 1 self.identification &= 0xffff return self.identification def create_packet(self, primary_ip_address, vlan_id=None): """Prepare a VRRP packet. Returns a newly created os_ken.lib.packet.packet.Packet object with appropriate protocol header objects added by add_protocol(). It's caller's responsibility to serialize(). The serialized packet would looks like the ones described in the following sections. * RFC 3768 5.1. VRRP Packet Format * RFC 5798 5.1. VRRP Packet Format ================== ==================== Argument Description ================== ==================== primary_ip_address Source IP address vlan_id VLAN ID. None for no VLAN. ================== ==================== """ if self.is_ipv6: traffic_class = 0xc0 # set tos to internetwork control flow_label = 0 payload_length = ipv6.ipv6._MIN_LEN + len(self) # XXX _MIN_LEN e = ethernet.ethernet(VRRP_IPV6_DST_MAC_ADDRESS, vrrp_ipv6_src_mac_address(self.vrid), ether.ETH_TYPE_IPV6) ip = ipv6.ipv6(6, traffic_class, flow_label, payload_length, inet.IPPROTO_VRRP, VRRP_IPV6_HOP_LIMIT, primary_ip_address, VRRP_IPV6_DST_ADDRESS) else: header_length = ipv4.ipv4._MIN_LEN // 4 # XXX _MIN_LEN total_length = 0 tos = 0xc0 # set tos to internetwork control identification = self.get_identification() e = ethernet.ethernet(VRRP_IPV4_DST_MAC_ADDRESS, vrrp_ipv4_src_mac_address(self.vrid), ether.ETH_TYPE_IP) ip = ipv4.ipv4(4, header_length, tos, total_length, identification, 0, 0, VRRP_IPV4_TTL, inet.IPPROTO_VRRP, 0, primary_ip_address, VRRP_IPV4_DST_ADDRESS) p = packet.Packet() p.add_protocol(e) if vlan_id is not None: vlan_ = vlan.vlan(0, 0, vlan_id, e.ethertype) e.ethertype = ether.ETH_TYPE_8021Q p.add_protocol(vlan_) p.add_protocol(ip) p.add_protocol(self) return p @classmethod def parser(cls, buf): (version_type,) = struct.unpack_from(cls._VERSION_PACK_STR, buf) version, _type = vrrp_from_version_type(version_type) cls_ = cls._VRRP_VERSIONS[version] return cls_.parser(buf) @staticmethod def serialize_static(vrrp_, prev): # self can be a instance of vrrpv2 or vrrpv3. assert isinstance(vrrp_, vrrp) cls = vrrp._VRRP_VERSIONS[vrrp_.version] return cls.serialize_static(vrrp_, prev) def serialize(self, payload, prev): return self.serialize_static(self, prev) @staticmethod def is_valid_ttl(ipvx): version = ipvx.version if version == 4: return ipvx.ttl == VRRP_IPV4_TTL if version == 6: return ipvx.hop_limit == VRRP_IPV6_HOP_LIMIT raise ValueError('invalid ip version %d' % version) def is_valid(self): cls = self._VRRP_VERSIONS.get(self.version, None) if cls is None: return False return cls.is_valid(self) # max_adver_int is in seconds @vrrp.register_vrrp_version(VRRP_VERSION_V2, 1) class vrrpv2(vrrp): """VRRPv2 (RFC 3768) header encoder/decoder class. Unlike other os_ken.lib.packet.packet_base.PacketBase derived classes, *create* method should be used to instantiate an object of this class. """ _PACK_STR = '!BBBBBBH' _MIN_LEN = struct.calcsize(_PACK_STR) _CHECKSUM_PACK_STR = '!H' _CHECKSUM_OFFSET = 6 _AUTH_DATA_PACK_STR = '!II' _AUTH_DATA_LEN = struct.calcsize('!II') def __len__(self): return (self._MIN_LEN + self._IPV4_ADDRESS_LEN * self.count_ip + self._AUTH_DATA_LEN) def checksum_ok(self, ipvx, vrrp_buf): return packet_utils.checksum(vrrp_buf) == 0 @staticmethod def create(type_, vrid, priority, max_adver_int, ip_addresses): """Unlike other os_ken.lib.packet.packet_base.PacketBase derived classes, this method should be used to instantiate an object of this class. This method's arguments are same as os_ken.lib.packet.vrrp.vrrp object's attributes of the same name. (except that *type_* corresponds to *type* attribute.) """ return vrrp.create_version(VRRP_VERSION_V2, type_, vrid, priority, max_adver_int, ip_addresses, auth_type=VRRP_AUTH_NO_AUTH, auth_data=VRRP_AUTH_DATA) @staticmethod def _ip_addresses_pack_str(count_ip): return '!' + vrrpv2._IPV4_ADDRESS_PACK_STR_RAW * count_ip @classmethod def parser(cls, buf): (version_type, vrid, priority, count_ip, auth_type, adver_int, checksum) = struct.unpack_from(cls._PACK_STR, buf) (version, type_) = vrrp_from_version_type(version_type) offset = cls._MIN_LEN ip_addresses_pack_str = cls._ip_addresses_pack_str(count_ip) ip_addresses_bin = struct.unpack_from(ip_addresses_pack_str, buf, offset) ip_addresses = [addrconv.ipv4.bin_to_text(x) for x in ip_addresses_bin] offset += struct.calcsize(ip_addresses_pack_str) auth_data = struct.unpack_from(cls._AUTH_DATA_PACK_STR, buf, offset) msg = cls(version, type_, vrid, priority, count_ip, adver_int, checksum, ip_addresses, auth_type, auth_data) return msg, None, buf[len(msg):] @staticmethod def serialize_static(vrrp_, prev): assert not vrrp_.is_ipv6 # vrrpv2 defines only IPv4 ip_addresses_pack_str = vrrpv2._ip_addresses_pack_str(vrrp_.count_ip) ip_addresses_len = struct.calcsize(ip_addresses_pack_str) vrrp_len = vrrpv2._MIN_LEN + ip_addresses_len + vrrpv2._AUTH_DATA_LEN checksum = False if vrrp_.checksum is None: checksum = True vrrp_.checksum = 0 if vrrp_.auth_type is None: vrrp_.auth_type = VRRP_AUTH_NO_AUTH if vrrp_.auth_data is None: vrrp_.auth_data = VRRP_AUTH_DATA buf = bytearray(vrrp_len) offset = 0 struct.pack_into(vrrpv2._PACK_STR, buf, offset, vrrp_to_version_type(vrrp_.version, vrrp_.type), vrrp_.vrid, vrrp_.priority, vrrp_.count_ip, vrrp_.auth_type, vrrp_.max_adver_int, vrrp_.checksum) offset += vrrpv2._MIN_LEN struct.pack_into(ip_addresses_pack_str, buf, offset, *[addrconv.ipv4.text_to_bin(x) for x in vrrp_.ip_addresses]) offset += ip_addresses_len struct.pack_into(vrrpv2._AUTH_DATA_PACK_STR, buf, offset, *vrrp_.auth_data) if checksum: vrrp_.checksum = packet_utils.checksum(buf) struct.pack_into(vrrpv2._CHECKSUM_PACK_STR, buf, vrrpv2._CHECKSUM_OFFSET, vrrp_.checksum) return buf def is_valid(self): return (self.version == VRRP_VERSION_V2 and self.type == VRRP_TYPE_ADVERTISEMENT and VRRP_VRID_MIN <= self.vrid and self.vrid <= VRRP_VRID_MAX and VRRP_PRIORITY_MIN <= self.priority and self.priority <= VRRP_PRIORITY_MAX and self.auth_type == VRRP_AUTH_NO_AUTH and VRRP_V2_MAX_ADVER_INT_MIN <= self.max_adver_int and self.max_adver_int <= VRRP_V2_MAX_ADVER_INT_MAX and self.count_ip == len(self.ip_addresses)) # max_adver_int is in centi seconds: 1 second = 100 centiseconds @vrrp.register_vrrp_version(VRRP_VERSION_V3, 100) class vrrpv3(vrrp): """VRRPv3 (RFC 5798) header encoder/decoder class. Unlike other os_ken.lib.packet.packet_base.PacketBase derived classes, *create* method should be used to instantiate an object of this class. """ _PACK_STR = '!BBBBHH' _MIN_LEN = struct.calcsize(_PACK_STR) _CHECKSUM_PACK_STR = '!H' _CHECKSUM_OFFSET = 6 def __len__(self): if self.is_ipv6: address_len = self._IPV6_ADDRESS_LEN else: address_len = self._IPV4_ADDRESS_LEN return self._MIN_LEN + address_len * self.count_ip def checksum_ok(self, ipvx, vrrp_buf): # There are two interpretation of IPv4 checksum # include IPv4 pseudo header or not. # http://www.ietf.org/mail-archive/web/vrrp/current/msg01473.html # if not self.is_ipv6: # return packet_utils.checksum(vrrp_buf) == 0 return packet_utils.checksum_ip(ipvx, len(self), vrrp_buf) == 0 @staticmethod def create(type_, vrid, priority, max_adver_int, ip_addresses): """Unlike other os_ken.lib.packet.packet_base.PacketBase derived classes, this method should be used to instantiate an object of this class. This method's arguments are same as os_ken.lib.packet.vrrp.vrrp object's attributes of the same name. (except that *type_* corresponds to *type* attribute.) """ return vrrp.create_version(VRRP_VERSION_V3, type_, vrid, priority, max_adver_int, ip_addresses) @classmethod def parser(cls, buf): (version_type, vrid, priority, count_ip, max_adver_int, checksum) = struct.unpack_from(cls._PACK_STR, buf) (version, type_) = vrrp_from_version_type(version_type) # _rsvd = (max_adver_int & ~VRRP_V3_MAX_ADVER_INT_MASK) >> 12 # asssert _rsvd == 0 max_adver_int &= VRRP_V3_MAX_ADVER_INT_MASK offset = cls._MIN_LEN address_len = (len(buf) - offset) // count_ip # Address version (IPv4 or IPv6) is determined by network layer # header type. # Unfortunately it isn't available. Guess it by vrrp packet length. if address_len == cls._IPV4_ADDRESS_LEN: pack_str = '!' + cls._IPV4_ADDRESS_PACK_STR_RAW * count_ip conv = addrconv.ipv4.bin_to_text elif address_len == cls._IPV6_ADDRESS_LEN: pack_str = '!' + cls._IPV6_ADDRESS_PACK_STR_RAW * count_ip conv = addrconv.ipv6.bin_to_text else: raise ValueError( 'unknown address version address_len %d count_ip %d' % ( address_len, count_ip)) ip_addresses_bin = struct.unpack_from(pack_str, buf, offset) ip_addresses = [conv(x) for x in ip_addresses_bin] msg = cls(version, type_, vrid, priority, count_ip, max_adver_int, checksum, ip_addresses) return msg, None, buf[len(msg):] @staticmethod def serialize_static(vrrp_, prev): if isinstance(prev, ipv4.ipv4): assert type(vrrp_.ip_addresses[0]) == str conv = addrconv.ipv4.text_to_bin ip_address_pack_raw = vrrpv3._IPV4_ADDRESS_PACK_STR_RAW elif isinstance(prev, ipv6.ipv6): assert type(vrrp_.ip_addresses[0]) == str conv = addrconv.ipv6.text_to_bin ip_address_pack_raw = vrrpv3._IPV6_ADDRESS_PACK_STR_RAW else: raise ValueError('Unkown network layer %s' % type(prev)) ip_addresses_pack_str = '!' + ip_address_pack_raw * vrrp_.count_ip ip_addresses_len = struct.calcsize(ip_addresses_pack_str) vrrp_len = vrrpv3._MIN_LEN + ip_addresses_len checksum = False if vrrp_.checksum is None: checksum = True vrrp_.checksum = 0 buf = bytearray(vrrp_len) assert vrrp_.max_adver_int <= VRRP_V3_MAX_ADVER_INT_MASK struct.pack_into(vrrpv3._PACK_STR, buf, 0, vrrp_to_version_type(vrrp_.version, vrrp_.type), vrrp_.vrid, vrrp_.priority, vrrp_.count_ip, vrrp_.max_adver_int, vrrp_.checksum) struct.pack_into(ip_addresses_pack_str, buf, vrrpv3._MIN_LEN, *[conv(x) for x in vrrp_.ip_addresses]) if checksum: vrrp_.checksum = packet_utils.checksum_ip(prev, len(buf), buf) struct.pack_into(vrrpv3._CHECKSUM_PACK_STR, buf, vrrpv3._CHECKSUM_OFFSET, vrrp_.checksum) return buf def is_valid(self): return (self.version == VRRP_VERSION_V3 and self.type == VRRP_TYPE_ADVERTISEMENT and VRRP_VRID_MIN <= self.vrid and self.vrid <= VRRP_VRID_MAX and VRRP_PRIORITY_MIN <= self.priority and self.priority <= VRRP_PRIORITY_MAX and VRRP_V3_MAX_ADVER_INT_MIN <= self.max_adver_int and self.max_adver_int <= VRRP_V3_MAX_ADVER_INT_MAX and self.count_ip == len(self.ip_addresses)) ipv4.ipv4.register_packet_type(vrrp, inet.IPPROTO_VRRP) ipv6.ipv6.register_packet_type(vrrp, inet.IPPROTO_VRRP) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/packet/vxlan.py0000664000175000017500000000560200000000000020011 0ustar00zuulzuul00000000000000# Copyright (C) 2016 Nippon Telegraph and Telephone 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. import struct import logging from . import packet_base from os_ken.lib import type_desc LOG = logging.getLogger(__name__) UDP_DST_PORT = 4789 UDP_DST_PORT_OLD = 8472 # for backward compatibility like Linux class vxlan(packet_base.PacketBase): """VXLAN (RFC 7348) header encoder/decoder class. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. ============== ==================== Attribute Description ============== ==================== vni VXLAN Network Identifier ============== ==================== """ # Note: Python has no format character for 24 bits field. # we use uint32 format character instead and bit-shift at serializing. _PACK_STR = '!II' _MIN_LEN = struct.calcsize(_PACK_STR) # VXLAN Header: # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # |R|R|R|R|I|R|R|R| Reserved | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | VXLAN Network Identifier (VNI) | Reserved | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ def __init__(self, vni): super(vxlan, self).__init__() self.vni = vni @classmethod def parser(cls, buf): (flags_reserved, vni_rserved) = struct.unpack_from(cls._PACK_STR, buf) # Check VXLAN flags is valid assert (1 << 3) == (flags_reserved >> 24) # Note: To avoid cyclic import, import ethernet module here from os_ken.lib.packet import ethernet return cls(vni_rserved >> 8), ethernet.ethernet, buf[cls._MIN_LEN:] def serialize(self, payload, prev): return struct.pack(self._PACK_STR, 1 << (3 + 24), self.vni << 8) def vni_from_bin(buf): """ Converts binary representation VNI to integer. :param buf: binary representation of VNI. :return: VNI integer. """ return type_desc.Int3.to_user(bytes(buf)) def vni_to_bin(vni): """ Converts integer VNI to binary representation. :param vni: integer of VNI :return: binary representation of VNI. """ return type_desc.Int3.from_user(vni) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/packet/zebra.py0000664000175000017500000037215700000000000020000 0ustar00zuulzuul00000000000000# Copyright (C) 2017 Nippon Telegraph and Telephone 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. """ Zebra protocol parser/serializer Zebra Protocol is used to communicate with the zebra daemon. """ import abc import socket import struct import logging import netaddr from packaging import version as packaging_version from os_ken import flags as cfg_flags # For loading 'zapi' option definition from os_ken.cfg import CONF from os_ken.lib import addrconv from os_ken.lib import ip from os_ken.lib import stringify from os_ken.lib import type_desc from . import packet_base from . import bgp from . import safi as packet_safi LOG = logging.getLogger(__name__) # Default Zebra protocol version _DEFAULT_VERSION = 3 _DEFAULT_FRR_VERSION = 4 _FRR_VERSION_2_0 = packaging_version.Version('2.0') _FRR_VERSION_3_0 = packaging_version.Version('3.0') # Constants in quagga/lib/zebra.h # Default Zebra TCP port ZEBRA_PORT = 2600 # Zebra message types ZEBRA_INTERFACE_ADD = 1 ZEBRA_INTERFACE_DELETE = 2 ZEBRA_INTERFACE_ADDRESS_ADD = 3 ZEBRA_INTERFACE_ADDRESS_DELETE = 4 ZEBRA_INTERFACE_UP = 5 ZEBRA_INTERFACE_DOWN = 6 ZEBRA_IPV4_ROUTE_ADD = 7 ZEBRA_IPV4_ROUTE_DELETE = 8 ZEBRA_IPV6_ROUTE_ADD = 9 ZEBRA_IPV6_ROUTE_DELETE = 10 ZEBRA_REDISTRIBUTE_ADD = 11 ZEBRA_REDISTRIBUTE_DELETE = 12 ZEBRA_REDISTRIBUTE_DEFAULT_ADD = 13 ZEBRA_REDISTRIBUTE_DEFAULT_DELETE = 14 ZEBRA_IPV4_NEXTHOP_LOOKUP = 15 ZEBRA_IPV6_NEXTHOP_LOOKUP = 16 ZEBRA_IPV4_IMPORT_LOOKUP = 17 ZEBRA_IPV6_IMPORT_LOOKUP = 18 ZEBRA_INTERFACE_RENAME = 19 ZEBRA_ROUTER_ID_ADD = 20 ZEBRA_ROUTER_ID_DELETE = 21 ZEBRA_ROUTER_ID_UPDATE = 22 ZEBRA_HELLO = 23 ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB = 24 ZEBRA_VRF_UNREGISTER = 25 ZEBRA_INTERFACE_LINK_PARAMS = 26 ZEBRA_NEXTHOP_REGISTER = 27 ZEBRA_NEXTHOP_UNREGISTER = 28 ZEBRA_NEXTHOP_UPDATE = 29 ZEBRA_MESSAGE_MAX = 30 # Zebra message types on FRRouting FRR_ZEBRA_INTERFACE_ADD = 0 FRR_ZEBRA_INTERFACE_DELETE = 1 FRR_ZEBRA_INTERFACE_ADDRESS_ADD = 2 FRR_ZEBRA_INTERFACE_ADDRESS_DELETE = 3 FRR_ZEBRA_INTERFACE_UP = 4 FRR_ZEBRA_INTERFACE_DOWN = 5 FRR_ZEBRA_IPV4_ROUTE_ADD = 6 FRR_ZEBRA_IPV4_ROUTE_DELETE = 7 FRR_ZEBRA_IPV6_ROUTE_ADD = 8 FRR_ZEBRA_IPV6_ROUTE_DELETE = 9 FRR_ZEBRA_REDISTRIBUTE_ADD = 10 FRR_ZEBRA_REDISTRIBUTE_DELETE = 11 FRR_ZEBRA_REDISTRIBUTE_DEFAULT_ADD = 12 FRR_ZEBRA_REDISTRIBUTE_DEFAULT_DELETE = 13 FRR_ZEBRA_ROUTER_ID_ADD = 14 FRR_ZEBRA_ROUTER_ID_DELETE = 15 FRR_ZEBRA_ROUTER_ID_UPDATE = 16 FRR_ZEBRA_HELLO = 17 FRR_ZEBRA_NEXTHOP_REGISTER = 18 FRR_ZEBRA_NEXTHOP_UNREGISTER = 19 FRR_ZEBRA_NEXTHOP_UPDATE = 20 FRR_ZEBRA_INTERFACE_NBR_ADDRESS_ADD = 21 FRR_ZEBRA_INTERFACE_NBR_ADDRESS_DELETE = 22 FRR_ZEBRA_INTERFACE_BFD_DEST_UPDATE = 23 FRR_ZEBRA_IMPORT_ROUTE_REGISTER = 24 FRR_ZEBRA_IMPORT_ROUTE_UNREGISTER = 25 FRR_ZEBRA_IMPORT_CHECK_UPDATE = 26 FRR_ZEBRA_IPV4_ROUTE_IPV6_NEXTHOP_ADD = 27 FRR_ZEBRA_BFD_DEST_REGISTER = 28 FRR_ZEBRA_BFD_DEST_DEREGISTER = 29 FRR_ZEBRA_BFD_DEST_UPDATE = 30 FRR_ZEBRA_BFD_DEST_REPLAY = 31 FRR_ZEBRA_REDISTRIBUTE_IPV4_ADD = 32 FRR_ZEBRA_REDISTRIBUTE_IPV4_DEL = 33 FRR_ZEBRA_REDISTRIBUTE_IPV6_ADD = 34 FRR_ZEBRA_REDISTRIBUTE_IPV6_DEL = 35 FRR_ZEBRA_VRF_UNREGISTER = 36 FRR_ZEBRA_VRF_ADD = 37 FRR_ZEBRA_VRF_DELETE = 38 FRR_ZEBRA_INTERFACE_VRF_UPDATE = 39 FRR_ZEBRA_BFD_CLIENT_REGISTER = 40 FRR_ZEBRA_INTERFACE_ENABLE_RADV = 41 FRR_ZEBRA_INTERFACE_DISABLE_RADV = 42 FRR_ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB = 43 FRR_ZEBRA_INTERFACE_LINK_PARAMS = 44 FRR_ZEBRA_MPLS_LABELS_ADD = 45 FRR_ZEBRA_MPLS_LABELS_DELETE = 46 FRR_ZEBRA_IPV4_NEXTHOP_ADD = 47 FRR_ZEBRA_IPV4_NEXTHOP_DELETE = 48 FRR_ZEBRA_IPV6_NEXTHOP_ADD = 49 FRR_ZEBRA_IPV6_NEXTHOP_DELETE = 50 # Zebra route types ZEBRA_ROUTE_SYSTEM = 0 ZEBRA_ROUTE_KERNEL = 1 ZEBRA_ROUTE_CONNECT = 2 ZEBRA_ROUTE_STATIC = 3 ZEBRA_ROUTE_RIP = 4 ZEBRA_ROUTE_RIPNG = 5 ZEBRA_ROUTE_OSPF = 6 ZEBRA_ROUTE_OSPF6 = 7 ZEBRA_ROUTE_ISIS = 8 ZEBRA_ROUTE_BGP = 9 ZEBRA_ROUTE_PIM = 10 ZEBRA_ROUTE_HSLS = 11 ZEBRA_ROUTE_OLSR = 12 ZEBRA_ROUTE_BABEL = 13 ZEBRA_ROUTE_MAX = 14 # Zebra route types on FRRouting FRR_ZEBRA_ROUTE_SYSTEM = 0 FRR_ZEBRA_ROUTE_KERNEL = 1 FRR_ZEBRA_ROUTE_CONNECT = 2 FRR_ZEBRA_ROUTE_STATIC = 3 FRR_ZEBRA_ROUTE_RIP = 4 FRR_ZEBRA_ROUTE_RIPNG = 5 FRR_ZEBRA_ROUTE_OSPF = 6 FRR_ZEBRA_ROUTE_OSPF6 = 7 FRR_ZEBRA_ROUTE_ISIS = 8 FRR_ZEBRA_ROUTE_BGP = 9 FRR_ZEBRA_ROUTE_PIM = 10 FRR_ZEBRA_ROUTE_HSLS = 11 FRR_ZEBRA_ROUTE_OLSR = 12 FRR_ZEBRA_ROUTE_TABLE = 13 FRR_ZEBRA_ROUTE_LDP = 14 FRR_ZEBRA_ROUTE_VNC = 15 FRR_ZEBRA_ROUTE_VNC_DIRECT = 16 FRR_ZEBRA_ROUTE_VNC_DIRECT_RH = 17 FRR_ZEBRA_ROUTE_BGP_DIRECT = 18 FRR_ZEBRA_ROUTE_BGP_DIRECT_EXT = 19 FRR_ZEBRA_ROUTE_ALL = 20 FRR_ZEBRA_ROUTE_MAX = 21 # Zebra message flags ZEBRA_FLAG_INTERNAL = 0x01 ZEBRA_FLAG_SELFROUTE = 0x02 ZEBRA_FLAG_BLACKHOLE = 0x04 ZEBRA_FLAG_IBGP = 0x08 ZEBRA_FLAG_SELECTED = 0x10 ZEBRA_FLAG_FIB_OVERRIDE = 0x20 ZEBRA_FLAG_STATIC = 0x40 ZEBRA_FLAG_REJECT = 0x80 # Zebra message flags on FRRouting FRR_ZEBRA_FLAG_INTERNAL = 0x01 FRR_ZEBRA_FLAG_SELFROUTE = 0x02 FRR_ZEBRA_FLAG_BLACKHOLE = 0x04 FRR_ZEBRA_FLAG_IBGP = 0x08 FRR_ZEBRA_FLAG_SELECTED = 0x10 FRR_ZEBRA_FLAG_STATIC = 0x40 FRR_ZEBRA_FLAG_REJECT = 0x80 FRR_ZEBRA_FLAG_SCOPE_LINK = 0x100 FRR_ZEBRA_FLAG_FIB_OVERRIDE = 0x200 # Zebra nexthop flags ZEBRA_NEXTHOP_IFINDEX = 1 ZEBRA_NEXTHOP_IFNAME = 2 ZEBRA_NEXTHOP_IPV4 = 3 ZEBRA_NEXTHOP_IPV4_IFINDEX = 4 ZEBRA_NEXTHOP_IPV4_IFNAME = 5 ZEBRA_NEXTHOP_IPV6 = 6 ZEBRA_NEXTHOP_IPV6_IFINDEX = 7 ZEBRA_NEXTHOP_IPV6_IFNAME = 8 ZEBRA_NEXTHOP_BLACKHOLE = 9 # Zebra nexthop flags on FRRouting FRR_ZEBRA_NEXTHOP_IFINDEX = 1 FRR_ZEBRA_NEXTHOP_IPV4 = 2 FRR_ZEBRA_NEXTHOP_IPV4_IFINDEX = 3 FRR_ZEBRA_NEXTHOP_IPV6 = 4 FRR_ZEBRA_NEXTHOP_IPV6_IFINDEX = 5 FRR_ZEBRA_NEXTHOP_BLACKHOLE = 6 # Constants in quagga/lib/zclient.h # Zebra API message flags ZAPI_MESSAGE_NEXTHOP = 0x01 ZAPI_MESSAGE_IFINDEX = 0x02 ZAPI_MESSAGE_DISTANCE = 0x04 ZAPI_MESSAGE_METRIC = 0x08 ZAPI_MESSAGE_MTU = 0x10 ZAPI_MESSAGE_TAG = 0x20 # Zebra API message flags on FRRouting. # Note: Constants for TAG/MTU is inverted from Quagga version. FRR_ZAPI_MESSAGE_NEXTHOP = 0x01 FRR_ZAPI_MESSAGE_IFINDEX = 0x02 FRR_ZAPI_MESSAGE_DISTANCE = 0x04 FRR_ZAPI_MESSAGE_METRIC = 0x08 FRR_ZAPI_MESSAGE_TAG = 0x10 FRR_ZAPI_MESSAGE_MTU = 0x20 FRR_ZAPI_MESSAGE_SRCPFX = 0x40 FRR_ZAPI_MESSAGE_LABEL = 0x80 # Constants in quagga/lib/if.h # Interface name length # Linux define value in /usr/include/linux/if.h. # #define IFNAMSIZ 16 # FreeBSD define value in /usr/include/net/if.h. # #define IFNAMSIZ 16 INTERFACE_NAMSIZE = 20 INTERFACE_HWADDR_MAX = 20 # Zebra internal interface status ZEBRA_INTERFACE_ACTIVE = 1 << 0 ZEBRA_INTERFACE_SUB = 1 << 1 ZEBRA_INTERFACE_LINKDETECTION = 1 << 2 # Followings are extended on FRRouting ZEBRA_INTERFACE_VRF_LOOPBACK = 1 << 3 # Zebra interface connected address flags ZEBRA_IFA_SECONDARY = 1 << 0 ZEBRA_IFA_PEER = 1 << 1 ZEBRA_IFA_UNNUMBERED = 1 << 2 # Zebra link layer types ZEBRA_LLT_UNKNOWN = 0 ZEBRA_LLT_ETHER = 1 ZEBRA_LLT_EETHER = 2 ZEBRA_LLT_AX25 = 3 ZEBRA_LLT_PRONET = 4 ZEBRA_LLT_IEEE802 = 5 ZEBRA_LLT_ARCNET = 6 ZEBRA_LLT_APPLETLK = 7 ZEBRA_LLT_DLCI = 8 ZEBRA_LLT_ATM = 9 ZEBRA_LLT_METRICOM = 10 ZEBRA_LLT_IEEE1394 = 11 ZEBRA_LLT_EUI64 = 12 ZEBRA_LLT_INFINIBAND = 13 ZEBRA_LLT_SLIP = 14 ZEBRA_LLT_CSLIP = 15 ZEBRA_LLT_SLIP6 = 16 ZEBRA_LLT_CSLIP6 = 17 ZEBRA_LLT_RSRVD = 18 ZEBRA_LLT_ADAPT = 19 ZEBRA_LLT_ROSE = 20 ZEBRA_LLT_X25 = 21 ZEBRA_LLT_PPP = 22 ZEBRA_LLT_CHDLC = 23 ZEBRA_LLT_LAPB = 24 ZEBRA_LLT_RAWHDLC = 25 ZEBRA_LLT_IPIP = 26 ZEBRA_LLT_IPIP6 = 27 ZEBRA_LLT_FRAD = 28 ZEBRA_LLT_SKIP = 29 ZEBRA_LLT_LOOPBACK = 30 ZEBRA_LLT_LOCALTLK = 31 ZEBRA_LLT_FDDI = 32 ZEBRA_LLT_SIT = 33 ZEBRA_LLT_IPDDP = 34 ZEBRA_LLT_IPGRE = 35 ZEBRA_LLT_IP6GRE = 36 ZEBRA_LLT_PIMREG = 37 ZEBRA_LLT_HIPPI = 38 ZEBRA_LLT_ECONET = 39 ZEBRA_LLT_IRDA = 40 ZEBRA_LLT_FCPP = 41 ZEBRA_LLT_FCAL = 42 ZEBRA_LLT_FCPL = 43 ZEBRA_LLT_FCFABRIC = 44 ZEBRA_LLT_IEEE802_TR = 45 ZEBRA_LLT_IEEE80211 = 46 ZEBRA_LLT_IEEE80211_RADIOTAP = 47 ZEBRA_LLT_IEEE802154 = 48 ZEBRA_LLT_IEEE802154_PHY = 49 # Link Parameters Status LP_UNSET = 0x0000 LP_TE = 0x0001 LP_MAX_BW = 0x0002 LP_MAX_RSV_BW = 0x0004 LP_UNRSV_BW = 0x0008 LP_ADM_GRP = 0x0010 LP_RMT_AS = 0x0020 LP_DELAY = 0x0040 LP_MM_DELAY = 0x0080 LP_DELAY_VAR = 0x0100 LP_PKT_LOSS = 0x0200 LP_RES_BW = 0x0400 LP_AVA_BW = 0x0800 LP_USE_BW = 0x1000 LP_TE_METRIC = 0x2000 # "non-official" architectural constants MAX_CLASS_TYPE = 8 # Constants in frr/zebra/zebra_ptm.h # Interface PTM Enable configuration ZEBRA_IF_PTM_ENABLE_OFF = 0 ZEBRA_IF_PTM_ENABLE_ON = 1 ZEBRA_IF_PTM_ENABLE_UNSPEC = 2 # PTM status ZEBRA_PTM_STATUS_DOWN = 0 ZEBRA_PTM_STATUS_UP = 1 ZEBRA_PTM_STATUS_UNKNOWN = 2 # Constants in frr/lib/bfd.h # BFD status BFD_STATUS_UNKNOWN = 1 << 0 BFD_STATUS_DOWN = 1 << 1 BFD_STATUS_UP = 1 << 2 # Constants in frr/lib/vrf.h # VRF name length VRF_NAMSIZ = 36 # Constants in frr/lib/mpls.h # Reserved MPLS label values MPLS_V4_EXP_NULL_LABEL = 0 MPLS_RA_LABEL = 1 MPLS_V6_EXP_NULL_LABEL = 2 MPLS_IMP_NULL_LABEL = 3 MPLS_ENTROPY_LABEL_INDICATOR = 7 MPLS_GAL_LABEL = 13 MPLS_OAM_ALERT_LABEL = 14 MPLS_EXTENSION_LABEL = 15 MPLS_MIN_RESERVED_LABEL = 0 MPLS_MAX_RESERVED_LABEL = 15 MPLS_MIN_UNRESERVED_LABEL = 16 MPLS_MAX_UNRESERVED_LABEL = 1048575 # Utility functions/classes IPv4Prefix = bgp.IPAddrPrefix IPv6Prefix = bgp.IP6AddrPrefix def _parse_ip_prefix(family, buf): if family == socket.AF_INET: prefix, rest = bgp.IPAddrPrefix.parser(buf) elif family == socket.AF_INET6: prefix, rest = IPv6Prefix.parser(buf) else: raise struct.error('Unsupported family: %d' % family) return prefix.prefix, rest def _serialize_ip_prefix(prefix): if ip.valid_ipv4(prefix): prefix_addr, prefix_num = prefix.split('/') return bgp.IPAddrPrefix(int(prefix_num), prefix_addr).serialize() elif ip.valid_ipv6(prefix): prefix_addr, prefix_num = prefix.split('/') return IPv6Prefix(int(prefix_num), prefix_addr).serialize() else: raise ValueError('Invalid prefix: %s' % prefix) # Family and Zebra Prefix format: # 0 1 2 3 # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Family | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | IPv4/v6 prefix (4 bytes or 16 bytes) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Prefix len | # +-+-+-+-+-+-+-+-+ _ZEBRA_FAMILY_FMT = '!B' # family _ZEBRA_FAMILY_SIZE = struct.calcsize(_ZEBRA_FAMILY_FMT) _ZEBRA_IPV4_PREFIX_FMT = '!4sB' # prefix, prefix_len _ZEBRA_IPV6_PREFIX_FMT = '!16sB' _ZEBRA_IPV4_PREFIX_SIZE = struct.calcsize(_ZEBRA_IPV4_PREFIX_FMT) _ZEBRA_IPV6_PREFIX_SIZE = struct.calcsize(_ZEBRA_IPV6_PREFIX_FMT) _ZEBRA_FAMILY_IPV4_PREFIX_FMT = '!B4sB' # family, prefix, prefix_len _ZEBRA_FAMILY_IPV6_PREFIX_FMT = '!B16sB' # family, prefix, prefix_len def _parse_zebra_family_prefix(buf): """ Parses family and prefix in Zebra format. """ (family,) = struct.unpack_from(_ZEBRA_FAMILY_FMT, buf) rest = buf[_ZEBRA_FAMILY_SIZE:] if socket.AF_INET == family: (prefix, p_len) = struct.unpack_from(_ZEBRA_IPV4_PREFIX_FMT, rest) prefix = '%s/%d' % (addrconv.ipv4.bin_to_text(prefix), p_len) rest = rest[_ZEBRA_IPV4_PREFIX_SIZE:] elif socket.AF_INET6 == family: (prefix, p_len) = struct.unpack_from(_ZEBRA_IPV6_PREFIX_FMT, rest) prefix = '%s/%d' % (addrconv.ipv6.bin_to_text(prefix), p_len) rest = rest[_ZEBRA_IPV6_PREFIX_SIZE:] else: raise struct.error('Unsupported family: %d' % family) return family, prefix, rest def _serialize_zebra_family_prefix(prefix): """ Serializes family and prefix in Zebra format. """ if ip.valid_ipv4(prefix): family = socket.AF_INET # fixup prefix_addr, prefix_num = prefix.split('/') return family, struct.pack( _ZEBRA_FAMILY_IPV4_PREFIX_FMT, family, addrconv.ipv4.text_to_bin(prefix_addr), int(prefix_num)) elif ip.valid_ipv6(prefix): family = socket.AF_INET6 # fixup prefix_addr, prefix_num = prefix.split('/') return family, struct.pack( _ZEBRA_FAMILY_IPV6_PREFIX_FMT, family, addrconv.ipv6.text_to_bin(prefix_addr), int(prefix_num)) raise ValueError('Invalid prefix: %s' % prefix) def _is_frr_version_ge(compared_version): return CONF['zapi'].frr_version >= compared_version class InterfaceLinkParams(stringify.StringifyMixin): """ Interface Link Parameters class for if_link_params structure. """ # Interface Link Parameters structure: # 0 1 2 3 # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Status of Link Parameters | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Traffic Engineering metric | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | (float) Maximum Bandwidth | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | (float) Maximum Reservable Bandwidth | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Number of Unreserved Bandwidth Classes (max is MAX_CLASS_TYPE)| # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | (float) Unreserved Bandwidth per Class Type | # | ... repeats Number of Unreserved Bandwidth Classes times | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Administrative group | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Remote AS number | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Remote IP address | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Link Average Delay | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Link Min Delay | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Link Max Delay | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Link Delay Variation | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | (float) Link Packet Loss | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | (float) Residual Bandwidth | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | (float) Available Bandwidth | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | (float) Utilized Bandwidth | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # lp_status, te_metric, max_bw, max_reserved_bw, bw_cls_num _HEADER_FMT = '!IIffI' HEADER_SIZE = struct.calcsize(_HEADER_FMT) _REPEATED_FMT = '!f' REPEATED_SIZE = struct.calcsize(_REPEATED_FMT) # admin_group, remote_as, remote_ip, # average_delay, min_delay, max_delay, delay_var, # pkt_loss, residual_bw, average_bw, utilized_bw _FOOTER_FMT = '!II4sIIIIffff' FOOTER_SIZE = struct.calcsize(_FOOTER_FMT) def __init__(self, lp_status, te_metric, max_bw, max_reserved_bw, unreserved_bw, admin_group, remote_as, remote_ip, average_delay, min_delay, max_delay, delay_var, pkt_loss, residual_bw, average_bw, utilized_bw): super(InterfaceLinkParams, self).__init__() self.lp_status = lp_status self.te_metric = te_metric self.max_bw = max_bw self.max_reserved_bw = max_reserved_bw assert isinstance(unreserved_bw, (list, tuple)) assert len(unreserved_bw) == MAX_CLASS_TYPE self.unreserved_bw = unreserved_bw self.admin_group = admin_group self.remote_as = remote_as assert ip.valid_ipv4(remote_ip) self.remote_ip = remote_ip self.average_delay = average_delay self.min_delay = min_delay self.max_delay = max_delay self.delay_var = delay_var self.pkt_loss = pkt_loss self.residual_bw = residual_bw self.average_bw = average_bw self.utilized_bw = utilized_bw @classmethod def parse(cls, buf): (lp_status, te_metric, max_bw, max_reserved_bw, bw_cls_num) = struct.unpack_from(cls._HEADER_FMT, buf) if MAX_CLASS_TYPE < bw_cls_num: bw_cls_num = MAX_CLASS_TYPE offset = cls.HEADER_SIZE unreserved_bw = [] for _ in range(bw_cls_num): (u_bw,) = struct.unpack_from(cls._REPEATED_FMT, buf, offset) unreserved_bw.append(u_bw) offset += cls.REPEATED_SIZE (admin_group, remote_as, remote_ip, average_delay, min_delay, max_delay, delay_var, pkt_loss, residual_bw, average_bw, utilized_bw) = struct.unpack_from( cls._FOOTER_FMT, buf, offset) offset += cls.FOOTER_SIZE remote_ip = addrconv.ipv4.bin_to_text(remote_ip) return cls(lp_status, te_metric, max_bw, max_reserved_bw, unreserved_bw, admin_group, remote_as, remote_ip, average_delay, min_delay, max_delay, delay_var, pkt_loss, residual_bw, average_bw, utilized_bw), buf[offset:] def serialize(self): buf = struct.pack( self._HEADER_FMT, self.lp_status, self.te_metric, self.max_bw, self.max_reserved_bw, len(self.unreserved_bw)) for u_bw in self.unreserved_bw: buf += struct.pack(self._REPEATED_FMT, u_bw) remote_ip = addrconv.ipv4.text_to_bin(self.remote_ip) buf += struct.pack( self._FOOTER_FMT, self.admin_group, self.remote_as, remote_ip, self.average_delay, self.min_delay, self.max_delay, self.delay_var, self.pkt_loss, self.residual_bw, self.average_bw, self.utilized_bw) return buf class _NextHop(type_desc.TypeDisp, stringify.StringifyMixin, metaclass=abc.ABCMeta): """ Base class for Zebra Nexthop structure. """ # Zebra Nexthop structure: # 0 1 2 3 # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Nexthop Type | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | IPv4/v6 address or Interface Index number (Variable) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ _HEADER_FMT = '!B' HEADER_SIZE = struct.calcsize(_HEADER_FMT) def __init__(self, ifindex=None, ifname=None, addr=None, type_=None): super(_NextHop, self).__init__() self.ifindex = ifindex self.ifname = ifname self.addr = addr self.type = type_ @classmethod @abc.abstractmethod def parse(cls, buf): (type_,) = struct.unpack_from(cls._HEADER_FMT, buf) rest = buf[cls.HEADER_SIZE:] subcls = cls._lookup_type(type_) if subcls is None: raise struct.error('unsupported Nexthop type: %d' % type_) nexthop, rest = subcls.parse(rest) nexthop.type = type_ return nexthop, rest @abc.abstractmethod def _serialize(self): return b'' def serialize(self, version=_DEFAULT_VERSION): if self.type is None: if version <= 3: nh_cls = _NextHop elif version == 4: nh_cls = _FrrNextHop else: raise ValueError( 'Unsupported Zebra protocol version: %d' % version) self.type = nh_cls._rev_lookup_type(self.__class__) return struct.pack(self._HEADER_FMT, self.type) + self._serialize() class _FrrNextHop(_NextHop, metaclass=abc.ABCMeta): """ Base class for Zebra Nexthop structure for translating nexthop types on FRRouting. """ _NEXTHOP_COUNT_FMT = '!B' # nexthop_count _NEXTHOP_COUNT_SIZE = struct.calcsize(_NEXTHOP_COUNT_FMT) def _parse_nexthops(buf, version=_DEFAULT_VERSION): (nexthop_count,) = struct.unpack_from(_NEXTHOP_COUNT_FMT, buf) rest = buf[_NEXTHOP_COUNT_SIZE:] if version <= 3: nh_cls = _NextHop elif version == 4: nh_cls = _FrrNextHop else: raise struct.error( 'Unsupported Zebra protocol version: %d' % version) nexthops = [] for _ in range(nexthop_count): nexthop, rest = nh_cls.parse(rest) nexthops.append(nexthop) return nexthops, rest def _serialize_nexthops(nexthops, version=_DEFAULT_VERSION): nexthop_count = len(nexthops) buf = struct.pack(_NEXTHOP_COUNT_FMT, nexthop_count) if nexthop_count == 0: return buf for nexthop in nexthops: buf += nexthop.serialize(version=version) return buf @_FrrNextHop.register_type(FRR_ZEBRA_NEXTHOP_IFINDEX) @_NextHop.register_type(ZEBRA_NEXTHOP_IFINDEX) class NextHopIFIndex(_NextHop): """ Nexthop class for ZEBRA_NEXTHOP_IFINDEX type. """ _BODY_FMT = '!I' # ifindex BODY_SIZE = struct.calcsize(_BODY_FMT) @classmethod def parse(cls, buf): (ifindex,) = struct.unpack_from(cls._BODY_FMT, buf) rest = buf[cls.BODY_SIZE:] return cls(ifindex=ifindex), rest def _serialize(self): return struct.pack(self._BODY_FMT, self.ifindex) @_NextHop.register_type(ZEBRA_NEXTHOP_IFNAME) class NextHopIFName(_NextHop): """ Nexthop class for ZEBRA_NEXTHOP_IFNAME type. """ _BODY_FMT = '!I' # ifindex BODY_SIZE = struct.calcsize(_BODY_FMT) @classmethod def parse(cls, buf): (ifindex,) = struct.unpack_from(cls._BODY_FMT, buf) rest = buf[cls.BODY_SIZE:] return cls(ifindex=ifindex), rest def _serialize(self): return struct.pack(self._BODY_FMT, self.ifindex) @_FrrNextHop.register_type(FRR_ZEBRA_NEXTHOP_IPV4) @_NextHop.register_type(ZEBRA_NEXTHOP_IPV4) class NextHopIPv4(_NextHop): """ Nexthop class for ZEBRA_NEXTHOP_IPV4 type. """ _BODY_FMT = '!4s' # addr(IPv4) BODY_SIZE = struct.calcsize(_BODY_FMT) _BODY_FMT_FRR_V3 = '!4sI' # addr(IPv4), ifindex BODY_SIZE_FRR_V3 = struct.calcsize(_BODY_FMT_FRR_V3) @classmethod def parse(cls, buf): if _is_frr_version_ge(_FRR_VERSION_3_0): (addr, ifindex) = struct.unpack_from(cls._BODY_FMT_FRR_V3, buf) addr = addrconv.ipv4.bin_to_text(addr) rest = buf[cls.BODY_SIZE_FRR_V3:] return cls(ifindex=ifindex, addr=addr), rest addr = addrconv.ipv4.bin_to_text(buf[:cls.BODY_SIZE]) rest = buf[cls.BODY_SIZE:] return cls(addr=addr), rest def _serialize(self): if _is_frr_version_ge(_FRR_VERSION_3_0) and self.ifindex: addr = addrconv.ipv4.text_to_bin(self.addr) return struct.pack(self._BODY_FMT_FRR_V3, addr, self.ifindex) return addrconv.ipv4.text_to_bin(self.addr) @_FrrNextHop.register_type(FRR_ZEBRA_NEXTHOP_IPV4_IFINDEX) @_NextHop.register_type(ZEBRA_NEXTHOP_IPV4_IFINDEX) class NextHopIPv4IFIndex(_NextHop): """ Nexthop class for ZEBRA_NEXTHOP_IPV4_IFINDEX type. """ _BODY_FMT = '!4sI' # addr(IPv4), ifindex BODY_SIZE = struct.calcsize(_BODY_FMT) @classmethod def parse(cls, buf): (addr, ifindex) = struct.unpack_from(cls._BODY_FMT, buf) addr = addrconv.ipv4.bin_to_text(addr) rest = buf[cls.BODY_SIZE:] return cls(ifindex=ifindex, addr=addr), rest def _serialize(self): addr = addrconv.ipv4.text_to_bin(self.addr) return struct.pack(self._BODY_FMT, addr, self.ifindex) @_NextHop.register_type(ZEBRA_NEXTHOP_IPV4_IFNAME) class NextHopIPv4IFName(_NextHop): """ Nexthop class for ZEBRA_NEXTHOP_IPV4_IFNAME type. """ _BODY_FMT = '!4sI' # addr(IPv4), ifindex BODY_SIZE = struct.calcsize(_BODY_FMT) @classmethod def parse(cls, buf): (addr, ifindex) = struct.unpack_from(cls._BODY_FMT, buf) addr = addrconv.ipv4.bin_to_text(addr) rest = buf[cls.BODY_SIZE:] return cls(ifindex=ifindex, addr=addr), rest def _serialize(self): addr = addrconv.ipv4.text_to_bin(self.addr) return struct.pack(self._BODY_FMT, addr, self.ifindex) @_FrrNextHop.register_type(FRR_ZEBRA_NEXTHOP_IPV6) @_NextHop.register_type(ZEBRA_NEXTHOP_IPV6) class NextHopIPv6(_NextHop): """ Nexthop class for ZEBRA_NEXTHOP_IPV6 type. """ _BODY_FMT = '!16s' # addr(IPv6) BODY_SIZE = struct.calcsize(_BODY_FMT) _BODY_FMT_FRR_V3 = '!16sI' # addr(IPv6), ifindex BODY_SIZE_FRR_V3 = struct.calcsize(_BODY_FMT_FRR_V3) @classmethod def parse(cls, buf): if _is_frr_version_ge(_FRR_VERSION_3_0): (addr, ifindex) = struct.unpack_from(cls._BODY_FMT_FRR_V3, buf) addr = addrconv.ipv4.bin_to_text(addr) rest = buf[cls.BODY_SIZE_FRR_V3:] return cls(ifindex=ifindex, addr=addr), rest addr = addrconv.ipv6.bin_to_text(buf[:cls.BODY_SIZE]) rest = buf[cls.BODY_SIZE:] return cls(addr=addr), rest def _serialize(self): if _is_frr_version_ge(_FRR_VERSION_3_0) and self.ifindex: addr = addrconv.ipv4.text_to_bin(self.addr) return struct.pack(self._BODY_FMT_FRR_V3, addr, self.ifindex) return addrconv.ipv6.text_to_bin(self.addr) @_FrrNextHop.register_type(FRR_ZEBRA_NEXTHOP_IPV6_IFINDEX) @_NextHop.register_type(ZEBRA_NEXTHOP_IPV6_IFINDEX) class NextHopIPv6IFIndex(_NextHop): """ Nexthop class for ZEBRA_NEXTHOP_IPV6_IFINDEX type. """ _BODY_FMT = '!16sI' # addr(IPv6), ifindex BODY_SIZE = struct.calcsize(_BODY_FMT) @classmethod def parse(cls, buf): (addr, ifindex) = struct.unpack_from(cls._BODY_FMT, buf) addr = addrconv.ipv6.bin_to_text(addr) rest = buf[cls.BODY_SIZE:] return cls(ifindex=ifindex, addr=addr), rest def _serialize(self): addr = addrconv.ipv6.text_to_bin(self.addr) return struct.pack(self._BODY_FMT, addr, self.ifindex) @_NextHop.register_type(ZEBRA_NEXTHOP_IPV6_IFNAME) class NextHopIPv6IFName(_NextHop): """ Nexthop class for ZEBRA_NEXTHOP_IPV6_IFNAME type. """ _BODY_FMT = '!16sI' # addr(IPv6), ifindex BODY_SIZE = struct.calcsize(_BODY_FMT) @classmethod def parse(cls, buf): (addr, ifindex) = struct.unpack_from(cls._BODY_FMT, buf) addr = addrconv.ipv6.bin_to_text(addr) rest = buf[cls.BODY_SIZE:] return cls(ifindex=ifindex, addr=addr), rest def _serialize(self): addr = addrconv.ipv6.text_to_bin(self.addr) return struct.pack(self._BODY_FMT, addr, self.ifindex) @_FrrNextHop.register_type(FRR_ZEBRA_NEXTHOP_BLACKHOLE) @_NextHop.register_type(ZEBRA_NEXTHOP_BLACKHOLE) class NextHopBlackhole(_NextHop): """ Nexthop class for ZEBRA_NEXTHOP_BLACKHOLE type. """ @classmethod def parse(cls, buf): return cls(), buf def _serialize(self): return b'' class RegisteredNexthop(stringify.StringifyMixin): """ Unit of ZEBRA_NEXTHOP_REGISTER message body. """ # Unit of Zebra Nexthop Register message body: # 0 1 2 3 # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Connected | Family | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | IPv4/v6 Prefix (Variable) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ _HEADER_FMT = '!?H' HEADER_SIZE = struct.calcsize(_HEADER_FMT) # Note: connected is renamed to flags on FRRouting. def __init__(self, connected, family, prefix): super(RegisteredNexthop, self).__init__() self.connected = connected self.family = family if isinstance(prefix, (IPv4Prefix, IPv6Prefix)): prefix = prefix.prefix self.prefix = prefix @property def flags(self): return self.connected @flags.setter def flags(self, v): self.connected = v @classmethod def parse(cls, buf): (connected, family) = struct.unpack_from(cls._HEADER_FMT, buf) rest = buf[cls.HEADER_SIZE:] prefix, rest = _parse_ip_prefix(family, rest) return cls(connected, family, prefix), rest def serialize(self): buf = struct.pack(self._HEADER_FMT, self.connected, self.family) return buf + _serialize_ip_prefix(self.prefix) # Zebra message class class ZebraMessage(packet_base.PacketBase): """ Zebra protocol parser/serializer class. An instance has the following attributes at least. Most of them are same to the on-wire counterparts but in host byte order. __init__ takes the corresponding args in this order. ============== ========================================================== Attribute Description ============== ========================================================== length Total packet length including this header. The minimum length is 3 bytes for version 0 messages, 6 bytes for version 1/2 messages and 8 bytes for version 3 messages. version Version number of the Zebra protocol message. To instantiate messages with other than the default version, ``version`` must be specified. vrf_id VRF ID for the route contained in message. Not present in version 0/1/2 messages in the on-wire structure, and always 0 for theses version. command Zebra Protocol command, which denotes message type. body Messages body. An instance of subclass of ``_ZebraMessageBody`` named like "Zebra + " (e.g., ``ZebraHello``). Or ``None`` if message does not contain any body. ============== ========================================================== .. Note:: To instantiate Zebra messages, ``command`` can be omitted when the valid ``body`` is specified. :: >>> from os_ken.lib.packet import zebra >>> zebra.ZebraMessage(body=zebra.ZebraHello()) ZebraMessage(body=ZebraHello(route_type=14),command=23, length=None,version=3,vrf_id=0) On the other hand, if ``body`` is omitted, ``command`` must be specified. :: >>> zebra.ZebraMessage(command=zebra.ZEBRA_INTERFACE_ADD) ZebraMessage(body=None,command=1,length=None,version=3,vrf_id=0) """ # Zebra Protocol Common Header (version 0): # 0 1 2 3 # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Length | Command | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ _V0_HEADER_FMT = '!HB' V0_HEADER_SIZE = struct.calcsize(_V0_HEADER_FMT) _MIN_LEN = V0_HEADER_SIZE # Zebra Protocol Common Header (version 1): # 0 1 2 3 # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Length | Marker | Version | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Command | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ _V1_HEADER_FMT = '!HBBH' V1_HEADER_SIZE = struct.calcsize(_V1_HEADER_FMT) # Zebra Protocol Common Header (version 3): # 0 1 2 3 # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Length | Marker | Version | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | VRF ID | Command | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ _V3_HEADER_FMT = '!HBBHH' V3_HEADER_SIZE = struct.calcsize(_V3_HEADER_FMT) # Note: Marker should be 0xff(=255) in the version>=1 header. # Also, FRRouting uses the different marker value. _MARKER = 0xff _LT_MARKER = 0xfe def __init__(self, length=None, version=_DEFAULT_VERSION, vrf_id=0, command=None, body=None): super(ZebraMessage, self).__init__() self.length = length self.version = version self.vrf_id = vrf_id self.command = command self.body = body def _fill_command(self): assert isinstance(self.body, _ZebraMessageBody) body_base_cls = _ZebraMessageBody if self.version == 4: body_base_cls = _FrrZebraMessageBody self.command = body_base_cls.rev_lookup_command(self.body.__class__) @classmethod def get_header_size(cls, version): if version == 0: return cls.V0_HEADER_SIZE elif version in [1, 2]: return cls.V1_HEADER_SIZE elif version in [3, 4]: return cls.V3_HEADER_SIZE else: raise ValueError( 'Unsupported Zebra protocol version: %d' % version) @classmethod def parse_header(cls, buf): (length, marker) = struct.unpack_from(cls._V0_HEADER_FMT, buf) if marker not in [cls._MARKER, cls._LT_MARKER]: command = marker body_buf = buf[cls.V0_HEADER_SIZE:length] # version=0, vrf_id=0 return length, 0, 0, command, body_buf (length, marker, version, command) = struct.unpack_from( cls._V1_HEADER_FMT, buf) if version in [1, 2]: body_buf = buf[cls.V1_HEADER_SIZE:length] # vrf_id=0 return length, version, 0, command, body_buf (length, marker, version, vrf_id, command) = struct.unpack_from( cls._V3_HEADER_FMT, buf) if version == 3 or (version == 4 and marker == cls._LT_MARKER): body_buf = buf[cls.V3_HEADER_SIZE:length] return length, version, vrf_id, command, body_buf raise struct.error( 'Failed to parse Zebra protocol header: ' 'marker=%d, version=%d' % (marker, version)) @classmethod def get_body_class(cls, version, command): if version == 4: return _FrrZebraMessageBody.lookup_command(command) else: return _ZebraMessageBody.lookup_command(command) @classmethod def _parser_impl(cls, buf, from_zebra=False): buf = bytes(buf) (length, version, vrf_id, command, body_buf) = cls.parse_header(buf) if body_buf: body_cls = cls.get_body_class(version, command) if from_zebra: body = body_cls.parse_from_zebra(body_buf, version=version) else: body = body_cls.parse(body_buf, version=version) else: body = None rest = buf[length:] if from_zebra: return (cls(length, version, vrf_id, command, body), _ZebraMessageFromZebra, rest) return cls(length, version, vrf_id, command, body), cls, rest @classmethod def parser(cls, buf): return cls._parser_impl(buf) def serialize_header(self, body_len): if self.version == 0: self.length = self.V0_HEADER_SIZE + body_len # fixup return struct.pack( self._V0_HEADER_FMT, self.length, self.command) elif self.version in [1, 2]: self.length = self.V1_HEADER_SIZE + body_len # fixup return struct.pack( self._V1_HEADER_FMT, self.length, self._MARKER, self.version, self.command) elif self.version in [3, 4]: if self.version == 3: _marker = self._MARKER else: # self.version == 4 _marker = self._LT_MARKER self.length = self.V3_HEADER_SIZE + body_len # fixup return struct.pack( self._V3_HEADER_FMT, self.length, _marker, self.version, self.vrf_id, self.command) else: raise ValueError( 'Unsupported Zebra protocol version: %d' % self.version) def serialize(self, _payload=None, _prev=None): if self.body is None: assert self.command is not None body = b'' else: assert isinstance(self.body, _ZebraMessageBody) self._fill_command() # fixup body = self.body.serialize(version=self.version) return self.serialize_header(len(body)) + body class _ZebraMessageFromZebra(ZebraMessage): """ This class is corresponding to the message sent from Zebra daemon. """ @classmethod def parser(cls, buf): return ZebraMessage._parser_impl(buf, from_zebra=True) # Alias zebra = ZebraMessage # Zebra message body classes class _ZebraMessageBody(type_desc.TypeDisp, stringify.StringifyMixin): """ Base class for Zebra message body. """ @classmethod def lookup_command(cls, command): return cls._lookup_type(command) @classmethod def rev_lookup_command(cls, body_cls): return cls._rev_lookup_type(body_cls) @classmethod def parse(cls, buf, version=_DEFAULT_VERSION): return cls() @classmethod def parse_from_zebra(cls, buf, version=_DEFAULT_VERSION): return cls.parse(buf, version=version) def serialize(self, version=_DEFAULT_VERSION): return b'' class _FrrZebraMessageBody(_ZebraMessageBody): """ Pseudo message body class for translating message types on FRRouting. """ @_FrrZebraMessageBody.register_unknown_type() @_ZebraMessageBody.register_unknown_type() class ZebraUnknownMessage(_ZebraMessageBody): """ Message body class for Unknown command. """ def __init__(self, buf): super(ZebraUnknownMessage, self).__init__() self.buf = buf @classmethod def parse(cls, buf, version=_DEFAULT_VERSION): return cls(buf) def serialize(self, version=_DEFAULT_VERSION): return self.buf class _ZebraInterface(_ZebraMessageBody, metaclass=abc.ABCMeta): """ Base class for ZEBRA_INTERFACE_ADD, ZEBRA_INTERFACE_DELETE, ZEBRA_INTERFACE_UP and ZEBRA_INTERFACE_DOWN message body. """ # Zebra Interface Add/Delete message body: # 0 1 2 3 # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Interface Name (INTERFACE_NAMSIZE bytes length) | # | | # | | # | | # | | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Interface index | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Status | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Interface flags | # | | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | (PTM Enable) | (PTM Status) | v4(FRRouting) # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Metric | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | (Speed): v4(FRRouting v3.0 or later) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Interface's MTU for IPv4 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Interface's MTU for IPv6 | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Bandwidth | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | (Link Layer Type): v3 or later | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Hardware Address Length | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Hardware Address if HW length different from 0 | # | ... max is INTERFACE_HWADDR_MAX | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | link_params? | Whether a link-params follows: 1 or 0. # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Link params 0 or 1 INTERFACE_LINK_PARAMS_SIZE sized | # | .... (struct if_link_params). | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # ifname, ifindex, status, if_flags, metric, ifmtu, ifmtu6, bandwidth, # hw_addr_len _HEADER_FMT = '!%dsIBQIIIII' % INTERFACE_NAMSIZE HEADER_SIZE = struct.calcsize(_HEADER_FMT) # ifname, ifindex, status, if_flags, metric, ifmtu, ifmtu6, bandwidth, # ll_type, hw_addr_len _V3_HEADER_FMT = '!%dsIBQIIIIII' % INTERFACE_NAMSIZE V3_HEADER_SIZE = struct.calcsize(_V3_HEADER_FMT) # ifname, ifindex, status, if_flags, ptm_enable, ptm_status, metric, # ifmtu, ifmtu6, bandwidth, ll_type, hw_addr_len _V4_HEADER_FMT_2_0 = '!%dsIBQBBIIIIII' % INTERFACE_NAMSIZE V4_HEADER_SIZE_2_0 = struct.calcsize(_V4_HEADER_FMT_2_0) # ifname, ifindex, status, if_flags, ptm_enable, ptm_status, metric, # speed, ifmtu, ifmtu6, bandwidth, ll_type, hw_addr_len _V4_HEADER_FMT_3_0 = '!%dsIBQBBIIIIIII' % INTERFACE_NAMSIZE V4_HEADER_SIZE_3_0 = struct.calcsize(_V4_HEADER_FMT_3_0) # link_params_state (whether a link-params follows) _LP_STATE_FMT = '!?' LP_STATE_SIZE = struct.calcsize(_LP_STATE_FMT) # See InterfaceLinkParams class for Link params structure def __init__(self, ifname=None, ifindex=None, status=None, if_flags=None, ptm_enable=None, ptm_status=None, metric=None, speed=None, ifmtu=None, ifmtu6=None, bandwidth=None, ll_type=None, hw_addr_len=0, hw_addr=None, link_params=None): super(_ZebraInterface, self).__init__() self.ifname = ifname self.ifindex = ifindex self.status = status self.if_flags = if_flags self.ptm_enable = ptm_enable self.ptm_status = ptm_status self.metric = metric self.speed = speed self.ifmtu = ifmtu self.ifmtu6 = ifmtu6 self.bandwidth = bandwidth self.ll_type = ll_type self.hw_addr_lenght = hw_addr_len hw_addr = hw_addr or b'' self.hw_addr = hw_addr assert (isinstance(link_params, InterfaceLinkParams) or link_params is None) self.link_params = link_params @classmethod def parse(cls, buf, version=_DEFAULT_VERSION): ptm_enable = None ptm_status = None speed = None ll_type = None if version <= 2: (ifname, ifindex, status, if_flags, metric, ifmtu, ifmtu6, bandwidth, hw_addr_len) = struct.unpack_from(cls._HEADER_FMT, buf) rest = buf[cls.HEADER_SIZE:] elif version == 3: (ifname, ifindex, status, if_flags, metric, ifmtu, ifmtu6, bandwidth, ll_type, hw_addr_len) = struct.unpack_from(cls._V3_HEADER_FMT, buf) rest = buf[cls.V3_HEADER_SIZE:] elif version == 4: if _is_frr_version_ge(_FRR_VERSION_3_0): (ifname, ifindex, status, if_flags, ptm_enable, ptm_status, metric, speed, ifmtu, ifmtu6, bandwidth, ll_type, hw_addr_len) = struct.unpack_from(cls._V4_HEADER_FMT_3_0, buf) rest = buf[cls.V4_HEADER_SIZE_3_0:] elif _is_frr_version_ge(_FRR_VERSION_2_0): (ifname, ifindex, status, if_flags, ptm_enable, ptm_status, metric, ifmtu, ifmtu6, bandwidth, ll_type, hw_addr_len) = struct.unpack_from(cls._V4_HEADER_FMT_2_0, buf) rest = buf[cls.V4_HEADER_SIZE_2_0:] else: raise struct.error( 'Unsupported FRRouting version: %s' % CONF['zapi'].frr_version) else: raise struct.error( 'Unsupported Zebra protocol version: %d' % version) ifname = str(str(ifname.strip(b'\x00'), 'ascii')) hw_addr_len = min(hw_addr_len, INTERFACE_HWADDR_MAX) hw_addr_bin = rest[:hw_addr_len] rest = rest[hw_addr_len:] if 0 < hw_addr_len < 7: # Assuming MAC address hw_addr = addrconv.mac.bin_to_text( hw_addr_bin + b'\x00' * (6 - hw_addr_len)) else: # Unknown hardware address hw_addr = hw_addr_bin if not rest: return cls(ifname, ifindex, status, if_flags, ptm_enable, ptm_status, metric, speed, ifmtu, ifmtu6, bandwidth, ll_type, hw_addr_len, hw_addr) (link_param_state,) = struct.unpack_from(cls._LP_STATE_FMT, rest) rest = rest[cls.LP_STATE_SIZE:] if link_param_state: link_params, rest = InterfaceLinkParams.parse(rest) else: link_params = None return cls(ifname, ifindex, status, if_flags, ptm_enable, ptm_status, metric, speed, ifmtu, ifmtu6, bandwidth, ll_type, hw_addr_len, hw_addr, link_params) def serialize(self, version=_DEFAULT_VERSION): if self.ifname is None: # Case for sending message to Zebra return b'' # fixup if netaddr.valid_mac(self.hw_addr): # MAC address hw_addr_len = 6 hw_addr = addrconv.mac.text_to_bin(self.hw_addr) else: # Unknown hardware address hw_addr_len = len(self.hw_addr) hw_addr = self.hw_addr if version <= 2: return struct.pack( self._HEADER_FMT, self.ifname.encode('ascii'), self.ifindex, self.status, self.if_flags, self.metric, self.ifmtu, self.ifmtu6, self.bandwidth, hw_addr_len) + hw_addr elif version == 3: buf = struct.pack( self._V3_HEADER_FMT, self.ifname.encode('ascii'), self.ifindex, self.status, self.if_flags, self.metric, self.ifmtu, self.ifmtu6, self.bandwidth, self.ll_type, hw_addr_len) + hw_addr elif version == 4: if _is_frr_version_ge(_FRR_VERSION_3_0): buf = struct.pack( self._V4_HEADER_FMT_3_0, self.ifname.encode('ascii'), self.ifindex, self.status, self.if_flags, self.ptm_enable, self.ptm_status, self.metric, self.speed, self.ifmtu, self.ifmtu6, self.bandwidth, self.ll_type, hw_addr_len) + hw_addr elif _is_frr_version_ge(_FRR_VERSION_2_0): buf = struct.pack( self._V4_HEADER_FMT_2_0, self.ifname.encode('ascii'), self.ifindex, self.status, self.if_flags, self.ptm_enable, self.ptm_status, self.metric, self.ifmtu, self.ifmtu6, self.bandwidth, self.ll_type, hw_addr_len) + hw_addr else: raise ValueError( 'Unsupported FRRouting version: %s' % CONF['zapi'].frr_version) else: raise ValueError( 'Unsupported Zebra protocol version: %d' % version) if isinstance(self.link_params, InterfaceLinkParams): buf += struct.pack(self._LP_STATE_FMT, True) buf += self.link_params.serialize() else: buf += struct.pack(self._LP_STATE_FMT, False) return buf @_FrrZebraMessageBody.register_type(FRR_ZEBRA_INTERFACE_ADD) @_ZebraMessageBody.register_type(ZEBRA_INTERFACE_ADD) class ZebraInterfaceAdd(_ZebraInterface): """ Message body class for ZEBRA_INTERFACE_ADD. """ @_FrrZebraMessageBody.register_type(FRR_ZEBRA_INTERFACE_DELETE) @_ZebraMessageBody.register_type(ZEBRA_INTERFACE_DELETE) class ZebraInterfaceDelete(_ZebraInterface): """ Message body class for ZEBRA_INTERFACE_DELETE. """ class _ZebraInterfaceAddress(_ZebraMessageBody, metaclass=abc.ABCMeta): """ Base class for ZEBRA_INTERFACE_ADDRESS_ADD and ZEBRA_INTERFACE_ADDRESS_DELETE message body. """ # Zebra Interface Address Add/Delete message body: # 0 1 2 3 # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Interface index | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | IFC Flags | flags for connected address # +-+-+-+-+-+-+-+-+ # | Family | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | IPv4/v6 Prefix (Variable) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Prefix len | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | IPv4/v6 Destination Address (Variable) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ _HEADER_FMT = '!IB' # ifindex, ifc_flags HEADER_SIZE = struct.calcsize(_HEADER_FMT) def __init__(self, ifindex, ifc_flags, family, prefix, dest): super(_ZebraInterfaceAddress, self).__init__() self.ifindex = ifindex self.ifc_flags = ifc_flags self.family = family if isinstance(prefix, (IPv4Prefix, IPv6Prefix)): prefix = prefix.prefix self.prefix = prefix assert ip.valid_ipv4(dest) or ip.valid_ipv6(dest) self.dest = dest @classmethod def parse(cls, buf, version=_DEFAULT_VERSION): (ifindex, ifc_flags) = struct.unpack_from(cls._HEADER_FMT, buf) rest = buf[cls.HEADER_SIZE:] (family, prefix, rest) = _parse_zebra_family_prefix(rest) if socket.AF_INET == family: dest = addrconv.ipv4.bin_to_text(rest) elif socket.AF_INET6 == family: dest = addrconv.ipv6.bin_to_text(rest) else: raise struct.error('Unsupported family: %d' % family) return cls(ifindex, ifc_flags, family, prefix, dest) def serialize(self, version=_DEFAULT_VERSION): (self.family, # fixup body_bin) = _serialize_zebra_family_prefix(self.prefix) if ip.valid_ipv4(self.dest): body_bin += addrconv.ipv4.text_to_bin(self.dest) elif ip.valid_ipv6(self.prefix): body_bin += addrconv.ipv6.text_to_bin(self.dest) else: raise ValueError( 'Invalid destination address: %s' % self.dest) return struct.pack(self._HEADER_FMT, self.ifindex, self.ifc_flags) + body_bin @_FrrZebraMessageBody.register_type(FRR_ZEBRA_INTERFACE_ADDRESS_ADD) @_ZebraMessageBody.register_type(ZEBRA_INTERFACE_ADDRESS_ADD) class ZebraInterfaceAddressAdd(_ZebraInterfaceAddress): """ Message body class for ZEBRA_INTERFACE_ADDRESS_ADD. """ @_FrrZebraMessageBody.register_type(FRR_ZEBRA_INTERFACE_ADDRESS_DELETE) @_ZebraMessageBody.register_type(ZEBRA_INTERFACE_ADDRESS_DELETE) class ZebraInterfaceAddressDelete(_ZebraInterfaceAddress): """ Message body class for ZEBRA_INTERFACE_ADDRESS_DELETE. """ @_FrrZebraMessageBody.register_type(FRR_ZEBRA_INTERFACE_UP) @_ZebraMessageBody.register_type(ZEBRA_INTERFACE_UP) class ZebraInterfaceUp(_ZebraInterface): """ Message body class for ZEBRA_INTERFACE_UP. """ @_FrrZebraMessageBody.register_type(FRR_ZEBRA_INTERFACE_DOWN) @_ZebraMessageBody.register_type(ZEBRA_INTERFACE_DOWN) class ZebraInterfaceDown(_ZebraInterface): """ Message body class for ZEBRA_INTERFACE_DOWN. """ class _ZebraIPRoute(_ZebraMessageBody, metaclass=abc.ABCMeta): """ Base class for ZEBRA_IPV4_ROUTE_* and ZEBRA_IPV6_ROUTE_* message body. .. Note:: Zebra IPv4/IPv6 Route message have asymmetric structure. If the message sent from Zebra Daemon, set 'from_zebra=True' to create an instance of this class. """ # Zebra IPv4/IPv6 Route message body (Protocol Daemons -> Zebra Daemon): # 0 1 2 3 # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Route Type | Flags | Message | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | SAFI | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | IPv4/v6 Prefix (Variable) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Nexthop Num | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Nexthops (Variable) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | (Distance) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | (Metric) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | (MTU) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | (TAG) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # # Zebra IPv4/IPv6 Route message body on FRRouting # (Protocol Daemons -> Zebra Daemon): # 0 1 2 3 # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Route Type | Instance | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Flags | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Message | SAFI | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | IPv4/v6 Prefix (Variable) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | (IPv4/v6 Source Prefix): v4(FRRouting v3.0 or later) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Nexthop Num | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Nexthops (Variable) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | (Distance) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | (Metric) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | (TAG) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | (MTU) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # # Zebra IPv4/IPv6 Route message body (Zebra Daemon -> Protocol Daemons): # 0 1 2 3 # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Route Type | Flags | Message | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | IPv4/v6 Prefix (Variable) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | (Nexthop Num) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | (Nexthops (Variable)) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | (IFIndex Num) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | (Interface indexes) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | (Distance) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | (Metric) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | (MTU) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | (TAG) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # # Zebra IPv4/IPv6 Route message body on FRRouting # (Zebra Daemon -> Protocol Daemons): # 0 1 2 3 # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Route Type | Instance | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Flags | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Message | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | IPv4/v6 Prefix (Variable) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | (IPv4/v6 Source Prefix): v4(FRRouting v3.0 or later) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | (Nexthop Num) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | (Nexthops (Variable)) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | (IFIndex Num) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | (Interface indexes) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | (Distance) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | (Metric) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | (TAG) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ _HEADER_FMT = '!BBB' # type, flags, message HEADER_SIZE = struct.calcsize(_HEADER_FMT) _V4_HEADER_FMT = '!BHIB' # type, instance, flags, message V4_HEADER_SIZE = struct.calcsize(_V4_HEADER_FMT) _SAFI_FMT = '!H' # safi SAFI_SIZE = struct.calcsize(_SAFI_FMT) _NUM_FMT = '!B' # nexthop_num or ifindex_num NUM_SIZE = struct.calcsize(_NUM_FMT) _IFINDEX_FMT = '!I' # ifindex IFINDEX_SIZE = struct.calcsize(_IFINDEX_FMT) # API type specific constants _FAMILY = None # either socket.AF_INET or socket.AF_INET6 def __init__(self, route_type, flags, message, safi=None, prefix=None, src_prefix=None, nexthops=None, ifindexes=None, distance=None, metric=None, mtu=None, tag=None, instance=None, from_zebra=False): super(_ZebraIPRoute, self).__init__() self.route_type = route_type self.instance = instance self.flags = flags self.message = message # SAFI should be included if this message sent to Zebra. if from_zebra: self.safi = None else: self.safi = safi or packet_safi.UNICAST assert prefix is not None if isinstance(prefix, (IPv4Prefix, IPv6Prefix)): prefix = prefix.prefix self.prefix = prefix if isinstance(src_prefix, (IPv4Prefix, IPv6Prefix)): src_prefix = src_prefix.prefix self.src_prefix = src_prefix # Nexthops should be a list of str representations of IP address # if this message sent from Zebra, otherwise a list of _Nexthop # subclasses. nexthops = nexthops or [] if from_zebra: for nexthop in nexthops: assert ip.valid_ipv4(nexthop) or ip.valid_ipv6(nexthop) else: for nexthop in nexthops: assert isinstance(nexthop, _NextHop) self.nexthops = nexthops # Interface indexes should be included if this message sent from # Zebra. if from_zebra: ifindexes = ifindexes or [] for ifindex in ifindexes: assert isinstance(ifindex, int) self.ifindexes = ifindexes else: self.ifindexes = None self.distance = distance self.metric = metric self.mtu = mtu self.tag = tag # is this message sent from Zebra message or not. self.from_zebra = from_zebra @classmethod def _parse_message_option(cls, message, flag, fmt, buf): if message & flag: (option,) = struct.unpack_from(fmt, buf) return option, buf[struct.calcsize(fmt):] return None, buf @classmethod def _parse_impl(cls, buf, version=_DEFAULT_VERSION, from_zebra=False): instance = None if version <= 3: (route_type, flags, message,) = struct.unpack_from( cls._HEADER_FMT, buf) rest = buf[cls.HEADER_SIZE:] elif version == 4: (route_type, instance, flags, message,) = struct.unpack_from( cls._V4_HEADER_FMT, buf) rest = buf[cls.V4_HEADER_SIZE:] else: raise struct.error( 'Unsupported Zebra protocol version: %d' % version) if from_zebra: safi = None else: (safi,) = struct.unpack_from(cls._SAFI_FMT, rest) rest = rest[cls.SAFI_SIZE:] prefix, rest = _parse_ip_prefix(cls._FAMILY, rest) src_prefix = None if version == 4 and message & FRR_ZAPI_MESSAGE_SRCPFX: src_prefix, rest = _parse_ip_prefix(cls._FAMILY, rest) if from_zebra and message & ZAPI_MESSAGE_NEXTHOP: nexthops = [] (nexthop_num,) = struct.unpack_from(cls._NUM_FMT, rest) rest = rest[cls.NUM_SIZE:] if cls._FAMILY == socket.AF_INET: for _ in range(nexthop_num): nexthop = addrconv.ipv4.bin_to_text(rest[:4]) nexthops.append(nexthop) rest = rest[4:] else: # cls._FAMILY == socket.AF_INET6: for _ in range(nexthop_num): nexthop = addrconv.ipv6.bin_to_text(rest[:16]) nexthops.append(nexthop) rest = rest[16:] else: nexthops, rest = _parse_nexthops(rest, version) ifindexes = [] if from_zebra and message & ZAPI_MESSAGE_IFINDEX: (ifindex_num,) = struct.unpack_from(cls._NUM_FMT, rest) rest = rest[cls.NUM_SIZE:] for _ in range(ifindex_num): (ifindex,) = struct.unpack_from(cls._IFINDEX_FMT, rest) ifindexes.append(ifindex) rest = rest[cls.IFINDEX_SIZE:] if version <= 3: distance, rest = cls._parse_message_option( message, ZAPI_MESSAGE_DISTANCE, '!B', rest) metric, rest = cls._parse_message_option( message, ZAPI_MESSAGE_METRIC, '!I', rest) mtu, rest = cls._parse_message_option( message, ZAPI_MESSAGE_MTU, '!I', rest) tag, rest = cls._parse_message_option( message, ZAPI_MESSAGE_TAG, '!I', rest) elif version == 4: distance, rest = cls._parse_message_option( message, FRR_ZAPI_MESSAGE_DISTANCE, '!B', rest) metric, rest = cls._parse_message_option( message, FRR_ZAPI_MESSAGE_METRIC, '!I', rest) tag, rest = cls._parse_message_option( message, FRR_ZAPI_MESSAGE_TAG, '!I', rest) mtu, rest = cls._parse_message_option( message, FRR_ZAPI_MESSAGE_MTU, '!I', rest) else: raise struct.error( 'Unsupported Zebra protocol version: %d' % version) return cls(route_type, flags, message, safi, prefix, src_prefix, nexthops, ifindexes, distance, metric, mtu, tag, instance, from_zebra=from_zebra) @classmethod def parse(cls, buf, version=_DEFAULT_VERSION): return cls._parse_impl(buf, version=version) @classmethod def parse_from_zebra(cls, buf, version=_DEFAULT_VERSION): return cls._parse_impl(buf, version=version, from_zebra=True) def _serialize_message_option(self, option, flag, fmt): if option is None: return b'' # fixup self.message |= flag return struct.pack(fmt, option) def serialize(self, version=_DEFAULT_VERSION): prefix = _serialize_ip_prefix(self.prefix) if version == 4 and self.src_prefix: self.message |= FRR_ZAPI_MESSAGE_SRCPFX # fixup prefix += _serialize_ip_prefix(self.src_prefix) nexthops = b'' if self.from_zebra and self.nexthops: self.message |= ZAPI_MESSAGE_NEXTHOP # fixup nexthops += struct.pack(self._NUM_FMT, len(self.nexthops)) for nexthop in self.nexthops: nexthops += ip.text_to_bin(nexthop) else: self.message |= ZAPI_MESSAGE_NEXTHOP # fixup nexthops = _serialize_nexthops(self.nexthops, version=version) ifindexes = b'' if self.ifindexes and self.from_zebra: self.message |= ZAPI_MESSAGE_IFINDEX # fixup ifindexes += struct.pack(self._NUM_FMT, len(self.ifindexes)) for ifindex in self.ifindexes: ifindexes += struct.pack(self._IFINDEX_FMT, ifindex) if version <= 3: options = self._serialize_message_option( self.distance, ZAPI_MESSAGE_DISTANCE, '!B') options += self._serialize_message_option( self.metric, ZAPI_MESSAGE_METRIC, '!I') options += self._serialize_message_option( self.mtu, ZAPI_MESSAGE_MTU, '!I') options += self._serialize_message_option( self.tag, ZAPI_MESSAGE_TAG, '!I') header = struct.pack( self._HEADER_FMT, self.route_type, self.flags, self.message) elif version == 4: options = self._serialize_message_option( self.distance, FRR_ZAPI_MESSAGE_DISTANCE, '!B') options += self._serialize_message_option( self.metric, FRR_ZAPI_MESSAGE_METRIC, '!I') options += self._serialize_message_option( self.tag, FRR_ZAPI_MESSAGE_TAG, '!I') options += self._serialize_message_option( self.mtu, FRR_ZAPI_MESSAGE_MTU, '!I') header = struct.pack( self._V4_HEADER_FMT, self.route_type, self.instance, self.flags, self.message) else: raise ValueError( 'Unsupported Zebra protocol version: %d' % version) if not self.from_zebra: header += struct.pack(self._SAFI_FMT, self.safi) return header + prefix + nexthops + ifindexes + options class _ZebraIPv4Route(_ZebraIPRoute): """ Base class for ZEBRA_IPV4_ROUTE_* message body. """ _FAMILY = socket.AF_INET @_FrrZebraMessageBody.register_type(FRR_ZEBRA_IPV4_ROUTE_ADD) @_ZebraMessageBody.register_type(ZEBRA_IPV4_ROUTE_ADD) class ZebraIPv4RouteAdd(_ZebraIPv4Route): """ Message body class for ZEBRA_IPV4_ROUTE_ADD. """ @_FrrZebraMessageBody.register_type(FRR_ZEBRA_IPV4_ROUTE_DELETE) @_ZebraMessageBody.register_type(ZEBRA_IPV4_ROUTE_DELETE) class ZebraIPv4RouteDelete(_ZebraIPv4Route): """ Message body class for ZEBRA_IPV4_ROUTE_DELETE. """ class _ZebraIPv6Route(_ZebraIPRoute): """ Base class for ZEBRA_IPV6_ROUTE_* message body. """ _FAMILY = socket.AF_INET6 @_FrrZebraMessageBody.register_type(FRR_ZEBRA_IPV6_ROUTE_ADD) @_ZebraMessageBody.register_type(ZEBRA_IPV6_ROUTE_ADD) class ZebraIPv6RouteAdd(_ZebraIPv6Route): """ Message body class for ZEBRA_IPV6_ROUTE_ADD. """ @_FrrZebraMessageBody.register_type(FRR_ZEBRA_IPV6_ROUTE_DELETE) @_ZebraMessageBody.register_type(ZEBRA_IPV6_ROUTE_DELETE) class ZebraIPv6RouteDelete(_ZebraIPv6Route): """ Message body class for ZEBRA_IPV6_ROUTE_DELETE. """ @_FrrZebraMessageBody.register_type(FRR_ZEBRA_IPV4_ROUTE_IPV6_NEXTHOP_ADD) class ZebraIPv4RouteIPv6NexthopAdd(_ZebraIPv4Route): """ Message body class for FRR_ZEBRA_IPV4_ROUTE_IPV6_NEXTHOP_ADD. """ class _ZebraRedistribute(_ZebraMessageBody, metaclass=abc.ABCMeta): """ Base class for ZEBRA_REDISTRIBUTE_ADD and ZEBRA_REDISTRIBUTE_DELETE message body. """ # Zebra Redistribute message body: # 0 1 2 3 # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Route Type | # +-+-+-+-+-+-+-+-+ # # Zebra Redistribute message body on FRRouting: # 0 1 2 3 # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | AFI | Route Type | Instance | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++-+-+-+-+-+-+-+-++-+-+-+-+-+-+ _HEADER_FMT = '!B' # route_type HEADER_SIZE = struct.calcsize(_HEADER_FMT) _V4_HEADER_FMT = '!BBH' # afi, route_type, instance V4_HEADER_SIZE = struct.calcsize(_V4_HEADER_FMT) def __init__(self, route_type, afi=None, instance=None): super(_ZebraRedistribute, self).__init__() self.afi = afi self.route_type = route_type self.instance = instance @classmethod def parse(cls, buf, version=_DEFAULT_VERSION): afi = None instance = None if version <= 3: (route_type,) = struct.unpack_from(cls._HEADER_FMT, buf) elif version == 4: (afi, route_type, instance) = struct.unpack_from(cls._V4_HEADER_FMT, buf) else: raise struct.error( 'Unsupported Zebra protocol version: %d' % version) return cls(route_type, afi, instance) def serialize(self, version=_DEFAULT_VERSION): if version <= 3: return struct.pack(self._HEADER_FMT, self.route_type) elif version == 4: return struct.pack(self._V4_HEADER_FMT, self.afi, self.route_type, self.instance) else: raise ValueError( 'Unsupported Zebra protocol version: %d' % version) @_FrrZebraMessageBody.register_type(FRR_ZEBRA_REDISTRIBUTE_ADD) @_ZebraMessageBody.register_type(ZEBRA_REDISTRIBUTE_ADD) class ZebraRedistributeAdd(_ZebraRedistribute): """ Message body class for ZEBRA_REDISTRIBUTE_ADD. """ @_FrrZebraMessageBody.register_type(FRR_ZEBRA_REDISTRIBUTE_DELETE) @_ZebraMessageBody.register_type(ZEBRA_REDISTRIBUTE_DELETE) class ZebraRedistributeDelete(_ZebraRedistribute): """ Message body class for ZEBRA_REDISTRIBUTE_DELETE. """ class _ZebraRedistributeDefault(_ZebraMessageBody, metaclass=abc.ABCMeta): """ Base class for ZEBRA_REDISTRIBUTE_DEFAULT_ADD and ZEBRA_REDISTRIBUTE_DEFAULT_DELETE message body. """ @_FrrZebraMessageBody.register_type(FRR_ZEBRA_REDISTRIBUTE_DEFAULT_ADD) @_ZebraMessageBody.register_type(ZEBRA_REDISTRIBUTE_DEFAULT_ADD) class ZebraRedistributeDefaultAdd(_ZebraRedistribute): """ Message body class for ZEBRA_REDISTRIBUTE_DEFAULT_ADD. """ @_FrrZebraMessageBody.register_type(FRR_ZEBRA_REDISTRIBUTE_DEFAULT_DELETE) @_ZebraMessageBody.register_type(ZEBRA_REDISTRIBUTE_DEFAULT_DELETE) class ZebraRedistributeDefaultDelete(_ZebraRedistribute): """ Message body class for ZEBRA_REDISTRIBUTE_DEFAULT_DELETE. """ class _ZebraIPNexthopLookup(_ZebraMessageBody, metaclass=abc.ABCMeta): """ Base class for ZEBRA_IPV4_NEXTHOP_LOOKUP and ZEBRA_IPV6_NEXTHOP_LOOKUP message body. """ # Zebra IPv4/v6 Nexthop Lookup message body: # 0 1 2 3 # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | IPv4/v6 address | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Metric | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Nexthop Num | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Nexthops (Variable) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ _METRIC_FMT = '!I' # metric METRIC_SIZE = struct.calcsize(_METRIC_FMT) # Message type specific constants ADDR_CLS = None # either addrconv.ipv4 or addrconv.ipv6 ADDR_LEN = None # IP address length in bytes def __init__(self, addr, metric=None, nexthops=None): super(_ZebraIPNexthopLookup, self).__init__() assert ip.valid_ipv4(addr) or ip.valid_ipv6(addr) self.addr = addr self.metric = metric nexthops = nexthops or [] for nexthop in nexthops: assert isinstance(nexthop, _NextHop) self.nexthops = nexthops @classmethod def parse(cls, buf, version=_DEFAULT_VERSION): addr = cls.ADDR_CLS.bin_to_text(buf[:cls.ADDR_LEN]) rest = buf[cls.ADDR_LEN:] metric = None if rest: # Note: Case for ZEBRA_IPV4_NEXTHOP_LOOKUP request (metric,) = struct.unpack_from(cls._METRIC_FMT, rest) rest = rest[cls.METRIC_SIZE:] nexthops = None if rest: nexthops, rest = _parse_nexthops(rest, version) return cls(addr, metric, nexthops) def serialize(self, version=_DEFAULT_VERSION): buf = self.ADDR_CLS.text_to_bin(self.addr) if self.metric is None: return buf buf += struct.pack(self._METRIC_FMT, self.metric) return buf + _serialize_nexthops(self.nexthops, version=version) @_ZebraMessageBody.register_type(ZEBRA_IPV4_NEXTHOP_LOOKUP) class ZebraIPv4NexthopLookup(_ZebraIPNexthopLookup): """ Message body class for ZEBRA_IPV4_NEXTHOP_LOOKUP. """ ADDR_CLS = addrconv.ipv4 ADDR_LEN = 4 @_ZebraMessageBody.register_type(ZEBRA_IPV6_NEXTHOP_LOOKUP) class ZebraIPv6NexthopLookup(_ZebraIPNexthopLookup): """ Message body class for ZEBRA_IPV6_NEXTHOP_LOOKUP. """ ADDR_CLS = addrconv.ipv6 ADDR_LEN = 16 class _ZebraIPImportLookup(_ZebraMessageBody, metaclass=abc.ABCMeta): """ Base class for ZEBRA_IPV4_IMPORT_LOOKUP and ZEBRA_IPV6_IMPORT_LOOKUP message body. .. Note:: Zebra IPv4/v6 Import Lookup message have asymmetric structure. If the message sent from Zebra Daemon, set 'from_zebra=True' to create an instance of this class. """ # Zebra IPv4/v6 Import Lookup message body # (Protocol Daemons -> Zebra Daemon): # 0 1 2 3 # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Prefix Len | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | IPv4/v6 Prefix (4 bytes or 16 bytes) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # # Zebra IPv4/v6 Import Lookup message body # (Zebra Daemons -> Protocol Daemon): # 0 1 2 3 # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | IPv4/v6 Prefix (4 bytes or 16 bytes) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Metric | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Nexthop Num | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Nexthops (Variable) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ _PREFIX_LEN_FMT = '!B' # prefix_len PREFIX_LEN_SIZE = struct.calcsize(_PREFIX_LEN_FMT) _METRIC_FMT = '!I' # metric METRIC_SIZE = struct.calcsize(_METRIC_FMT) # Message type specific constants PREFIX_CLS = None # either addrconv.ipv4 or addrconv.ipv6 PREFIX_LEN = None # IP prefix length in bytes def __init__(self, prefix, metric=None, nexthops=None, from_zebra=False): super(_ZebraIPImportLookup, self).__init__() if not from_zebra: assert ip.valid_ipv4(prefix) or ip.valid_ipv6(prefix) else: if isinstance(prefix, (IPv4Prefix, IPv6Prefix)): prefix = prefix.prefix else: assert ip.valid_ipv4(prefix) or ip.valid_ipv6(prefix) self.prefix = prefix self.metric = metric nexthops = nexthops or [] for nexthop in nexthops: assert isinstance(nexthop, _NextHop) self.nexthops = nexthops self.from_zebra = from_zebra @classmethod def parse_impl(cls, buf, version=_DEFAULT_VERSION, from_zebra=False): if not from_zebra: (prefix_len,) = struct.unpack_from(cls._PREFIX_LEN_FMT, buf) rest = buf[cls.PREFIX_LEN_SIZE:] prefix = cls.PREFIX_CLS.bin_to_text(rest[:cls.PREFIX_LEN]) return cls('%s/%d' % (prefix, prefix_len), from_zebra=False) prefix = cls.PREFIX_CLS.bin_to_text(buf[:cls.PREFIX_LEN]) rest = buf[4:] (metric,) = struct.unpack_from(cls._METRIC_FMT, rest) rest = rest[cls.METRIC_SIZE:] nexthops, rest = _parse_nexthops(rest, version) return cls(prefix, metric, nexthops, from_zebra=True) @classmethod def parse(cls, buf, version=_DEFAULT_VERSION): return cls.parse_impl(buf, version=version, from_zebra=False) @classmethod def parse_from_zebra(cls, buf, version=_DEFAULT_VERSION): return cls.parse_impl(buf, version=version, from_zebra=True) def serialize(self, version=_DEFAULT_VERSION): if not self.from_zebra: if ip.valid_ipv4(self.prefix) or ip.valid_ipv6(self.prefix): prefix, prefix_len = self.prefix.split('/') return struct.pack( self._PREFIX_LEN_FMT, int(prefix_len)) + self.PREFIX_CLS.text_to_bin(prefix) else: raise ValueError('Invalid prefix: %s' % self.prefix) if ip.valid_ipv4(self.prefix) or ip.valid_ipv6(self.prefix): buf = self.PREFIX_CLS.text_to_bin(self.prefix) else: raise ValueError('Invalid prefix: %s' % self.prefix) buf += struct.pack(self._METRIC_FMT, self.metric) return buf + _serialize_nexthops(self.nexthops, version=version) @_ZebraMessageBody.register_type(ZEBRA_IPV4_IMPORT_LOOKUP) class ZebraIPv4ImportLookup(_ZebraIPImportLookup): """ Message body class for ZEBRA_IPV4_IMPORT_LOOKUP. """ PREFIX_CLS = addrconv.ipv4 PREFIX_LEN = 4 @_ZebraMessageBody.register_type(ZEBRA_IPV6_IMPORT_LOOKUP) class ZebraIPv6ImportLookup(_ZebraIPImportLookup): """ Message body class for ZEBRA_IPV6_IMPORT_LOOKUP. """ PREFIX_CLS = addrconv.ipv6 PREFIX_LEN = 16 # Note: Not implemented in quagga/zebra/zserv.c # @_ZebraMessageBody.register_type(ZEBRA_INTERFACE_RENAME) # class ZebraInterfaceRename(_ZebraMessageBody): @_FrrZebraMessageBody.register_type(FRR_ZEBRA_ROUTER_ID_ADD) @_ZebraMessageBody.register_type(ZEBRA_ROUTER_ID_ADD) class ZebraRouterIDAdd(_ZebraMessageBody): """ Message body class for ZEBRA_ROUTER_ID_ADD. """ @_FrrZebraMessageBody.register_type(FRR_ZEBRA_ROUTER_ID_DELETE) @_ZebraMessageBody.register_type(ZEBRA_ROUTER_ID_DELETE) class ZebraRouterIDDelete(_ZebraMessageBody): """ Message body class for ZEBRA_ROUTER_ID_DELETE. """ @_FrrZebraMessageBody.register_type(FRR_ZEBRA_ROUTER_ID_UPDATE) @_ZebraMessageBody.register_type(ZEBRA_ROUTER_ID_UPDATE) class ZebraRouterIDUpdate(_ZebraMessageBody): """ Message body class for ZEBRA_ROUTER_ID_UPDATE. """ # Zebra Router ID Update message body: # 0 1 2 3 # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Family | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | IPv4/v6 prefix | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Prefix len | # +-+-+-+-+-+-+-+-+ def __init__(self, family, prefix): super(ZebraRouterIDUpdate, self).__init__() self.family = family if isinstance(prefix, (IPv4Prefix, IPv6Prefix)): prefix = prefix.prefix self.prefix = prefix @classmethod def parse(cls, buf, version=_DEFAULT_VERSION): (family, prefix, _) = _parse_zebra_family_prefix(buf) return cls(family, prefix) def serialize(self, version=_DEFAULT_VERSION): (self.family, # fixup buf) = _serialize_zebra_family_prefix(self.prefix) return buf @_FrrZebraMessageBody.register_type(FRR_ZEBRA_HELLO) @_ZebraMessageBody.register_type(ZEBRA_HELLO) class ZebraHello(_ZebraMessageBody): """ Message body class for ZEBRA_HELLO. """ # Zebra Hello message body: # 0 1 2 3 # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Route Type | (Instance): v4(FRRouting) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ _HEADER_FMT = '!B' # route_type HEADER_SIZE = struct.calcsize(_HEADER_FMT) _V4_HEADER_FMT = '!BH' # route_type, instance V4_HEADER_SIZE = struct.calcsize(_V4_HEADER_FMT) def __init__(self, route_type, instance=None): super(ZebraHello, self).__init__() self.route_type = route_type self.instance = instance @classmethod def parse(cls, buf, version=_DEFAULT_VERSION): instance = None if version <= 3: (route_type,) = struct.unpack_from(cls._HEADER_FMT, buf) elif version == 4: (route_type, instance) = struct.unpack_from(cls._V4_HEADER_FMT, buf) else: raise struct.error( 'Unsupported Zebra protocol version: %d' % version) return cls(route_type, instance) def serialize(self, version=_DEFAULT_VERSION): if version <= 3: return struct.pack(self._HEADER_FMT, self.route_type) elif version == 4: return struct.pack(self._V4_HEADER_FMT, self.route_type, self.instance) else: raise ValueError( 'Unsupported Zebra protocol version: %d' % version) class _ZebraIPNexthopLookupMRib(_ZebraMessageBody, metaclass=abc.ABCMeta): """ Base class for ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB (and ZEBRA_IPV6_NEXTHOP_LOOKUP_MRIB) message body. """ # Zebra IPv4/v6 Nexthop Lookup MRIB message body: # 0 1 2 3 # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | IPv4/v6 address | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Distance | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Metric | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Nexthop Num | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Nexthops (Variable) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ _DISTANCE_METRIC_FMT = '!BI' # distance, metric DISTANCE_METRIC_SIZE = struct.calcsize(_DISTANCE_METRIC_FMT) # Message type specific constants ADDR_CLS = None # either addrconv.ipv4 or addrconv.ipv6 ADDR_LEN = None # IP address length in bytes def __init__(self, addr, distance=None, metric=None, nexthops=None): super(_ZebraIPNexthopLookupMRib, self).__init__() assert ip.valid_ipv4(addr) or ip.valid_ipv6(addr) self.addr = addr self.distance = distance self.metric = metric nexthops = nexthops or [] for nexthop in nexthops: assert isinstance(nexthop, _NextHop) self.nexthops = nexthops @classmethod def parse(cls, buf, version=_DEFAULT_VERSION): addr = cls.ADDR_CLS.bin_to_text(buf[:cls.ADDR_LEN]) rest = buf[cls.ADDR_LEN:] if not rest: return cls(addr) (distance, metric) = struct.unpack_from(cls._DISTANCE_METRIC_FMT, rest) rest = rest[cls.DISTANCE_METRIC_SIZE:] nexthops, rest = _parse_nexthops(rest, version) return cls(addr, distance, metric, nexthops) def serialize(self, version=_DEFAULT_VERSION): buf = self.ADDR_CLS.text_to_bin(self.addr) if self.distance is None or self.metric is None: return buf buf += struct.pack( self._DISTANCE_METRIC_FMT, self.distance, self.metric) return buf + _serialize_nexthops(self.nexthops, version=version) @_FrrZebraMessageBody.register_type(FRR_ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB) @_ZebraMessageBody.register_type(ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB) class ZebraIPv4NexthopLookupMRib(_ZebraIPNexthopLookupMRib): """ Message body class for ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB. """ ADDR_CLS = addrconv.ipv4 ADDR_LEN = 4 @_FrrZebraMessageBody.register_type(FRR_ZEBRA_VRF_UNREGISTER) @_ZebraMessageBody.register_type(ZEBRA_VRF_UNREGISTER) class ZebraVrfUnregister(_ZebraMessageBody): """ Message body class for ZEBRA_VRF_UNREGISTER. """ @_FrrZebraMessageBody.register_type(FRR_ZEBRA_INTERFACE_LINK_PARAMS) @_ZebraMessageBody.register_type(ZEBRA_INTERFACE_LINK_PARAMS) class ZebraInterfaceLinkParams(_ZebraMessageBody): """ Message body class for ZEBRA_INTERFACE_LINK_PARAMS. """ # Zebra Interface Link Parameters message body: # 0 1 2 3 # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Interface Index | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Interface Link Parameters | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ _HEADER_FMT = '!I' # ifindex HEADER_SIZE = struct.calcsize(_HEADER_FMT) # See InterfaceLinkParams class for Interface Link Parameters structure def __init__(self, ifindex, link_params): super(ZebraInterfaceLinkParams, self).__init__() self.ifindex = ifindex assert isinstance(link_params, InterfaceLinkParams) self.link_params = link_params @classmethod def parse(cls, buf, version=_DEFAULT_VERSION): (ifindex,) = struct.unpack_from(cls._HEADER_FMT, buf) rest = buf[cls.HEADER_SIZE:] link_params, rest = InterfaceLinkParams.parse(rest) return cls(ifindex, link_params) def serialize(self, version=_DEFAULT_VERSION): buf = struct.pack(self._HEADER_FMT, self.ifindex) return buf + self.link_params.serialize() class _ZebraNexthopRegister(_ZebraMessageBody): """ Base class for ZEBRA_NEXTHOP_REGISTER and ZEBRA_NEXTHOP_UNREGISTER message body. """ # Zebra Nexthop Register message body: # (Repeat of RegisteredNexthop class) def __init__(self, nexthops): super(_ZebraNexthopRegister, self).__init__() nexthops = nexthops or [] for nexthop in nexthops: assert isinstance(nexthop, RegisteredNexthop) self.nexthops = nexthops @classmethod def parse(cls, buf, version=_DEFAULT_VERSION): nexthops = [] while buf: nexthop, buf = RegisteredNexthop.parse(buf) nexthops.append(nexthop) return cls(nexthops) def serialize(self, version=_DEFAULT_VERSION): buf = b'' for nexthop in self.nexthops: buf += nexthop.serialize() return buf @_FrrZebraMessageBody.register_type(FRR_ZEBRA_NEXTHOP_REGISTER) @_ZebraMessageBody.register_type(ZEBRA_NEXTHOP_REGISTER) class ZebraNexthopRegister(_ZebraNexthopRegister): """ Message body class for ZEBRA_NEXTHOP_REGISTER. """ @_FrrZebraMessageBody.register_type(FRR_ZEBRA_NEXTHOP_UNREGISTER) @_ZebraMessageBody.register_type(ZEBRA_NEXTHOP_UNREGISTER) class ZebraNexthopUnregister(_ZebraNexthopRegister): """ Message body class for ZEBRA_NEXTHOP_UNREGISTER. """ @_FrrZebraMessageBody.register_type(FRR_ZEBRA_NEXTHOP_UPDATE) @_ZebraMessageBody.register_type(ZEBRA_NEXTHOP_UPDATE) class ZebraNexthopUpdate(_ZebraMessageBody): """ Message body class for ZEBRA_NEXTHOP_UPDATE. """ # Zebra IPv4/v6 Nexthop Update message body: # 0 1 2 3 # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Family | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | IPv4/v6 prefix | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | (Distance) | v4(FRRouting v3.0 or later) # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Metric | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Nexthop Num | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Nexthops (Variable) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ _FAMILY_FMT = '!H' # family FAMILY_SIZE = struct.calcsize(_FAMILY_FMT) _DISTANCE_FMT = '!B' # metric DISTANCE_SIZE = struct.calcsize(_DISTANCE_FMT) _METRIC_FMT = '!I' # metric METRIC_SIZE = struct.calcsize(_METRIC_FMT) def __init__(self, family, prefix, distance=None, metric=None, nexthops=None): super(ZebraNexthopUpdate, self).__init__() self.family = family if isinstance(prefix, (IPv4Prefix, IPv6Prefix)): prefix = prefix.prefix self.prefix = prefix if _is_frr_version_ge(_FRR_VERSION_3_0): assert distance is not None self.distance = distance assert metric is not None self.metric = metric nexthops = nexthops or [] for nexthop in nexthops: assert isinstance(nexthop, _NextHop) self.nexthops = nexthops @classmethod def parse(cls, buf, version=_DEFAULT_VERSION): (family,) = struct.unpack_from(cls._FAMILY_FMT, buf) rest = buf[cls.FAMILY_SIZE:] prefix, rest = _parse_ip_prefix(family, rest) distance = None if _is_frr_version_ge(_FRR_VERSION_3_0): (distance,) = struct.unpack_from(cls._DISTANCE_FMT, rest) rest = rest[cls.DISTANCE_SIZE:] (metric,) = struct.unpack_from(cls._METRIC_FMT, rest) rest = rest[cls.METRIC_SIZE:] nexthops, rest = _parse_nexthops(rest, version) return cls(family, prefix, distance, metric, nexthops) def serialize(self, version=_DEFAULT_VERSION): # fixup if ip.valid_ipv4(self.prefix): self.family = socket.AF_INET elif ip.valid_ipv6(self.prefix): self.family = socket.AF_INET6 else: raise ValueError('Invalid prefix: %s' % self.prefix) buf = struct.pack(self._FAMILY_FMT, self.family) buf += _serialize_ip_prefix(self.prefix) if _is_frr_version_ge(_FRR_VERSION_3_0): buf += struct.pack(self._DISTANCE_FMT, self.distance) buf += struct.pack(self._METRIC_FMT, self.metric) return buf + _serialize_nexthops(self.nexthops, version=version) class _ZebraInterfaceNbrAddress(_ZebraMessageBody): """ Base class for FRR_ZEBRA_INTERFACE_NBR_ADDRESS_* message body. """ # Zebra Interface Neighbor Address message body: # 0 1 2 3 # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Interface index | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Family | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | IPv4/v6 prefix | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Prefix len | # +-+-+-+-+-+-+-+-+ _HEADER_FMT = '!I' # ifindex HEADER_SIZE = struct.calcsize(_HEADER_FMT) def __init__(self, ifindex, family, prefix): super(_ZebraInterfaceNbrAddress, self).__init__() self.ifindex = ifindex self.family = family if isinstance(prefix, (IPv4Prefix, IPv6Prefix)): prefix = prefix.prefix self.prefix = prefix @classmethod def parse(cls, buf, version=_DEFAULT_VERSION): (ifindex,) = struct.unpack_from(cls._HEADER_FMT, buf) rest = buf[cls.HEADER_SIZE:] (family, prefix, _) = _parse_zebra_family_prefix(rest) return cls(ifindex, family, prefix) def serialize(self, version=_DEFAULT_VERSION): (self.family, # fixup body_bin) = _serialize_zebra_family_prefix(self.prefix) return struct.pack(self._HEADER_FMT, self.ifindex) + body_bin @_FrrZebraMessageBody.register_type(FRR_ZEBRA_INTERFACE_NBR_ADDRESS_ADD) class ZebraInterfaceNbrAddressAdd(_ZebraInterfaceNbrAddress): """ Message body class for FRR_ZEBRA_INTERFACE_NBR_ADDRESS_ADD. """ @_FrrZebraMessageBody.register_type(FRR_ZEBRA_INTERFACE_NBR_ADDRESS_DELETE) class ZebraInterfaceNbrAddressDelete(_ZebraInterfaceNbrAddress): """ Message body class for FRR_ZEBRA_INTERFACE_NBR_ADDRESS_DELETE. """ @_FrrZebraMessageBody.register_type(FRR_ZEBRA_INTERFACE_BFD_DEST_UPDATE) class ZebraInterfaceBfdDestinationUpdate(_ZebraMessageBody): """ Message body class for FRR_ZEBRA_INTERFACE_BFD_DEST_UPDATE. """ # Zebra Interface BFD Destination Update message body: # 0 1 2 3 # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Interface index | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Dst Family | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Dst IPv4/v6 prefix | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Dst Plen | # +-+-+-+-+-+-+-+-+ # | Status | # +-+-+-+-+-+-+-+-+ # | Src Family | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Source IPv4/v6 prefix | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Src Plen | # +-+-+-+-+-+-+-+-+ _HEADER_FMT = '!I' # ifindex HEADER_SIZE = struct.calcsize(_HEADER_FMT) _STATUS_FMT = '!B' # status STATUS_SIZE = struct.calcsize(_STATUS_FMT) def __init__(self, ifindex, dst_family, dst_prefix, status, src_family, src_prefix): super(ZebraInterfaceBfdDestinationUpdate, self).__init__() self.ifindex = ifindex self.dst_family = dst_family if isinstance(dst_prefix, (IPv4Prefix, IPv6Prefix)): dst_prefix = dst_prefix.prefix self.dst_prefix = dst_prefix self.status = status self.src_family = src_family if isinstance(src_prefix, (IPv4Prefix, IPv6Prefix)): src_prefix = src_prefix.prefix self.src_prefix = src_prefix @classmethod def parse(cls, buf, version=_DEFAULT_VERSION): (ifindex,) = struct.unpack_from(cls._HEADER_FMT, buf) rest = buf[cls.HEADER_SIZE:] (dst_family, dst_prefix, rest) = _parse_zebra_family_prefix(rest) (status,) = struct.unpack_from(cls._STATUS_FMT, rest) rest = rest[cls.STATUS_SIZE:] (src_family, src_prefix, _) = _parse_zebra_family_prefix(rest) return cls(ifindex, dst_family, dst_prefix, status, src_family, src_prefix) def serialize(self, version=_DEFAULT_VERSION): (self.dst_family, # fixup dst_bin) = _serialize_zebra_family_prefix(self.dst_prefix) status_bin = struct.pack( self._STATUS_FMT, self.status) (self.src_family, # fixup src_bin) = _serialize_zebra_family_prefix(self.src_prefix) return struct.pack( self._HEADER_FMT, self.ifindex) + dst_bin + status_bin + src_bin @_FrrZebraMessageBody.register_type(FRR_ZEBRA_IMPORT_ROUTE_REGISTER) class ZebraImportRouteRegister(_ZebraNexthopRegister): """ Message body class for FRR_ZEBRA_IMPORT_ROUTE_REGISTER. """ @_FrrZebraMessageBody.register_type(FRR_ZEBRA_IMPORT_ROUTE_UNREGISTER) class ZebraImportRouteUnregister(_ZebraNexthopRegister): """ Message body class for FRR_ZEBRA_IMPORT_ROUTE_UNREGISTER. """ @_FrrZebraMessageBody.register_type(FRR_ZEBRA_IMPORT_CHECK_UPDATE) class ZebraImportCheckUpdate(ZebraNexthopUpdate): """ Message body class for FRR_ZEBRA_IMPORT_CHECK_UPDATE. """ class _ZebraBfdDestination(_ZebraMessageBody): """ Base class for FRR_ZEBRA_BFD_DEST_REGISTER and FRR_ZEBRA_BFD_DEST_UPDATE message body. """ # Zebra BFD Destination message body: # 0 1 2 3 # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | PID | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Destination Family | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Destination IPv4/v6 prefix (4 bytes or 16 bytes) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Min RX Timer | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Min TX Timer | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Detect Mult | # +-+-+-+-+-+-+-+-+ # | Multi Hop | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Source Family | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Source IPv4/v6 prefix (4 bytes or 16 bytes) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | (MultiHopCnt) | if Multi Hop enabled # +-+-+-+-+-+-+-+-+ # | (IFName Len) | if Multi Hop disabled # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | (Interface Name (Variable)) if Multi Hop disabled | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ _HEADER_FMT = '!I' # pid HEADER_SIZE = struct.calcsize(_HEADER_FMT) _FAMILY_FMT = '!H' FAMILY_SIZE = struct.calcsize(_FAMILY_FMT) _BODY_FMT = '!IIBB' # min_rx_timer, min_tx_timer, detect_mult, multi_hop BODY_SIZE = struct.calcsize(_BODY_FMT) _FOOTER_FMT = '!B' # multi_hop_count or ifname_len FOOTER_SIZE = struct.calcsize(_FOOTER_FMT) def __init__(self, pid, dst_family, dst_prefix, min_rx_timer, min_tx_timer, detect_mult, multi_hop, src_family, src_prefix, multi_hop_count=None, ifname=None): super(_ZebraBfdDestination, self).__init__() self.pid = pid self.dst_family = dst_family assert ip.valid_ipv4(dst_prefix) or ip.valid_ipv6(dst_prefix) self.dst_prefix = dst_prefix self.min_rx_timer = min_rx_timer self.min_tx_timer = min_tx_timer self.detect_mult = detect_mult self.multi_hop = multi_hop self.src_family = src_family assert ip.valid_ipv4(src_prefix) or ip.valid_ipv6(src_prefix) self.src_prefix = src_prefix self.multi_hop_count = multi_hop_count self.ifname = ifname @classmethod def _parse_family_prefix(cls, buf): (family,) = struct.unpack_from(cls._FAMILY_FMT, buf) rest = buf[cls.FAMILY_SIZE:] if socket.AF_INET == family: return family, addrconv.ipv4.bin_to_text(rest[:4]), rest[4:] elif socket.AF_INET6 == family: return family, addrconv.ipv6.bin_to_text(rest[:16]), rest[16:] raise struct.error('Unsupported family: %d' % family) @classmethod def parse(cls, buf, version=_DEFAULT_VERSION): (pid,) = struct.unpack_from(cls._HEADER_FMT, buf) rest = buf[cls.HEADER_SIZE:] (dst_family, dst_prefix, rest) = cls._parse_family_prefix(rest) (min_rx_timer, min_tx_timer, detect_mult, multi_hop) = struct.unpack_from(cls._BODY_FMT, rest) rest = rest[cls.BODY_SIZE:] (src_family, src_prefix, rest) = cls._parse_family_prefix(rest) multi_hop_count = None ifname = None if multi_hop: (multi_hop_count,) = struct.unpack_from(cls._FOOTER_FMT, rest) else: (ifname_len,) = struct.unpack_from(cls._FOOTER_FMT, rest) ifname_bin = rest[cls.FOOTER_SIZE:cls.FOOTER_SIZE + ifname_len] ifname = str(str(ifname_bin.strip(b'\x00'), 'ascii')) return cls(pid, dst_family, dst_prefix, min_rx_timer, min_tx_timer, detect_mult, multi_hop, src_family, src_prefix, multi_hop_count, ifname) def _serialize_family_prefix(self, prefix): if ip.valid_ipv4(prefix): family = socket.AF_INET return (family, struct.pack(self._FAMILY_FMT, family) + addrconv.ipv4.text_to_bin(prefix)) elif ip.valid_ipv6(prefix): family = socket.AF_INET6 return (family, struct.pack(self._FAMILY_FMT, family) + addrconv.ipv6.text_to_bin(prefix)) raise ValueError('Invalid prefix: %s' % prefix) def serialize(self, version=_DEFAULT_VERSION): (self.dst_family, # fixup dst_bin) = self._serialize_family_prefix(self.dst_prefix) body_bin = struct.pack( self._BODY_FMT, self.min_rx_timer, self.min_tx_timer, self.detect_mult, self.multi_hop) (self.src_family, # fixup src_bin) = self._serialize_family_prefix(self.src_prefix) if self.multi_hop: footer_bin = struct.pack( self._FOOTER_FMT, self.multi_hop_count) else: ifname_bin = self.ifname.encode('ascii') footer_bin = struct.pack( self._FOOTER_FMT, len(ifname_bin)) + ifname_bin return struct.pack( self._HEADER_FMT, self.pid) + dst_bin + body_bin + src_bin + footer_bin @_FrrZebraMessageBody.register_type(FRR_ZEBRA_BFD_DEST_REGISTER) class ZebraBfdDestinationRegister(_ZebraBfdDestination): """ Message body class for FRR_ZEBRA_BFD_DEST_REGISTER. """ @_FrrZebraMessageBody.register_type(FRR_ZEBRA_BFD_DEST_DEREGISTER) class ZebraBfdDestinationDeregister(_ZebraMessageBody): """ Message body class for FRR_ZEBRA_BFD_DEST_DEREGISTER. """ # 0 1 2 3 # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | PID | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Family | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Destination IPv4/v6 prefix (4 bytes or 16 bytes) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Multi Hop | # +-+-+-+-+-+-+-+-+ # | Family | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Source IPv4/v6 prefix (4 bytes or 16 bytes) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | (MultiHopCnt) | if Multi Hop enabled # +-+-+-+-+-+-+-+-+ # | (IF Name Len) | if Multi Hop disabled # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | (IF Name (Variable)) if Multi Hop disabled | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ _HEADER_FMT = '!I' # pid HEADER_SIZE = struct.calcsize(_HEADER_FMT) _FAMILY_FMT = '!H' FAMILY_SIZE = struct.calcsize(_FAMILY_FMT) _BODY_FMT = '!B' # multi_hop BODY_SIZE = struct.calcsize(_BODY_FMT) _FOOTER_FMT = '!B' # multi_hop_count or ifname_len FOOTER_SIZE = struct.calcsize(_FOOTER_FMT) def __init__(self, pid, dst_family, dst_prefix, multi_hop, src_family, src_prefix, multi_hop_count=None, ifname=None): super(ZebraBfdDestinationDeregister, self).__init__() self.pid = pid self.dst_family = dst_family assert ip.valid_ipv4(dst_prefix) or ip.valid_ipv6(dst_prefix) self.dst_prefix = dst_prefix self.multi_hop = multi_hop self.src_family = src_family assert ip.valid_ipv4(src_prefix) or ip.valid_ipv6(src_prefix) self.src_prefix = src_prefix self.multi_hop_count = multi_hop_count self.ifname = ifname @classmethod def _parse_family_prefix(cls, buf): (family,) = struct.unpack_from(cls._FAMILY_FMT, buf) rest = buf[cls.FAMILY_SIZE:] if socket.AF_INET == family: return family, addrconv.ipv4.bin_to_text(rest[:4]), rest[4:] elif socket.AF_INET6 == family: return family, addrconv.ipv6.bin_to_text(rest[:16]), rest[16:] raise struct.error('Unsupported family: %d' % family) @classmethod def parse(cls, buf, version=_DEFAULT_VERSION): (pid,) = struct.unpack_from(cls._HEADER_FMT, buf) rest = buf[cls.HEADER_SIZE:] (dst_family, dst_prefix, rest) = cls._parse_family_prefix(rest) (multi_hop,) = struct.unpack_from(cls._BODY_FMT, rest) rest = rest[cls.BODY_SIZE:] (src_family, src_prefix, rest) = cls._parse_family_prefix(rest) multi_hop_count = None ifname = None if multi_hop: (multi_hop_count,) = struct.unpack_from(cls._FOOTER_FMT, rest) else: (ifname_len,) = struct.unpack_from(cls._FOOTER_FMT, rest) ifname_bin = rest[cls.FOOTER_SIZE:cls.FOOTER_SIZE + ifname_len] ifname = str(str(ifname_bin.strip(b'\x00'), 'ascii')) return cls(pid, dst_family, dst_prefix, multi_hop, src_family, src_prefix, multi_hop_count, ifname) def _serialize_family_prefix(self, prefix): if ip.valid_ipv4(prefix): family = socket.AF_INET return (family, struct.pack(self._FAMILY_FMT, family) + addrconv.ipv4.text_to_bin(prefix)) elif ip.valid_ipv6(prefix): family = socket.AF_INET6 return (family, struct.pack(self._FAMILY_FMT, family) + addrconv.ipv6.text_to_bin(prefix)) raise ValueError('Invalid prefix: %s' % prefix) def serialize(self, version=_DEFAULT_VERSION): (self.dst_family, # fixup dst_bin) = self._serialize_family_prefix(self.dst_prefix) body_bin = struct.pack(self._BODY_FMT, self.multi_hop) (self.src_family, # fixup src_bin) = self._serialize_family_prefix(self.src_prefix) if self.multi_hop: footer_bin = struct.pack( self._FOOTER_FMT, self.multi_hop_count) else: ifname_bin = self.ifname.encode('ascii') footer_bin = struct.pack( self._FOOTER_FMT, len(ifname_bin)) + ifname_bin return struct.pack( self._HEADER_FMT, self.pid) + dst_bin + body_bin + src_bin + footer_bin @_FrrZebraMessageBody.register_type(FRR_ZEBRA_BFD_DEST_UPDATE) class ZebraBfdDestinationUpdate(_ZebraBfdDestination): """ Message body class for FRR_ZEBRA_BFD_DEST_UPDATE. """ @_FrrZebraMessageBody.register_type(FRR_ZEBRA_BFD_DEST_REPLAY) class ZebraBfdDestinationReply(_ZebraMessageBody): """ Message body class for FRR_ZEBRA_BFD_DEST_REPLAY. """ class _ZebraRedistributeIPv4(_ZebraIPRoute): """ Base class for FRR_ZEBRA_REDISTRIBUTE_IPV4_* message body. """ _FAMILY = socket.AF_INET @_FrrZebraMessageBody.register_type(FRR_ZEBRA_REDISTRIBUTE_IPV4_ADD) class ZebraRedistributeIPv4Add(_ZebraRedistributeIPv4): """ Message body class for FRR_ZEBRA_IPV4_ROUTE_ADD. """ @_FrrZebraMessageBody.register_type(FRR_ZEBRA_REDISTRIBUTE_IPV4_DEL) class ZebraRedistributeIPv4Delete(_ZebraRedistributeIPv4): """ Message body class for FRR_ZEBRA_IPV4_ROUTE_DELETE. """ class _ZebraRedistributeIPv6(_ZebraIPRoute): """ Base class for FRR_ZEBRA_REDISTRIBUTE_IPV6_* message body. """ _FAMILY = socket.AF_INET6 @_FrrZebraMessageBody.register_type(FRR_ZEBRA_REDISTRIBUTE_IPV6_ADD) class ZebraRedistributeIPv6Add(_ZebraRedistributeIPv6): """ Message body class for FRR_ZEBRA_REDISTRIBUTE_IPV6_ADD. """ @_FrrZebraMessageBody.register_type(FRR_ZEBRA_REDISTRIBUTE_IPV6_DEL) class ZebraRedistributeIPv6Delete(_ZebraRedistributeIPv6): """ Message body class for FRR_ZEBRA_REDISTRIBUTE_IPV6_DEL. """ class _ZebraVrf(_ZebraMessageBody): """ Base class for FRR_ZEBRA_VRF_ADD and FRR_ZEBRA_VRF_DELETE message body. """ # Zebra VRF Add/Delete message body: # 0 1 2 3 # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | VRF Name (VRF_NAMSIZ bytes length) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ _HEADER_FMT = '!%ds' % VRF_NAMSIZ def __init__(self, vrf_name): super(_ZebraVrf, self).__init__() self.vrf_name = vrf_name @classmethod def parse(cls, buf, version=_DEFAULT_FRR_VERSION): vrf_name_bin = buf[:VRF_NAMSIZ] vrf_name = str(str(vrf_name_bin.strip(b'\x00'), 'ascii')) return cls(vrf_name) def serialize(self, version=_DEFAULT_FRR_VERSION): return struct.pack(self._HEADER_FMT, self.vrf_name.encode('ascii')) @_FrrZebraMessageBody.register_type(FRR_ZEBRA_VRF_ADD) class ZebraVrfAdd(_ZebraVrf): """ Message body class for FRR_ZEBRA_VRF_ADD. """ @_FrrZebraMessageBody.register_type(FRR_ZEBRA_VRF_DELETE) class ZebraVrfDelete(_ZebraVrf): """ Message body class for FRR_ZEBRA_VRF_DELETE. """ @_FrrZebraMessageBody.register_type(FRR_ZEBRA_INTERFACE_VRF_UPDATE) class ZebraInterfaceVrfUpdate(_ZebraMessageBody): """ Message body class for FRR_ZEBRA_INTERFACE_VRF_UPDATE. """ # Zebra Interface VRF Update message body: # 0 1 2 3 # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Interface Index | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | VRF ID | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ _HEADER_FMT = '!IH' # ifindex, vrf_id def __init__(self, ifindex, vrf_id): super(ZebraInterfaceVrfUpdate, self).__init__() self.ifindex = ifindex self.vrf_id = vrf_id @classmethod def parse(cls, buf, version=_DEFAULT_FRR_VERSION): (ifindex, vrf_id) = struct.unpack_from(cls._HEADER_FMT, buf) return cls(ifindex, vrf_id) def serialize(self, version=_DEFAULT_FRR_VERSION): return struct.pack(self._HEADER_FMT, self.ifindex, self.vrf_id) class _ZebraBfdClient(_ZebraMessageBody): """ Base class for FRR_ZEBRA_BFD_CLIENT_*. """ # Zebra BFD Client message body: # 0 1 2 3 # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | PID | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ _HEADER_FMT = '!I' # pid HEADER_SIZE = struct.calcsize(_HEADER_FMT) def __init__(self, pid): super(_ZebraBfdClient, self).__init__() self.pid = pid @classmethod def parse(cls, buf, version=_DEFAULT_FRR_VERSION): (pid,) = struct.unpack_from(cls._HEADER_FMT, buf) return cls(pid) def serialize(self, version=_DEFAULT_FRR_VERSION): return struct.pack(self._HEADER_FMT, self.pid) @_FrrZebraMessageBody.register_type(FRR_ZEBRA_BFD_CLIENT_REGISTER) class ZebraBfdClientRegister(_ZebraBfdClient): """ Message body class for FRR_ZEBRA_BFD_CLIENT_REGISTER. """ class _ZebraInterfaceRadv(_ZebraMessageBody): """ Base class for FRR_ZEBRA_INTERFACE_*_RADV message body. """ # Zebra interface Router Advertisement message body: # 0 1 2 3 # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Interface Index | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | RA Interval | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ _HEADER_FMT = '!II' # ifindex, interval HEADER_SIZE = struct.calcsize(_HEADER_FMT) def __init__(self, ifindex, interval): super(_ZebraInterfaceRadv, self).__init__() self.ifindex = ifindex self.interval = interval @classmethod def parse(cls, buf, version=_DEFAULT_FRR_VERSION): (ifindex, interval,) = struct.unpack_from(cls._HEADER_FMT, buf) return cls(ifindex, interval) def serialize(self, version=_DEFAULT_FRR_VERSION): return struct.pack(self._HEADER_FMT, self.ifindex, self.interval) @_FrrZebraMessageBody.register_type(FRR_ZEBRA_INTERFACE_ENABLE_RADV) class ZebraInterfaceEnableRadv(_ZebraInterfaceRadv): """ Message body class for FRR_ZEBRA_INTERFACE_ENABLE_RADV. """ @_FrrZebraMessageBody.register_type(FRR_ZEBRA_INTERFACE_DISABLE_RADV) class ZebraInterfaceDisableRadv(_ZebraInterfaceRadv): """ Message body class for FRR_ZEBRA_INTERFACE_DISABLE_RADV. """ class _ZebraMplsLabels(_ZebraMessageBody): """ Base class for ZEBRA_MPLS_LABELS_* message body. """ # Zebra MPLS Labels message body: # 0 1 2 3 # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Route Type | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Family | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | IPv4/v6 Prefix (4 bytes/16 bytes) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Prefix Len | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Gate IPv4/v6 Address (4 bytes/16 bytes) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Interface Index: v4(FRRouting v3.0 or later) | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Distance | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | In Label | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ # | Out Label | # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ _HEADER_FMT = '!B' # route_type HEADER_SIZE = struct.calcsize(_HEADER_FMT) _FAMILY_FMT = '!I' FAMILY_SIZE = struct.calcsize(_FAMILY_FMT) _IPV4_PREFIX_FMT = '!4sB' # prefix, prefix_len _IPV6_PREFIX_FMT = '!16sB' IPV4_PREFIX_SIZE = struct.calcsize(_IPV4_PREFIX_FMT) IPV6_PREFIX_SIZE = struct.calcsize(_IPV6_PREFIX_FMT) _FAMILY_IPV4_PREFIX_FMT = '!I4sB' _FAMILY_IPV6_PREFIX_FMT = '!I16sB' _IFINDEX_FMT = '!I' IFINDEX_SIZE = struct.calcsize(_IFINDEX_FMT) _BODY_FMT = '!BII' # distance, in_label, out_label def __init__(self, route_type, family, prefix, gate_addr, ifindex=None, distance=None, in_label=None, out_label=None): super(_ZebraMplsLabels, self).__init__() self.route_type = route_type self.family = family if isinstance(prefix, (IPv4Prefix, IPv6Prefix)): prefix = prefix.prefix self.prefix = prefix assert ip.valid_ipv4(gate_addr) or ip.valid_ipv6(gate_addr) self.gate_addr = gate_addr if _is_frr_version_ge(_FRR_VERSION_3_0): assert ifindex is not None self.ifindex = ifindex assert distance is not None self.distance = distance assert in_label is not None self.in_label = in_label assert out_label is not None self.out_label = out_label @classmethod def _parse_family_prefix(cls, buf): (family,) = struct.unpack_from(cls._FAMILY_FMT, buf) rest = buf[cls.FAMILY_SIZE:] if socket.AF_INET == family: (prefix, p_len) = struct.unpack_from(cls._IPV4_PREFIX_FMT, rest) prefix = '%s/%d' % (addrconv.ipv4.bin_to_text(prefix), p_len) rest = rest[cls.IPV4_PREFIX_SIZE:] elif socket.AF_INET6 == family: (prefix, p_len) = struct.unpack_from(cls._IPV6_PREFIX_FMT, rest) prefix = '%s/%d' % (addrconv.ipv6.bin_to_text(prefix), p_len) rest = rest[cls.IPV6_PREFIX_SIZE:] else: raise struct.error('Unsupported family: %d' % family) return family, prefix, rest @classmethod def parse(cls, buf, version=_DEFAULT_FRR_VERSION): (route_type,) = struct.unpack_from(cls._HEADER_FMT, buf) rest = buf[cls.HEADER_SIZE:] (family, prefix, rest) = cls._parse_family_prefix(rest) if family == socket.AF_INET: gate_addr = addrconv.ipv4.bin_to_text(rest[:4]) rest = rest[4:] elif family == socket.AF_INET6: gate_addr = addrconv.ipv6.bin_to_text(rest[:16]) rest = rest[16:] else: raise struct.error('Unsupported family: %d' % family) ifindex = None if _is_frr_version_ge(_FRR_VERSION_3_0): (ifindex,) = struct.unpack_from(cls._IFINDEX_FMT, rest) rest = rest[cls.IFINDEX_SIZE:] (distance, in_label, out_label) = struct.unpack_from(cls._BODY_FMT, rest) return cls(route_type, family, prefix, gate_addr, ifindex, distance, in_label, out_label) def _serialize_family_prefix(self, prefix): if ip.valid_ipv4(prefix): family = socket.AF_INET # fixup prefix_addr, prefix_num = prefix.split('/') return family, struct.pack( self._FAMILY_IPV4_PREFIX_FMT, family, addrconv.ipv4.text_to_bin(prefix_addr), int(prefix_num)) elif ip.valid_ipv6(prefix): family = socket.AF_INET6 # fixup prefix_addr, prefix_num = prefix.split('/') return family, struct.pack( self._FAMILY_IPV6_PREFIX_FMT, family, addrconv.ipv6.text_to_bin(prefix_addr), int(prefix_num)) raise ValueError('Invalid prefix: %s' % prefix) def serialize(self, version=_DEFAULT_FRR_VERSION): (self.family, # fixup prefix_bin) = self._serialize_family_prefix(self.prefix) if self.family == socket.AF_INET: gate_addr_bin = addrconv.ipv4.text_to_bin(self.gate_addr) elif self.family == socket.AF_INET6: gate_addr_bin = addrconv.ipv6.text_to_bin(self.gate_addr) else: raise ValueError('Unsupported family: %d' % self.family) body_bin = b'' if _is_frr_version_ge(_FRR_VERSION_3_0): body_bin = struct.pack(self._IFINDEX_FMT, self.ifindex) body_bin += struct.pack( self._BODY_FMT, self.distance, self.in_label, self.out_label) return struct.pack( self._HEADER_FMT, self.route_type) + prefix_bin + gate_addr_bin + body_bin @_FrrZebraMessageBody.register_type(FRR_ZEBRA_MPLS_LABELS_ADD) class ZebraMplsLabelsAdd(_ZebraMplsLabels): """ Message body class for FRR_ZEBRA_MPLS_LABELS_ADD. """ @_FrrZebraMessageBody.register_type(FRR_ZEBRA_MPLS_LABELS_DELETE) class ZebraMplsLabelsDelete(_ZebraMplsLabels): """ Message body class for FRR_ZEBRA_MPLS_LABELS_DELETE. """ class _ZebraIPv4Nexthop(_ZebraIPRoute): """ Base class for FRR_ZEBRA_IPV4_NEXTHOP_* message body. """ _FAMILY = socket.AF_INET @_FrrZebraMessageBody.register_type(FRR_ZEBRA_IPV4_NEXTHOP_ADD) class ZebraIPv4NexthopAdd(_ZebraIPv4Nexthop): """ Message body class for FRR_ZEBRA_IPV4_NEXTHOP_ADD. """ @_FrrZebraMessageBody.register_type(FRR_ZEBRA_IPV4_NEXTHOP_DELETE) class ZebraIPv4NexthopDelete(_ZebraIPv4Nexthop): """ Message body class for FRR_ZEBRA_IPV4_NEXTHOP_DELETE. """ class _ZebraIPv6Nexthop(_ZebraIPRoute): """ Base class for FRR_ZEBRA_IPV6_NEXTHOP_* message body. """ _FAMILY = socket.AF_INET6 @_FrrZebraMessageBody.register_type(FRR_ZEBRA_IPV6_NEXTHOP_ADD) class ZebraIPv6NexthopAdd(_ZebraIPv6Nexthop): """ Message body class for FRR_ZEBRA_IPV6_NEXTHOP_ADD. """ @_FrrZebraMessageBody.register_type(FRR_ZEBRA_IPV6_NEXTHOP_DELETE) class ZebraIPv6NexthopDelete(_ZebraIPv6Nexthop): """ Message body class for FRR_ZEBRA_IPV6_NEXTHOP_DELETE. """ ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/pcaplib.py0000664000175000017500000002642700000000000017034 0ustar00zuulzuul00000000000000# Copyright (C) 2015 Nippon Telegraph and Telephone 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. """ Parsing libpcap and reading/writing PCAP file. Reference source: http://wiki.wireshark.org/Development/LibpcapFileFormat Libpcap File Format +---------------------+ | | | Global Header | | | +---------------------+ | Packet Header | +---------------------+ | Packet Data | +---------------------+ | Packet Header | +---------------------+ | Packet Data | +---------------------+ | ... | +---------------------+ """ import struct import sys import time class PcapFileHdr(object): """ Global Header typedef struct pcap_hdr_s { guint32 magic_number; /* magic number */ guint16 version_major; /* major version number */ guint16 version_minor; /* minor version number */ gint32 thiszone; /* GMT to local correction */ guint32 sigfigs; /* accuracy of timestamps */ guint32 snaplen; /* max length of captured packets, in octets */ guint32 network; /* data link type */ } pcap_hdr_t; 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Magic Number | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Version Major | Version Minor | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Thiszone | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Sigfigs | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Snaplen | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Network | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ File Format """ _FILE_HDR_FMT = '4sHHIIII' _FILE_HDR_FMT_BIG_ENDIAN = '>' + _FILE_HDR_FMT _FILE_HDR_FMT_LITTLE_ENDIAN = '<' + _FILE_HDR_FMT FILE_HDR_SIZE = struct.calcsize(_FILE_HDR_FMT) # Magic Number field is used to detect the file format itself and # the byte ordering. MAGIC_NUMBER_IDENTICAL = b'\xa1\xb2\xc3\xd4' # Big Endian MAGIC_NUMBER_SWAPPED = b'\xd4\xc3\xb2\xa1' # Little Endian def __init__(self, magic=MAGIC_NUMBER_SWAPPED, version_major=2, version_minor=4, thiszone=0, sigfigs=0, snaplen=0, network=0): self.magic = magic self.version_major = version_major self.version_minor = version_minor self.thiszone = thiszone self.sigfigs = sigfigs self.snaplen = snaplen self.network = network @classmethod def parser(cls, buf): magic_buf = buf[:4] if magic_buf == cls.MAGIC_NUMBER_IDENTICAL: # Big Endian fmt = cls._FILE_HDR_FMT_BIG_ENDIAN byteorder = 'big' elif magic_buf == cls.MAGIC_NUMBER_SWAPPED: # Little Endian fmt = cls._FILE_HDR_FMT_LITTLE_ENDIAN byteorder = 'little' else: raise struct.error('Invalid byte ordered pcap file.') return cls(*struct.unpack_from(fmt, buf)), byteorder def serialize(self): if sys.byteorder == 'big': # Big Endian fmt = self._FILE_HDR_FMT_BIG_ENDIAN self.magic = self.MAGIC_NUMBER_IDENTICAL else: # Little Endian fmt = self._FILE_HDR_FMT_LITTLE_ENDIAN self.magic = self.MAGIC_NUMBER_SWAPPED return struct.pack(fmt, self.magic, self.version_major, self.version_minor, self.thiszone, self.sigfigs, self.snaplen, self.network) class PcapPktHdr(object): """ Record (Packet) Header typedef struct pcaprec_hdr_s { guint32 ts_sec; /* timestamp seconds */ guint32 ts_usec; /* timestamp microseconds */ guint32 incl_len; /* number of octets of packet saved in file */ guint32 orig_len; /* actual length of packet */ } pcaprec_hdr_t; 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Timestamp Seconds | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Timestamp Microseconds | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Number of octets of saved in file | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Actual length of packet | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Record (Packet) Header Format """ _PKT_HDR_FMT = 'IIII' _PKT_HDR_FMT_BIG_ENDIAN = '>' + _PKT_HDR_FMT _PKT_HDR_FMT_LITTLE_ENDIAN = '<' + _PKT_HDR_FMT PKT_HDR_SIZE = struct.calcsize(_PKT_HDR_FMT) def __init__(self, ts_sec=0, ts_usec=0, incl_len=0, orig_len=0): self.ts_sec = ts_sec self.ts_usec = ts_usec self.incl_len = incl_len self.orig_len = orig_len @classmethod def parser(cls, buf, byteorder='little'): if not buf: raise IndexError('No data') if byteorder == 'big': # Big Endian fmt = cls._PKT_HDR_FMT_BIG_ENDIAN else: # Little Endian fmt = cls._PKT_HDR_FMT_LITTLE_ENDIAN (ts_sec, ts_usec, incl_len, orig_len) = struct.unpack_from(fmt, buf) hdr = cls(ts_sec, ts_usec, incl_len, orig_len) return hdr, buf[cls.PKT_HDR_SIZE:cls.PKT_HDR_SIZE + incl_len] def serialize(self): if sys.byteorder == 'big': # Big Endian fmt = self._PKT_HDR_FMT_BIG_ENDIAN else: # Little Endian fmt = self._PKT_HDR_FMT_LITTLE_ENDIAN return struct.pack(fmt, self.ts_sec, self.ts_usec, self.incl_len, self.orig_len) class Reader(object): """ PCAP file reader ================ =================================== Argument Description ================ =================================== file_obj File object which reading PCAP file in binary mode ================ =================================== Example of usage:: from os_ken.lib import pcaplib from os_ken.lib.packet import packet frame_count = 0 # iterate pcaplib.Reader that yields (timestamp, packet_data) # in the PCAP file for ts, buf in pcaplib.Reader(open('test.pcap', 'rb')): frame_count += 1 pkt = packet.Packet(buf) print("%d, %f, %s" % (frame_count, ts, pkt)) """ def __init__(self, file_obj): self._fp = file_obj buf = self._fp.read(PcapFileHdr.FILE_HDR_SIZE) # Read only pcap file header self.pcap_header, self._file_byteorder = PcapFileHdr.parser(buf) # Read pcap data with out header self._pcap_body = self._fp.read() self._fp.close() self._next_pos = 0 def __iter__(self): return self def next(self): try: pkt_hdr, pkt_data = PcapPktHdr.parser( self._pcap_body[self._next_pos:], self._file_byteorder) self._next_pos += pkt_hdr.incl_len + PcapPktHdr.PKT_HDR_SIZE except IndexError: raise StopIteration() return pkt_hdr.ts_sec + (pkt_hdr.ts_usec / 1e6), pkt_data # for Python 3 compatible __next__ = next class Writer(object): """ PCAP file writer ========== ================================================== Argument Description ========== ================================================== file_obj File object which writing PCAP file in binary mode snaplen Max length of captured packets (in octets) network Data link type. (e.g. 1 for Ethernet, see `tcpdump.org`_ for details) ========== ================================================== .. _tcpdump.org: http://www.tcpdump.org/linktypes.html Example of usage:: ... from os_ken.lib import pcaplib class SimpleSwitch13(app_manager.OSKenApp): OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION] def __init__(self, *args, **kwargs): super(SimpleSwitch13, self).__init__(*args, **kwargs) self.mac_to_port = {} # Create pcaplib.Writer instance with a file object # for the PCAP file self.pcap_writer = pcaplib.Writer(open('mypcap.pcap', 'wb')) ... @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER) def _packet_in_handler(self, ev): # Dump the packet data into PCAP file self.pcap_writer.write_pkt(ev.msg.data) ... """ def __init__(self, file_obj, snaplen=65535, network=1): self._f = file_obj self.snaplen = snaplen self.network = network self._write_pcap_file_hdr() def _write_pcap_file_hdr(self): pcap_file_hdr = PcapFileHdr(snaplen=self.snaplen, network=self.network) self._f.write(pcap_file_hdr.serialize()) def _write_pkt_hdr(self, ts, buf_len): sec = int(ts) usec = int(round(ts % 1, 6) * 1e6) if sec != 0 else 0 pc_pkt_hdr = PcapPktHdr(ts_sec=sec, ts_usec=usec, incl_len=buf_len, orig_len=buf_len) self._f.write(pc_pkt_hdr.serialize()) def write_pkt(self, buf, ts=None): ts = time.time() if ts is None else ts # Check the max length of captured packets buf_len = len(buf) if buf_len > self.snaplen: buf_len = self.snaplen buf = buf[:self.snaplen] self._write_pkt_hdr(ts, buf_len) self._f.write(buf) def __del__(self): self._f.close() ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/port_no.py0000664000175000017500000000175200000000000017074 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone 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. # Internal representation of port_no id is int(32bit) # string representation is in hex without '0x' _PORT_NO_LEN = 8 _PORT_NO_FMT = '%0{0}x'.format(_PORT_NO_LEN) PORT_NO_PATTERN = r'[0-9a-f]{%d}' % _PORT_NO_LEN def port_no_to_str(port_no): return _PORT_NO_FMT % port_no def str_to_port_no(port_no_str): assert len(port_no_str) == _PORT_NO_LEN return int(port_no_str, 16) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/rpc.py0000664000175000017500000002365500000000000016206 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013 YAMAMOTO Takashi # # 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. # Specification: # - msgpack # https://github.com/msgpack/msgpack/blob/master/spec.md # - msgpack-rpc # https://github.com/msgpack-rpc/msgpack-rpc/blob/master/spec.md from collections import deque import select import msgpack class MessageType(object): REQUEST = 0 RESPONSE = 1 NOTIFY = 2 class MessageEncoder(object): """msgpack-rpc encoder/decoder. intended to be transport-agnostic. """ def __init__(self): super(MessageEncoder, self).__init__() # NOTE(ralonsoh): msgpack>=1.0.0 self._packer = msgpack.Packer() # The strict_map_key=False option is required to use int keys in # maps; it is disabled by default to prevent hash collision denial # of service attacks (hashdos) in scenarios where an attacker can # control the keys to be hashed. self._unpacker = msgpack.Unpacker(strict_map_key=False) self._next_msgid = 0 def _create_msgid(self): this_id = self._next_msgid self._next_msgid = (self._next_msgid + 1) % 0xffffffff return this_id def create_request(self, method, params): assert isinstance(method, (str, bytes)) assert isinstance(params, list) msgid = self._create_msgid() return (self._packer.pack( [MessageType.REQUEST, msgid, method, params]), msgid) def create_response(self, msgid, error=None, result=None): assert isinstance(msgid, int) assert 0 <= msgid <= 0xffffffff assert error is None or result is None return self._packer.pack([MessageType.RESPONSE, msgid, error, result]) def create_notification(self, method, params): assert isinstance(method, (str, bytes)) assert isinstance(params, list) return self._packer.pack([MessageType.NOTIFY, method, params]) def get_and_dispatch_messages(self, data, disp_table): """dissect messages from a raw stream data. disp_table[type] should be a callable for the corresponding MessageType. """ self._unpacker.feed(data) for m in self._unpacker: self._dispatch_message(m, disp_table) @staticmethod def _dispatch_message(m, disp_table): # XXX validation t = m[0] try: f = disp_table[t] except KeyError: # ignore messages with unknown type return f(m[1:]) class EndPoint(object): """An endpoint *sock* is a socket-like. it can be either blocking or non-blocking. """ def __init__(self, sock, encoder=None, disp_table=None): if encoder is None: encoder = MessageEncoder() self._encoder = encoder self._sock = sock if disp_table is None: self._table = { MessageType.REQUEST: self._enqueue_incoming_request, MessageType.RESPONSE: self._enqueue_incoming_response, MessageType.NOTIFY: self._enqueue_incoming_notification } else: self._table = disp_table self._send_buffer = bytearray() # msgids for which we sent a request but have not received a response self._pending_requests = set() # queues for incoming messages self._requests = deque() self._notifications = deque() self._responses = {} self._incoming = 0 # number of incoming messages in our queues self._closed_by_peer = False def selectable(self): rlist = [self._sock] wlist = [] if self._send_buffer: wlist.append(self._sock) return rlist, wlist def process_outgoing(self): try: sent_bytes = self._sock.send(self._send_buffer) except IOError: sent_bytes = 0 del self._send_buffer[:sent_bytes] def process_incoming(self): self.receive_messages(all=True) def process(self): self.process_outgoing() self.process_incoming() def block(self): rlist, wlist = self.selectable() select.select(rlist, wlist, rlist + wlist) def serve(self): while not self._closed_by_peer: self.block() self.process() def _send_message(self, msg): self._send_buffer += msg self.process_outgoing() def send_request(self, method, params): """Send a request """ msg, msgid = self._encoder.create_request(method, params) self._send_message(msg) self._pending_requests.add(msgid) return msgid def send_response(self, msgid, error=None, result=None): """Send a response """ msg = self._encoder.create_response(msgid, error, result) self._send_message(msg) def send_notification(self, method, params): """Send a notification """ msg = self._encoder.create_notification(method, params) self._send_message(msg) def receive_messages(self, all=False): """Try to receive some messages. Received messages are put on the internal queues. They can be retrieved using get_xxx() methods. Returns True if there's something queued for get_xxx() methods. """ while all or self._incoming == 0: try: packet = self._sock.recv(4096) # XXX the size is arbitrary except IOError: packet = None if not packet: if packet is not None: # socket closed by peer self._closed_by_peer = True break self._encoder.get_and_dispatch_messages(packet, self._table) return self._incoming > 0 def _enqueue_incoming_request(self, m): self._requests.append(m) self._incoming += 1 def _enqueue_incoming_response(self, m): msgid, error, result = m try: self._pending_requests.remove(msgid) except KeyError: # bogus msgid # XXXwarn return assert msgid not in self._responses self._responses[msgid] = (error, result) self._incoming += 1 def _enqueue_incoming_notification(self, m): self._notifications.append(m) self._incoming += 1 def _get_message(self, q): try: m = q.popleft() assert self._incoming > 0 self._incoming -= 1 return m except IndexError: return None def get_request(self): return self._get_message(self._requests) def get_response(self, msgid): try: m = self._responses.pop(msgid) assert self._incoming > 0 self._incoming -= 1 except KeyError: return None error, result = m return result, error def get_notification(self): return self._get_message(self._notifications) class RPCError(Exception): """an error from server """ def __init__(self, error): super(RPCError, self).__init__() self._error = error def get_value(self): return self._error def __str__(self): return str(self._error) class Client(object): """a convenient class for a pure rpc client *sock* is a socket-like. it should be blocking. """ def __init__(self, sock, encoder=None, notification_callback=None): self._endpoint = EndPoint(sock, encoder) if notification_callback is None: # ignore notifications by default self._notification_callback = lambda n: None else: self._notification_callback = notification_callback def _process_input_notification(self): n = self._endpoint.get_notification() if n: self._notification_callback(n) def _process_input_request(self): # ignore requests as we are a pure client # XXXwarn self._endpoint.get_request() def call(self, method, params): """synchronous call. send a request and wait for a response. return a result. or raise RPCError exception if the peer sends us an error. """ msgid = self._endpoint.send_request(method, params) while True: if not self._endpoint.receive_messages(): raise EOFError("EOF") res = self._endpoint.get_response(msgid) if res: result, error = res if error is None: return result raise RPCError(error) self._process_input_notification() self._process_input_request() def send_notification(self, method, params): """send a notification to the peer. """ self._endpoint.send_notification(method, params) def receive_notification(self): """wait for the next incoming message. intended to be used when we have nothing to send but want to receive notifications. """ if not self._endpoint.receive_messages(): raise EOFError("EOF") self._process_input_notification() self._process_input_request() def peek_notification(self): while True: rlist, _wlist = self._endpoint.selectable() rlist, _wlist, _xlist = select.select(rlist, [], [], 0) if not rlist: break self.receive_notification() ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/snortlib.py0000664000175000017500000000725200000000000017251 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone 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. import os import logging from os_ken.lib import hub, alert from os_ken.base import app_manager from os_ken.controller import event BUFSIZE = alert.AlertPkt._ALERTPKT_SIZE SOCKFILE = "/tmp/snort_alert" class EventAlert(event.EventBase): def __init__(self, msg): super(EventAlert, self).__init__() self.msg = msg class SnortLib(app_manager.OSKenApp): def __init__(self): super(SnortLib, self).__init__() self.name = 'snortlib' self.config = {'unixsock': True} self._set_logger() self.sock = None self.nwsock = None def set_config(self, config): assert isinstance(config, dict) self.config = config def start_socket_server(self): if not self.config.get('unixsock'): if self.config.get('port') is None: self.config['port'] = 51234 self._start_recv_nw_sock(self.config.get('port')) else: self._start_recv() self.logger.info(self.config) def _recv_loop(self): self.logger.info("Unix socket start listening...") while True: data = self.sock.recv(BUFSIZE) msg = alert.AlertPkt.parser(data) if msg: self.send_event_to_observers(EventAlert(msg)) def _start_recv(self): if os.path.exists(SOCKFILE): os.unlink(SOCKFILE) self.sock = hub.socket.socket(hub.socket.AF_UNIX, hub.socket.SOCK_DGRAM) self.sock.bind(SOCKFILE) hub.spawn(self._recv_loop) def _start_recv_nw_sock(self, port): self.nwsock = hub.socket.socket(hub.socket.AF_INET, hub.socket.SOCK_STREAM) self.nwsock.setsockopt(hub.socket.SOL_SOCKET, hub.socket.SO_REUSEADDR, 1) self.nwsock.bind(('0.0.0.0', port)) self.nwsock.listen(5) hub.spawn(self._accept_loop_nw_sock) def _accept_loop_nw_sock(self): self.logger.info("Network socket server start listening...") while True: conn, addr = self.nwsock.accept() self.logger.info("Connected with %s", addr[0]) hub.spawn(self._recv_loop_nw_sock, conn, addr) def _recv_loop_nw_sock(self, conn, addr): buf = bytes() while True: ret = conn.recv(BUFSIZE) if len(ret) == 0: self.logger.info("Disconnected from %s", addr[0]) break buf += ret while len(buf) >= BUFSIZE: # self.logger.debug("Received buffer size: %d", len(buf)) data = buf[:BUFSIZE] msg = alert.AlertPkt.parser(data) if msg: self.send_event_to_observers(EventAlert(msg)) buf = buf[BUFSIZE:] def _set_logger(self): """change log format.""" self.logger.propagate = False hdl = logging.StreamHandler() fmt_str = '[snort][%(levelname)s] %(message)s' hdl.setFormatter(logging.Formatter(fmt_str)) self.logger.addHandler(hdl) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/sockaddr.py0000664000175000017500000000352300000000000017204 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2014 YAMAMOTO Takashi # # 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. import platform import socket import struct from os_ken.lib import addrconv system = platform.system() if system == 'Linux': # on linux, # no ss_len # u16 ss_family _HDR_FMT = "H" _HAVE_SS_LEN = False else: # assume # u8 ss_len # u8 ss_family _HDR_FMT = "BB" _HAVE_SS_LEN = True # RFC 2553 _SS_MAXSIZE = 128 _SS_ALIGNSIZE = 8 _SIN_SIZE = 16 # sizeof(struct sockaddr_in) _HDR_LEN = struct.calcsize(_HDR_FMT) def _hdr(ss_len, af): if _HAVE_SS_LEN: return struct.pack(_HDR_FMT, ss_len, af) else: return struct.pack(_HDR_FMT, af) def _pad_to(data, total_len): pad_len = total_len - len(data) return data + pad_len * b'\0' def sa_in4(addr, port=0): data = struct.pack("!H4s", port, addrconv.ipv4.text_to_bin(addr)) hdr = _hdr(_SIN_SIZE, socket.AF_INET) return _pad_to(hdr + data, _SIN_SIZE) def sa_in6(addr, port=0, flowinfo=0, scope_id=0): data = struct.pack("!HI16sI", port, flowinfo, addrconv.ipv6.text_to_bin(addr), scope_id) hdr = _hdr(_HDR_LEN + len(data), socket.AF_INET6) return hdr + data def sa_to_ss(sa): return _pad_to(sa, _SS_MAXSIZE) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/sockopt.py0000664000175000017500000000417500000000000017100 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2014 YAMAMOTO Takashi # # 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. import platform import socket import struct from os_ken.lib import sockaddr TCP_MD5SIG_LINUX = 0x0e TCP_MD5SIG_BSD = 0x10 def _set_tcp_md5sig_linux(s, addr, key): # struct tcp_md5sig { # struct sockaddr_storage addr; # u16 pad1; # u16 keylen; # u32 pad2; # u8 key[80]; # } af = s.family if af == socket.AF_INET: sa = sockaddr.sa_in4(addr) elif af == socket.AF_INET6: sa = sockaddr.sa_in6(addr) else: raise ValueError("unsupported af %s" % (af,)) ss = sockaddr.sa_to_ss(sa) tcp_md5sig = ss + struct.pack("2xH4x80s", len(key), key) s.setsockopt(socket.IPPROTO_TCP, TCP_MD5SIG_LINUX, tcp_md5sig) def _set_tcp_md5sig_bsd(s, _addr, _key): # NOTE: On this platform, address and key need to be set using setkey(8). tcp_md5sig = struct.pack("I", 1) s.setsockopt(socket.IPPROTO_TCP, TCP_MD5SIG_BSD, tcp_md5sig) def set_tcp_md5sig(s, addr, key): """Enable TCP-MD5 on the given socket. :param s: Socket :param addr: Associated address. On some platforms, this has no effect. :param key: Key. On some platforms, this has no effect. """ impls = { 'FreeBSD': _set_tcp_md5sig_bsd, 'Linux': _set_tcp_md5sig_linux, 'NetBSD': _set_tcp_md5sig_bsd, } system = platform.system() try: impl = impls[system] except KeyError: raise NotImplementedError("TCP-MD5 unsupported on this platform") impl(s, addr, key) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/stplib.py0000664000175000017500000013501300000000000016707 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone 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. import datetime import logging from os_ken.base import app_manager from os_ken.controller import event from os_ken.controller import handler from os_ken.controller import ofp_event from os_ken.controller.handler import set_ev_cls from os_ken.exception import OSKenException from os_ken.exception import OFPUnknownVersion from os_ken.lib import hub from os_ken.lib import mac from os_ken.lib.dpid import dpid_to_str from os_ken.lib.packet import bpdu from os_ken.lib.packet import ethernet from os_ken.lib.packet import llc from os_ken.lib.packet import packet from os_ken.ofproto import ofproto_v1_0 from os_ken.ofproto import ofproto_v1_2 from os_ken.ofproto import ofproto_v1_3 MAX_PORT_NO = 0xfff # for OpenFlow 1.2/1.3 BPDU_PKT_IN_PRIORITY = 0xffff NO_PKT_IN_PRIORITY = 0xfffe # Result of compared config BPDU priority. SUPERIOR = -1 REPEATED = 0 INFERIOR = 1 # Port role DESIGNATED_PORT = 0 # The port which sends BPDU. ROOT_PORT = 1 # The port which receives BPDU from a root bridge. NON_DESIGNATED_PORT = 2 # The port which blocked. """ How to decide the port roles. Root bridge: a bridge has smallest bridge ID is chosen as a root. it sends original config BPDU. Non Root bridge: forwards config BPDU received from the root bridge. +-----------------------+ | Root bridge | +-----------------------+ (D) (D) | | | | (R) (R) +-----------------+ +-----------------+ | Non Root bridge |(D)---(ND)| Non Root bridge | +-----------------+ +-----------------+ ROOT_PORT(R): the nearest port to a root bridge of the bridge. it is determined by the cost of the path, etc. DESIGNATED_PORT(D): the port of the side near the root bridge of each link. it is determined by the cost of the path, etc. NON_DESIGNATED_PORT(ND): the port other than a ROOT_PORT and DESIGNATED_PORT. """ # Port state # DISABLE: Administratively down or link down by an obstacle. # BLOCK : Not part of spanning tree. # LISTEN : Not learning or relaying frames. # LEARN : Learning but not relaying frames. # FORWARD: Learning and relaying frames. PORT_STATE_DISABLE = 0 PORT_STATE_BLOCK = 1 PORT_STATE_LISTEN = 2 PORT_STATE_LEARN = 3 PORT_STATE_FORWARD = 4 # for OpenFlow 1.0 PORT_CONFIG_V1_0 = {PORT_STATE_DISABLE: (ofproto_v1_0.OFPPC_NO_RECV_STP | ofproto_v1_0.OFPPC_NO_RECV | ofproto_v1_0.OFPPC_NO_FLOOD | ofproto_v1_0.OFPPC_NO_FWD), PORT_STATE_BLOCK: (ofproto_v1_0.OFPPC_NO_RECV | ofproto_v1_0.OFPPC_NO_FLOOD | ofproto_v1_0.OFPPC_NO_FWD), PORT_STATE_LISTEN: (ofproto_v1_0.OFPPC_NO_RECV | ofproto_v1_0.OFPPC_NO_FLOOD), PORT_STATE_LEARN: ofproto_v1_0.OFPPC_NO_FLOOD, PORT_STATE_FORWARD: 0} # for OpenFlow 1.2 PORT_CONFIG_V1_2 = {PORT_STATE_DISABLE: (ofproto_v1_2.OFPPC_NO_RECV | ofproto_v1_2.OFPPC_NO_FWD), PORT_STATE_BLOCK: (ofproto_v1_2.OFPPC_NO_FWD | ofproto_v1_2.OFPPC_NO_PACKET_IN), PORT_STATE_LISTEN: ofproto_v1_2.OFPPC_NO_PACKET_IN, PORT_STATE_LEARN: ofproto_v1_2.OFPPC_NO_PACKET_IN, PORT_STATE_FORWARD: 0} # for OpenFlow 1.3 PORT_CONFIG_V1_3 = {PORT_STATE_DISABLE: (ofproto_v1_3.OFPPC_NO_RECV | ofproto_v1_3.OFPPC_NO_FWD), PORT_STATE_BLOCK: (ofproto_v1_3.OFPPC_NO_FWD | ofproto_v1_3.OFPPC_NO_PACKET_IN), PORT_STATE_LISTEN: ofproto_v1_3.OFPPC_NO_PACKET_IN, PORT_STATE_LEARN: ofproto_v1_3.OFPPC_NO_PACKET_IN, PORT_STATE_FORWARD: 0} """ Port state machine +------------------------<--------------------------+ | |*2 +--> [BLOCK] -----+--> [LISTEN] ----> [LEARN] ------+----> [FORWARD] *3 | | 15sec | 15sec *1 | | |*3 |*3 |*3 +----<---+------<------+----------<----------+ *1 if port role == DESIGNATED_PORT or ROOT_PORT *2 if port role == NON_DESIGNATED_PORT *3 re-calculation of Spanning tree occurred. When bridge has started, each port state is set to [LISTEN] except port configuration is disable. If port configuration is disable or link down occurred, the port state is set to [DISABLE] """ # Throw this event when network topology is changed. # Flush filtering database, when you receive this event. class EventTopologyChange(event.EventBase): def __init__(self, dp): super(EventTopologyChange, self).__init__() self.dp = dp # Throw this event when port status is changed. class EventPortStateChange(event.EventBase): def __init__(self, dp, port): super(EventPortStateChange, self).__init__() self.dp = dp self.port_no = port.ofport.port_no self.port_state = port.state # Event for receive packet in message except BPDU packet. class EventPacketIn(event.EventBase): def __init__(self, msg): super(EventPacketIn, self).__init__() self.msg = msg # For Python3 compatibility # Note: The following is the official workaround for cmp() in Python2. # https://docs.python.org/3.0/whatsnew/3.0.html#ordering-comparisons def cmp(a, b): return (a > b) - (a < b) class Stp(app_manager.OSKenApp): """ STP(spanning tree) library. """ OFP_VERSIONS = [ofproto_v1_0.OFP_VERSION, ofproto_v1_2.OFP_VERSION, ofproto_v1_3.OFP_VERSION] def __init__(self): super(Stp, self).__init__() self.name = 'stplib' self._set_logger() self.config = {} self.bridge_list = {} def close(self): for dpid in self.bridge_list: self._unregister_bridge(dpid) def _set_logger(self): self.logger.propagate = False hdlr = logging.StreamHandler() fmt_str = '[STP][%(levelname)s] dpid=%(dpid)s: %(message)s' hdlr.setFormatter(logging.Formatter(fmt_str)) self.logger.addHandler(hdlr) def set_config(self, config): """ Use this API if you want to set up configuration of each bridge and ports. Set configuration with 'config' parameter as follows. config = {: {'bridge': {'priority': , 'sys_ext_id': , 'max_age': , 'hello_time': , 'fwd_delay': } 'ports': {: {'priority': , 'path_cost': , 'enable': }, : {...},,,}} : {...}, : {...},,,} NOTE: You may omit each field. If omitted, a default value is set up. It becomes effective when a bridge starts. Default values: ------------------------------------------------------ | bridge | priority | bpdu.DEFAULT_BRIDGE_PRIORITY | | | sys_ext_id | 0 | | | max_age | bpdu.DEFAULT_MAX_AGE | | | hello_time | bpdu.DEFAULT_HELLO_TIME | | | fwd_delay | bpdu.DEFAULT_FORWARD_DELAY | |--------|------------|------------------------------| | port | priority | bpdu.DEFAULT_PORT_PRIORITY | | | path_cost | (Set up automatically | | | | according to link speed.) | | | enable | True | ------------------------------------------------------ """ assert isinstance(config, dict) self.config = config @set_ev_cls(ofp_event.EventOFPStateChange, [handler.MAIN_DISPATCHER, handler.DEAD_DISPATCHER]) def dispacher_change(self, ev): assert ev.datapath is not None if ev.state == handler.MAIN_DISPATCHER: self._register_bridge(ev.datapath) elif ev.state == handler.DEAD_DISPATCHER: self._unregister_bridge(ev.datapath.id) def _register_bridge(self, dp): self._unregister_bridge(dp.id) dpid_str = {'dpid': dpid_to_str(dp.id)} self.logger.info('Join as stp bridge.', extra=dpid_str) try: bridge = Bridge(dp, self.logger, self.config.get(dp.id, {}), self.send_event_to_observers) except OFPUnknownVersion as message: self.logger.error(str(message), extra=dpid_str) return self.bridge_list[dp.id] = bridge def _unregister_bridge(self, dp_id): if dp_id in self.bridge_list: self.bridge_list[dp_id].delete() del self.bridge_list[dp_id] self.logger.info('Leave stp bridge.', extra={'dpid': dpid_to_str(dp_id)}) @set_ev_cls(ofp_event.EventOFPPacketIn, handler.MAIN_DISPATCHER) def packet_in_handler(self, ev): if ev.msg.datapath.id in self.bridge_list: bridge = self.bridge_list[ev.msg.datapath.id] bridge.packet_in_handler(ev.msg) @set_ev_cls(ofp_event.EventOFPPortStatus, handler.MAIN_DISPATCHER) def port_status_handler(self, ev): dp = ev.msg.datapath dpid_str = {'dpid': dpid_to_str(dp.id)} port = ev.msg.desc reason = ev.msg.reason link_down_flg = port.state & 0b1 if dp.id in self.bridge_list: bridge = self.bridge_list[dp.id] if reason is dp.ofproto.OFPPR_ADD: self.logger.info('[port=%d] Port add.', port.port_no, extra=dpid_str) bridge.port_add(port) elif reason is dp.ofproto.OFPPR_DELETE: self.logger.info('[port=%d] Port delete.', port.port_no, extra=dpid_str) bridge.port_delete(port) else: assert reason is dp.ofproto.OFPPR_MODIFY if bridge.ports_state[port.port_no] == port.state: # Do nothing self.logger.debug('[port=%d] Link status not changed.', port.port_no, extra=dpid_str) return if link_down_flg: self.logger.info('[port=%d] Link down.', port.port_no, extra=dpid_str) bridge.link_down(port) else: self.logger.info('[port=%d] Link up.', port.port_no, extra=dpid_str) bridge.link_up(port) @staticmethod def compare_root_path(path_cost1, path_cost2, bridge_id1, bridge_id2, port_id1, port_id2): """ Decide the port of the side near a root bridge. It is compared by the following priorities. 1. root path cost 2. designated bridge ID value 3. designated port ID value """ result = Stp._cmp_value(path_cost1, path_cost2) if not result: result = Stp._cmp_value(bridge_id1, bridge_id2) if not result: result = Stp._cmp_value(port_id1, port_id2) return result @staticmethod def compare_bpdu_info(my_priority, my_times, rcv_priority, rcv_times): """ Check received BPDU is superior to currently held BPDU by the following comparison. - root bridge ID value - root path cost - designated bridge ID value - designated port ID value - times """ if my_priority is None: result = SUPERIOR else: result = Stp._cmp_value(rcv_priority.root_id.value, my_priority.root_id.value) if not result: result = Stp.compare_root_path( rcv_priority.root_path_cost, my_priority.root_path_cost, rcv_priority.designated_bridge_id.value, my_priority.designated_bridge_id.value, rcv_priority.designated_port_id.value, my_priority.designated_port_id.value) if not result: result1 = Stp._cmp_value( rcv_priority.designated_bridge_id.value, mac.haddr_to_int( my_priority.designated_bridge_id.mac_addr)) result2 = Stp._cmp_value( rcv_priority.designated_port_id.value, my_priority.designated_port_id.port_no) if not result1 and not result2: result = SUPERIOR else: result = Stp._cmp_obj(rcv_times, my_times) return result @staticmethod def _cmp_value(value1, value2): result = cmp(value1, value2) if result < 0: return SUPERIOR elif result == 0: return REPEATED else: return INFERIOR @staticmethod def _cmp_obj(obj1, obj2): for key in obj1.__dict__.keys(): if (not hasattr(obj2, key) or getattr(obj1, key) != getattr(obj2, key)): return SUPERIOR return REPEATED class Bridge(object): _DEFAULT_VALUE = {'priority': bpdu.DEFAULT_BRIDGE_PRIORITY, 'sys_ext_id': 0, 'max_age': bpdu.DEFAULT_MAX_AGE, 'hello_time': bpdu.DEFAULT_HELLO_TIME, 'fwd_delay': bpdu.DEFAULT_FORWARD_DELAY} def __init__(self, dp, logger, config, send_ev_func): super(Bridge, self).__init__() self.dp = dp self.logger = logger self.dpid_str = {'dpid': dpid_to_str(dp.id)} self.send_event = send_ev_func # Bridge data bridge_conf = config.get('bridge', {}) values = self._DEFAULT_VALUE for key, value in bridge_conf.items(): values[key] = value system_id = list(dp.ports.values())[0].hw_addr self.bridge_id = BridgeId(values['priority'], values['sys_ext_id'], system_id) self.bridge_times = Times(0, # message_age values['max_age'], values['hello_time'], values['fwd_delay']) # Root bridge data self.root_priority = Priority(self.bridge_id, 0, None, None) self.root_times = self.bridge_times # Ports self.ports = {} self.ports_state = {} self.ports_conf = config.get('ports', {}) for ofport in dp.ports.values(): self.port_add(ofport) # Install BPDU PacketIn flow. (OpenFlow 1.2/1.3) if dp.ofproto == ofproto_v1_2 or dp.ofproto == ofproto_v1_3: ofctl = OfCtl_v1_2later(self.dp) ofctl.add_bpdu_pkt_in_flow() @property def is_root_bridge(self): return bool(self.bridge_id.value == self.root_priority.root_id.value) def delete(self): for port in self.ports.values(): port.delete() def port_add(self, ofport): if ofport.port_no <= MAX_PORT_NO: port_conf = self.ports_conf.get(ofport.port_no, {}) self.ports[ofport.port_no] = Port(self.dp, self.logger, port_conf, self.send_event, self.recalculate_spanning_tree, self.topology_change_notify, self.bridge_id, self.bridge_times, ofport) self.ports_state[ofport.port_no] = ofport.state def port_delete(self, ofp_port): self.link_down(ofp_port) self.ports[ofp_port.port_no].delete() del self.ports[ofp_port.port_no] del self.ports_state[ofp_port.port_no] def link_up(self, ofp_port): port = self.ports[ofp_port.port_no] port.up(DESIGNATED_PORT, self.root_priority, self.root_times) self.ports_state[ofp_port.port_no] = ofp_port.state def link_down(self, ofp_port): """ DESIGNATED_PORT/NON_DESIGNATED_PORT: change status to DISABLE. ROOT_PORT: change status to DISABLE and recalculate STP. """ port = self.ports[ofp_port.port_no] init_stp_flg = bool(port.role is ROOT_PORT) port.down(PORT_STATE_DISABLE, msg_init=True) self.ports_state[ofp_port.port_no] = ofp_port.state if init_stp_flg: self.recalculate_spanning_tree() def packet_in_handler(self, msg): dp = msg.datapath if dp.ofproto == ofproto_v1_0: in_port_no = msg.in_port else: assert dp.ofproto == ofproto_v1_2 or dp.ofproto == ofproto_v1_3 in_port_no = None for match_field in msg.match.fields: if match_field.header == dp.ofproto.OXM_OF_IN_PORT: in_port_no = match_field.value break if in_port_no not in self.ports: return in_port = self.ports[in_port_no] if in_port.state == PORT_STATE_DISABLE: return pkt = packet.Packet(msg.data) if bpdu.ConfigurationBPDUs in pkt: # Received Configuration BPDU. # - If received superior BPDU: # Re-calculates spanning tree. # - If received Topology Change BPDU: # Throws EventTopologyChange. # Forwards Topology Change BPDU. (bpdu_pkt, ) = pkt.get_protocols(bpdu.ConfigurationBPDUs) if bpdu_pkt.message_age > bpdu_pkt.max_age: log_msg = 'Drop BPDU packet which message_age exceeded.' self.logger.debug(log_msg, extra=self.dpid_str) return rcv_info, rcv_tc = in_port.rcv_config_bpdu(bpdu_pkt) if rcv_info is SUPERIOR: self.logger.info('[port=%d] Receive superior BPDU.', in_port_no, extra=self.dpid_str) self.recalculate_spanning_tree(init=False) elif rcv_tc: self.send_event(EventTopologyChange(self.dp)) if in_port.role is ROOT_PORT: self._forward_tc_bpdu(rcv_tc) elif bpdu.TopologyChangeNotificationBPDUs in pkt: # Received Topology Change Notification BPDU. # Send Topology Change Ack BPDU and throws EventTopologyChange. # - Root bridge: # Sends Topology Change BPDU from all port. # - Non root bridge: # Sends Topology Change Notification BPDU to root bridge. in_port.transmit_ack_bpdu() self.topology_change_notify(None) elif bpdu.RstBPDUs in pkt: # Received Rst BPDU. # TODO: RSTP pass else: # Received non BPDU packet. # Throws EventPacketIn. self.send_event(EventPacketIn(msg)) def recalculate_spanning_tree(self, init=True): """ Re-calculation of spanning tree. """ # All port down. for port in self.ports.values(): if port.state is not PORT_STATE_DISABLE: port.down(PORT_STATE_BLOCK, msg_init=init) # Send topology change event. if init: self.send_event(EventTopologyChange(self.dp)) # Update tree roles. port_roles = {} self.root_priority = Priority(self.bridge_id, 0, None, None) self.root_times = self.bridge_times if init: self.logger.info('Root bridge.', extra=self.dpid_str) for port_no in self.ports: port_roles[port_no] = DESIGNATED_PORT else: (port_roles, self.root_priority, self.root_times) = self._spanning_tree_algorithm() # All port up. for port_no, role in port_roles.items(): if self.ports[port_no].state is not PORT_STATE_DISABLE: self.ports[port_no].up(role, self.root_priority, self.root_times) def _spanning_tree_algorithm(self): """ Update tree roles. - Root bridge: all port is DESIGNATED_PORT. - Non root bridge: select one ROOT_PORT and some DESIGNATED_PORT, and the other port is set to NON_DESIGNATED_PORT.""" port_roles = {} root_port = self._select_root_port() if root_port is None: # My bridge is a root bridge. self.logger.info('Root bridge.', extra=self.dpid_str) root_priority = self.root_priority root_times = self.root_times for port_no in self.ports: if self.ports[port_no].state is not PORT_STATE_DISABLE: port_roles[port_no] = DESIGNATED_PORT else: # Other bridge is a root bridge. self.logger.info('Non root bridge.', extra=self.dpid_str) root_priority = root_port.designated_priority root_times = root_port.designated_times port_roles[root_port.ofport.port_no] = ROOT_PORT d_ports = self._select_designated_port(root_port) for port_no in d_ports: port_roles[port_no] = DESIGNATED_PORT for port in self.ports.values(): if port.state is not PORT_STATE_DISABLE: port_roles.setdefault(port.ofport.port_no, NON_DESIGNATED_PORT) return port_roles, root_priority, root_times def _select_root_port(self): """ ROOT_PORT is the nearest port to a root bridge. It is determined by the cost of path, etc. """ root_port = None for port in self.ports.values(): root_msg = (self.root_priority if root_port is None else root_port.designated_priority) port_msg = port.designated_priority if port.state is PORT_STATE_DISABLE or port_msg is None: continue if root_msg.root_id.value > port_msg.root_id.value: result = SUPERIOR elif root_msg.root_id.value == port_msg.root_id.value: if root_msg.designated_bridge_id is None: result = INFERIOR else: result = Stp.compare_root_path( port_msg.root_path_cost, root_msg.root_path_cost, port_msg.designated_bridge_id.value, root_msg.designated_bridge_id.value, port_msg.designated_port_id.value, root_msg.designated_port_id.value) else: result = INFERIOR if result is SUPERIOR: root_port = port return root_port def _select_designated_port(self, root_port): """ DESIGNATED_PORT is a port of the side near the root bridge of each link. It is determined by the cost of each path, etc same as ROOT_PORT. """ d_ports = [] root_msg = root_port.designated_priority for port in self.ports.values(): port_msg = port.designated_priority if (port.state is PORT_STATE_DISABLE or port.ofport.port_no == root_port.ofport.port_no): continue if (port_msg is None or (port_msg.root_id.value != root_msg.root_id.value)): d_ports.append(port.ofport.port_no) else: result = Stp.compare_root_path( root_msg.root_path_cost, port_msg.root_path_cost - port.path_cost, self.bridge_id.value, port_msg.designated_bridge_id.value, port.port_id.value, port_msg.designated_port_id.value) if result is SUPERIOR: d_ports.append(port.ofport.port_no) return d_ports def topology_change_notify(self, port_state): notice = False if port_state is PORT_STATE_FORWARD: for port in self.ports.values(): if port.role is DESIGNATED_PORT: notice = True break else: notice = True if notice: self.send_event(EventTopologyChange(self.dp)) if self.is_root_bridge: self._transmit_tc_bpdu() else: self._transmit_tcn_bpdu() def _transmit_tc_bpdu(self): for port in self.ports.values(): port.transmit_tc_bpdu() def _transmit_tcn_bpdu(self): root_port = None for port in self.ports.values(): if port.role is ROOT_PORT: root_port = port break if root_port: root_port.transmit_tcn_bpdu() def _forward_tc_bpdu(self, fwd_flg): for port in self.ports.values(): port.send_tc_flg = fwd_flg class Port(object): _DEFAULT_VALUE = {'priority': bpdu.DEFAULT_PORT_PRIORITY, 'path_cost': bpdu.PORT_PATH_COST_10MB, 'enable': True} def __init__(self, dp, logger, config, send_ev_func, timeout_func, topology_change_func, bridge_id, bridge_times, ofport): super(Port, self).__init__() self.dp = dp self.logger = logger self.dpid_str = {'dpid': dpid_to_str(dp.id)} self.config_enable = config.get('enable', self._DEFAULT_VALUE['enable']) self.send_event = send_ev_func self.wait_bpdu_timeout = timeout_func self.topology_change_notify = topology_change_func self.ofctl = (OfCtl_v1_0(dp) if dp.ofproto == ofproto_v1_0 else OfCtl_v1_2later(dp)) # Bridge data self.bridge_id = bridge_id # Root bridge data self.port_priority = None self.port_times = None # ofproto_v1_X_parser.OFPPhyPort data self.ofport = ofport # Port data values = self._DEFAULT_VALUE path_costs = {dp.ofproto.OFPPF_10MB_HD: bpdu.PORT_PATH_COST_10MB, dp.ofproto.OFPPF_10MB_FD: bpdu.PORT_PATH_COST_10MB, dp.ofproto.OFPPF_100MB_HD: bpdu.PORT_PATH_COST_100MB, dp.ofproto.OFPPF_100MB_FD: bpdu.PORT_PATH_COST_100MB, dp.ofproto.OFPPF_1GB_HD: bpdu.PORT_PATH_COST_1GB, dp.ofproto.OFPPF_1GB_FD: bpdu.PORT_PATH_COST_1GB, dp.ofproto.OFPPF_10GB_FD: bpdu.PORT_PATH_COST_10GB} for rate in sorted(path_costs, reverse=True): if ofport.curr & rate: values['path_cost'] = path_costs[rate] break for key, value in values.items(): values[key] = value self.port_id = PortId(values['priority'], ofport.port_no) self.path_cost = values['path_cost'] self.state = (None if self.config_enable else PORT_STATE_DISABLE) self.role = None # Receive BPDU data self.designated_priority = None self.designated_times = None # BPDU handling threads self.send_bpdu_thread = PortThread(self._transmit_bpdu) self.wait_bpdu_thread = PortThread(self._wait_bpdu_timer) self.send_tc_flg = None self.send_tc_timer = None self.send_tcn_flg = None self.wait_timer_event = None # State machine thread self.state_machine = PortThread(self._state_machine) self.state_event = None self.up(DESIGNATED_PORT, Priority(bridge_id, 0, None, None), bridge_times) self.state_machine.start() self.logger.debug('[port=%d] Start port state machine.', self.ofport.port_no, extra=self.dpid_str) def delete(self): self.state_machine.stop() self.send_bpdu_thread.stop() self.wait_bpdu_thread.stop() if self.state_event is not None: self.state_event.set() self.state_event = None if self.wait_timer_event is not None: self.wait_timer_event.set() self.wait_timer_event = None self.logger.debug('[port=%d] Stop port threads.', self.ofport.port_no, extra=self.dpid_str) def up(self, role, root_priority, root_times): """ A port is started in the state of LISTEN. """ self.port_priority = root_priority self.port_times = root_times state = (PORT_STATE_LISTEN if self.config_enable else PORT_STATE_DISABLE) self._change_role(role) self._change_status(state) def down(self, state, msg_init=False): """ A port will be in the state of DISABLE or BLOCK, and be stopped. """ assert (state is PORT_STATE_DISABLE or state is PORT_STATE_BLOCK) if not self.config_enable: return if msg_init: self.designated_priority = None self.designated_times = None self._change_role(DESIGNATED_PORT) self._change_status(state) def _state_machine(self): """ Port state machine. Change next status when timer is exceeded or _change_status() method is called.""" role_str = {ROOT_PORT: 'ROOT_PORT ', DESIGNATED_PORT: 'DESIGNATED_PORT ', NON_DESIGNATED_PORT: 'NON_DESIGNATED_PORT'} state_str = {PORT_STATE_DISABLE: 'DISABLE', PORT_STATE_BLOCK: 'BLOCK', PORT_STATE_LISTEN: 'LISTEN', PORT_STATE_LEARN: 'LEARN', PORT_STATE_FORWARD: 'FORWARD'} if self.state is PORT_STATE_DISABLE: self.ofctl.set_port_status(self.ofport, self.state) while True: self.logger.info('[port=%d] %s / %s', self.ofport.port_no, role_str[self.role], state_str[self.state], extra=self.dpid_str) self.state_event = hub.Event() timer = self._get_timer() if timer: timeout = hub.Timeout(timer) try: self.state_event.wait() except hub.Timeout as t: if t is not timeout: err_msg = 'Internal error. Not my timeout.' raise OSKenException(msg=err_msg) new_state = self._get_next_state() self._change_status(new_state, thread_switch=False) finally: timeout.cancel() else: self.state_event.wait() self.state_event = None def _get_timer(self): timer = {PORT_STATE_DISABLE: None, PORT_STATE_BLOCK: None, PORT_STATE_LISTEN: self.port_times.forward_delay, PORT_STATE_LEARN: self.port_times.forward_delay, PORT_STATE_FORWARD: None} return timer[self.state] def _get_next_state(self): next_state = {PORT_STATE_DISABLE: None, PORT_STATE_BLOCK: None, PORT_STATE_LISTEN: PORT_STATE_LEARN, PORT_STATE_LEARN: (PORT_STATE_FORWARD if (self.role is ROOT_PORT or self.role is DESIGNATED_PORT) else PORT_STATE_BLOCK), PORT_STATE_FORWARD: None} return next_state[self.state] def _change_status(self, new_state, thread_switch=True): if new_state is not PORT_STATE_DISABLE: self.ofctl.set_port_status(self.ofport, new_state) if(new_state is PORT_STATE_FORWARD or (self.state is PORT_STATE_FORWARD and (new_state is PORT_STATE_DISABLE or new_state is PORT_STATE_BLOCK))): self.topology_change_notify(new_state) if (new_state is PORT_STATE_DISABLE or new_state is PORT_STATE_BLOCK): self.send_tc_flg = False self.send_tc_timer = None self.send_tcn_flg = False self.send_bpdu_thread.stop() elif new_state is PORT_STATE_LISTEN: self.send_bpdu_thread.start() self.state = new_state self.send_event(EventPortStateChange(self.dp, self)) if self.state_event is not None: self.state_event.set() self.state_event = None if thread_switch: hub.sleep(0) # For thread switching. def _change_role(self, new_role): if self.role is new_role: return self.role = new_role if (new_role is ROOT_PORT or new_role is NON_DESIGNATED_PORT): self.wait_bpdu_thread.start() else: assert new_role is DESIGNATED_PORT self.wait_bpdu_thread.stop() def rcv_config_bpdu(self, bpdu_pkt): # Check received BPDU is superior to currently held BPDU. root_id = BridgeId(bpdu_pkt.root_priority, bpdu_pkt.root_system_id_extension, bpdu_pkt.root_mac_address) root_path_cost = bpdu_pkt.root_path_cost designated_bridge_id = BridgeId(bpdu_pkt.bridge_priority, bpdu_pkt.bridge_system_id_extension, bpdu_pkt.bridge_mac_address) designated_port_id = PortId(bpdu_pkt.port_priority, bpdu_pkt.port_number) msg_priority = Priority(root_id, root_path_cost, designated_bridge_id, designated_port_id) msg_times = Times(bpdu_pkt.message_age, bpdu_pkt.max_age, bpdu_pkt.hello_time, bpdu_pkt.forward_delay) rcv_info = Stp.compare_bpdu_info(self.designated_priority, self.designated_times, msg_priority, msg_times) if rcv_info is SUPERIOR: self.designated_priority = msg_priority self.designated_times = msg_times chk_flg = False if ((rcv_info is SUPERIOR or rcv_info is REPEATED) and (self.role is ROOT_PORT or self.role is NON_DESIGNATED_PORT)): self._update_wait_bpdu_timer() chk_flg = True elif rcv_info is INFERIOR and self.role is DESIGNATED_PORT: chk_flg = True # Check TopologyChange flag. rcv_tc = False if chk_flg: tc_flag_mask = 0b00000001 tcack_flag_mask = 0b10000000 if bpdu_pkt.flags & tc_flag_mask: self.logger.debug('[port=%d] receive TopologyChange BPDU.', self.ofport.port_no, extra=self.dpid_str) rcv_tc = True if bpdu_pkt.flags & tcack_flag_mask: self.logger.debug('[port=%d] receive TopologyChangeAck BPDU.', self.ofport.port_no, extra=self.dpid_str) if self.send_tcn_flg: self.send_tcn_flg = False return rcv_info, rcv_tc def _update_wait_bpdu_timer(self): if self.wait_timer_event is not None: self.wait_timer_event.set() self.wait_timer_event = None self.logger.debug('[port=%d] Wait BPDU timer is updated.', self.ofport.port_no, extra=self.dpid_str) hub.sleep(0) # For thread switching. def _wait_bpdu_timer(self): time_exceed = False while True: self.wait_timer_event = hub.Event() message_age = (self.designated_times.message_age if self.designated_times else 0) timer = self.port_times.max_age - message_age timeout = hub.Timeout(timer) try: self.wait_timer_event.wait() except hub.Timeout as t: if t is not timeout: err_msg = 'Internal error. Not my timeout.' raise OSKenException(msg=err_msg) self.logger.info('[port=%d] Wait BPDU timer is exceeded.', self.ofport.port_no, extra=self.dpid_str) time_exceed = True finally: timeout.cancel() self.wait_timer_event = None if time_exceed: break if time_exceed: # Bridge.recalculate_spanning_tree hub.spawn(self.wait_bpdu_timeout) def _transmit_bpdu(self): while True: # Send config BPDU packet if port role is DESIGNATED_PORT. if self.role == DESIGNATED_PORT: now = datetime.datetime.today() if self.send_tc_timer and self.send_tc_timer < now: self.send_tc_timer = None self.send_tc_flg = False if not self.send_tc_flg: flags = 0b00000000 log_msg = '[port=%d] Send Config BPDU.' else: flags = 0b00000001 log_msg = '[port=%d] Send TopologyChange BPDU.' bpdu_data = self._generate_config_bpdu(flags) self.ofctl.send_packet_out(self.ofport.port_no, bpdu_data) self.logger.debug(log_msg, self.ofport.port_no, extra=self.dpid_str) # Send Topology Change Notification BPDU until receive Ack. if self.send_tcn_flg: bpdu_data = self._generate_tcn_bpdu() self.ofctl.send_packet_out(self.ofport.port_no, bpdu_data) self.logger.debug('[port=%d] Send TopologyChangeNotify BPDU.', self.ofport.port_no, extra=self.dpid_str) hub.sleep(self.port_times.hello_time) def transmit_tc_bpdu(self): """ Set send_tc_flg to send Topology Change BPDU. """ if not self.send_tc_flg: timer = datetime.timedelta(seconds=self.port_times.max_age + self.port_times.forward_delay) self.send_tc_timer = datetime.datetime.today() + timer self.send_tc_flg = True def transmit_ack_bpdu(self): """ Send Topology Change Ack BPDU. """ ack_flags = 0b10000001 bpdu_data = self._generate_config_bpdu(ack_flags) self.ofctl.send_packet_out(self.ofport.port_no, bpdu_data) def transmit_tcn_bpdu(self): self.send_tcn_flg = True def _generate_config_bpdu(self, flags): src_mac = self.ofport.hw_addr dst_mac = bpdu.BRIDGE_GROUP_ADDRESS length = (bpdu.bpdu._PACK_LEN + bpdu.ConfigurationBPDUs.PACK_LEN + llc.llc._PACK_LEN + llc.ControlFormatU._PACK_LEN) e = ethernet.ethernet(dst_mac, src_mac, length) l = llc.llc(llc.SAP_BPDU, llc.SAP_BPDU, llc.ControlFormatU()) b = bpdu.ConfigurationBPDUs( flags=flags, root_priority=self.port_priority.root_id.priority, root_mac_address=self.port_priority.root_id.mac_addr, root_path_cost=self.port_priority.root_path_cost + self.path_cost, bridge_priority=self.bridge_id.priority, bridge_mac_address=self.bridge_id.mac_addr, port_priority=self.port_id.priority, port_number=self.ofport.port_no, message_age=self.port_times.message_age + 1, max_age=self.port_times.max_age, hello_time=self.port_times.hello_time, forward_delay=self.port_times.forward_delay) pkt = packet.Packet() pkt.add_protocol(e) pkt.add_protocol(l) pkt.add_protocol(b) pkt.serialize() return pkt.data def _generate_tcn_bpdu(self): src_mac = self.ofport.hw_addr dst_mac = bpdu.BRIDGE_GROUP_ADDRESS length = (bpdu.bpdu._PACK_LEN + bpdu.TopologyChangeNotificationBPDUs.PACK_LEN + llc.llc._PACK_LEN + llc.ControlFormatU._PACK_LEN) e = ethernet.ethernet(dst_mac, src_mac, length) l = llc.llc(llc.SAP_BPDU, llc.SAP_BPDU, llc.ControlFormatU()) b = bpdu.TopologyChangeNotificationBPDUs() pkt = packet.Packet() pkt.add_protocol(e) pkt.add_protocol(l) pkt.add_protocol(b) pkt.serialize() return pkt.data class PortThread(object): def __init__(self, function): super(PortThread, self).__init__() self.function = function self.thread = None def start(self): self.stop() self.thread = hub.spawn(self.function) def stop(self): if self.thread is not None: hub.kill(self.thread) hub.joinall([self.thread]) self.thread = None class BridgeId(object): def __init__(self, priority, system_id_extension, mac_addr): super(BridgeId, self).__init__() self.priority = priority self.system_id_extension = system_id_extension self.mac_addr = mac_addr self.value = bpdu.ConfigurationBPDUs.encode_bridge_id( priority, system_id_extension, mac_addr) class PortId(object): def __init__(self, priority, port_no): super(PortId, self).__init__() self.priority = priority self.port_no = port_no self.value = bpdu.ConfigurationBPDUs.encode_port_id(priority, port_no) class Priority(object): def __init__(self, root_id, root_path_cost, designated_bridge_id, designated_port_id): super(Priority, self).__init__() self.root_id = root_id self.root_path_cost = root_path_cost self.designated_bridge_id = designated_bridge_id self.designated_port_id = designated_port_id class Times(object): def __init__(self, message_age, max_age, hello_time, forward_delay): super(Times, self).__init__() self.message_age = message_age self.max_age = max_age self.hello_time = hello_time self.forward_delay = forward_delay class OfCtl_v1_0(object): def __init__(self, dp): super(OfCtl_v1_0, self).__init__() self.dp = dp def send_packet_out(self, out_port, data): actions = [self.dp.ofproto_parser.OFPActionOutput(out_port, 0)] self.dp.send_packet_out(buffer_id=self.dp.ofproto.OFP_NO_BUFFER, in_port=self.dp.ofproto.OFPP_CONTROLLER, actions=actions, data=data) def set_port_status(self, port, state): ofproto_parser = self.dp.ofproto_parser mask = 0b1111111 msg = ofproto_parser.OFPPortMod(self.dp, port.port_no, port.hw_addr, PORT_CONFIG_V1_0[state], mask, port.advertised) self.dp.send_msg(msg) class OfCtl_v1_2later(OfCtl_v1_0): def __init__(self, dp): super(OfCtl_v1_2later, self).__init__(dp) def set_port_status(self, port, state): ofp = self.dp.ofproto parser = self.dp.ofproto_parser config = {ofproto_v1_2: PORT_CONFIG_V1_2, ofproto_v1_3: PORT_CONFIG_V1_3} # Only turn on the relevant bits defined on OpenFlow 1.2+, otherwise # some switch that follows the specification strictly will report # OFPPMFC_BAD_CONFIG error. mask = 0b1100101 msg = parser.OFPPortMod(self.dp, port.port_no, port.hw_addr, config[ofp][state], mask, port.advertised) self.dp.send_msg(msg) if config[ofp][state] & ofp.OFPPC_NO_PACKET_IN: self.add_no_pkt_in_flow(port.port_no) else: self.del_no_pkt_in_flow(port.port_no) def add_bpdu_pkt_in_flow(self): ofp = self.dp.ofproto parser = self.dp.ofproto_parser match = parser.OFPMatch(eth_dst=bpdu.BRIDGE_GROUP_ADDRESS) actions = [parser.OFPActionOutput(ofp.OFPP_CONTROLLER, ofp.OFPCML_NO_BUFFER)] inst = [parser.OFPInstructionActions(ofp.OFPIT_APPLY_ACTIONS, actions)] mod = parser.OFPFlowMod(self.dp, priority=BPDU_PKT_IN_PRIORITY, match=match, instructions=inst) self.dp.send_msg(mod) def add_no_pkt_in_flow(self, in_port): parser = self.dp.ofproto_parser match = parser.OFPMatch(in_port=in_port) mod = parser.OFPFlowMod(self.dp, priority=NO_PKT_IN_PRIORITY, match=match) self.dp.send_msg(mod) def del_no_pkt_in_flow(self, in_port): ofp = self.dp.ofproto parser = self.dp.ofproto_parser match = parser.OFPMatch(in_port=in_port) mod = parser.OFPFlowMod(self.dp, command=ofp.OFPFC_DELETE_STRICT, out_port=ofp.OFPP_ANY, out_group=ofp.OFPG_ANY, priority=NO_PKT_IN_PRIORITY, match=match) self.dp.send_msg(mod) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/stringify.py0000664000175000017500000003151600000000000017433 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013 YAMAMOTO Takashi # # 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. import base64 import inspect # Some arguments to __init__ is mangled in order to avoid name conflicts # with builtin names. # The standard mangling is to append '_' in order to avoid name clashes # with reserved keywords. # # PEP8: # Function and method arguments # If a function argument's name clashes with a reserved keyword, # it is generally better to append a single trailing underscore # rather than use an abbreviation or spelling corruption. Thus # class_ is better than clss. (Perhaps better is to avoid such # clashes by using a synonym.) # # grep __init__ *.py | grep '[^_]_\>' showed that # 'len', 'property', 'set', 'type' # A bit more generic way is adopted import builtins _RESERVED_KEYWORD = dir(builtins) _mapdict = lambda f, d: dict([(k, f(v)) for k, v in d.items()]) _mapdict_key = lambda f, d: dict([(f(k), v) for k, v in d.items()]) _mapdict_kv = lambda f, d: dict([(k, f(k, v)) for k, v in d.items()]) class TypeDescr(object): pass class AsciiStringType(TypeDescr): @staticmethod def encode(v): # TODO: AsciiStringType data should probably be stored as # text_type in class data. This isinstance() check exists # because OFPDescStats violates this. if isinstance(v, str): return v return str(v, 'ascii') @staticmethod def decode(v): return v class Utf8StringType(TypeDescr): @staticmethod def encode(v): return str(v, 'utf-8') @staticmethod def decode(v): return v.encode('utf-8') class AsciiStringListType(TypeDescr): @staticmethod def encode(v): return [AsciiStringType.encode(x) for x in v] @staticmethod def decode(v): return [AsciiStringType.decode(x) for x in v] class NXFlowSpecFieldType(TypeDescr): # ("field_name", 0) <-> ["field_name", 0] @staticmethod def encode(v): if not isinstance(v, tuple): return v field, ofs = v return [field, ofs] @staticmethod def decode(v): if not isinstance(v, list): return v field, ofs = v return field, ofs _types = { 'ascii': AsciiStringType, 'utf-8': Utf8StringType, 'asciilist': AsciiStringListType, 'nx-flow-spec-field': NXFlowSpecFieldType, # XXX this should not be here } class StringifyMixin(object): _TYPE = {} """_TYPE class attribute is used to annotate types of attributes. This type information is used to find an appropriate conversion for a JSON style dictionary. Currently the following types are implemented. ========= ============= Type Description ========= ============= ascii US-ASCII utf-8 UTF-8 asciilist list of ascii ========= ============= Example:: _TYPE = { 'ascii': [ 'hw_addr', ], 'utf-8': [ 'name', ] } """ _class_prefixes = [] _class_suffixes = [] # List of attributes ignored in the str and json representations. _base_attributes = [] # Optional attributes included in the str and json representations. # e.g.) In case of attributes are property, the attributes will be # skipped in the str and json representations. # Then, please specify the attributes into this list. _opt_attributes = [] def stringify_attrs(self): """an override point for sub classes""" return obj_python_attrs(self) def __str__(self): # repr() to escape binaries return self.__class__.__name__ + '(' + \ ','.join("%s=%s" % (k, repr(v)) for k, v in self.stringify_attrs()) + ')' __repr__ = __str__ # note: str(list) uses __repr__ for elements @classmethod def _is_class(cls, dict_): # we distinguish a dict like OFPSwitchFeatures.ports # from OFPxxx classes using heuristics. # Examples of OFP classes: # {"OFPMatch": { ... }} # {"MTIPv6SRC": { ... }} assert isinstance(dict_, dict) if len(dict_) != 1: return False k = list(dict_.keys())[0] if not isinstance(k, (bytes, str)): return False for p in cls._class_prefixes: if k.startswith(p): return True for p in cls._class_suffixes: if k.endswith(p): return True return False @classmethod def _get_type(cls, k): if hasattr(cls, '_TYPE'): for t, attrs in cls._TYPE.items(): if k in attrs: return _types[t] return None @classmethod def _get_encoder(cls, k, encode_string): t = cls._get_type(k) if t: return t.encode return cls._get_default_encoder(encode_string) @classmethod def _encode_value(cls, k, v, encode_string=base64.b64encode): return cls._get_encoder(k, encode_string)(v) @classmethod def _get_default_encoder(cls, encode_string): def _encode(v): if isinstance(v, (bytes, str)): if isinstance(v, str): v = v.encode('utf-8') json_value = encode_string(v) json_value = json_value.decode('ascii') elif isinstance(v, list): json_value = [_encode(ve) for ve in v] elif isinstance(v, dict): json_value = _mapdict(_encode, v) # while a python dict key can be any hashable object, # a JSON object key should be a string. json_value = _mapdict_key(str, json_value) assert not cls._is_class(json_value) else: try: json_value = v.to_jsondict() except Exception: json_value = v return json_value return _encode def to_jsondict(self, encode_string=base64.b64encode): """ This method returns a JSON style dict to describe this object. The returned dict is compatible with json.dumps() and json.loads(). Suppose ClassName object inherits StringifyMixin. For an object like the following:: ClassName(Param1=100, Param2=200) this method would produce:: { "ClassName": {"Param1": 100, "Param2": 200} } This method takes the following arguments. .. tabularcolumns:: |l|L| ============= ===================================================== Argument Description ============= ===================================================== encode_string (Optional) specify how to encode attributes which has python 'str' type. The default is base64. This argument is used only for attributes which don't have explicit type annotations in _TYPE class attribute. ============= ===================================================== """ dict_ = {} encode = lambda key, val: self._encode_value(key, val, encode_string) for k, v in obj_attrs(self): dict_[k] = encode(k, v) return {self.__class__.__name__: dict_} @classmethod def cls_from_jsondict_key(cls, k): # find a class with the given name from our class' module. import sys mod = sys.modules[cls.__module__] return getattr(mod, k) @classmethod def obj_from_jsondict(cls, jsondict, **additional_args): assert len(jsondict) == 1 for k, v in jsondict.items(): obj_cls = cls.cls_from_jsondict_key(k) return obj_cls.from_jsondict(v, **additional_args) @classmethod def _get_decoder(cls, k, decode_string): t = cls._get_type(k) if t: return t.decode return cls._get_default_decoder(decode_string) @classmethod def _decode_value(cls, k, json_value, decode_string=base64.b64decode, **additional_args): # Note: To avoid passing redundant arguments (e.g. 'datapath' for # non OFP classes), we omit '**additional_args' here. return cls._get_decoder(k, decode_string)(json_value) @classmethod def _get_default_decoder(cls, decode_string): def _decode(json_value, **additional_args): if isinstance(json_value, (bytes, str)): v = decode_string(json_value) elif isinstance(json_value, list): v = [_decode(jv) for jv in json_value] elif isinstance(json_value, dict): if cls._is_class(json_value): v = cls.obj_from_jsondict(json_value, **additional_args) else: v = _mapdict(_decode, json_value) # XXX: Hack # try to restore integer keys used by # OFPSwitchFeatures.ports. try: v = _mapdict_key(int, v) except ValueError: pass else: v = json_value return v return _decode @staticmethod def _restore_args(dict_): def restore(k): if k in _RESERVED_KEYWORD: return k + '_' return k return _mapdict_key(restore, dict_) @classmethod def from_jsondict(cls, dict_, decode_string=base64.b64decode, **additional_args): r"""Create an instance from a JSON style dict. Instantiate this class with parameters specified by the dict. This method takes the following arguments. .. tabularcolumns:: |l|L| =============== ===================================================== Argument Descrpition =============== ===================================================== dict\_ A dictionary which describes the parameters. For example, {"Param1": 100, "Param2": 200} decode_string (Optional) specify how to decode strings. The default is base64. This argument is used only for attributes which don't have explicit type annotations in _TYPE class attribute. additional_args (Optional) Additional kwargs for constructor. =============== ===================================================== """ decode = lambda k, x: cls._decode_value(k, x, decode_string, **additional_args) kwargs = cls._restore_args(_mapdict_kv(decode, dict_)) try: return cls(**dict(kwargs, **additional_args)) except TypeError: # debug print("CLS %s" % cls) print("ARG %s" % dict_) print("KWARG %s" % kwargs) raise @classmethod def set_classes(cls, registered_dict): cls._class_prefixes.extend([v.__name__ for v in registered_dict.values()]) def obj_python_attrs(msg_): """iterate object attributes for stringify purposes """ # a special case for namedtuple which seems widely used in # ofp parser implementations. if hasattr(msg_, '_fields'): for k in msg_._fields: yield(k, getattr(msg_, k)) return base = getattr(msg_, '_base_attributes', []) opt = getattr(msg_, '_opt_attributes', []) for k, v in inspect.getmembers(msg_): if k in opt: pass elif k.startswith('_'): continue elif callable(v): continue elif k in base: continue elif hasattr(msg_.__class__, k): continue yield (k, v) def obj_attrs(msg_): """similar to obj_python_attrs() but deals with python reserved keywords """ if isinstance(msg_, StringifyMixin): itr = msg_.stringify_attrs() else: # probably called by msg_str_attr itr = obj_python_attrs(msg_) for k, v in itr: if k.endswith('_') and k[:-1] in _RESERVED_KEYWORD: # XXX currently only StringifyMixin has restoring logic assert isinstance(msg_, StringifyMixin) k = k[:-1] yield (k, v) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/type_desc.py0000664000175000017500000000742400000000000017375 0ustar00zuulzuul00000000000000# Copyright (C) 2015 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2015 YAMAMOTO Takashi # # 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. import base64 import struct from os_ken.lib import addrconv class TypeDescr(object): pass class IntDescr(TypeDescr): def __init__(self, size): self.size = size def to_user(self, binary): i = 0 for _ in range(self.size): c = binary[:1] i = i * 256 + ord(c) binary = binary[1:] return i def from_user(self, i): binary = b'' for _ in range(self.size): binary = struct.Struct(">B").pack(i & 255) + binary i //= 256 return binary Int1 = IntDescr(1) Int2 = IntDescr(2) Int3 = IntDescr(3) Int4 = IntDescr(4) Int8 = IntDescr(8) Int9 = IntDescr(9) Int16 = IntDescr(16) def _split_str(s, n): """ split string into list of strings by specified number. """ length = len(s) return [s[i:i + n] for i in range(0, length, n)] class IntDescrMlt(TypeDescr): def __init__(self, length, num): self.length = length self.num = num self.size = length * num def to_user(self, binary): assert len(binary) == self.size lb = _split_str(binary, self.length) li = [] for b in lb: i = 0 for _ in range(self.length): c = b[:1] i = i * 256 + ord(c) b = b[1:] li.append(i) return tuple(li) def from_user(self, li): assert len(li) == self.num binary = b'' for i in li: b = b'' for _ in range(self.length): b = struct.Struct(">B").pack(i & 255) + b i //= 256 binary += b return binary Int4Double = IntDescrMlt(4, 2) class MacAddr(TypeDescr): size = 6 to_user = addrconv.mac.bin_to_text from_user = addrconv.mac.text_to_bin class IPv4Addr(TypeDescr): size = 4 to_user = addrconv.ipv4.bin_to_text from_user = addrconv.ipv4.text_to_bin class IPv6Addr(TypeDescr): size = 16 to_user = addrconv.ipv6.bin_to_text from_user = addrconv.ipv6.text_to_bin class UnknownType(TypeDescr): @staticmethod def to_user(data): return base64.b64encode(data).decode('ascii') from_user = staticmethod(base64.b64decode) class TypeDisp(object): _TYPES = {} _REV_TYPES = None _UNKNOWN_TYPE = None @classmethod def register_unknown_type(cls): def _register_type(subcls): cls._UNKNOWN_TYPE = subcls return subcls return _register_type @classmethod def register_type(cls, type_): cls._TYPES = cls._TYPES.copy() def _register_type(subcls): cls._TYPES[type_] = subcls cls._REV_TYPES = None return subcls return _register_type @classmethod def _lookup_type(cls, type_): try: return cls._TYPES[type_] except KeyError: return cls._UNKNOWN_TYPE @classmethod def _rev_lookup_type(cls, targ_cls): if cls._REV_TYPES is None: rev = dict((v, k) for k, v in cls._TYPES.items()) cls._REV_TYPES = rev return cls._REV_TYPES[targ_cls] ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.0941048 os-ken-2.10.0/os_ken/lib/xflow/0000775000175000017500000000000000000000000016174 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/xflow/__init__.py0000664000175000017500000000006000000000000020301 0ustar00zuulzuul00000000000000""" An implementation of sFlow and NetFlow. """ ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/xflow/netflow.py0000664000175000017500000000765100000000000020235 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone 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. import struct NETFLOW_V1 = 0x01 NETFLOW_V5 = 0x05 NETFLOW_V6 = 0x06 NETFLOW_V7 = 0x07 NETFLOW_V8 = 0x08 NETFLOW_V9 = 0x09 class NetFlow(object): _PACK_STR = '!H' _NETFLOW_VERSIONS = {} @staticmethod def register_netflow_version(version): def _register_netflow_version(cls): NetFlow._NETFLOW_VERSIONS[version] = cls return cls return _register_netflow_version def __init__(self): super(NetFlow, self).__init__() @classmethod def parser(cls, buf): (version,) = struct.unpack_from(cls._PACK_STR, buf) cls_ = cls._NETFLOW_VERSIONS.get(version, None) if cls_: return cls_.parser(buf) else: return None @NetFlow.register_netflow_version(NETFLOW_V5) class NetFlowV5(object): _PACK_STR = '!HHIIIIBBH' _MIN_LEN = struct.calcsize(_PACK_STR) def __init__(self, version, count, sys_uptime, unix_secs, unix_nsecs, flow_sequence, engine_type, engine_id, sampling_interval, flows=None): self.version = version self.count = count self.sys_uptime = sys_uptime self.unix_secs = unix_secs self.unix_nsecs = unix_nsecs self.flow_sequence = flow_sequence self.engine_type = engine_type self.engine_id = engine_id self.sampling_interval = sampling_interval @classmethod def parser(cls, buf): (version, count, sys_uptime, unix_secs, unix_nsecs, flow_sequence, engine_type, engine_id, sampling_interval) = \ struct.unpack_from(cls._PACK_STR, buf) msg = cls(version, count, sys_uptime, unix_secs, unix_nsecs, flow_sequence, engine_type, engine_id, sampling_interval) offset = cls._MIN_LEN msg.flows = [] while len(buf) > offset: f = NetFlowV5Flow.parser(buf, offset) offset += NetFlowV5Flow._MIN_LEN msg.flows.append(f) return msg class NetFlowV5Flow(object): _PACK_STR = '!IIIHHIIIIHHxBBBHHBB2x' _MIN_LEN = struct.calcsize(_PACK_STR) def __init__(self, srcaddr, dstaddr, nexthop, input_, output, dpkts, doctets, first, last, srcport, dstport, tcp_flags, prot, tos, src_as, dst_as, src_mask, dst_mask): self.srcaddr = srcaddr self.dstaddr = dstaddr self.nexthop = nexthop self.input = input_ self.output = output self.dpkts = dpkts self.doctets = doctets self.first = first self.last = last self.srcport = srcport self.dstport = dstport self.tcp_flags = tcp_flags self.prot = prot self.tos = tos self.src_as = src_as self.dst_as = dst_as self.src_mask = src_mask self.dst_mask = dst_mask @classmethod def parser(cls, buf, offset): (srcaddr, dstaddr, nexthop, input_, output, dpkts, doctets, first, last, srcport, dstport, tcp_flags, prot, tos, src_as, dst_as, src_mask, dst_mask) = struct.unpack_from( cls._PACK_STR, buf, offset) msg = cls(srcaddr, dstaddr, nexthop, input_, output, dpkts, doctets, first, last, srcport, dstport, tcp_flags, prot, tos, src_as, dst_as, src_mask, dst_mask) return msg ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/lib/xflow/sflow.py0000664000175000017500000003623000000000000017704 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone 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. import struct import logging SFLOW_V2 = 0x00000002 SFLOW_V3 = 0x00000003 SFLOW_V4 = 0x00000004 SFLOW_V5 = 0x00000005 LOG = logging.getLogger('os_ken.lib.xflow.sflow') class sFlow(object): _PACK_STR = '!i' _SFLOW_VERSIONS = {} @staticmethod def register_sflow_version(version): def _register_sflow_version(cls): sFlow._SFLOW_VERSIONS[version] = cls return cls return _register_sflow_version def __init__(self): super(sFlow, self).__init__() @classmethod def parser(cls, buf): (version,) = struct.unpack_from(cls._PACK_STR, buf) cls_ = cls._SFLOW_VERSIONS.get(version, None) if cls_: return cls_.parser(buf) else: return None @sFlow.register_sflow_version(SFLOW_V5) class sFlowV5(object): _PACK_STR = '!ii' _PACK_STR_IPV4 = '!iiIIIII' _PACK_STR_IPV6 = '!ii4IIIII' _AGENT_IPTYPE_V4 = 1 _AGENT_IPTYPE_V6 = 2 _MIN_LEN_V4 = struct.calcsize(_PACK_STR_IPV4) _MIN_LEN_V6 = struct.calcsize(_PACK_STR_IPV6) def __init__(self, version, address_type, agent_address, sub_agent_id, sequence_number, uptime, samples_num, samples): super(sFlowV5, self).__init__() self.version = version self.address_type = address_type self.agent_address = agent_address self.sub_agent_id = sub_agent_id self.sequence_number = sequence_number self.uptime = uptime self.samples_num = samples_num self.samples = samples @classmethod def parser(cls, buf): (version, address_type) = struct.unpack_from(cls._PACK_STR, buf) if address_type == cls._AGENT_IPTYPE_V4: pack_str = cls._PACK_STR_IPV4 min_len = cls._MIN_LEN_V4 elif address_type == cls._AGENT_IPTYPE_V6: pack_str = cls._PACK_STR_IPV6 min_len = cls._MIN_LEN_V6 else: LOG.info("Unknown address_type. sFlowV5.address_type=%d", address_type) return None (version, address_type, agent_address, sub_agent_id, sequence_number, uptime, samples_num) = struct.unpack_from(pack_str, buf) offset = min_len samples = [] while len(buf) > offset: sample = sFlowV5Sample.parser(buf, offset) offset += sFlowV5Sample.MIN_LEN + sample.sample_length samples.append(sample) msg = cls(version, address_type, agent_address, sub_agent_id, sequence_number, uptime, samples_num, samples) return msg class sFlowV5Sample(object): _PACK_STR = '!II' MIN_LEN = struct.calcsize(_PACK_STR) def __init__(self, enterprise, sample_format, sample_length, sample): super(sFlowV5Sample, self).__init__() self.enterprise = enterprise self.sample_format = sample_format self.sample_length = sample_length self.sample = sample @classmethod def parser(cls, buf, offset): (sampledata_format, sample_length) = struct.unpack_from(cls._PACK_STR, buf, offset) format_mask = 0xfff enterprise_shiftbit = 12 sample_format = sampledata_format & format_mask enterprise = sampledata_format >> enterprise_shiftbit offset += cls.MIN_LEN if sample_format == 1: # Flow Sample sample = sFlowV5FlowSample.parser(buf, offset) elif sample_format == 2: # Counter Sample sample = sFlowV5CounterSample.parser(buf, offset) else: # TODO: # sample_format == 3 : Expanded Flow Sample # sample_format == 4 : Expanded Counter Sample LOG.info("Unknown format. sFlowV5Sample.sample_format=%d", sample_format) pack_str = '!%sc' % sample_length sample = struct.unpack_from(pack_str, buf, offset) msg = cls(enterprise, sample_format, sample_length, sample) return msg class sFlowV5FlowSample(object): _PACK_STR = '!IIIIIIII' def __init__(self, sequence_number, source_id_type, source_id_index, sampling_rate, sample_pool, drops, input_if, output_if, flow_records_num, flow_records): super(sFlowV5FlowSample, self).__init__() self.sequence_number = sequence_number self.source_id_type = source_id_type self.source_id_index = source_id_index self.sampling_rate = sampling_rate self.sample_pool = sample_pool self.drops = drops self.input_if = input_if self.output_if = output_if self.flow_records_num = flow_records_num self.flow_records = flow_records @classmethod def parser(cls, buf, offset): (sequence_number, source_id, sampling_rate, sample_pool, drops, input_if, output_if, flow_records_num) = struct.unpack_from(cls._PACK_STR, buf, offset) index_mask = 0xffffff type_shiftbit = 24 source_id_index = source_id & index_mask source_id_type = source_id >> type_shiftbit offset += struct.calcsize(cls._PACK_STR) flow_records = [] for i in range(flow_records_num): flow_record = sFlowV5FlowRecord.parser(buf, offset) offset += sFlowV5FlowRecord.MIN_LEN + flow_record.flow_data_length flow_records.append(flow_record) msg = cls(sequence_number, source_id_type, source_id_index, sampling_rate, sample_pool, drops, input_if, output_if, flow_records_num, flow_records) return msg class sFlowV5FlowRecord(object): _PACK_STR = '!II' MIN_LEN = struct.calcsize(_PACK_STR) def __init__(self, enterprise, flow_data_format, flow_data_length, flow_data): super(sFlowV5FlowRecord, self).__init__() self.enterprise = enterprise self.flow_data_format = flow_data_format self.flow_data_length = flow_data_length self.flow_data = flow_data @classmethod def parser(cls, buf, offset): (flowdata_format, flow_data_length) = struct.unpack_from(cls._PACK_STR, buf, offset) format_mask = 0xfff enterprise_shiftbit = 12 flow_data_format = flowdata_format & format_mask enterprise = flowdata_format >> enterprise_shiftbit offset += cls.MIN_LEN if flow_data_format == 1: # Raw Packet Header flow_data = sFlowV5RawPacketHeader.parser(buf, offset) elif flow_data_format == 1001: # Extended Switch Data flow_data = sFlowV5ExtendedSwitchData.parser(buf, offset) else: # TODO: # flow_data_format == 2 : Ethernet Frame Data # flow_data_format == 3 : IPv4 Data # flow_data_format == 4 : IPv6 Data # flow_data_format == 1002 : Extended Router Data # flow_data_format == 1003 : Extended Gateway Data # flow_data_format == 1004 : Extended User Data # flow_data_format == 1005 : Extended Url Data # flow_data_format == 1006 : Extended MPLS Data # flow_data_format == 1007 : Extended NAT Data # flow_data_format == 1008 : Extended MPLS Tunnel # flow_data_format == 1009 : Extended MPLS VC # flow_data_format == 1010 : Extended MPLS FEC # flow_data_format == 1011 : Extended MPLS LVP FEC # flow_data_format == 1012 : Extended VLAN tunnel LOG.info("Unknown format. sFlowV5FlowRecord.flow_data_format=%d", flow_data_format) pack_str = '!%sc' % flow_data_length flow_data = struct.unpack_from(pack_str, buf, offset) msg = cls(enterprise, flow_data_format, flow_data_length, flow_data) return msg class sFlowV5RawPacketHeader(object): _PACK_STR = '!iIII' def __init__(self, header_protocol, frame_length, stripped, header_size, header): super(sFlowV5RawPacketHeader, self).__init__() self.header_protocol = header_protocol self.frame_length = frame_length self.stripped = stripped self.header_size = header_size self.header = header @classmethod def parser(cls, buf, offset): (header_protocol, frame_length, stripped, header_size) = struct.unpack_from(cls._PACK_STR, buf, offset) offset += struct.calcsize(cls._PACK_STR) header_pack_str = '!%sc' % header_size header = struct.unpack_from(header_pack_str, buf, offset) msg = cls(header_protocol, frame_length, stripped, header_size, header) return msg class sFlowV5ExtendedSwitchData(object): _PACK_STR = '!IIII' def __init__(self, src_vlan, src_priority, dest_vlan, dest_priority): super(sFlowV5ExtendedSwitchData, self).__init__() self.src_vlan = src_vlan self.src_priority = src_priority self.dest_vlan = dest_vlan self.dest_priority = dest_priority @classmethod def parser(cls, buf, offset): (src_vlan, src_priority, dest_vlan, dest_priority) = struct.unpack_from(cls._PACK_STR, buf, offset) msg = cls(src_vlan, src_priority, dest_vlan, dest_priority) return msg class sFlowV5CounterSample(object): _PACK_STR = '!III' def __init__(self, sequence_number, source_id_type, source_id_index, counters_records_num, counters_records): super(sFlowV5CounterSample, self).__init__() self.sequence_number = sequence_number self.source_id_type = source_id_type self.source_id_index = source_id_index self.counters_records_num = counters_records_num self.counters_records = counters_records @classmethod def parser(cls, buf, offset): (sequence_number, source_id, counters_records_num) = struct.unpack_from(cls._PACK_STR, buf, offset) index_mask = 0xffffff type_shiftbit = 24 source_id_index = source_id & index_mask source_id_type = source_id >> type_shiftbit offset += struct.calcsize(cls._PACK_STR) counters_records = [] for i in range(counters_records_num): counter_record = sFlowV5CounterRecord.parser(buf, offset) offset += sFlowV5CounterRecord.MIN_LEN offset += counter_record.counter_data_length counters_records.append(counter_record) msg = cls(sequence_number, source_id_type, source_id_index, counters_records_num, counters_records) return msg class sFlowV5CounterRecord(object): _PACK_STR = '!II' MIN_LEN = struct.calcsize(_PACK_STR) def __init__(self, enterprise, counter_data_format, counter_data_length, counter_data): super(sFlowV5CounterRecord, self).__init__() self.enterprise = enterprise self.counter_data_format = counter_data_format self.counter_data_length = counter_data_length self.counter_data = counter_data @classmethod def parser(cls, buf, offset): (counterdata_format, counter_data_length) = struct.unpack_from(cls._PACK_STR, buf, offset) format_mask = 0xfff enterprise_shiftbit = 12 counter_data_format = counterdata_format & format_mask enterprise = counterdata_format >> enterprise_shiftbit offset += cls.MIN_LEN if counter_data_format == 1: # Generic Interface Counters counter_data = sFlowV5GenericInterfaceCounters.parser(buf, offset) else: # TODO: # counter_data_format == 2 : Ethernet Interface Counters # counter_data_format == 3 : Token Ring Counters # counter_data_format == 4 : 100 BaseVG Interface Counters # counter_data_format == 5 : VLAN Counters # counter_data_format == 1001 : Processor Information LOG.info("Unknown format. " + "sFlowV5CounterRecord.counter_data_format=%d" % counter_data_format) pack_str = '!%sc' % counter_data_length counter_data = struct.unpack_from(pack_str, buf, offset) msg = cls(enterprise, counter_data_format, counter_data_length, counter_data) return msg class sFlowV5GenericInterfaceCounters(object): _PACK_STR = '!IIQIIQIIIIIIQIIIIII' def __init__(self, ifIndex, ifType, ifSpeed, ifDirection, ifAdminStatus, ifOperStatus, ifInOctets, ifInUcastPkts, ifInMulticastPkts, ifInBroadcastPkts, ifInDiscards, ifInErrors, ifInUnknownProtos, ifOutOctets, ifOutUcastPkts, ifOutMulticastPkts, ifOutBroadcastPkts, ifOutDiscards, ifOutErrors, ifPromiscuousMode): super(sFlowV5GenericInterfaceCounters, self).__init__() self.ifIndex = ifIndex self.ifType = ifType self.ifSpeed = ifSpeed self.ifDirection = ifDirection self.ifAdminStatus = ifAdminStatus self.ifOperStatus = ifOperStatus self.ifInOctets = ifInOctets self.ifInUcastPkts = ifInUcastPkts self.ifInMulticastPkts = ifInMulticastPkts self.ifInBroadcastPkts = ifInBroadcastPkts self.ifInDiscards = ifInDiscards self.ifInErrors = ifInErrors self.ifInUnknownProtos = ifInUnknownProtos self.ifOutOctets = ifOutOctets self.ifOutUcastPkts = ifOutUcastPkts self.ifOutMulticastPkts = ifOutMulticastPkts self.ifOutBroadcastPkts = ifOutBroadcastPkts self.ifOutDiscards = ifOutDiscards self.ifOutErrors = ifOutErrors self.ifPromiscuousMode = ifPromiscuousMode @classmethod def parser(cls, buf, offset): (ifIndex, ifType, ifSpeed, ifDirection, ifStatus, ifInOctets, ifInUcastPkts, ifInMulticastPkts, ifInBroadcastPkts, ifInDiscards, ifInErrors, ifInUnknownProtos, ifOutOctets, ifOutUcastPkts, ifOutMulticastPkts, ifOutBroadcastPkts, ifOutDiscards, ifOutErrors, ifPromiscuousMode,) = struct.unpack_from(cls._PACK_STR, buf, offset) ifStatus_mask = 0x1 ifAdminStatus_shiftbit = 1 ifOperStatus = ifStatus & ifStatus_mask ifAdminStatus = ifStatus >> ifAdminStatus_shiftbit & ifStatus_mask msg = cls(ifIndex, ifType, ifSpeed, ifDirection, ifAdminStatus, ifOperStatus, ifInOctets, ifInUcastPkts, ifInMulticastPkts, ifInBroadcastPkts, ifInDiscards, ifInErrors, ifInUnknownProtos, ifOutOctets, ifOutUcastPkts, ifOutMulticastPkts, ifOutBroadcastPkts, ifOutDiscards, ifOutErrors, ifPromiscuousMode) return msg ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/log.py0000664000175000017500000000646100000000000015431 0ustar00zuulzuul00000000000000# Copyright (C) 2011 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2011 Isaku Yamahata # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. from os_ken import cfg import inspect import platform import logging import logging.config import logging.handlers import os import sys try: import ConfigParser except ImportError: import configparser as ConfigParser CONF = cfg.CONF CONF.register_cli_opts([ cfg.IntOpt('default-log-level', default=None, help='default log level'), cfg.BoolOpt('verbose', default=False, help='show debug output'), cfg.BoolOpt('use-stderr', default=True, help='log to standard error'), cfg.BoolOpt('use-syslog', default=False, help='output to syslog'), cfg.StrOpt('log-dir', default=None, help='log file directory'), cfg.StrOpt('log-file', default=None, help='log file name'), cfg.StrOpt('log-file-mode', default='0644', help='default log file permission'), cfg.StrOpt('log-config-file', default=None, help='Path to a logging config file to use') ]) _EARLY_LOG_HANDLER = None def early_init_log(level=None): global _EARLY_LOG_HANDLER _EARLY_LOG_HANDLER = logging.StreamHandler(sys.stderr) log = logging.getLogger() log.addHandler(_EARLY_LOG_HANDLER) if level is not None: log.setLevel(level) def _get_log_file(): if CONF.log_file: return CONF.log_file if CONF.log_dir: return os.path.join(CONF.log_dir, os.path.basename(inspect.stack()[-1][1])) + '.log' return None def init_log(): global _EARLY_LOG_HANDLER log = logging.getLogger() if CONF.log_config_file: try: logging.config.fileConfig(CONF.log_config_file, disable_existing_loggers=False) except ConfigParser.Error as e: print('Failed to parse %s: %s' % (CONF.log_config_file, e), file=sys.stderr) sys.exit(2) return if CONF.use_stderr: log.addHandler(logging.StreamHandler(sys.stderr)) if _EARLY_LOG_HANDLER is not None: log.removeHandler(_EARLY_LOG_HANDLER) _EARLY_LOG_HANDLER = None if CONF.use_syslog: if platform.system() == 'Darwin': address = '/var/run/syslog' else: address = '/dev/log' syslog = logging.handlers.SysLogHandler(address=address) log.addHandler(syslog) log_file = _get_log_file() if log_file is not None: log.addHandler(logging.handlers.WatchedFileHandler(log_file)) mode = int(CONF.log_file_mode, 8) os.chmod(log_file, mode) if CONF.default_log_level is not None: log.setLevel(CONF.default_log_level) elif CONF.verbose: log.setLevel(logging.DEBUG) else: log.setLevel(logging.INFO) ././@PaxHeader0000000000000000000000000000003300000000000011451 xustar000000000000000027 mtime=1724334546.098105 os-ken-2.10.0/os_ken/ofproto/0000775000175000017500000000000000000000000015757 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/ofproto/__init__.py0000664000175000017500000000213100000000000020065 0ustar00zuulzuul00000000000000# Copyright (C) 2013,2014 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013 Isaku Yamahata # # 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. import glob import inspect import os.path from os_ken.ofproto import ofproto_protocol def get_ofp_modules(): """get modules pair for the constants and parser of OF-wire of a given OF version. """ return ofproto_protocol._versions def get_ofp_module(ofp_version): """get modules pair for the constants and parser of OF-wire of a given OF version. """ return get_ofp_modules()[ofp_version] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/ofproto/ether.py0000664000175000017500000000012200000000000017433 0ustar00zuulzuul00000000000000# This module is for backward compat from os_ken.lib.packet.ether_types import * ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/ofproto/inet.py0000664000175000017500000000011700000000000017267 0ustar00zuulzuul00000000000000# This module is for backward compat from os_ken.lib.packet.in_proto import * ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/ofproto/nicira_ext.py0000664000175000017500000007532600000000000020473 0ustar00zuulzuul00000000000000# Copyright (C) 2011, 2012 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2011, 2012 Isaku Yamahata # # 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. # Nicira extensions # Many of these definitions are common among OpenFlow versions. import sys from struct import calcsize from os_ken.lib import type_desc from os_ken.ofproto.ofproto_common import OFP_HEADER_SIZE from os_ken.ofproto import oxm_fields # Action subtypes NXAST_RESUBMIT = 1 NXAST_SET_TUNNEL = 2 NXAST_DROP_SPOOFED_ARP__OBSOLETE = 3 NXAST_SET_QUEUE = 4 NXAST_POP_QUEUE = 5 NXAST_REG_MOVE = 6 NXAST_REG_LOAD = 7 NXAST_NOTE = 8 NXAST_SET_TUNNEL64 = 9 NXAST_MULTIPATH = 10 NXAST_AUTOPATH = 11 NXAST_BUNDLE = 12 NXAST_BUNDLE_LOAD = 13 NXAST_RESUBMIT_TABLE = 14 NXAST_OUTPUT_REG = 15 NXAST_LEARN = 16 NXAST_EXIT = 17 NXAST_DEC_TTL = 18 NXAST_FIN_TIMEOUT = 19 NXAST_CONTROLLER = 20 NXAST_DEC_TTL_CNT_IDS = 21 NXAST_PUSH_MPLS = 23 NXAST_POP_MPLS = 24 NXAST_SET_MPLS_TTL = 25 NXAST_DEC_MPLS_TTL = 26 NXAST_STACK_PUSH = 27 NXAST_STACK_POP = 28 NXAST_SAMPLE = 29 NXAST_SET_MPLS_LABEL = 30 NXAST_SET_MPLS_TC = 31 NXAST_OUTPUT_REG2 = 32 NXAST_REG_LOAD2 = 33 NXAST_CONJUNCTION = 34 NXAST_CT = 35 NXAST_NAT = 36 NXAST_CONTROLLER2 = 37 NXAST_SAMPLE2 = 38 NXAST_OUTPUT_TRUNC = 39 NXAST_CT_CLEAR = 43 NXAST_RAW_ENCAP = 46 NXAST_RAW_DECAP = 47 NXAST_DEC_NSH_TTL = 48 NX_ACTION_RESUBMIT_PACK_STR = '!HHIHHB3x' NX_ACTION_RESUBMIT_SIZE = 16 assert calcsize(NX_ACTION_RESUBMIT_PACK_STR) == NX_ACTION_RESUBMIT_SIZE NX_ACTION_SET_TUNNEL_PACK_STR = '!HHIH2xI' NX_ACTION_SET_TUNNEL_SIZE = 16 assert calcsize(NX_ACTION_SET_TUNNEL_PACK_STR) == NX_ACTION_SET_TUNNEL_SIZE NX_ACTION_SET_QUEUE_PACK_STR = '!HHIH2xI' NX_ACTION_SET_QUEUE_SIZE = 16 assert calcsize(NX_ACTION_SET_QUEUE_PACK_STR) == NX_ACTION_SET_QUEUE_SIZE NX_ACTION_POP_QUEUE_PACK_STR = '!HHIH6x' NX_ACTION_POP_QUEUE_SIZE = 16 assert calcsize(NX_ACTION_POP_QUEUE_PACK_STR) == NX_ACTION_POP_QUEUE_SIZE NX_ACTION_REG_MOVE_PACK_STR = '!HHIHHHHII' NX_ACTION_REG_MOVE_SIZE = 24 assert calcsize(NX_ACTION_REG_MOVE_PACK_STR) == NX_ACTION_REG_MOVE_SIZE NX_ACTION_REG_LOAD_PACK_STR = '!HHIHHIQ' NX_ACTION_REG_LOAD_SIZE = 24 assert calcsize(NX_ACTION_REG_LOAD_PACK_STR) == NX_ACTION_REG_LOAD_SIZE NX_ACTION_SET_TUNNEL64_PACK_STR = '!HHIH6xQ' NX_ACTION_SET_TUNNEL64_SIZE = 24 assert calcsize(NX_ACTION_SET_TUNNEL64_PACK_STR) == NX_ACTION_SET_TUNNEL64_SIZE NX_ACTION_MULTIPATH_PACK_STR = '!HHIHHH2xHHI2xHI' NX_ACTION_MULTIPATH_SIZE = 32 assert calcsize(NX_ACTION_MULTIPATH_PACK_STR) == NX_ACTION_MULTIPATH_SIZE NX_ACTION_NOTE_PACK_STR = '!HHIH6B' NX_ACTION_NOTE_SIZE = 16 assert calcsize(NX_ACTION_NOTE_PACK_STR) == NX_ACTION_NOTE_SIZE NX_ACTION_BUNDLE_PACK_STR = '!HHIHHHHIHHI4x' NX_ACTION_BUNDLE_SIZE = 32 NX_ACTION_BUNDLE_0_SIZE = 24 assert calcsize(NX_ACTION_BUNDLE_PACK_STR) == NX_ACTION_BUNDLE_SIZE NX_ACTION_AUTOPATH_PACK_STR = '!HHIHHII4x' NX_ACTION_AUTOPATH_SIZE = 24 assert calcsize(NX_ACTION_AUTOPATH_PACK_STR) == NX_ACTION_AUTOPATH_SIZE NX_ACTION_OUTPUT_REG_PACK_STR = '!HHIHHIH6x' NX_ACTION_OUTPUT_REG_SIZE = 24 assert calcsize(NX_ACTION_OUTPUT_REG_PACK_STR) == NX_ACTION_OUTPUT_REG_SIZE NX_ACTION_LEARN_PACK_STR = '!HHIHHHHQHBxHH' NX_ACTION_LEARN_SIZE = 32 assert calcsize(NX_ACTION_LEARN_PACK_STR) == NX_ACTION_LEARN_SIZE NX_ACTION_CONTROLLER_PACK_STR = '!HHIHHHBB' NX_ACTION_CONTROLLER_SIZE = 16 assert calcsize(NX_ACTION_CONTROLLER_PACK_STR) == NX_ACTION_CONTROLLER_SIZE NX_ACTION_FIN_TIMEOUT_PACK_STR = '!HHIHHH2x' NX_ACTION_FIN_TIMEOUT_SIZE = 16 assert calcsize(NX_ACTION_FIN_TIMEOUT_PACK_STR) == NX_ACTION_FIN_TIMEOUT_SIZE NX_ACTION_HEADER_PACK_STR = '!HHIH6x' NX_ACTION_HEADER_SIZE = 16 NX_ACTION_HEADER_0_SIZE = 2 assert calcsize(NX_ACTION_HEADER_PACK_STR) == NX_ACTION_HEADER_SIZE # Messages NXT_ROLE_REQUEST = 10 NXT_ROLE_REPLY = 11 NXT_SET_FLOW_FORMAT = 12 NXT_FLOW_MOD = 13 NXT_FLOW_REMOVED = 14 NXT_FLOW_MOD_TABLE_ID = 15 NXT_SET_PACKET_IN_FORMAT = 16 NXT_PACKET_IN = 17 NXT_FLOW_AGE = 18 NXT_SET_ASYNC_CONFIG = 19 NXT_SET_CONTROLLER_ID = 20 NXT_PACKET_IN2 = 30 # nx_packet_in2_prop_type NXPINT_PACKET = 0 NXPINT_FULL_LEN = 1 NXPINT_BUFFER_ID = 2 NXPINT_TABLE_ID = 3 NXPINT_COOKIE = 4 NXPINT_REASON = 5 NXPINT_METADATA = 6 NXPINT_USERDATA = 7 NXPINT_CONTINUATION = 8 # enum nx_role NX_ROLE_OTHER = 0 NX_ROLE_MASTER = 1 NX_ROLE_SLAVE = 2 # enum nx_flow_format NXFF_OPENFLOW10 = 0 NXFF_NXM = 2 # enum nx_packet_in_format NXPIF_OPENFLOW10 = 0 NXPIF_NXM = 1 # enum nx_stats_types NXST_FLOW = 0 NXST_AGGREGATE = 1 NXST_FLOW_MONITOR = 2 # enum nx_action_controller2_prop_type NXAC2PT_MAX_LEN = 0 NXAC2PT_CONTROLLER_ID = 1 NXAC2PT_REASON = 2 NXAC2PT_USERDATA = 3 NXAC2PT_PAUSE = 4 NICIRA_HEADER_PACK_STR = '!II' NICIRA_HEADER_SIZE = 16 assert (calcsize(NICIRA_HEADER_PACK_STR) + OFP_HEADER_SIZE == NICIRA_HEADER_SIZE) NX_ROLE_PACK_STR = '!I' NX_ROLE_SIZE = 20 assert (calcsize(NX_ROLE_PACK_STR) + NICIRA_HEADER_SIZE == NX_ROLE_SIZE) NX_FLOW_MOD_PACK_STR = '!Q4HI3H6x' NX_FLOW_MOD_SIZE = 48 assert (calcsize(NX_FLOW_MOD_PACK_STR) + NICIRA_HEADER_SIZE == NX_FLOW_MOD_SIZE) NX_SET_FLOW_FORMAT_PACK_STR = '!I' NX_SET_FLOW_FORMAT_SIZE = 20 assert (calcsize(NX_SET_FLOW_FORMAT_PACK_STR) + NICIRA_HEADER_SIZE == NX_SET_FLOW_FORMAT_SIZE) NX_FLOW_REMOVED_PACK_STR = '!QHBxIIHHQQ' NX_FLOW_REMOVED_SIZE = 56 assert (calcsize(NX_FLOW_REMOVED_PACK_STR) + NICIRA_HEADER_SIZE == NX_FLOW_REMOVED_SIZE) NX_FLOW_MOD_TABLE_ID_PACK_STR = '!B7x' NX_FLOW_MOD_TABLE_ID_SIZE = 24 assert (calcsize(NX_FLOW_MOD_TABLE_ID_PACK_STR) + NICIRA_HEADER_SIZE == NX_FLOW_MOD_TABLE_ID_SIZE) NX_SET_PACKET_IN_FORMAT_PACK_STR = '!I' NX_SET_PACKET_IN_FORMAT_SIZE = 20 assert (calcsize(NX_SET_PACKET_IN_FORMAT_PACK_STR) + NICIRA_HEADER_SIZE == NX_SET_PACKET_IN_FORMAT_SIZE) NX_PACKET_IN_PACK_STR = '!IHBBQH6x' NX_PACKET_IN_SIZE = 40 assert (calcsize(NX_PACKET_IN_PACK_STR) + NICIRA_HEADER_SIZE == NX_PACKET_IN_SIZE) NX_ASYNC_CONFIG_PACK_STR = '!IIIIII' NX_ASYNC_CONFIG_SIZE = 40 assert (calcsize(NX_ASYNC_CONFIG_PACK_STR) + NICIRA_HEADER_SIZE == NX_ASYNC_CONFIG_SIZE) NX_CONTROLLER_ID_PACK_STR = '!6xH' NX_CONTROLLER_ID_SIZE = 24 assert (calcsize(NX_CONTROLLER_ID_PACK_STR) + NICIRA_HEADER_SIZE == NX_CONTROLLER_ID_SIZE) NX_STATS_MSG_PACK_STR = '!I4x' NX_STATS_MSG0_SIZE = 8 assert calcsize(NX_STATS_MSG_PACK_STR) == NX_STATS_MSG0_SIZE NX_STATS_MSG_SIZE = 24 _OFP_VENDOR_STATS_MSG_SIZE = 16 assert (calcsize(NX_STATS_MSG_PACK_STR) + _OFP_VENDOR_STATS_MSG_SIZE == NX_STATS_MSG_SIZE) NX_FLOW_STATS_REQUEST_PACK_STR = '!2HB3x' NX_FLOW_STATS_REQUEST_SIZE = 8 assert (calcsize(NX_FLOW_STATS_REQUEST_PACK_STR) == NX_FLOW_STATS_REQUEST_SIZE) NX_FLOW_STATS_PACK_STR = '!HBxIIHHHHHHQQQ' NX_FLOW_STATS_SIZE = 48 assert calcsize(NX_FLOW_STATS_PACK_STR) == NX_FLOW_STATS_SIZE NX_AGGREGATE_STATS_REQUEST_PACK_STR = '!2HB3x' NX_AGGREGATE_STATS_REQUEST_SIZE = 8 assert (calcsize(NX_AGGREGATE_STATS_REQUEST_PACK_STR) == NX_AGGREGATE_STATS_REQUEST_SIZE) NX_AGGREGATE_STATS_REPLY_PACK_STR = '!QQI4x' NX_AGGREGATE_STATS_REPLY_SIZE = 24 assert (calcsize(NX_AGGREGATE_STATS_REPLY_PACK_STR) == NX_AGGREGATE_STATS_REPLY_SIZE) # enum nx_hash_fields NX_HASH_FIELDS_ETH_SRC = 0 NX_HASH_FIELDS_SYMMETRIC_L4 = 1 # enum nx_mp_algorithm NX_MP_ALG_MODULO_N = 0 NX_MP_ALG_HASH_THRESHOLD = 1 NX_MP_ALG_HRW = 2 NX_MP_ALG_ITER_HASH = 3 # enum nx_bd_algorithm NX_BD_ALG_ACTIVE_BACKUP = 0 NX_BD_ALG_HRW = 1 # nx_learn constants NX_LEARN_N_BITS_MASK = 0x3ff NX_LEARN_SRC_FIELD = 0 << 13 # Copy from field. NX_LEARN_SRC_IMMEDIATE = 1 << 13 # Copy from immediate value. NX_LEARN_SRC_MASK = 1 << 13 NX_LEARN_DST_MATCH = 0 << 11 # Add match criterion. NX_LEARN_DST_LOAD = 1 << 11 # Add NXAST_REG_LOAD action NX_LEARN_DST_OUTPUT = 2 << 11 # Add OFPAT_OUTPUT action. NX_LEARN_DST_RESERVED = 3 << 11 # Not yet defined. NX_LEARN_DST_MASK = 3 << 11 # nx_ct constants NX_CT_F_COMMIT = 1 << 0 NX_CT_F_FORCE = 1 << 1 NX_CT_RECIRC_NONE = 0xff # OFPTT_ALL # nx_nat constants NX_NAT_RANGE_IPV4_MIN = 1 << 0 NX_NAT_RANGE_IPV4_MAX = 1 << 1 NX_NAT_RANGE_IPV6_MIN = 1 << 2 NX_NAT_RANGE_IPV6_MAX = 1 << 3 NX_NAT_RANGE_PROTO_MIN = 1 << 4 NX_NAT_RANGE_PROTO_MAX = 1 << 5 # nx ip_frag constants FLOW_NW_FRAG_ANY = 1 << 0 # Set for any IP frag. FLOW_NW_FRAG_LATER = 1 << 1 # Set for IP frag with nonzero offset. FLOW_NW_FRAG_MASK = FLOW_NW_FRAG_ANY | FLOW_NW_FRAG_LATER # nx ip_frag match values NXM_IP_FRAG_NO = (0, FLOW_NW_FRAG_MASK) NXM_IP_FRAG_YES = (FLOW_NW_FRAG_ANY, FLOW_NW_FRAG_ANY) NXM_IP_FRAG_FIRST = (FLOW_NW_FRAG_ANY, FLOW_NW_FRAG_MASK) NXM_IP_FRAG_LATER = (FLOW_NW_FRAG_LATER, FLOW_NW_FRAG_LATER) NXM_IP_FRAG_NOT_LATER = (0, FLOW_NW_FRAG_LATER) def ofs_nbits(start, end): r""" The utility method for ofs_nbits This method is used in the class to set the ofs_nbits. This method converts start/end bits into ofs_nbits required to specify the bit range of OXM/NXM fields. ofs_nbits can be calculated as following:: ofs_nbits = (start << 6) + (end - start) The parameter start/end means the OXM/NXM field of ovs-ofctl command. .. field[start..end] .. +------------------------------------------+ | *field*\ **[**\ *start*\..\ *end*\ **]** | +------------------------------------------+ ================ ====================================================== Attribute Description ================ ====================================================== start Start bit for OXM/NXM field end End bit for OXM/NXM field ================ ====================================================== """ return (start << 6) + (end - start) def ofs_nbits_str(n): start = 0 while True: start += 1 if (start << 6) > n: break start -= 1 end = n + start - (start << 6) return "[%d..%d]" % (start, end) def nxm_header__(vendor, field, hasmask, length): return (vendor << 16) | (field << 9) | (hasmask << 8) | length def nxm_header(vendor, field, length): return nxm_header__(vendor, field, 0, length) def nxm_header_w(vendor, field, length): return nxm_header__(vendor, field, 1, (length) * 2) NXM_OF_IN_PORT = nxm_header(0x0000, 0, 2) NXM_OF_ETH_DST = nxm_header(0x0000, 1, 6) NXM_OF_ETH_DST_W = nxm_header_w(0x0000, 1, 6) NXM_OF_ETH_SRC = nxm_header(0x0000, 2, 6) NXM_OF_ETH_SRC_W = nxm_header_w(0x0000, 2, 6) NXM_OF_ETH_TYPE = nxm_header(0x0000, 3, 2) NXM_OF_VLAN_TCI = nxm_header(0x0000, 4, 2) NXM_OF_VLAN_TCI_W = nxm_header_w(0x0000, 4, 2) NXM_OF_IP_TOS = nxm_header(0x0000, 5, 1) NXM_OF_IP_PROTO = nxm_header(0x0000, 6, 1) NXM_OF_IP_SRC = nxm_header(0x0000, 7, 4) NXM_OF_IP_SRC_W = nxm_header_w(0x0000, 7, 4) NXM_OF_IP_DST = nxm_header(0x0000, 8, 4) NXM_OF_IP_DST_W = nxm_header_w(0x0000, 8, 4) NXM_OF_TCP_SRC = nxm_header(0x0000, 9, 2) NXM_OF_TCP_SRC_W = nxm_header_w(0x0000, 9, 2) NXM_OF_TCP_DST = nxm_header(0x0000, 10, 2) NXM_OF_TCP_DST_W = nxm_header_w(0x0000, 10, 2) NXM_OF_UDP_SRC = nxm_header(0x0000, 11, 2) NXM_OF_UDP_SRC_W = nxm_header_w(0x0000, 11, 2) NXM_OF_UDP_DST = nxm_header(0x0000, 12, 2) NXM_OF_UDP_DST_W = nxm_header_w(0x0000, 12, 2) NXM_OF_ICMP_TYPE = nxm_header(0x0000, 13, 1) NXM_OF_ICMP_CODE = nxm_header(0x0000, 14, 1) NXM_OF_ARP_OP = nxm_header(0x0000, 15, 2) NXM_OF_ARP_SPA = nxm_header(0x0000, 16, 4) NXM_OF_ARP_SPA_W = nxm_header_w(0x0000, 16, 4) NXM_OF_ARP_TPA = nxm_header(0x0000, 17, 4) NXM_OF_ARP_TPA_W = nxm_header_w(0x0000, 17, 4) NXM_NX_TUN_ID = nxm_header(0x0001, 16, 8) NXM_NX_TUN_ID_W = nxm_header_w(0x0001, 16, 8) NXM_NX_TUN_IPV4_SRC = nxm_header(0x0001, 31, 4) NXM_NX_TUN_IPV4_SRC_W = nxm_header_w(0x0001, 31, 4) NXM_NX_TUN_IPV4_DST = nxm_header(0x0001, 32, 4) NXM_NX_TUN_IPV4_DST_W = nxm_header_w(0x0001, 32, 4) NXM_NX_ARP_SHA = nxm_header(0x0001, 17, 6) NXM_NX_ARP_THA = nxm_header(0x0001, 18, 6) NXM_NX_IPV6_SRC = nxm_header(0x0001, 19, 16) NXM_NX_IPV6_SRC_W = nxm_header_w(0x0001, 19, 16) NXM_NX_IPV6_DST = nxm_header(0x0001, 20, 16) NXM_NX_IPV6_DST_W = nxm_header_w(0x0001, 20, 16) NXM_NX_ICMPV6_TYPE = nxm_header(0x0001, 21, 1) NXM_NX_ICMPV6_CODE = nxm_header(0x0001, 22, 1) NXM_NX_ND_TARGET = nxm_header(0x0001, 23, 16) NXM_NX_ND_TARGET_W = nxm_header_w(0x0001, 23, 16) NXM_NX_ND_SLL = nxm_header(0x0001, 24, 6) NXM_NX_ND_TLL = nxm_header(0x0001, 25, 6) NXM_NX_IP_FRAG = nxm_header(0x0001, 26, 1) NXM_NX_IP_FRAG_W = nxm_header_w(0x0001, 26, 1) NXM_NX_IPV6_LABEL = nxm_header(0x0001, 27, 4) NXM_NX_IP_ECN = nxm_header(0x0001, 28, 1) NXM_NX_IP_TTL = nxm_header(0x0001, 29, 1) NXM_NX_PKT_MARK = nxm_header(0x0001, 33, 4) NXM_NX_PKT_MARK_W = nxm_header_w(0x0001, 33, 4) NXM_NX_TCP_FLAGS = nxm_header(0x0001, 34, 2) NXM_NX_TCP_FLAGS_W = nxm_header_w(0x0001, 34, 2) def nxm_nx_reg(idx): return nxm_header(0x0001, idx, 4) def nxm_nx_reg_w(idx): return nxm_header_w(0x0001, idx, 4) NXM_HEADER_PACK_STRING = '!I' # # The followings are implementations for OpenFlow 1.2+ # sys.modules[__name__].__doc__ = """ The API of this class is the same as ``OFPMatch``. You can define the flow match by the keyword arguments. The following arguments are available. ================ =============== ============================================== Argument Value Description ================ =============== ============================================== in_port_nxm Integer 16bit OpenFlow port number. eth_dst_nxm MAC address Ethernet destination address. eth_src_nxm MAC address Ethernet source address. eth_type_nxm Integer 16bit Ethernet type. Needed to support Nicira extensions that require the eth_type to be set. (i.e. tcp_flags_nxm) vlan_tci Integer 16bit VLAN TCI. Basically same as vlan_vid plus vlan_pcp. nw_tos Integer 8bit IP ToS or IPv6 traffic class field dscp. Requires setting fields: eth_type_nxm = [0x0800 (IPv4)|0x86dd (IPv6)] ip_proto_nxm Integer 8bit IP protocol. Needed to support Nicira extensions that require the ip_proto to be set. (i.e. tcp_flags_nxm) Requires setting fields: eth_type_nxm = [0x0800 (IPv4)|0x86dd (IPv6)] ipv4_src_nxm IPv4 address IPv4 source address. Requires setting fields: eth_type_nxm = 0x0800 (IPv4) ipv4_dst_nxm IPv4 address IPv4 destination address. Requires setting fields: eth_type_nxm = 0x0800 (IPv4) tcp_src_nxm Integer 16bit TCP source port. Requires setting fields: eth_type_nxm = [0x0800 (IPv4)|0x86dd (IPv6)] and ip_proto_nxm = 6 (TCP) tcp_dst_nxm Integer 16bit TCP destination port. Requires setting fields: eth_type_nxm = [0x0800 (IPv4)|0x86dd (IPv6)] and ip_proto_nxm = 6 (TCP) udp_src_nxm Integer 16bit UDP source port. Requires setting fields: eth_type_nxm = [0x0800 (IPv4)|0x86dd (IPv6)] and ip_proto_nxm = 17 (UDP) udp_dst_nxm Integer 16bit UDP destination port. eth_type_nxm = [0x0800 (IPv4)|0x86dd (IPv6)] and ip_proto_nxm = 17 (UDP) icmpv4_type_nxm Integer 8bit Type matches the ICMP type and code matches the ICMP code. Requires setting fields: eth_type_nxm = 0x0800 (IPv4) and ip_proto_nxm = 1 (ICMP) icmpv4_code_nxm Integer 8bit Type matches the ICMP type and code matches the ICMP code. Requires setting fields: eth_type_nxm = 0x0800 (IPv4) and ip_proto_nxm = 1 (ICMP) arp_op_nxm Integer 16bit Only ARP opcodes between 1 and 255 should be specified for matching. Requires setting fields: eth_type_nxm = 0x0806 (ARP) arp_spa_nxm IPv4 address An address may be specified as an IP address or host name. Requires setting fields: eth_type_nxm = 0x0806 (ARP) arp_tpa_nxm IPv4 address An address may be specified as an IP address or host name. Requires setting fields: eth_type_nxm = 0x0806 (ARP) tunnel_id_nxm Integer 64bit Tunnel identifier. arp_sha_nxm MAC address An address is specified as 6 pairs of hexadecimal digits delimited by colons. Requires setting fields: eth_type_nxm = 0x0806 (ARP) arp_tha_nxm MAC address An address is specified as 6 pairs of hexadecimal digits delimited by colons. Requires setting fields: eth_type_nxm = 0x0806 (ARP) ipv6_src_nxm IPv6 address IPv6 source address. Requires setting fields: eth_type_nxm = 0x86dd (IPv6) ipv6_dst_nxm IPv6 address IPv6 destination address. Requires setting fields: eth_type_nxm = 0x86dd (IPv6) icmpv6_type_nxm Integer 8bit Type matches the ICMP type and code matches the ICMP code. Requires setting fields: eth_type_nxm = 0x86dd (IPv6) and ip_proto_nxm = 58 (ICMP for IPv6) icmpv6_code_nxm Integer 8bit Type matches the ICMP type and code matches the ICMP code. Requires setting fields: eth_type_nxm = 0x86dd (IPv6) and ip_proto_nxm = 58 (ICMP for IPv6) nd_target IPv6 address The target address ipv6. Requires setting fields: eth_type_nxm = 0x86dd (IPv6) and ip_proto_nxm = 58 (ICMP for IPv6) nd_sll MAC address The source link-layer address option. Requires setting fields: eth_type_nxm = 0x86dd (IPv6) and ip_proto_nxm = 58 (ICMP for IPv6) and icmpv6_type_nxm = 135 (Neighbor solicitation) nd_tll MAC address The target link-layer address option. Requires setting fields: eth_type_nxm = 0x86dd (IPv6) and ip_proto_nxm = 58 (ICMP for IPv6) and icmpv6_type_nxm = 136 (Neighbor advertisement) ip_frag Integer 8bit frag_type specifies what kind of IP fragments or non-fragments to match. Requires setting fields: eth_type_nxm = [0x0800 (IPv4)|0x86dd (IPv6)] ipv6_label Integer 32bit Matches IPv6 flow label. Requires setting fields: eth_type_nxm = 0x86dd (IPv6) ip_ecn_nxm Integer 8bit Matches ecn bits in IP ToS or IPv6 traffic class fields. Requires setting fields: eth_type_nxm = [0x0800 (IPv4)|0x86dd (IPv6)] nw_ttl Integer 8bit IP TTL or IPv6 hop limit value ttl. Requires setting fields: eth_type_nxm = [0x0800 (IPv4)|0x86dd (IPv6)] mpls_ttl Integer 8bit The TTL of the outer MPLS label stack entry of a packet. Requires setting fields: eth_type_nxm = 0x8847 (MPLS Unicast) tun_ipv4_src IPv4 address Tunnel IPv4 source address. Requires setting fields: eth_type_nxm = 0x0800 (IPv4) tun_ipv4_dst IPv4 address Tunnel IPv4 destination address. Requires setting fields: eth_type_nxm = 0x0800 (IPv4) pkt_mark Integer 32bit Packet metadata mark. tcp_flags_nxm Integer 16bit TCP Flags. Requires setting fields: eth_type_nxm = [0x0800 (IP)|0x86dd (IPv6)] and ip_proto_nxm = 6 (TCP) conj_id Integer 32bit Conjunction ID used only with the conjunction action tun_gbp_id Integer 16bit The group policy identifier in the VXLAN header. tun_gbp_flags Integer 8bit The group policy flags in the VXLAN header. tun_flags Integer 16bit Flags indicating various aspects of the tunnel encapsulation. ct_state Integer 32bit Conntrack state. ct_zone Integer 16bit Conntrack zone. ct_mark Integer 32bit Conntrack mark. ct_label Integer 128bit Conntrack label. tun_ipv6_src IPv6 address Tunnel IPv6 source address. Requires setting fields: eth_type_nxm = 0x86dd (IPv6) tun_ipv6_dst IPv6 address Tunnel IPv6 destination address. Requires setting fields: eth_type_nxm = 0x86dd (IPv6) _recirc_id Integer 32bit ID for recirculation. _dp_hash Integer 32bit Flow hash computed in Datapath. nsh_flags Integer 8bit Flags field in NSH Base Header. Requires eth_type_nxm = 0x894f (NSH). Since OpenFlow 1.3 and OVS v2.8. nsh_mdtype Integer 8bit Metadata Type in NSH Base Header. Requires eth_type_nxm = 0x894f (NSH). Since OpenFlow 1.3 and OVS v2.8. nsh_np Integer 8bit Next Protocol type in NSH Base Header. Requires eth_type_nxm = 0x894f (NSH). Since OpenFlow 1.3 and OVS v2.8. nsh_spi Integer 32bit Service Path Identifier in NSH Service Path Header. Requires eth_type_nxm = 0x894f (NSH). Since OpenFlow 1.3 and OVS v2.8. nsh_si Integer 8bit Service Index in NSH Service Path Header. Requires eth_type_nxm = 0x894f (NSH). Since OpenFlow 1.3 and OVS v2.8. nsh_c Integer 32bit Context fields in NSH Context Header. is a number of 1-4. Requires eth_type_nxm = 0x894f (NSH). Since OpenFlow 1.3 and OVS v2.8. nsh_ttl Integer 8bit TTL field in NSH Base Header. Requires eth_type_nxm = 0x894f (NSH). Since OpenFlow 1.3 and OVS v2.9. reg Integer 32bit Packet register. is register number 0-15. xxreg Integer 128bit Packet extended-extended register. is register number 0-3. ================ =============== ============================================== .. Note:: Setting the TCP flags via the nicira extensions. This is required when using OVS version < 2.4. When using the nxm fields, you need to use any nxm prereq fields as well or you will receive a OFPBMC_BAD_PREREQ error Example:: # WILL NOT work flag = tcp.TCP_ACK match = parser.OFPMatch( tcp_flags_nxm=(flag, flag), ip_proto=inet.IPPROTO_TCP, eth_type=eth_type) # Works flag = tcp.TCP_ACK match = parser.OFPMatch( tcp_flags_nxm=(flag, flag), ip_proto_nxm=inet.IPPROTO_TCP, eth_type_nxm=eth_type) """ oxm_types = [ # OFPXMC_NXM_0 oxm_fields.NiciraExtended0('in_port_nxm', 0, type_desc.Int2), oxm_fields.NiciraExtended0('eth_dst_nxm', 1, type_desc.MacAddr), oxm_fields.NiciraExtended0('eth_src_nxm', 2, type_desc.MacAddr), oxm_fields.NiciraExtended0('eth_type_nxm', 3, type_desc.Int2), oxm_fields.NiciraExtended0('vlan_tci', 4, type_desc.Int2), oxm_fields.NiciraExtended0('nw_tos', 5, type_desc.Int1), oxm_fields.NiciraExtended0('ip_proto_nxm', 6, type_desc.Int1), oxm_fields.NiciraExtended0('ipv4_src_nxm', 7, type_desc.IPv4Addr), oxm_fields.NiciraExtended0('ipv4_dst_nxm', 8, type_desc.IPv4Addr), oxm_fields.NiciraExtended0('tcp_src_nxm', 9, type_desc.Int2), oxm_fields.NiciraExtended0('tcp_dst_nxm', 10, type_desc.Int2), oxm_fields.NiciraExtended0('udp_src_nxm', 11, type_desc.Int2), oxm_fields.NiciraExtended0('udp_dst_nxm', 12, type_desc.Int2), oxm_fields.NiciraExtended0('icmpv4_type_nxm', 13, type_desc.Int1), oxm_fields.NiciraExtended0('icmpv4_code_nxm', 14, type_desc.Int1), oxm_fields.NiciraExtended0('arp_op_nxm', 15, type_desc.Int2), oxm_fields.NiciraExtended0('arp_spa_nxm', 16, type_desc.IPv4Addr), oxm_fields.NiciraExtended0('arp_tpa_nxm', 17, type_desc.IPv4Addr), # OFPXMC_NXM_1 oxm_fields.NiciraExtended1('tunnel_id_nxm', 16, type_desc.Int8), oxm_fields.NiciraExtended1('arp_sha_nxm', 17, type_desc.MacAddr), oxm_fields.NiciraExtended1('arp_tha_nxm', 18, type_desc.MacAddr), oxm_fields.NiciraExtended1('ipv6_src_nxm', 19, type_desc.IPv6Addr), oxm_fields.NiciraExtended1('ipv6_dst_nxm', 20, type_desc.IPv6Addr), oxm_fields.NiciraExtended1('icmpv6_type_nxm', 21, type_desc.Int1), oxm_fields.NiciraExtended1('icmpv6_code_nxm', 22, type_desc.Int1), oxm_fields.NiciraExtended1('nd_target', 23, type_desc.IPv6Addr), oxm_fields.NiciraExtended1('nd_sll', 24, type_desc.MacAddr), oxm_fields.NiciraExtended1('nd_tll', 25, type_desc.MacAddr), oxm_fields.NiciraExtended1('ip_frag', 26, type_desc.Int1), oxm_fields.NiciraExtended1('ipv6_label', 27, type_desc.Int4), oxm_fields.NiciraExtended1('ip_ecn_nxm', 28, type_desc.Int1), oxm_fields.NiciraExtended1('nw_ttl', 29, type_desc.Int1), oxm_fields.NiciraExtended1('mpls_ttl', 30, type_desc.Int1), oxm_fields.NiciraExtended1('tun_ipv4_src', 31, type_desc.IPv4Addr), oxm_fields.NiciraExtended1('tun_ipv4_dst', 32, type_desc.IPv4Addr), oxm_fields.NiciraExtended1('pkt_mark', 33, type_desc.Int4), oxm_fields.NiciraExtended1('tcp_flags_nxm', 34, type_desc.Int2), oxm_fields.NiciraExtended1('conj_id', 37, type_desc.Int4), oxm_fields.NiciraExtended1('tun_gbp_id', 38, type_desc.Int2), oxm_fields.NiciraExtended1('tun_gbp_flags', 39, type_desc.Int1), oxm_fields.NiciraExtended1('tun_flags', 104, type_desc.Int2), oxm_fields.NiciraExtended1('ct_state', 105, type_desc.Int4), oxm_fields.NiciraExtended1('ct_zone', 106, type_desc.Int2), oxm_fields.NiciraExtended1('ct_mark', 107, type_desc.Int4), oxm_fields.NiciraExtended1('ct_label', 108, type_desc.Int16), oxm_fields.NiciraExtended1('tun_ipv6_src', 109, type_desc.IPv6Addr), oxm_fields.NiciraExtended1('tun_ipv6_dst', 110, type_desc.IPv6Addr), # Prefix the name with '_' to indicate this is not intended to be used # in wild. # Because the following definitions are supposed to be internal use only # in OVS. oxm_fields.NiciraExtended1('_recirc_id', 36, type_desc.Int4), # The following definition is merely for testing 64-bit experimenter OXMs. # Following Open vSwitch, we use dp_hash for this purpose. # Prefix the name with '_' to indicate this is not intended to be used # in wild. oxm_fields.NiciraExperimenter('_dp_hash', 0, type_desc.Int4), # Nicira Experimenter for Network Service Header oxm_fields.NiciraNshExperimenter('nsh_flags', 1, type_desc.Int1), oxm_fields.NiciraNshExperimenter('nsh_mdtype', 2, type_desc.Int1), oxm_fields.NiciraNshExperimenter('nsh_np', 3, type_desc.Int1), # aka "nsp" oxm_fields.NiciraNshExperimenter('nsh_spi', 4, type_desc.Int4), # aka "nsi" oxm_fields.NiciraNshExperimenter('nsh_si', 5, type_desc.Int1), # aka "nshc" oxm_fields.NiciraNshExperimenter('nsh_c1', 6, type_desc.Int4), oxm_fields.NiciraNshExperimenter('nsh_c2', 7, type_desc.Int4), oxm_fields.NiciraNshExperimenter('nsh_c3', 8, type_desc.Int4), oxm_fields.NiciraNshExperimenter('nsh_c4', 9, type_desc.Int4), oxm_fields.NiciraNshExperimenter('nsh_ttl', 10, type_desc.Int1), # Support for matching/setting NX registers 0-15 oxm_fields.NiciraExtended1('reg0', 0, type_desc.Int4), oxm_fields.NiciraExtended1('reg1', 1, type_desc.Int4), oxm_fields.NiciraExtended1('reg2', 2, type_desc.Int4), oxm_fields.NiciraExtended1('reg3', 3, type_desc.Int4), oxm_fields.NiciraExtended1('reg4', 4, type_desc.Int4), oxm_fields.NiciraExtended1('reg5', 5, type_desc.Int4), oxm_fields.NiciraExtended1('reg6', 6, type_desc.Int4), oxm_fields.NiciraExtended1('reg7', 7, type_desc.Int4), oxm_fields.NiciraExtended1('reg8', 8, type_desc.Int4), oxm_fields.NiciraExtended1('reg9', 9, type_desc.Int4), oxm_fields.NiciraExtended1('reg10', 10, type_desc.Int4), oxm_fields.NiciraExtended1('reg11', 11, type_desc.Int4), oxm_fields.NiciraExtended1('reg12', 12, type_desc.Int4), oxm_fields.NiciraExtended1('reg13', 13, type_desc.Int4), oxm_fields.NiciraExtended1('reg14', 14, type_desc.Int4), oxm_fields.NiciraExtended1('reg15', 15, type_desc.Int4), # Support for matching/setting NX extended-extended registers 0-3 oxm_fields.NiciraExtended1('xxreg0', 111, type_desc.Int16), oxm_fields.NiciraExtended1('xxreg1', 112, type_desc.Int16), oxm_fields.NiciraExtended1('xxreg2', 113, type_desc.Int16), oxm_fields.NiciraExtended1('xxreg3', 114, type_desc.Int16), ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/ofproto/nx_actions.py0000664000175000017500000032313400000000000020504 0ustar00zuulzuul00000000000000# Copyright (C) 2015 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2015 YAMAMOTO Takashi # # 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. import struct from os_ken import utils from os_ken.lib import type_desc from os_ken.ofproto import nicira_ext from os_ken.ofproto import ofproto_common from os_ken.lib.pack_utils import msg_pack_into from os_ken.ofproto.ofproto_parser import StringifyMixin def generate(ofp_name, ofpp_name): import sys ofp = sys.modules[ofp_name] ofpp = sys.modules[ofpp_name] class _NXFlowSpec(StringifyMixin): _hdr_fmt_str = '!H' # 2 bit 0s, 1 bit src, 2 bit dst, 11 bit n_bits _dst_type = None _subclasses = {} _TYPE = { 'nx-flow-spec-field': [ 'src', 'dst', ] } def __init__(self, src, dst, n_bits): self.src = src self.dst = dst self.n_bits = n_bits @classmethod def register(cls, subcls): assert issubclass(subcls, cls) assert subcls._dst_type not in cls._subclasses cls._subclasses[subcls._dst_type] = subcls @classmethod def parse(cls, buf): (hdr,) = struct.unpack_from(cls._hdr_fmt_str, buf, 0) rest = buf[struct.calcsize(cls._hdr_fmt_str):] if hdr == 0: return None, rest # all-0 header is no-op for padding src_type = (hdr >> 13) & 0x1 dst_type = (hdr >> 11) & 0x3 n_bits = hdr & 0x3ff subcls = cls._subclasses[dst_type] if src_type == 0: # subfield src = cls._parse_subfield(rest) rest = rest[6:] elif src_type == 1: # immediate src_len = (n_bits + 15) // 16 * 2 src_bin = rest[:src_len] src = type_desc.IntDescr(size=src_len).to_user(src_bin) rest = rest[src_len:] if dst_type == 0: # match dst = cls._parse_subfield(rest) rest = rest[6:] elif dst_type == 1: # load dst = cls._parse_subfield(rest) rest = rest[6:] elif dst_type == 2: # output dst = '' # empty return subcls(src=src, dst=dst, n_bits=n_bits), rest def serialize(self): buf = bytearray() if isinstance(self.src, tuple): src_type = 0 # subfield else: src_type = 1 # immediate # header val = (src_type << 13) | (self._dst_type << 11) | self.n_bits msg_pack_into(self._hdr_fmt_str, buf, 0, val) # src if src_type == 0: # subfield buf += self._serialize_subfield(self.src) elif src_type == 1: # immediate src_len = (self.n_bits + 15) // 16 * 2 buf += type_desc.IntDescr(size=src_len).from_user(self.src) # dst if self._dst_type == 0: # match buf += self._serialize_subfield(self.dst) elif self._dst_type == 1: # load buf += self._serialize_subfield(self.dst) elif self._dst_type == 2: # output pass # empty return buf @staticmethod def _parse_subfield(buf): (n, len) = ofp.oxm_parse_header(buf, 0) assert len == 4 # only 4-bytes NXM/OXM are defined field = ofp.oxm_to_user_header(n) rest = buf[len:] (ofs,) = struct.unpack_from('!H', rest, 0) return (field, ofs) @staticmethod def _serialize_subfield(subfield): (field, ofs) = subfield buf = bytearray() n = ofp.oxm_from_user_header(field) ofp.oxm_serialize_header(n, buf, 0) assert len(buf) == 4 # only 4-bytes NXM/OXM are defined msg_pack_into('!H', buf, 4, ofs) return buf class NXFlowSpecMatch(_NXFlowSpec): """ Specification for adding match criterion This class is used by ``NXActionLearn``. For the usage of this class, please refer to ``NXActionLearn``. ================ ====================================================== Attribute Description ================ ====================================================== src OXM/NXM header and Start bit for source field dst OXM/NXM header and Start bit for destination field n_bits The number of bits from the start bit ================ ====================================================== """ # Add a match criteria # an example of the corresponding ovs-ofctl syntax: # NXM_OF_VLAN_TCI[0..11] _dst_type = 0 class NXFlowSpecLoad(_NXFlowSpec): """ Add NXAST_REG_LOAD actions This class is used by ``NXActionLearn``. For the usage of this class, please refer to ``NXActionLearn``. ================ ====================================================== Attribute Description ================ ====================================================== src OXM/NXM header and Start bit for source field dst OXM/NXM header and Start bit for destination field n_bits The number of bits from the start bit ================ ====================================================== """ # Add NXAST_REG_LOAD actions # an example of the corresponding ovs-ofctl syntax: # NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[] _dst_type = 1 class NXFlowSpecOutput(_NXFlowSpec): """ Add an OFPAT_OUTPUT action This class is used by ``NXActionLearn``. For the usage of this class, please refer to ``NXActionLearn``. ================ ====================================================== Attribute Description ================ ====================================================== src OXM/NXM header and Start bit for source field dst Must be '' n_bits The number of bits from the start bit ================ ====================================================== """ # Add an OFPAT_OUTPUT action # an example of the corresponding ovs-ofctl syntax: # output:NXM_OF_IN_PORT[] _dst_type = 2 def __init__(self, src, n_bits, dst=''): assert dst == '' super(NXFlowSpecOutput, self).__init__(src=src, dst=dst, n_bits=n_bits) class NXAction(ofpp.OFPActionExperimenter): _fmt_str = '!H' # subtype _subtypes = {} _experimenter = ofproto_common.NX_EXPERIMENTER_ID def __init__(self): super(NXAction, self).__init__(self._experimenter) self.subtype = self._subtype @classmethod def parse(cls, buf): fmt_str = NXAction._fmt_str (subtype,) = struct.unpack_from(fmt_str, buf, 0) subtype_cls = cls._subtypes.get(subtype) rest = buf[struct.calcsize(fmt_str):] if subtype_cls is None: return NXActionUnknown(subtype, rest) return subtype_cls.parser(rest) def serialize(self, buf, offset): data = self.serialize_body() payload_offset = ( ofp.OFP_ACTION_EXPERIMENTER_HEADER_SIZE + struct.calcsize(NXAction._fmt_str) ) self.len = utils.round_up(payload_offset + len(data), 8) super(NXAction, self).serialize(buf, offset) msg_pack_into(NXAction._fmt_str, buf, offset + ofp.OFP_ACTION_EXPERIMENTER_HEADER_SIZE, self.subtype) buf += data @classmethod def register(cls, subtype_cls): assert subtype_cls._subtype is not cls._subtypes cls._subtypes[subtype_cls._subtype] = subtype_cls class NXActionUnknown(NXAction): def __init__(self, subtype, data=None, type_=None, len_=None, experimenter=None): self._subtype = subtype super(NXActionUnknown, self).__init__() self.data = data @classmethod def parser(cls, buf): return cls(data=buf) def serialize_body(self): # fixup return bytearray() if self.data is None else self.data # For OpenFlow1.0 only class NXActionSetQueue(NXAction): r""" Set queue action This action sets the queue that should be used to queue when packets are output. And equivalent to the followings action of ovs-ofctl command. .. set_queue:queue .. +-------------------------+ | **set_queue**\:\ *queue*| +-------------------------+ ================ ====================================================== Attribute Description ================ ====================================================== queue_id Queue ID for the packets ================ ====================================================== .. note:: This actions is supported by ``OFPActionSetQueue`` in OpenFlow1.2 or later. Example:: actions += [parser.NXActionSetQueue(queue_id=10)] """ _subtype = nicira_ext.NXAST_SET_QUEUE # queue_id _fmt_str = '!2xI' def __init__(self, queue_id, type_=None, len_=None, vendor=None, subtype=None): super(NXActionSetQueue, self).__init__() self.queue_id = queue_id @classmethod def parser(cls, buf): (queue_id,) = struct.unpack_from(cls._fmt_str, buf, 0) return cls(queue_id) def serialize_body(self): data = bytearray() msg_pack_into(self._fmt_str, data, 0, self.queue_id) return data class NXActionPopQueue(NXAction): """ Pop queue action This action restors the queue to the value it was before any set_queue actions were applied. And equivalent to the followings action of ovs-ofctl command. .. pop_queue .. +---------------+ | **pop_queue** | +---------------+ Example:: actions += [parser.NXActionPopQueue()] """ _subtype = nicira_ext.NXAST_POP_QUEUE _fmt_str = '!6x' def __init__(self, type_=None, len_=None, experimenter=None, subtype=None): super(NXActionPopQueue, self).__init__() @classmethod def parser(cls, buf): return cls() def serialize_body(self): data = bytearray() msg_pack_into(self._fmt_str, data, 0) return data class NXActionRegLoad(NXAction): r""" Load literal value action This action loads a literal value into a field or part of a field. And equivalent to the followings action of ovs-ofctl command. .. load:value->dst[start..end] .. +-----------------------------------------------------------------+ | **load**\:\ *value*\->\ *dst*\ **[**\ *start*\..\ *end*\ **]** | +-----------------------------------------------------------------+ ================ ====================================================== Attribute Description ================ ====================================================== ofs_nbits Start and End for the OXM/NXM field. Setting method refer to the ``nicira_ext.ofs_nbits`` dst OXM/NXM header for destination field value OXM/NXM value to be loaded ================ ====================================================== Example:: actions += [parser.NXActionRegLoad( ofs_nbits=nicira_ext.ofs_nbits(4, 31), dst="eth_dst", value=0x112233)] """ _subtype = nicira_ext.NXAST_REG_LOAD _fmt_str = '!HIQ' # ofs_nbits, dst, value _TYPE = { 'ascii': [ 'dst', ] } def __init__(self, ofs_nbits, dst, value, type_=None, len_=None, experimenter=None, subtype=None): super(NXActionRegLoad, self).__init__() self.ofs_nbits = ofs_nbits self.dst = dst self.value = value @classmethod def parser(cls, buf): (ofs_nbits, dst, value,) = struct.unpack_from( cls._fmt_str, buf, 0) # Right-shift instead of using oxm_parse_header for simplicity... dst_name = ofp.oxm_to_user_header(dst >> 9) return cls(ofs_nbits, dst_name, value) def serialize_body(self): hdr_data = bytearray() n = ofp.oxm_from_user_header(self.dst) ofp.oxm_serialize_header(n, hdr_data, 0) (dst_num,) = struct.unpack_from('!I', bytes(hdr_data), 0) data = bytearray() msg_pack_into(self._fmt_str, data, 0, self.ofs_nbits, dst_num, self.value) return data class NXActionRegLoad2(NXAction): r""" Load literal value action This action loads a literal value into a field or part of a field. And equivalent to the followings action of ovs-ofctl command. .. set_field:value[/mask]->dst .. +------------------------------------------------------------+ | **set_field**\:\ *value*\ **[**\/\ *mask*\ **]**\->\ *dst* | +------------------------------------------------------------+ ================ ====================================================== Attribute Description ================ ====================================================== value OXM/NXM value to be loaded mask Mask for destination field dst OXM/NXM header for destination field ================ ====================================================== Example:: actions += [parser.NXActionRegLoad2(dst="tun_ipv4_src", value="192.168.10.0", mask="255.255.255.0")] """ _subtype = nicira_ext.NXAST_REG_LOAD2 _TYPE = { 'ascii': [ 'dst', 'value', ] } def __init__(self, dst, value, mask=None, type_=None, len_=None, experimenter=None, subtype=None): super(NXActionRegLoad2, self).__init__() self.dst = dst self.value = value self.mask = mask @classmethod def parser(cls, buf): (n, uv, mask, _len) = ofp.oxm_parse(buf, 0) dst, value = ofp.oxm_to_user(n, uv, mask) if isinstance(value, (tuple, list)): return cls(dst, value[0], value[1]) else: return cls(dst, value, None) def serialize_body(self): data = bytearray() if self.mask is None: value = self.value else: value = (self.value, self.mask) self._TYPE['ascii'].append('mask') n, value, mask = ofp.oxm_from_user(self.dst, value) len_ = ofp.oxm_serialize(n, value, mask, data, 0) msg_pack_into("!%dx" % (14 - len_), data, len_) return data class NXActionNote(NXAction): r""" Note action This action does nothing at all. And equivalent to the followings action of ovs-ofctl command. .. note:[hh].. .. +-----------------------------------+ | **note**\:\ **[**\ *hh*\ **]**\.. | +-----------------------------------+ ================ ====================================================== Attribute Description ================ ====================================================== note A list of integer type values ================ ====================================================== Example:: actions += [parser.NXActionNote(note=[0xaa,0xbb,0xcc,0xdd])] """ _subtype = nicira_ext.NXAST_NOTE # note _fmt_str = '!%dB' # set the integer array in a note def __init__(self, note, type_=None, len_=None, experimenter=None, subtype=None): super(NXActionNote, self).__init__() self.note = note @classmethod def parser(cls, buf): note = struct.unpack_from( cls._fmt_str % len(buf), buf, 0) return cls(list(note)) def serialize_body(self): assert isinstance(self.note, (tuple, list)) for n in self.note: assert isinstance(n, int) pad = (len(self.note) + nicira_ext.NX_ACTION_HEADER_0_SIZE) % 8 if pad: self.note += [0x0 for i in range(8 - pad)] note_len = len(self.note) data = bytearray() msg_pack_into(self._fmt_str % note_len, data, 0, *self.note) return data class _NXActionSetTunnelBase(NXAction): # _subtype, _fmt_str must be attributes of subclass. def __init__(self, tun_id, type_=None, len_=None, experimenter=None, subtype=None): super(_NXActionSetTunnelBase, self).__init__() self.tun_id = tun_id @classmethod def parser(cls, buf): (tun_id,) = struct.unpack_from( cls._fmt_str, buf, 0) return cls(tun_id) def serialize_body(self): data = bytearray() msg_pack_into(self._fmt_str, data, 0, self.tun_id) return data class NXActionSetTunnel(_NXActionSetTunnelBase): r""" Set Tunnel action This action sets the identifier (such as GRE) to the specified id. And equivalent to the followings action of ovs-ofctl command. .. note:: This actions is supported by ``OFPActionSetField`` in OpenFlow1.2 or later. .. set_tunnel:id .. +------------------------+ | **set_tunnel**\:\ *id* | +------------------------+ ================ ====================================================== Attribute Description ================ ====================================================== tun_id Tunnel ID(32bits) ================ ====================================================== Example:: actions += [parser.NXActionSetTunnel(tun_id=0xa)] """ _subtype = nicira_ext.NXAST_SET_TUNNEL # tun_id _fmt_str = '!2xI' class NXActionSetTunnel64(_NXActionSetTunnelBase): r""" Set Tunnel action This action outputs to a port that encapsulates the packet in a tunnel. And equivalent to the followings action of ovs-ofctl command. .. note:: This actions is supported by ``OFPActionSetField`` in OpenFlow1.2 or later. .. set_tunnel64:id .. +--------------------------+ | **set_tunnel64**\:\ *id* | +--------------------------+ ================ ====================================================== Attribute Description ================ ====================================================== tun_id Tunnel ID(64bits) ================ ====================================================== Example:: actions += [parser.NXActionSetTunnel64(tun_id=0xa)] """ _subtype = nicira_ext.NXAST_SET_TUNNEL64 # tun_id _fmt_str = '!6xQ' class NXActionRegMove(NXAction): r""" Move register action This action copies the src to dst. And equivalent to the followings action of ovs-ofctl command. .. move:src[start..end]->dst[start..end] .. +--------------------------------------------------------+ | **move**\:\ *src*\ **[**\ *start*\..\ *end*\ **]**\->\ | | *dst*\ **[**\ *start*\..\ *end* \ **]** | +--------------------------------------------------------+ ================ ====================================================== Attribute Description ================ ====================================================== src_field OXM/NXM header for source field dst_field OXM/NXM header for destination field n_bits Number of bits src_ofs Starting bit offset in source dst_ofs Starting bit offset in destination ================ ====================================================== .. CAUTION:: **src_start**\ and \ **src_end**\ difference and \ **dst_start**\ and \ **dst_end**\ difference must be the same. Example:: actions += [parser.NXActionRegMove(src_field="reg0", dst_field="reg1", n_bits=5, src_ofs=0 dst_ofs=10)] """ _subtype = nicira_ext.NXAST_REG_MOVE _fmt_str = '!HHH' # n_bits, src_ofs, dst_ofs # Followed by OXM fields (src, dst) and padding to 8 bytes boundary _TYPE = { 'ascii': [ 'src_field', 'dst_field', ] } def __init__(self, src_field, dst_field, n_bits, src_ofs=0, dst_ofs=0, type_=None, len_=None, experimenter=None, subtype=None): super(NXActionRegMove, self).__init__() self.n_bits = n_bits self.src_ofs = src_ofs self.dst_ofs = dst_ofs self.src_field = src_field self.dst_field = dst_field @classmethod def parser(cls, buf): (n_bits, src_ofs, dst_ofs,) = struct.unpack_from( cls._fmt_str, buf, 0) rest = buf[struct.calcsize(NXActionRegMove._fmt_str):] # src field (n, len) = ofp.oxm_parse_header(rest, 0) src_field = ofp.oxm_to_user_header(n) rest = rest[len:] # dst field (n, len) = ofp.oxm_parse_header(rest, 0) dst_field = ofp.oxm_to_user_header(n) rest = rest[len:] # ignore padding return cls(src_field, dst_field=dst_field, n_bits=n_bits, src_ofs=src_ofs, dst_ofs=dst_ofs) def serialize_body(self): # fixup data = bytearray() msg_pack_into(self._fmt_str, data, 0, self.n_bits, self.src_ofs, self.dst_ofs) # src field n = ofp.oxm_from_user_header(self.src_field) ofp.oxm_serialize_header(n, data, len(data)) # dst field n = ofp.oxm_from_user_header(self.dst_field) ofp.oxm_serialize_header(n, data, len(data)) return data class NXActionResubmit(NXAction): r""" Resubmit action This action searches one of the switch's flow tables. And equivalent to the followings action of ovs-ofctl command. .. resubmit:port .. +------------------------+ | **resubmit**\:\ *port* | +------------------------+ ================ ====================================================== Attribute Description ================ ====================================================== in_port New in_port for checking flow table ================ ====================================================== Example:: actions += [parser.NXActionResubmit(in_port=8080)] """ _subtype = nicira_ext.NXAST_RESUBMIT # in_port _fmt_str = '!H4x' def __init__(self, in_port=0xfff8, type_=None, len_=None, experimenter=None, subtype=None): super(NXActionResubmit, self).__init__() self.in_port = in_port @classmethod def parser(cls, buf): (in_port,) = struct.unpack_from( cls._fmt_str, buf, 0) return cls(in_port) def serialize_body(self): data = bytearray() msg_pack_into(self._fmt_str, data, 0, self.in_port) return data class NXActionResubmitTable(NXAction): r""" Resubmit action This action searches one of the switch's flow tables. And equivalent to the followings action of ovs-ofctl command. .. resubmit([port],[table]) .. +------------------------------------------------+ | **resubmit(**\[\ *port*\]\,[\ *table*\]\ **)** | +------------------------------------------------+ ================ ====================================================== Attribute Description ================ ====================================================== in_port New in_port for checking flow table table_id Checking flow tables ================ ====================================================== Example:: actions += [parser.NXActionResubmitTable(in_port=8080, table_id=10)] """ _subtype = nicira_ext.NXAST_RESUBMIT_TABLE # in_port, table_id _fmt_str = '!HB3x' def __init__(self, in_port=0xfff8, table_id=0xff, type_=None, len_=None, experimenter=None, subtype=None): super(NXActionResubmitTable, self).__init__() self.in_port = in_port self.table_id = table_id @classmethod def parser(cls, buf): (in_port, table_id) = struct.unpack_from( cls._fmt_str, buf, 0) return cls(in_port, table_id) def serialize_body(self): data = bytearray() msg_pack_into(self._fmt_str, data, 0, self.in_port, self.table_id) return data class NXActionOutputReg(NXAction): r""" Add output action This action outputs the packet to the OpenFlow port number read from src. And equivalent to the followings action of ovs-ofctl command. .. output:src[start...end] .. +-------------------------------------------------------+ | **output**\:\ *src*\ **[**\ *start*\...\ *end*\ **]** | +-------------------------------------------------------+ ================ ====================================================== Attribute Description ================ ====================================================== ofs_nbits Start and End for the OXM/NXM field. Setting method refer to the ``nicira_ext.ofs_nbits`` src OXM/NXM header for source field max_len Max length to send to controller ================ ====================================================== Example:: actions += [parser.NXActionOutputReg( ofs_nbits=nicira_ext.ofs_nbits(4, 31), src="reg0", max_len=1024)] """ _subtype = nicira_ext.NXAST_OUTPUT_REG # ofs_nbits, src, max_len _fmt_str = '!H4sH6x' _TYPE = { 'ascii': [ 'src', ] } def __init__(self, ofs_nbits, src, max_len, type_=None, len_=None, experimenter=None, subtype=None): super(NXActionOutputReg, self).__init__() self.ofs_nbits = ofs_nbits self.src = src self.max_len = max_len @classmethod def parser(cls, buf): (ofs_nbits, oxm_data, max_len) = struct.unpack_from( cls._fmt_str, buf, 0) (n, len_) = ofp.oxm_parse_header(oxm_data, 0) src = ofp.oxm_to_user_header(n) return cls(ofs_nbits, src, max_len) def serialize_body(self): data = bytearray() src = bytearray() oxm = ofp.oxm_from_user_header(self.src) ofp.oxm_serialize_header(oxm, src, 0), msg_pack_into(self._fmt_str, data, 0, self.ofs_nbits, bytes(src), self.max_len) return data class NXActionOutputReg2(NXAction): r""" Add output action This action outputs the packet to the OpenFlow port number read from src. And equivalent to the followings action of ovs-ofctl command. .. output:src[start...end] .. +-------------------------------------------------------+ | **output**\:\ *src*\ **[**\ *start*\...\ *end*\ **]** | +-------------------------------------------------------+ .. NOTE:: Like the ``NXActionOutputReg`` but organized so that there is room for a 64-bit experimenter OXM as 'src'. ================ ====================================================== Attribute Description ================ ====================================================== ofs_nbits Start and End for the OXM/NXM field. Setting method refer to the ``nicira_ext.ofs_nbits`` src OXM/NXM header for source field max_len Max length to send to controller ================ ====================================================== Example:: actions += [parser.NXActionOutputReg2( ofs_nbits=nicira_ext.ofs_nbits(4, 31), src="reg0", max_len=1024)] """ _subtype = nicira_ext.NXAST_OUTPUT_REG2 # ofs_nbits, src, max_len _fmt_str = '!HH4s' _TYPE = { 'ascii': [ 'src', ] } def __init__(self, ofs_nbits, src, max_len, type_=None, len_=None, experimenter=None, subtype=None): super(NXActionOutputReg2, self).__init__() self.ofs_nbits = ofs_nbits self.src = src self.max_len = max_len @classmethod def parser(cls, buf): (ofs_nbits, max_len, oxm_data) = struct.unpack_from( cls._fmt_str, buf, 0) (n, len_) = ofp.oxm_parse_header(oxm_data, 0) src = ofp.oxm_to_user_header(n) return cls(ofs_nbits, src, max_len) def serialize_body(self): data = bytearray() oxm_data = bytearray() oxm = ofp.oxm_from_user_header(self.src) ofp.oxm_serialize_header(oxm, oxm_data, 0), msg_pack_into(self._fmt_str, data, 0, self.ofs_nbits, self.max_len, bytes(oxm_data)) offset = len(data) msg_pack_into("!%dx" % (14 - offset), data, offset) return data class NXActionLearn(NXAction): r""" Adds or modifies flow action This action adds or modifies a flow in OpenFlow table. And equivalent to the followings action of ovs-ofctl command. .. learn(argument[,argument]...) .. +---------------------------------------------------+ | **learn(**\ *argument*\[,\ *argument*\]...\ **)** | +---------------------------------------------------+ ================ ====================================================== Attribute Description ================ ====================================================== table_id The table in which the new flow should be inserted specs Adds a match criterion to the new flow Please use the ``NXFlowSpecMatch`` in order to set the following format .. field=value field[start..end]=src[start..end] field[start..end] .. | *field*\=\ *value* | *field*\ **[**\ *start*\..\ *end*\ **]**\ =\ *src*\ **[**\ *start*\..\ *end*\ **]** | *field*\ **[**\ *start*\..\ *end*\ **]** | Please use the ``NXFlowSpecLoad`` in order to set the following format .. load:value->dst[start..end] load:src[start..end]->dst[start..end] .. | **load**\:\ *value*\ **->**\ *dst*\ **[**\ *start*\..\ *end*\ **]** | **load**\:\ *src*\ **[**\ *start*\..\ *end*\ **] ->**\ *dst*\ **[**\ *start*\..\ *end*\ **]** | Please use the ``NXFlowSpecOutput`` in order to set the following format .. output:field[start..end] .. | **output:**\ field\ **[**\ *start*\..\ *end*\ **]** idle_timeout Idle time before discarding(seconds) hard_timeout Max time before discarding(seconds) priority Priority level of flow entry cookie Cookie for new flow flags send_flow_rem fin_idle_timeout Idle timeout after FIN(seconds) fin_hard_timeout Hard timeout after FIN(seconds) ================ ====================================================== .. CAUTION:: The arguments specify the flow's match fields, actions, and other properties, as follows. At least one match criterion and one action argument should ordinarily be specified. Example:: actions += [ parser.NXActionLearn(able_id=10, specs=[parser.NXFlowSpecMatch(src=0x800, dst=('eth_type_nxm', 0), n_bits=16), parser.NXFlowSpecMatch(src=('reg1', 1), dst=('reg2', 3), n_bits=5), parser.NXFlowSpecMatch(src=('reg3', 1), dst=('reg3', 1), n_bits=5), parser.NXFlowSpecLoad(src=0, dst=('reg4', 3), n_bits=5), parser.NXFlowSpecLoad(src=('reg5', 1), dst=('reg6', 3), n_bits=5), parser.NXFlowSpecOutput(src=('reg7', 1), dst="", n_bits=5)], idle_timeout=180, hard_timeout=300, priority=1, cookie=0x64, flags=ofproto.OFPFF_SEND_FLOW_REM, fin_idle_timeout=180, fin_hard_timeout=300)] """ _subtype = nicira_ext.NXAST_LEARN # idle_timeout, hard_timeout, priority, cookie, flags, # table_id, pad, fin_idle_timeout, fin_hard_timeout _fmt_str = '!HHHQHBxHH' # Followed by flow_mod_specs def __init__(self, table_id, specs, idle_timeout=0, hard_timeout=0, priority=ofp.OFP_DEFAULT_PRIORITY, cookie=0, flags=0, fin_idle_timeout=0, fin_hard_timeout=0, type_=None, len_=None, experimenter=None, subtype=None): super(NXActionLearn, self).__init__() self.idle_timeout = idle_timeout self.hard_timeout = hard_timeout self.priority = priority self.cookie = cookie self.flags = flags self.table_id = table_id self.fin_idle_timeout = fin_idle_timeout self.fin_hard_timeout = fin_hard_timeout self.specs = specs @classmethod def parser(cls, buf): (idle_timeout, hard_timeout, priority, cookie, flags, table_id, fin_idle_timeout, fin_hard_timeout,) = struct.unpack_from( cls._fmt_str, buf, 0) rest = buf[struct.calcsize(cls._fmt_str):] # specs specs = [] while len(rest) > 0: spec, rest = _NXFlowSpec.parse(rest) if spec is None: continue specs.append(spec) return cls(idle_timeout=idle_timeout, hard_timeout=hard_timeout, priority=priority, cookie=cookie, flags=flags, table_id=table_id, fin_idle_timeout=fin_idle_timeout, fin_hard_timeout=fin_hard_timeout, specs=specs) def serialize_body(self): # fixup data = bytearray() msg_pack_into(self._fmt_str, data, 0, self.idle_timeout, self.hard_timeout, self.priority, self.cookie, self.flags, self.table_id, self.fin_idle_timeout, self.fin_hard_timeout) for spec in self.specs: data += spec.serialize() return data class NXActionExit(NXAction): """ Halt action This action causes OpenvSwitch to immediately halt execution of further actions. And equivalent to the followings action of ovs-ofctl command. .. exit .. +----------+ | **exit** | +----------+ Example:: actions += [parser.NXActionExit()] """ _subtype = nicira_ext.NXAST_EXIT _fmt_str = '!6x' def __init__(self, type_=None, len_=None, experimenter=None, subtype=None): super(NXActionExit, self).__init__() @classmethod def parser(cls, buf): return cls() def serialize_body(self): data = bytearray() msg_pack_into(self._fmt_str, data, 0) return data # For OpenFlow1.0 only class NXActionDecTtl(NXAction): """ Decrement IP TTL action This action decrements TTL of IPv4 packet or hop limit of IPv6 packet. And equivalent to the followings action of ovs-ofctl command. .. dec_ttl .. +-------------+ | **dec_ttl** | +-------------+ .. NOTE:: This actions is supported by ``OFPActionDecNwTtl`` in OpenFlow1.2 or later. Example:: actions += [parser.NXActionDecTtl()] """ _subtype = nicira_ext.NXAST_DEC_TTL _fmt_str = '!6x' def __init__(self, type_=None, len_=None, vendor=None, subtype=None): super(NXActionDecTtl, self).__init__() @classmethod def parser(cls, buf): return cls() def serialize_body(self): data = bytearray() msg_pack_into(self._fmt_str, data, 0) return data class NXActionController(NXAction): r""" Send packet in message action This action sends the packet to the OpenFlow controller as a packet in message. And equivalent to the followings action of ovs-ofctl command. .. controller(key=value...) .. +----------------------------------------------+ | **controller(**\ *key*\=\ *value*\...\ **)** | +----------------------------------------------+ ================ ====================================================== Attribute Description ================ ====================================================== max_len Max length to send to controller controller_id Controller ID to send packet-in reason Reason for sending the message ================ ====================================================== Example:: actions += [ parser.NXActionController(max_len=1024, controller_id=1, reason=ofproto.OFPR_INVALID_TTL)] """ _subtype = nicira_ext.NXAST_CONTROLLER # max_len, controller_id, reason _fmt_str = '!HHBx' def __init__(self, max_len, controller_id, reason, type_=None, len_=None, experimenter=None, subtype=None): super(NXActionController, self).__init__() self.max_len = max_len self.controller_id = controller_id self.reason = reason @classmethod def parser(cls, buf): (max_len, controller_id, reason) = struct.unpack_from( cls._fmt_str, buf) return cls(max_len, controller_id, reason) def serialize_body(self): data = bytearray() msg_pack_into(self._fmt_str, data, 0, self.max_len, self.controller_id, self.reason) return data class NXActionController2(NXAction): r""" Send packet in message action This action sends the packet to the OpenFlow controller as a packet in message. And equivalent to the followings action of ovs-ofctl command. .. controller(key=value...) .. +----------------------------------------------+ | **controller(**\ *key*\=\ *value*\...\ **)** | +----------------------------------------------+ ================ ====================================================== Attribute Description ================ ====================================================== max_len Max length to send to controller controller_id Controller ID to send packet-in reason Reason for sending the message userdata Additional data to the controller in the packet-in message pause Flag to pause pipeline to resume later ================ ====================================================== Example:: actions += [ parser.NXActionController(max_len=1024, controller_id=1, reason=ofproto.OFPR_INVALID_TTL, userdata=[0xa,0xb,0xc], pause=True)] """ _subtype = nicira_ext.NXAST_CONTROLLER2 _fmt_str = '!6x' _PACK_STR = '!HH' def __init__(self, type_=None, len_=None, vendor=None, subtype=None, **kwargs): super(NXActionController2, self).__init__() for arg in kwargs: if arg in NXActionController2Prop._NAMES: setattr(self, arg, kwargs[arg]) @classmethod def parser(cls, buf): cls_data = {} offset = 6 buf_len = len(buf) while buf_len > offset: (type_, length) = struct.unpack_from(cls._PACK_STR, buf, offset) offset += 4 try: subcls = NXActionController2Prop._TYPES[type_] except KeyError: subcls = NXActionController2PropUnknown data, size = subcls.parser_prop(buf[offset:], length - 4) offset += size cls_data[subcls._arg_name] = data return cls(**cls_data) def serialize_body(self): body = bytearray() msg_pack_into(self._fmt_str, body, 0) prop_list = [] for arg in self.__dict__: if arg in NXActionController2Prop._NAMES: prop_list.append((NXActionController2Prop._NAMES[arg], self.__dict__[arg])) prop_list.sort(key=lambda x: x[0].type) for subcls, value in prop_list: body += subcls.serialize_prop(value) return body class NXActionController2Prop(object): _TYPES = {} _NAMES = {} @classmethod def register_type(cls, type_): def _register_type(subcls): subcls.type = type_ NXActionController2Prop._TYPES[type_] = subcls NXActionController2Prop._NAMES[subcls._arg_name] = subcls return subcls return _register_type class NXActionController2PropUnknown(NXActionController2Prop): @classmethod def parser_prop(cls, buf, length): size = 4 return buf, size @classmethod def serialize_prop(cls, argment): data = bytearray() return data @NXActionController2Prop.register_type(nicira_ext.NXAC2PT_MAX_LEN) class NXActionController2PropMaxLen(NXActionController2Prop): # max_len _fmt_str = "!H2x" _arg_name = "max_len" @classmethod def parser_prop(cls, buf, length): size = 4 (max_len,) = struct.unpack_from( cls._fmt_str, buf, 0) return max_len, size @classmethod def serialize_prop(cls, max_len): data = bytearray() msg_pack_into("!HHH2x", data, 0, nicira_ext.NXAC2PT_MAX_LEN, 8, max_len) return data @NXActionController2Prop.register_type(nicira_ext.NXAC2PT_CONTROLLER_ID) class NXActionController2PropControllerId(NXActionController2Prop): # controller_id _fmt_str = "!H2x" _arg_name = "controller_id" @classmethod def parser_prop(cls, buf, length): size = 4 (controller_id,) = struct.unpack_from( cls._fmt_str, buf, 0) return controller_id, size @classmethod def serialize_prop(cls, controller_id): data = bytearray() msg_pack_into("!HHH2x", data, 0, nicira_ext.NXAC2PT_CONTROLLER_ID, 8, controller_id) return data @NXActionController2Prop.register_type(nicira_ext.NXAC2PT_REASON) class NXActionController2PropReason(NXActionController2Prop): # reason _fmt_str = "!B3x" _arg_name = "reason" @classmethod def parser_prop(cls, buf, length): size = 4 (reason,) = struct.unpack_from( cls._fmt_str, buf, 0) return reason, size @classmethod def serialize_prop(cls, reason): data = bytearray() msg_pack_into("!HHB3x", data, 0, nicira_ext.NXAC2PT_REASON, 5, reason) return data @NXActionController2Prop.register_type(nicira_ext.NXAC2PT_USERDATA) class NXActionController2PropUserData(NXActionController2Prop): # userdata _fmt_str = "!B" _arg_name = "userdata" @classmethod def parser_prop(cls, buf, length): userdata = [] offset = 0 while offset < length: u = struct.unpack_from(cls._fmt_str, buf, offset) userdata.append(u[0]) offset += 1 user_size = utils.round_up(length, 4) if user_size > 4 and (user_size % 8) == 0: size = utils.round_up(length, 4) + 4 else: size = utils.round_up(length, 4) return userdata, size @classmethod def serialize_prop(cls, userdata): data = bytearray() user_buf = bytearray() user_offset = 0 for user in userdata: msg_pack_into('!B', user_buf, user_offset, user) user_offset += 1 msg_pack_into("!HH", data, 0, nicira_ext.NXAC2PT_USERDATA, 4 + user_offset) data += user_buf if user_offset > 4: user_len = utils.round_up(user_offset, 4) brank_size = 0 if (user_len % 8) == 0: brank_size = 4 msg_pack_into("!%dx" % (user_len - user_offset + brank_size), data, 4 + user_offset) else: user_len = utils.round_up(user_offset, 4) msg_pack_into("!%dx" % (user_len - user_offset), data, 4 + user_offset) return data @NXActionController2Prop.register_type(nicira_ext.NXAC2PT_PAUSE) class NXActionController2PropPause(NXActionController2Prop): _arg_name = "pause" @classmethod def parser_prop(cls, buf, length): pause = True size = 4 return pause, size @classmethod def serialize_prop(cls, pause): data = bytearray() msg_pack_into("!HH4x", data, 0, nicira_ext.NXAC2PT_PAUSE, 4) return data class NXActionDecTtlCntIds(NXAction): r""" Decrement TTL action This action decrements TTL of IPv4 packet or hop limits of IPv6 packet. And equivalent to the followings action of ovs-ofctl command. .. dec_ttl(id1[,id2]...) .. +-------------------------------------------+ | **dec_ttl(**\ *id1*\[,\ *id2*\]...\ **)** | +-------------------------------------------+ ================ ====================================================== Attribute Description ================ ====================================================== cnt_ids Controller ids ================ ====================================================== Example:: actions += [parser.NXActionDecTtlCntIds(cnt_ids=[1,2,3])] .. NOTE:: If you want to set the following ovs-ofctl command. Please use ``OFPActionDecNwTtl``. +-------------+ | **dec_ttl** | +-------------+ """ _subtype = nicira_ext.NXAST_DEC_TTL_CNT_IDS # controllers _fmt_str = '!H4x' _fmt_len = 6 def __init__(self, cnt_ids, type_=None, len_=None, experimenter=None, subtype=None): super(NXActionDecTtlCntIds, self).__init__() self.cnt_ids = cnt_ids @classmethod def parser(cls, buf): (controllers,) = struct.unpack_from( cls._fmt_str, buf) offset = cls._fmt_len cnt_ids = [] for i in range(0, controllers): id_ = struct.unpack_from('!H', buf, offset) cnt_ids.append(id_[0]) offset += 2 return cls(cnt_ids) def serialize_body(self): assert isinstance(self.cnt_ids, (tuple, list)) for i in self.cnt_ids: assert isinstance(i, int) controllers = len(self.cnt_ids) data = bytearray() msg_pack_into(self._fmt_str, data, 0, controllers) offset = self._fmt_len for id_ in self.cnt_ids: msg_pack_into('!H', data, offset, id_) offset += 2 id_len = (utils.round_up(controllers, 4) - controllers) if id_len != 0: msg_pack_into('%dx' % id_len * 2, data, offset) return data # Use in only OpenFlow1.0 class NXActionMplsBase(NXAction): # ethertype _fmt_str = '!H4x' def __init__(self, ethertype, type_=None, len_=None, vendor=None, subtype=None): super(NXActionMplsBase, self).__init__() self.ethertype = ethertype @classmethod def parser(cls, buf): (ethertype,) = struct.unpack_from( cls._fmt_str, buf) return cls(ethertype) def serialize_body(self): data = bytearray() msg_pack_into(self._fmt_str, data, 0, self.ethertype) return data # For OpenFlow1.0 only class NXActionPushMpls(NXActionMplsBase): r""" Push MPLS action This action pushes a new MPLS header to the packet. And equivalent to the followings action of ovs-ofctl command. .. push_mpls:ethertype .. +-------------------------------+ | **push_mpls**\:\ *ethertype* | +-------------------------------+ ================ ====================================================== Attribute Description ================ ====================================================== ethertype Ether type(The value must be either 0x8847 or 0x8848) ================ ====================================================== .. NOTE:: This actions is supported by ``OFPActionPushMpls`` in OpenFlow1.2 or later. Example:: match = parser.OFPMatch(dl_type=0x0800) actions += [parser.NXActionPushMpls(ethertype=0x8847)] """ _subtype = nicira_ext.NXAST_PUSH_MPLS # For OpenFlow1.0 only class NXActionPopMpls(NXActionMplsBase): r""" Pop MPLS action This action pops the MPLS header from the packet. And equivalent to the followings action of ovs-ofctl command. .. pop_mpls:ethertype .. +------------------------------+ | **pop_mpls**\:\ *ethertype* | +------------------------------+ ================ ====================================================== Attribute Description ================ ====================================================== ethertype Ether type ================ ====================================================== .. NOTE:: This actions is supported by ``OFPActionPopMpls`` in OpenFlow1.2 or later. Example:: match = parser.OFPMatch(dl_type=0x8847) actions += [parser.NXActionPushMpls(ethertype=0x0800)] """ _subtype = nicira_ext.NXAST_POP_MPLS # For OpenFlow1.0 only class NXActionSetMplsTtl(NXAction): r""" Set MPLS TTL action This action sets the MPLS TTL. And equivalent to the followings action of ovs-ofctl command. .. set_mpls_ttl:ttl .. +---------------------------+ | **set_mpls_ttl**\:\ *ttl* | +---------------------------+ ================ ====================================================== Attribute Description ================ ====================================================== ttl MPLS TTL ================ ====================================================== .. NOTE:: This actions is supported by ``OFPActionSetMplsTtl`` in OpenFlow1.2 or later. Example:: actions += [parser.NXActionSetMplsTil(ttl=128)] """ _subtype = nicira_ext.NXAST_SET_MPLS_TTL # ethertype _fmt_str = '!B5x' def __init__(self, ttl, type_=None, len_=None, vendor=None, subtype=None): super(NXActionSetMplsTtl, self).__init__() self.ttl = ttl @classmethod def parser(cls, buf): (ttl,) = struct.unpack_from( cls._fmt_str, buf) return cls(ttl) def serialize_body(self): data = bytearray() msg_pack_into(self._fmt_str, data, 0, self.ttl) return data # For OpenFlow1.0 only class NXActionDecMplsTtl(NXAction): """ Decrement MPLS TTL action This action decrements the MPLS TTL. And equivalent to the followings action of ovs-ofctl command. .. dec_mpls_ttl .. +------------------+ | **dec_mpls_ttl** | +------------------+ .. NOTE:: This actions is supported by ``OFPActionDecMplsTtl`` in OpenFlow1.2 or later. Example:: actions += [parser.NXActionDecMplsTil()] """ _subtype = nicira_ext.NXAST_DEC_MPLS_TTL # ethertype _fmt_str = '!6x' def __init__(self, type_=None, len_=None, vendor=None, subtype=None): super(NXActionDecMplsTtl, self).__init__() @classmethod def parser(cls, buf): return cls() def serialize_body(self): data = bytearray() msg_pack_into(self._fmt_str, data, 0) return data # For OpenFlow1.0 only class NXActionSetMplsLabel(NXAction): r""" Set MPLS Lavel action This action sets the MPLS Label. And equivalent to the followings action of ovs-ofctl command. .. set_mpls_label:label .. +-------------------------------+ | **set_mpls_label**\:\ *label* | +-------------------------------+ ================ ====================================================== Attribute Description ================ ====================================================== label MPLS Label ================ ====================================================== .. NOTE:: This actions is supported by ``OFPActionSetField(mpls_label=label)`` in OpenFlow1.2 or later. Example:: actions += [parser.NXActionSetMplsLabel(label=0x10)] """ _subtype = nicira_ext.NXAST_SET_MPLS_LABEL # ethertype _fmt_str = '!2xI' def __init__(self, label, type_=None, len_=None, vendor=None, subtype=None): super(NXActionSetMplsLabel, self).__init__() self.label = label @classmethod def parser(cls, buf): (label,) = struct.unpack_from( cls._fmt_str, buf) return cls(label) def serialize_body(self): data = bytearray() msg_pack_into(self._fmt_str, data, 0, self.label) return data # For OpenFlow1.0 only class NXActionSetMplsTc(NXAction): r""" Set MPLS Tc action This action sets the MPLS Tc. And equivalent to the followings action of ovs-ofctl command. .. set_mpls_tc:tc .. +-------------------------+ | **set_mpls_tc**\:\ *tc* | +-------------------------+ ================ ====================================================== Attribute Description ================ ====================================================== tc MPLS Tc ================ ====================================================== .. NOTE:: This actions is supported by ``OFPActionSetField(mpls_label=tc)`` in OpenFlow1.2 or later. Example:: actions += [parser.NXActionSetMplsLabel(tc=0x10)] """ _subtype = nicira_ext.NXAST_SET_MPLS_TC # ethertype _fmt_str = '!B5x' def __init__(self, tc, type_=None, len_=None, vendor=None, subtype=None): super(NXActionSetMplsTc, self).__init__() self.tc = tc @classmethod def parser(cls, buf): (tc,) = struct.unpack_from( cls._fmt_str, buf) return cls(tc) def serialize_body(self): data = bytearray() msg_pack_into(self._fmt_str, data, 0, self.tc) return data class NXActionStackBase(NXAction): # start, field, end _fmt_str = '!H4sH' _TYPE = { 'ascii': [ 'field', ] } def __init__(self, field, start, end, type_=None, len_=None, experimenter=None, subtype=None): super(NXActionStackBase, self).__init__() self.field = field self.start = start self.end = end @classmethod def parser(cls, buf): (start, oxm_data, end) = struct.unpack_from( cls._fmt_str, buf, 0) (n, len_) = ofp.oxm_parse_header(oxm_data, 0) field = ofp.oxm_to_user_header(n) return cls(field, start, end) def serialize_body(self): data = bytearray() oxm_data = bytearray() oxm = ofp.oxm_from_user_header(self.field) ofp.oxm_serialize_header(oxm, oxm_data, 0) msg_pack_into(self._fmt_str, data, 0, self.start, bytes(oxm_data), self.end) offset = len(data) msg_pack_into("!%dx" % (12 - offset), data, offset) return data class NXActionStackPush(NXActionStackBase): r""" Push field action This action pushes field to top of the stack. And equivalent to the followings action of ovs-ofctl command. .. pop:dst[start...end] .. +----------------------------------------------------+ | **pop**\:\ *dst*\ **[**\ *start*\...\ *end*\ **]** | +----------------------------------------------------+ ================ ====================================================== Attribute Description ================ ====================================================== field OXM/NXM header for source field start Start bit for source field end End bit for source field ================ ====================================================== Example:: actions += [parser.NXActionStackPush(field="reg2", start=0, end=5)] """ _subtype = nicira_ext.NXAST_STACK_PUSH class NXActionStackPop(NXActionStackBase): r""" Pop field action This action pops field from top of the stack. And equivalent to the followings action of ovs-ofctl command. .. pop:src[start...end] .. +----------------------------------------------------+ | **pop**\:\ *src*\ **[**\ *start*\...\ *end*\ **]** | +----------------------------------------------------+ ================ ====================================================== Attribute Description ================ ====================================================== field OXM/NXM header for destination field start Start bit for destination field end End bit for destination field ================ ====================================================== Example:: actions += [parser.NXActionStackPop(field="reg2", start=0, end=5)] """ _subtype = nicira_ext.NXAST_STACK_POP class NXActionSample(NXAction): r""" Sample packets action This action samples packets and sends one sample for every sampled packet. And equivalent to the followings action of ovs-ofctl command. .. sample(argument[,argument]...) .. +----------------------------------------------------+ | **sample(**\ *argument*\[,\ *argument*\]...\ **)** | +----------------------------------------------------+ ================ ====================================================== Attribute Description ================ ====================================================== probability The number of sampled packets collector_set_id The unsigned 32-bit integer identifier of the set of sample collectors to send sampled packets to obs_domain_id The Unsigned 32-bit integer Observation Domain ID obs_point_id The unsigned 32-bit integer Observation Point ID ================ ====================================================== Example:: actions += [parser.NXActionSample(probability=3, collector_set_id=1, obs_domain_id=2, obs_point_id=3,)] """ _subtype = nicira_ext.NXAST_SAMPLE # probability, collector_set_id, obs_domain_id, obs_point_id _fmt_str = '!HIII' def __init__(self, probability, collector_set_id=0, obs_domain_id=0, obs_point_id=0, type_=None, len_=None, experimenter=None, subtype=None): super(NXActionSample, self).__init__() self.probability = probability self.collector_set_id = collector_set_id self.obs_domain_id = obs_domain_id self.obs_point_id = obs_point_id @classmethod def parser(cls, buf): (probability, collector_set_id, obs_domain_id, obs_point_id) = struct.unpack_from( cls._fmt_str, buf, 0) return cls(probability, collector_set_id, obs_domain_id, obs_point_id) def serialize_body(self): data = bytearray() msg_pack_into(self._fmt_str, data, 0, self.probability, self.collector_set_id, self.obs_domain_id, self.obs_point_id) return data class NXActionSample2(NXAction): r""" Sample packets action This action samples packets and sends one sample for every sampled packet. 'sampling_port' can be equal to ingress port or one of egress ports. And equivalent to the followings action of ovs-ofctl command. .. sample(argument[,argument]...) .. +----------------------------------------------------+ | **sample(**\ *argument*\[,\ *argument*\]...\ **)** | +----------------------------------------------------+ ================ ====================================================== Attribute Description ================ ====================================================== probability The number of sampled packets collector_set_id The unsigned 32-bit integer identifier of the set of sample collectors to send sampled packets to obs_domain_id The Unsigned 32-bit integer Observation Domain ID obs_point_id The unsigned 32-bit integer Observation Point ID sampling_port Sampling port number ================ ====================================================== Example:: actions += [parser.NXActionSample2(probability=3, collector_set_id=1, obs_domain_id=2, obs_point_id=3, sampling_port=8080)] """ _subtype = nicira_ext.NXAST_SAMPLE2 # probability, collector_set_id, obs_domain_id, # obs_point_id, sampling_port _fmt_str = '!HIIIH6x' def __init__(self, probability, collector_set_id=0, obs_domain_id=0, obs_point_id=0, sampling_port=0, type_=None, len_=None, experimenter=None, subtype=None): super(NXActionSample2, self).__init__() self.probability = probability self.collector_set_id = collector_set_id self.obs_domain_id = obs_domain_id self.obs_point_id = obs_point_id self.sampling_port = sampling_port @classmethod def parser(cls, buf): (probability, collector_set_id, obs_domain_id, obs_point_id, sampling_port) = struct.unpack_from( cls._fmt_str, buf, 0) return cls(probability, collector_set_id, obs_domain_id, obs_point_id, sampling_port) def serialize_body(self): data = bytearray() msg_pack_into(self._fmt_str, data, 0, self.probability, self.collector_set_id, self.obs_domain_id, self.obs_point_id, self.sampling_port) return data class NXActionFinTimeout(NXAction): r""" Change TCP timeout action This action changes the idle timeout or hard timeout or both, of this OpenFlow rule when the rule matches a TCP packet with the FIN or RST flag. And equivalent to the followings action of ovs-ofctl command. .. fin_timeout(argument[,argument]...) .. +---------------------------------------------------------+ | **fin_timeout(**\ *argument*\[,\ *argument*\]...\ **)** | +---------------------------------------------------------+ ================ ====================================================== Attribute Description ================ ====================================================== fin_idle_timeout Causes the flow to expire after the given number of seconds of inactivity fin_idle_timeout Causes the flow to expire after the given number of second, regardless of activity ================ ====================================================== Example:: match = parser.OFPMatch(ip_proto=6, eth_type=0x0800) actions += [parser.NXActionFinTimeout(fin_idle_timeout=30, fin_hard_timeout=60)] """ _subtype = nicira_ext.NXAST_FIN_TIMEOUT # fin_idle_timeout, fin_hard_timeout _fmt_str = '!HH2x' def __init__(self, fin_idle_timeout, fin_hard_timeout, type_=None, len_=None, experimenter=None, subtype=None): super(NXActionFinTimeout, self).__init__() self.fin_idle_timeout = fin_idle_timeout self.fin_hard_timeout = fin_hard_timeout @classmethod def parser(cls, buf): (fin_idle_timeout, fin_hard_timeout) = struct.unpack_from( cls._fmt_str, buf, 0) return cls(fin_idle_timeout, fin_hard_timeout) def serialize_body(self): data = bytearray() msg_pack_into(self._fmt_str, data, 0, self.fin_idle_timeout, self.fin_hard_timeout) return data class NXActionConjunction(NXAction): r""" Conjunctive matches action This action ties groups of individual OpenFlow flows into higher-level conjunctive flows. Please refer to the ovs-ofctl command manual for details. And equivalent to the followings action of ovs-ofctl command. .. conjunction(id,k/n) .. +--------------------------------------------------+ | **conjunction(**\ *id*\,\ *k*\ **/**\ *n*\ **)** | +--------------------------------------------------+ ================ ====================================================== Attribute Description ================ ====================================================== clause Number assigned to the flow's dimension n_clauses Specify the conjunctive flow's match condition id\_ Conjunction ID ================ ====================================================== Example:: actions += [parser.NXActionConjunction(clause=1, n_clauses=2, id_=10)] """ _subtype = nicira_ext.NXAST_CONJUNCTION # clause, n_clauses, id _fmt_str = '!BBI' def __init__(self, clause, n_clauses, id_, type_=None, len_=None, experimenter=None, subtype=None): super(NXActionConjunction, self).__init__() self.clause = clause self.n_clauses = n_clauses self.id = id_ @classmethod def parser(cls, buf): (clause, n_clauses, id_,) = struct.unpack_from( cls._fmt_str, buf, 0) return cls(clause, n_clauses, id_) def serialize_body(self): data = bytearray() msg_pack_into(self._fmt_str, data, 0, self.clause, self.n_clauses, self.id) return data class NXActionMultipath(NXAction): r""" Select multipath link action This action selects multipath link based on the specified parameters. Please refer to the ovs-ofctl command manual for details. And equivalent to the followings action of ovs-ofctl command. .. multipath(fields, basis, algorithm, n_links, arg, dst[start..end]) .. +-------------------------------------------------------------+ | **multipath(**\ *fields*\, \ *basis*\, \ *algorithm*\, | | *n_links*\, \ *arg*\, \ *dst*\[\ *start*\..\ *end*\]\ **)** | +-------------------------------------------------------------+ ================ ====================================================== Attribute Description ================ ====================================================== fields One of NX_HASH_FIELDS_* basis Universal hash parameter algorithm One of NX_MP_ALG_*. max_link Number of output links arg Algorithm-specific argument ofs_nbits Start and End for the OXM/NXM field. Setting method refer to the ``nicira_ext.ofs_nbits`` dst OXM/NXM header for source field ================ ====================================================== Example:: actions += [parser.NXActionMultipath( fields=nicira_ext.NX_HASH_FIELDS_SYMMETRIC_L4, basis=1024, algorithm=nicira_ext.NX_MP_ALG_HRW, max_link=5, arg=0, ofs_nbits=nicira_ext.ofs_nbits(4, 31), dst="reg2")] """ _subtype = nicira_ext.NXAST_MULTIPATH # fields, basis, algorithm, max_link, # arg, ofs_nbits, dst _fmt_str = '!HH2xHHI2xH4s' _TYPE = { 'ascii': [ 'dst', ] } def __init__(self, fields, basis, algorithm, max_link, arg, ofs_nbits, dst, type_=None, len_=None, experimenter=None, subtype=None): super(NXActionMultipath, self).__init__() self.fields = fields self.basis = basis self.algorithm = algorithm self.max_link = max_link self.arg = arg self.ofs_nbits = ofs_nbits self.dst = dst @classmethod def parser(cls, buf): (fields, basis, algorithm, max_link, arg, ofs_nbits, oxm_data) = struct.unpack_from( cls._fmt_str, buf, 0) (n, len_) = ofp.oxm_parse_header(oxm_data, 0) dst = ofp.oxm_to_user_header(n) return cls(fields, basis, algorithm, max_link, arg, ofs_nbits, dst) def serialize_body(self): data = bytearray() dst = bytearray() oxm = ofp.oxm_from_user_header(self.dst) ofp.oxm_serialize_header(oxm, dst, 0), msg_pack_into(self._fmt_str, data, 0, self.fields, self.basis, self.algorithm, self.max_link, self.arg, self.ofs_nbits, bytes(dst)) return data class _NXActionBundleBase(NXAction): # algorithm, fields, basis, slave_type, n_slaves # ofs_nbits _fmt_str = '!HHHIHH' def __init__(self, algorithm, fields, basis, slave_type, n_slaves, ofs_nbits, dst, slaves): super(_NXActionBundleBase, self).__init__() self.len = utils.round_up( nicira_ext.NX_ACTION_BUNDLE_0_SIZE + len(slaves) * 2, 8) self.algorithm = algorithm self.fields = fields self.basis = basis self.slave_type = slave_type self.n_slaves = n_slaves self.ofs_nbits = ofs_nbits self.dst = dst assert isinstance(slaves, (list, tuple)) for s in slaves: assert isinstance(s, int) self.slaves = slaves @classmethod def parser(cls, buf): # Add dst ('I') to _fmt_str (algorithm, fields, basis, slave_type, n_slaves, ofs_nbits, dst) = struct.unpack_from( cls._fmt_str + 'I', buf, 0) offset = (nicira_ext.NX_ACTION_BUNDLE_0_SIZE - nicira_ext.NX_ACTION_HEADER_0_SIZE - 8) if dst != 0: (n, len_) = ofp.oxm_parse_header(buf, offset) dst = ofp.oxm_to_user_header(n) slave_offset = (nicira_ext.NX_ACTION_BUNDLE_0_SIZE - nicira_ext.NX_ACTION_HEADER_0_SIZE) slaves = [] for i in range(0, n_slaves): s = struct.unpack_from('!H', buf, slave_offset) slaves.append(s[0]) slave_offset += 2 return cls(algorithm, fields, basis, slave_type, n_slaves, ofs_nbits, dst, slaves) def serialize_body(self): data = bytearray() slave_offset = (nicira_ext.NX_ACTION_BUNDLE_0_SIZE - nicira_ext.NX_ACTION_HEADER_0_SIZE) self.n_slaves = len(self.slaves) for s in self.slaves: msg_pack_into('!H', data, slave_offset, s) slave_offset += 2 pad_len = (utils.round_up(self.n_slaves, 4) - self.n_slaves) if pad_len != 0: msg_pack_into('%dx' % pad_len * 2, data, slave_offset) msg_pack_into(self._fmt_str, data, 0, self.algorithm, self.fields, self.basis, self.slave_type, self.n_slaves, self.ofs_nbits) offset = (nicira_ext.NX_ACTION_BUNDLE_0_SIZE - nicira_ext.NX_ACTION_HEADER_0_SIZE - 8) if self.dst == 0: msg_pack_into('I', data, offset, self.dst) else: oxm_data = ofp.oxm_from_user_header(self.dst) ofp.oxm_serialize_header(oxm_data, data, offset) return data class NXActionBundle(_NXActionBundleBase): r""" Select bundle link action This action selects bundle link based on the specified parameters. Please refer to the ovs-ofctl command manual for details. And equivalent to the followings action of ovs-ofctl command. .. bundle(fields, basis, algorithm, slave_type, slaves:[ s1, s2,...]) .. +-----------------------------------------------------------+ | **bundle(**\ *fields*\, \ *basis*\, \ *algorithm*\, | | *slave_type*\, \ *slaves*\:[ \ *s1*\, \ *s2*\,...]\ **)** | +-----------------------------------------------------------+ ================ ====================================================== Attribute Description ================ ====================================================== algorithm One of NX_MP_ALG_*. fields One of NX_HASH_FIELDS_* basis Universal hash parameter slave_type Type of slaves(must be NXM_OF_IN_PORT) n_slaves Number of slaves ofs_nbits Start and End for the OXM/NXM field. (must be zero) dst OXM/NXM header for source field(must be zero) slaves List of slaves ================ ====================================================== Example:: actions += [parser.NXActionBundle( algorithm=nicira_ext.NX_MP_ALG_HRW, fields=nicira_ext.NX_HASH_FIELDS_ETH_SRC, basis=0, slave_type=nicira_ext.NXM_OF_IN_PORT, n_slaves=2, ofs_nbits=0, dst=0, slaves=[2, 3])] """ _subtype = nicira_ext.NXAST_BUNDLE def __init__(self, algorithm, fields, basis, slave_type, n_slaves, ofs_nbits, dst, slaves): # NXAST_BUNDLE actions should have 'sofs_nbits' and 'dst' zeroed. super(NXActionBundle, self).__init__( algorithm, fields, basis, slave_type, n_slaves, ofs_nbits=0, dst=0, slaves=slaves) class NXActionBundleLoad(_NXActionBundleBase): r""" Select bundle link action This action has the same behavior as the bundle action, with one exception. Please refer to the ovs-ofctl command manual for details. And equivalent to the followings action of ovs-ofctl command. .. bundle_load(fields, basis, algorithm, slave_type, dst[start..end], slaves:[ s1, s2,...]) .. +-----------------------------------------------------------+ | **bundle_load(**\ *fields*\, \ *basis*\, \ *algorithm*\, | | *slave_type*\, \ *dst*\[\ *start*\... \*emd*\], | | \ *slaves*\:[ \ *s1*\, \ *s2*\,...]\ **)** | | +-----------------------------------------------------------+ ================ ====================================================== Attribute Description ================ ====================================================== algorithm One of NX_MP_ALG_*. fields One of NX_HASH_FIELDS_* basis Universal hash parameter slave_type Type of slaves(must be NXM_OF_IN_PORT) n_slaves Number of slaves ofs_nbits Start and End for the OXM/NXM field. Setting method refer to the ``nicira_ext.ofs_nbits`` dst OXM/NXM header for source field slaves List of slaves ================ ====================================================== Example:: actions += [parser.NXActionBundleLoad( algorithm=nicira_ext.NX_MP_ALG_HRW, fields=nicira_ext.NX_HASH_FIELDS_ETH_SRC, basis=0, slave_type=nicira_ext.NXM_OF_IN_PORT, n_slaves=2, ofs_nbits=nicira_ext.ofs_nbits(4, 31), dst="reg0", slaves=[2, 3])] """ _subtype = nicira_ext.NXAST_BUNDLE_LOAD _TYPE = { 'ascii': [ 'dst', ] } def __init__(self, algorithm, fields, basis, slave_type, n_slaves, ofs_nbits, dst, slaves): super(NXActionBundleLoad, self).__init__( algorithm, fields, basis, slave_type, n_slaves, ofs_nbits, dst, slaves) class NXActionCT(NXAction): r""" Pass traffic to the connection tracker action This action sends the packet through the connection tracker. And equivalent to the followings action of ovs-ofctl command. .. ct(argument[,argument]...) .. +------------------------------------------------+ | **ct(**\ *argument*\[,\ *argument*\]...\ **)** | +------------------------------------------------+ ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or more(Unspecified flag bits must be zero.) zone_src OXM/NXM header for source field zone_ofs_nbits Start and End for the OXM/NXM field. Setting method refer to the ``nicira_ext.ofs_nbits``. If you need set the Immediate value for zone, zone_src must be set to None or empty character string. recirc_table Recirculate to a specific table alg Well-known port number for the protocol actions Zero or more actions may immediately follow this action ================ ====================================================== .. NOTE:: If you set number to zone_src, Traceback occurs when you run the to_jsondict. Example:: match = parser.OFPMatch(eth_type=0x0800, ct_state=(0,32)) actions += [parser.NXActionCT( flags = 1, zone_src = "reg0", zone_ofs_nbits = nicira_ext.ofs_nbits(4, 31), recirc_table = 4, alg = 0, actions = [])] """ _subtype = nicira_ext.NXAST_CT # flags, zone_src, zone_ofs_nbits, recirc_table, # pad, alg _fmt_str = '!H4sHB3xH' _TYPE = { 'ascii': [ 'zone_src', ] } # Followed by actions def __init__(self, flags, zone_src, zone_ofs_nbits, recirc_table, alg, actions, type_=None, len_=None, experimenter=None, subtype=None): super(NXActionCT, self).__init__() self.flags = flags self.zone_src = zone_src self.zone_ofs_nbits = zone_ofs_nbits self.recirc_table = recirc_table self.alg = alg self.actions = actions @classmethod def parser(cls, buf): (flags, oxm_data, zone_ofs_nbits, recirc_table, alg,) = struct.unpack_from( cls._fmt_str, buf, 0) rest = buf[struct.calcsize(cls._fmt_str):] # OXM/NXM field if oxm_data == b'\x00' * 4: zone_src = "" else: (n, len_) = ofp.oxm_parse_header(oxm_data, 0) zone_src = ofp.oxm_to_user_header(n) # actions actions = [] while len(rest) > 0: action = ofpp.OFPAction.parser(rest, 0) actions.append(action) rest = rest[action.len:] return cls(flags, zone_src, zone_ofs_nbits, recirc_table, alg, actions) def serialize_body(self): data = bytearray() # If zone_src is zero, zone_ofs_nbits is zone_imm if not self.zone_src: zone_src = b'\x00' * 4 elif isinstance(self.zone_src, int): zone_src = struct.pack("!I", self.zone_src) else: zone_src = bytearray() oxm = ofp.oxm_from_user_header(self.zone_src) ofp.oxm_serialize_header(oxm, zone_src, 0) msg_pack_into(self._fmt_str, data, 0, self.flags, bytes(zone_src), self.zone_ofs_nbits, self.recirc_table, self.alg) for a in self.actions: a.serialize(data, len(data)) return data class NXActionCTClear(NXAction): """ Clear connection tracking state action This action clears connection tracking state from packets. And equivalent to the followings action of ovs-ofctl command. .. ct_clear .. +--------------+ | **ct_clear** | +--------------+ Example:: actions += [parser.NXActionCTClear()] """ _subtype = nicira_ext.NXAST_CT_CLEAR _fmt_str = '!6x' def __init__(self, type_=None, len_=None, experimenter=None, subtype=None): super(NXActionCTClear, self).__init__() @classmethod def parser(cls, buf): return cls() def serialize_body(self): data = bytearray() msg_pack_into(self._fmt_str, data, 0) return data class NXActionNAT(NXAction): r""" Network address translation action This action sends the packet through the connection tracker. And equivalent to the followings action of ovs-ofctl command. .. NOTE:: The following command image does not exist in ovs-ofctl command manual and has been created from the command response. .. nat(src=ip_min-ip_max : proto_min-proto-max) .. +--------------------------------------------------+ | **nat(src**\=\ *ip_min*\ **-**\ *ip_max*\ **:** | | *proto_min*\ **-**\ *proto-max*\ **)** | +--------------------------------------------------+ ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or more(Unspecified flag bits must be zero.) range_ipv4_min Range ipv4 address minimun range_ipv4_max Range ipv4 address maximun range_ipv6_min Range ipv6 address minimun range_ipv6_max Range ipv6 address maximun range_proto_min Range protocol minimum range_proto_max Range protocol maximun ================ ====================================================== .. CAUTION:: ``NXActionNAT`` must be defined in the actions in the ``NXActionCT``. Example:: match = parser.OFPMatch(eth_type=0x0800) actions += [ parser.NXActionCT( flags = 1, zone_src = "reg0", zone_ofs_nbits = nicira_ext.ofs_nbits(4, 31), recirc_table = 255, alg = 0, actions = [ parser.NXActionNAT( flags = 1, range_ipv4_min = "10.1.12.0", range_ipv4_max = "10.1.13.255", range_ipv6_min = "", range_ipv6_max = "", range_proto_min = 1, range_proto_max = 1023 ) ] ) ] """ _subtype = nicira_ext.NXAST_NAT # pad, flags, range_present _fmt_str = '!2xHH' # Followed by optional parameters _TYPE = { 'ascii': [ 'range_ipv4_max', 'range_ipv4_min', 'range_ipv6_max', 'range_ipv6_min', ] } def __init__(self, flags, range_ipv4_min='', range_ipv4_max='', range_ipv6_min='', range_ipv6_max='', range_proto_min=None, range_proto_max=None, type_=None, len_=None, experimenter=None, subtype=None): super(NXActionNAT, self).__init__() self.flags = flags self.range_ipv4_min = range_ipv4_min self.range_ipv4_max = range_ipv4_max self.range_ipv6_min = range_ipv6_min self.range_ipv6_max = range_ipv6_max self.range_proto_min = range_proto_min self.range_proto_max = range_proto_max @classmethod def parser(cls, buf): (flags, range_present) = struct.unpack_from( cls._fmt_str, buf, 0) rest = buf[struct.calcsize(cls._fmt_str):] # optional parameters kwargs = dict() if range_present & nicira_ext.NX_NAT_RANGE_IPV4_MIN: kwargs['range_ipv4_min'] = type_desc.IPv4Addr.to_user(rest[:4]) rest = rest[4:] if range_present & nicira_ext.NX_NAT_RANGE_IPV4_MAX: kwargs['range_ipv4_max'] = type_desc.IPv4Addr.to_user(rest[:4]) rest = rest[4:] if range_present & nicira_ext.NX_NAT_RANGE_IPV6_MIN: kwargs['range_ipv6_min'] = ( type_desc.IPv6Addr.to_user(rest[:16])) rest = rest[16:] if range_present & nicira_ext.NX_NAT_RANGE_IPV6_MAX: kwargs['range_ipv6_max'] = ( type_desc.IPv6Addr.to_user(rest[:16])) rest = rest[16:] if range_present & nicira_ext.NX_NAT_RANGE_PROTO_MIN: kwargs['range_proto_min'] = type_desc.Int2.to_user(rest[:2]) rest = rest[2:] if range_present & nicira_ext.NX_NAT_RANGE_PROTO_MAX: kwargs['range_proto_max'] = type_desc.Int2.to_user(rest[:2]) return cls(flags, **kwargs) def serialize_body(self): # Pack optional parameters first, as range_present needs # to be calculated. optional_data = b'' range_present = 0 if self.range_ipv4_min != '': range_present |= nicira_ext.NX_NAT_RANGE_IPV4_MIN optional_data += type_desc.IPv4Addr.from_user( self.range_ipv4_min) if self.range_ipv4_max != '': range_present |= nicira_ext.NX_NAT_RANGE_IPV4_MAX optional_data += type_desc.IPv4Addr.from_user( self.range_ipv4_max) if self.range_ipv6_min != '': range_present |= nicira_ext.NX_NAT_RANGE_IPV6_MIN optional_data += type_desc.IPv6Addr.from_user( self.range_ipv6_min) if self.range_ipv6_max != '': range_present |= nicira_ext.NX_NAT_RANGE_IPV6_MAX optional_data += type_desc.IPv6Addr.from_user( self.range_ipv6_max) if self.range_proto_min is not None: range_present |= nicira_ext.NX_NAT_RANGE_PROTO_MIN optional_data += type_desc.Int2.from_user( self.range_proto_min) if self.range_proto_max is not None: range_present |= nicira_ext.NX_NAT_RANGE_PROTO_MAX optional_data += type_desc.Int2.from_user( self.range_proto_max) data = bytearray() msg_pack_into(self._fmt_str, data, 0, self.flags, range_present) msg_pack_into('!%ds' % len(optional_data), data, len(data), optional_data) return data class NXActionOutputTrunc(NXAction): r""" Truncate output action This action truncate a packet into the specified size and outputs it. And equivalent to the followings action of ovs-ofctl command. .. output(port=port,max_len=max_len) .. +--------------------------------------------------------------+ | **output(port**\=\ *port*\,\ **max_len**\=\ *max_len*\ **)** | +--------------------------------------------------------------+ ================ ====================================================== Attribute Description ================ ====================================================== port Output port max_len Max bytes to send ================ ====================================================== Example:: actions += [parser.NXActionOutputTrunc(port=8080, max_len=1024)] """ _subtype = nicira_ext.NXAST_OUTPUT_TRUNC # port, max_len _fmt_str = '!HI' def __init__(self, port, max_len, type_=None, len_=None, experimenter=None, subtype=None): super(NXActionOutputTrunc, self).__init__() self.port = port self.max_len = max_len @classmethod def parser(cls, buf): (port, max_len) = struct.unpack_from( cls._fmt_str, buf, 0) return cls(port, max_len) def serialize_body(self): data = bytearray() msg_pack_into(self._fmt_str, data, 0, self.port, self.max_len) return data class NXActionEncapEther(NXAction): """ Encap Ether This action encaps package with ethernet And equivalent to the followings action of ovs-ofctl command. :: encap(ethernet) Example:: actions += [parser.NXActionEncapEther()] """ _subtype = nicira_ext.NXAST_RAW_ENCAP _fmt_str = '!HI' def __init__(self, type_=None, len_=None, vendor=None, subtype=None): super(NXActionEncapEther, self).__init__() self.hdr_size = 0 self.new_pkt_type = 0x00000000 @classmethod def parser(cls, buf): return cls() def serialize_body(self): data = bytearray() msg_pack_into(self._fmt_str, data, 0, self.hdr_size, self.new_pkt_type) return data class NXActionEncapNsh(NXAction): """ Encap nsh This action encaps package with nsh And equivalent to the followings action of ovs-ofctl command. :: encap(nsh(md_type=1)) Example:: actions += [parser.NXActionEncapNsh()] """ _subtype = nicira_ext.NXAST_RAW_ENCAP _fmt_str = '!HI' def __init__(self, type_=None, len_=None, vendor=None, subtype=None): super(NXActionEncapNsh, self).__init__() self.hdr_size = hdr_size self.new_pkt_type = 0x0001894F @classmethod def parser(cls, buf): return cls() def serialize_body(self): data = bytearray() msg_pack_into(self._fmt_str, data, 0, self.hdr_size, self.new_pkt_type) return data class NXActionDecNshTtl(NXAction): """ Decrement NSH TTL action This action decrements the TTL in the Network Service Header(NSH). This action was added in OVS v2.9. And equivalent to the followings action of ovs-ofctl command. :: dec_nsh_ttl Example:: actions += [parser.NXActionDecNshTtl()] """ _subtype = nicira_ext.NXAST_DEC_NSH_TTL _fmt_str = '!6x' def __init__(self, type_=None, len_=None, vendor=None, subtype=None): super(NXActionDecNshTtl, self).__init__() @classmethod def parser(cls, buf): return cls() def serialize_body(self): data = bytearray() msg_pack_into(self._fmt_str, data, 0) return data def add_attr(k, v): v.__module__ = ofpp.__name__ # Necessary for stringify stuff setattr(ofpp, k, v) add_attr('NXAction', NXAction) add_attr('NXActionUnknown', NXActionUnknown) classes = [ 'NXActionSetQueue', 'NXActionPopQueue', 'NXActionRegLoad', 'NXActionRegLoad2', 'NXActionNote', 'NXActionSetTunnel', 'NXActionSetTunnel64', 'NXActionRegMove', 'NXActionResubmit', 'NXActionResubmitTable', 'NXActionOutputReg', 'NXActionOutputReg2', 'NXActionLearn', 'NXActionExit', 'NXActionDecTtl', 'NXActionController', 'NXActionController2', 'NXActionDecTtlCntIds', 'NXActionPushMpls', 'NXActionPopMpls', 'NXActionSetMplsTtl', 'NXActionDecMplsTtl', 'NXActionSetMplsLabel', 'NXActionSetMplsTc', 'NXActionStackPush', 'NXActionStackPop', 'NXActionSample', 'NXActionSample2', 'NXActionFinTimeout', 'NXActionConjunction', 'NXActionMultipath', 'NXActionBundle', 'NXActionBundleLoad', 'NXActionCT', 'NXActionCTClear', 'NXActionNAT', 'NXActionOutputTrunc', '_NXFlowSpec', # exported for testing 'NXFlowSpecMatch', 'NXFlowSpecLoad', 'NXFlowSpecOutput', 'NXActionEncapNsh', 'NXActionEncapEther', 'NXActionDecNshTtl', ] vars = locals() for name in classes: cls = vars[name] add_attr(name, cls) if issubclass(cls, NXAction): NXAction.register(cls) if issubclass(cls, _NXFlowSpec): _NXFlowSpec.register(cls) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/ofproto/nx_match.py0000664000175000017500000011337200000000000020141 0ustar00zuulzuul00000000000000# Copyright (C) 2011-2015 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2011, 2012 Isaku Yamahata # Copyright (C) 2012 Simon Horman # # 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. import struct from os_ken import exception from os_ken.lib import mac from os_ken.lib.pack_utils import msg_pack_into from os_ken.ofproto import ether from os_ken.ofproto import ofproto_parser from os_ken.ofproto import ofproto_v1_0 from os_ken.ofproto import inet import logging LOG = logging.getLogger('os_ken.ofproto.nx_match') UINT64_MAX = (1 << 64) - 1 UINT32_MAX = (1 << 32) - 1 UINT16_MAX = (1 << 16) - 1 FWW_IN_PORT = 1 << 0 FWW_DL_TYPE = 1 << 4 FWW_NW_PROTO = 1 << 5 # No corresponding OFPFW_* bits FWW_NW_DSCP = 1 << 1 FWW_NW_ECN = 1 << 2 FWW_ARP_SHA = 1 << 3 FWW_ARP_THA = 1 << 6 FWW_IPV6_LABEL = 1 << 7 FWW_NW_TTL = 1 << 8 FWW_ALL = (1 << 13) - 1 FLOW_NW_FRAG_ANY = 1 << 0 FLOW_NW_FRAG_LATER = 1 << 1 FLOW_NW_FRAG_MASK = FLOW_NW_FRAG_ANY | FLOW_NW_FRAG_LATER IP_ECN_MASK = 0x03 IP_DSCP_MASK = 0xfc MF_PACK_STRING_BE64 = '!Q' MF_PACK_STRING_BE32 = '!I' MF_PACK_STRING_BE16 = '!H' MF_PACK_STRING_8 = '!B' MF_PACK_STRING_MAC = '!6s' MF_PACK_STRING_IPV6 = '!8H' _MF_FIELDS = {} FLOW_N_REGS = 8 # ovs 1.5 class Flow(ofproto_parser.StringifyMixin): def __init__(self): self.in_port = 0 self.dl_vlan = 0 self.dl_vlan_pcp = 0 self.dl_src = mac.DONTCARE self.dl_dst = mac.DONTCARE self.dl_type = 0 self.tp_dst = 0 self.tp_src = 0 self.nw_tos = 0 self.vlan_tci = 0 self.nw_ttl = 0 self.nw_proto = 0 self.arp_sha = 0 self.arp_tha = 0 self.nw_src = 0 self.nw_dst = 0 self.tun_id = 0 self.arp_spa = 0 self.arp_tpa = 0 self.ipv6_src = [] self.ipv6_dst = [] self.nd_target = [] self.nw_frag = 0 self.regs = [0] * FLOW_N_REGS self.ipv6_label = 0 self.pkt_mark = 0 self.tcp_flags = 0 class FlowWildcards(ofproto_parser.StringifyMixin): def __init__(self): self.dl_src_mask = 0 self.dl_dst_mask = 0 self.tp_src_mask = 0 self.tp_dst_mask = 0 self.nw_src_mask = 0 self.nw_dst_mask = 0 self.tun_id_mask = 0 self.arp_spa_mask = 0 self.arp_tpa_mask = 0 self.vlan_tci_mask = 0 self.ipv6_src_mask = [] self.ipv6_dst_mask = [] self.nd_target_mask = [] self.nw_frag_mask = 0 self.regs_bits = 0 self.regs_mask = [0] * FLOW_N_REGS self.wildcards = ofproto_v1_0.OFPFW_ALL self.pkt_mark_mask = 0 self.tcp_flags_mask = 0 class ClsRule(ofproto_parser.StringifyMixin): """describe a matching rule for OF 1.0 OFPMatch (and NX). """ def __init__(self, **kwargs): self.wc = FlowWildcards() self.flow = Flow() for key, value in kwargs.items(): if key[:3] == 'reg': register = int(key[3:] or -1) self.set_reg(register, value) continue setter = getattr(self, 'set_' + key, None) if not setter: LOG.error('Invalid kwarg specified to ClsRule (%s)', key) continue if not isinstance(value, (tuple, list)): value = (value, ) setter(*value) def set_in_port(self, port): self.wc.wildcards &= ~FWW_IN_PORT self.flow.in_port = port def set_dl_vlan(self, dl_vlan): self.wc.wildcards &= ~ofproto_v1_0.OFPFW_DL_VLAN self.flow.dl_vlan = dl_vlan def set_dl_vlan_pcp(self, dl_vlan_pcp): self.wc.wildcards &= ~ofproto_v1_0.OFPFW_DL_VLAN_PCP self.flow.dl_vlan_pcp = dl_vlan_pcp def set_dl_dst(self, dl_dst): self.flow.dl_dst = dl_dst def set_dl_dst_masked(self, dl_dst, mask): self.wc.dl_dst_mask = mask # bit-wise and of the corresponding elements of dl_dst and mask self.flow.dl_dst = mac.haddr_bitand(dl_dst, mask) def set_dl_src(self, dl_src): self.flow.dl_src = dl_src def set_dl_src_masked(self, dl_src, mask): self.wc.dl_src_mask = mask self.flow.dl_src = mac.haddr_bitand(dl_src, mask) def set_dl_type(self, dl_type): self.wc.wildcards &= ~FWW_DL_TYPE self.flow.dl_type = dl_type def set_dl_tci(self, tci): self.set_dl_tci_masked(tci, UINT16_MAX) def set_dl_tci_masked(self, tci, mask): self.wc.vlan_tci_mask = mask self.flow.vlan_tci = tci def set_tp_src(self, tp_src): self.set_tp_src_masked(tp_src, UINT16_MAX) def set_tp_src_masked(self, tp_src, mask): self.wc.tp_src_mask = mask self.flow.tp_src = tp_src & mask def set_tp_dst(self, tp_dst): self.set_tp_dst_masked(tp_dst, UINT16_MAX) def set_tp_dst_masked(self, tp_dst, mask): self.wc.tp_dst_mask = mask self.flow.tp_dst = tp_dst & mask def set_nw_proto(self, nw_proto): self.wc.wildcards &= ~FWW_NW_PROTO self.flow.nw_proto = nw_proto def set_nw_src(self, nw_src): self.set_nw_src_masked(nw_src, UINT32_MAX) def set_nw_src_masked(self, nw_src, mask): self.flow.nw_src = nw_src self.wc.nw_src_mask = mask def set_nw_dst(self, nw_dst): self.set_nw_dst_masked(nw_dst, UINT32_MAX) def set_nw_dst_masked(self, nw_dst, mask): self.flow.nw_dst = nw_dst self.wc.nw_dst_mask = mask def set_nw_dscp(self, nw_dscp): self.wc.wildcards &= ~FWW_NW_DSCP self.flow.nw_tos &= ~IP_DSCP_MASK self.flow.nw_tos |= nw_dscp & IP_DSCP_MASK def set_icmp_type(self, icmp_type): self.set_tp_src(icmp_type) def set_icmp_code(self, icmp_code): self.set_tp_dst(icmp_code) def set_tun_id(self, tun_id): self.set_tun_id_masked(tun_id, UINT64_MAX) def set_tun_id_masked(self, tun_id, mask): self.wc.tun_id_mask = mask self.flow.tun_id = tun_id & mask def set_nw_ecn(self, nw_ecn): self.wc.wildcards &= ~FWW_NW_ECN self.flow.nw_tos &= ~IP_ECN_MASK self.flow.nw_tos |= nw_ecn & IP_ECN_MASK def set_nw_ttl(self, nw_ttl): self.wc.wildcards &= ~FWW_NW_TTL self.flow.nw_ttl = nw_ttl def set_nw_frag(self, nw_frag): self.wc.nw_frag_mask |= FLOW_NW_FRAG_MASK self.flow.nw_frag = nw_frag def set_nw_frag_masked(self, nw_frag, mask): self.wc.nw_frag_mask = mask self.flow.nw_frag = nw_frag & mask def set_arp_spa(self, spa): self.set_arp_spa_masked(spa, UINT32_MAX) def set_arp_spa_masked(self, spa, mask): self.flow.arp_spa = spa self.wc.arp_spa_mask = mask def set_arp_tpa(self, tpa): self.set_arp_tpa_masked(tpa, UINT32_MAX) def set_arp_tpa_masked(self, tpa, mask): self.flow.arp_tpa = tpa self.wc.arp_tpa_mask = mask def set_arp_sha(self, sha): self.wc.wildcards &= ~FWW_ARP_SHA self.flow.arp_sha = sha def set_arp_tha(self, tha): self.wc.wildcards &= ~FWW_ARP_THA self.flow.arp_tha = tha def set_icmpv6_type(self, icmp_type): self.set_tp_src(icmp_type) def set_icmpv6_code(self, icmp_code): self.set_tp_dst(icmp_code) def set_ipv6_label(self, label): self.wc.wildcards &= ~FWW_IPV6_LABEL self.flow.ipv6_label = label def set_ipv6_src_masked(self, src, mask): self.wc.ipv6_src_mask = mask self.flow.ipv6_src = [x & y for (x, y) in zip(src, mask)] def set_ipv6_src(self, src): self.flow.ipv6_src = src def set_ipv6_dst_masked(self, dst, mask): self.wc.ipv6_dst_mask = mask self.flow.ipv6_dst = [x & y for (x, y) in zip(dst, mask)] def set_ipv6_dst(self, dst): self.flow.ipv6_dst = dst def set_nd_target_masked(self, target, mask): self.wc.nd_target_mask = mask self.flow.nd_target = [x & y for (x, y) in zip(target, mask)] def set_nd_target(self, target): self.flow.nd_target = target def set_reg(self, reg_idx, value): self.set_reg_masked(reg_idx, value, 0) def set_reg_masked(self, reg_idx, value, mask): self.wc.regs_mask[reg_idx] = mask self.flow.regs[reg_idx] = value self.wc.regs_bits |= (1 << reg_idx) def set_pkt_mark_masked(self, pkt_mark, mask): self.flow.pkt_mark = pkt_mark self.wc.pkt_mark_mask = mask def set_tcp_flags(self, tcp_flags, mask): self.flow.tcp_flags = tcp_flags self.wc.tcp_flags_mask = mask def flow_format(self): # Tunnel ID is only supported by NXM if self.wc.tun_id_mask != 0: return ofproto_v1_0.NXFF_NXM # Masking DL_DST is only supported by NXM if self.wc.dl_dst_mask: return ofproto_v1_0.NXFF_NXM # Masking DL_SRC is only supported by NXM if self.wc.dl_src_mask: return ofproto_v1_0.NXFF_NXM # ECN is only supported by NXM if not self.wc.wildcards & FWW_NW_ECN: return ofproto_v1_0.NXFF_NXM if self.wc.regs_bits > 0: return ofproto_v1_0.NXFF_NXM if self.flow.tcp_flags > 0: return ofproto_v1_0.NXFF_NXM return ofproto_v1_0.NXFF_OPENFLOW10 def match_tuple(self): """return a tuple which can be used as *args for ofproto_v1_0_parser.OFPMatch.__init__(). see Datapath.send_flow_mod. """ assert self.flow_format() == ofproto_v1_0.NXFF_OPENFLOW10 wildcards = ofproto_v1_0.OFPFW_ALL if not self.wc.wildcards & FWW_IN_PORT: wildcards &= ~ofproto_v1_0.OFPFW_IN_PORT if self.flow.dl_src != mac.DONTCARE: wildcards &= ~ofproto_v1_0.OFPFW_DL_SRC if self.flow.dl_dst != mac.DONTCARE: wildcards &= ~ofproto_v1_0.OFPFW_DL_DST if not self.wc.wildcards & FWW_DL_TYPE: wildcards &= ~ofproto_v1_0.OFPFW_DL_TYPE if self.flow.dl_vlan != 0: wildcards &= ~ofproto_v1_0.OFPFW_DL_VLAN if self.flow.dl_vlan_pcp != 0: wildcards &= ~ofproto_v1_0.OFPFW_DL_VLAN_PCP if self.flow.nw_tos != 0: wildcards &= ~ofproto_v1_0.OFPFW_NW_TOS if self.flow.nw_proto != 0: wildcards &= ~ofproto_v1_0.OFPFW_NW_PROTO if self.wc.nw_src_mask != 0 and "01" not in bin(self.wc.nw_src_mask): wildcards &= ~ofproto_v1_0.OFPFW_NW_SRC_MASK maskbits = (bin(self.wc.nw_src_mask).count("0") - 1) wildcards |= (maskbits << ofproto_v1_0.OFPFW_NW_SRC_SHIFT) if self.wc.nw_dst_mask != 0 and "01" not in bin(self.wc.nw_dst_mask): wildcards &= ~ofproto_v1_0.OFPFW_NW_DST_MASK maskbits = (bin(self.wc.nw_dst_mask).count("0") - 1) wildcards |= (maskbits << ofproto_v1_0.OFPFW_NW_DST_SHIFT) if self.flow.tp_src != 0: wildcards &= ~ofproto_v1_0.OFPFW_TP_SRC if self.flow.tp_dst != 0: wildcards &= ~ofproto_v1_0.OFPFW_TP_DST return (wildcards, self.flow.in_port, self.flow.dl_src, self.flow.dl_dst, self.flow.dl_vlan, self.flow.dl_vlan_pcp, self.flow.dl_type, self.flow.nw_tos & IP_DSCP_MASK, self.flow.nw_proto, self.flow.nw_src, self.flow.nw_dst, self.flow.tp_src, self.flow.tp_dst) def _set_nxm_headers(nxm_headers): '''Annotate corresponding NXM header''' def _set_nxm_headers_dec(self): self.nxm_headers = nxm_headers return self return _set_nxm_headers_dec def _register_make(cls): '''class decorator to Register mf make''' assert cls.nxm_headers is not None assert cls.nxm_headers is not [] for nxm_header in cls.nxm_headers: assert nxm_header not in _MF_FIELDS _MF_FIELDS[nxm_header] = cls.make return cls def mf_from_nxm_header(nxm_header): if nxm_header not in _MF_FIELDS: return None make = _MF_FIELDS.get(nxm_header) assert make is not None return make(nxm_header) class MFField(object): _FIELDS_HEADERS = {} @staticmethod def register_field_header(headers): def _register_field_header(cls): for header in headers: MFField._FIELDS_HEADERS[header] = cls return cls return _register_field_header def __init__(self, nxm_header, pack_str): self.nxm_header = nxm_header self.pack_str = pack_str self.n_bytes = struct.calcsize(pack_str) self.n_bits = self.n_bytes * 8 @classmethod def parser(cls, buf, offset): (header,) = struct.unpack_from('!I', buf, offset) cls_ = MFField._FIELDS_HEADERS.get(header) if cls_: field = cls_.field_parser(header, buf, offset) else: # print 'unknown field type' raise field.length = (header & 0xff) + 4 return field @classmethod def field_parser(cls, header, buf, offset): hasmask = (header >> 8) & 1 mask = None if hasmask: pack_str = '!' + cls.pack_str[1:] * 2 (value, mask) = struct.unpack_from(pack_str, buf, offset + 4) else: (value,) = struct.unpack_from(cls.pack_str, buf, offset + 4) return cls(header, value, mask) def _put(self, buf, offset, value): msg_pack_into(self.pack_str, buf, offset, value) return self.n_bytes def putw(self, buf, offset, value, mask): len_ = self._put(buf, offset, value) return len_ + self._put(buf, offset + len_, mask) def _is_all_ones(self, value): return value == (1 << self.n_bits) - 1 def putm(self, buf, offset, value, mask): if mask == 0: return 0 elif self._is_all_ones(mask): return self._put(buf, offset, value) else: return self.putw(buf, offset, value, mask) def _putv6(self, buf, offset, value): msg_pack_into(self.pack_str, buf, offset, *value) return self.n_bytes def putv6(self, buf, offset, value, mask): len_ = self._putv6(buf, offset, value) if len(mask): return len_ + self._putv6(buf, offset + len_, mask) return len_ @_register_make @_set_nxm_headers([ofproto_v1_0.NXM_OF_IN_PORT]) @MFField.register_field_header([ofproto_v1_0.NXM_OF_IN_PORT]) class MFInPort(MFField): pack_str = MF_PACK_STRING_BE16 def __init__(self, header, value, mask=None): super(MFInPort, self).__init__(header, MFInPort.pack_str) self.value = value @classmethod def make(cls, header): return cls(header, MFInPort.pack_str) def put(self, buf, offset, rule): return self._put(buf, offset, rule.flow.in_port) @_register_make @_set_nxm_headers([ofproto_v1_0.NXM_OF_ETH_DST, ofproto_v1_0.NXM_OF_ETH_DST_W]) @MFField.register_field_header([ofproto_v1_0.NXM_OF_ETH_DST, ofproto_v1_0.NXM_OF_ETH_DST_W]) class MFEthDst(MFField): pack_str = MF_PACK_STRING_MAC def __init__(self, header, value, mask=None): super(MFEthDst, self).__init__(header, MFEthDst.pack_str) self.value = value @classmethod def make(cls, header): return cls(header, MFEthDst.pack_str) def put(self, buf, offset, rule): if rule.wc.dl_dst_mask: return self.putw(buf, offset, rule.flow.dl_dst, rule.wc.dl_dst_mask) else: return self._put(buf, offset, rule.flow.dl_dst) @_register_make @_set_nxm_headers([ofproto_v1_0.NXM_OF_ETH_SRC, ofproto_v1_0.NXM_OF_ETH_SRC_W]) @MFField.register_field_header([ofproto_v1_0.NXM_OF_ETH_SRC, ofproto_v1_0.NXM_OF_ETH_SRC_W]) class MFEthSrc(MFField): pack_str = MF_PACK_STRING_MAC def __init__(self, header, value, mask=None): super(MFEthSrc, self).__init__(header, MFEthSrc.pack_str) self.value = value @classmethod def make(cls, header): return cls(header, MFEthSrc.pack_str) def put(self, buf, offset, rule): if rule.wc.dl_src_mask: return self.putw(buf, offset, rule.flow.dl_src, rule.wc.dl_src_mask) else: return self._put(buf, offset, rule.flow.dl_src) @_register_make @_set_nxm_headers([ofproto_v1_0.NXM_OF_ETH_TYPE]) @MFField.register_field_header([ofproto_v1_0.NXM_OF_ETH_TYPE]) class MFEthType(MFField): pack_str = MF_PACK_STRING_BE16 def __init__(self, header, value, mask=None): super(MFEthType, self).__init__(header, MFEthType.pack_str) self.value = value @classmethod def make(cls, header): return cls(header, MFEthType.pack_str) def put(self, buf, offset, rule): return self._put(buf, offset, rule.flow.dl_type) @_register_make @_set_nxm_headers([ofproto_v1_0.NXM_OF_VLAN_TCI, ofproto_v1_0.NXM_OF_VLAN_TCI_W]) @MFField.register_field_header([ofproto_v1_0.NXM_OF_VLAN_TCI, ofproto_v1_0.NXM_OF_VLAN_TCI_W]) class MFVlan(MFField): pack_str = MF_PACK_STRING_BE16 def __init__(self, header, value, mask=None): super(MFVlan, self).__init__(header, MFVlan.pack_str) self.value = value @classmethod def make(cls, header): return cls(header, MFVlan.pack_str) def put(self, buf, offset, rule): return self.putm(buf, offset, rule.flow.vlan_tci, rule.wc.vlan_tci_mask) @_register_make @_set_nxm_headers([ofproto_v1_0.NXM_OF_IP_TOS]) @MFField.register_field_header([ofproto_v1_0.NXM_OF_IP_TOS]) class MFIPDSCP(MFField): pack_str = MF_PACK_STRING_8 def __init__(self, header, value, mask=None): super(MFIPDSCP, self).__init__(header, MFIPDSCP.pack_str) self.value = value @classmethod def make(cls, header): return cls(header, MFIPDSCP.pack_str) def put(self, buf, offset, rule): return self._put(buf, offset, rule.flow.nw_tos & IP_DSCP_MASK) @_register_make @_set_nxm_headers([ofproto_v1_0.NXM_NX_TUN_ID, ofproto_v1_0.NXM_NX_TUN_ID_W]) @MFField.register_field_header([ofproto_v1_0.NXM_NX_TUN_ID, ofproto_v1_0.NXM_NX_TUN_ID_W]) class MFTunId(MFField): pack_str = MF_PACK_STRING_BE64 def __init__(self, header, value, mask=None): super(MFTunId, self).__init__(header, MFTunId.pack_str) self.value = value @classmethod def make(cls, header): return cls(header, MFTunId.pack_str) def put(self, buf, offset, rule): return self.putm(buf, offset, rule.flow.tun_id, rule.wc.tun_id_mask) @_register_make @_set_nxm_headers([ofproto_v1_0.NXM_OF_IP_SRC, ofproto_v1_0.NXM_OF_IP_SRC_W]) @MFField.register_field_header([ofproto_v1_0.NXM_OF_IP_SRC, ofproto_v1_0.NXM_OF_IP_SRC_W]) class MFIPSrc(MFField): pack_str = MF_PACK_STRING_BE32 def __init__(self, header, value, mask=None): super(MFIPSrc, self).__init__(header, MFIPSrc.pack_str) self.value = value self.mask = mask @classmethod def make(cls, header): return cls(header, MFIPSrc.pack_str) def put(self, buf, offset, rule): return self.putm(buf, offset, rule.flow.nw_src, rule.wc.nw_src_mask) @_register_make @_set_nxm_headers([ofproto_v1_0.NXM_OF_IP_DST, ofproto_v1_0.NXM_OF_IP_DST_W]) @MFField.register_field_header([ofproto_v1_0.NXM_OF_IP_DST, ofproto_v1_0.NXM_OF_IP_DST_W]) class MFIPDst(MFField): pack_str = MF_PACK_STRING_BE32 def __init__(self, header, value, mask=None): super(MFIPDst, self).__init__(header, MFIPDst.pack_str) self.value = value self.mask = mask @classmethod def make(cls, header): return cls(header, MFIPDst.pack_str) def put(self, buf, offset, rule): return self.putm(buf, offset, rule.flow.nw_dst, rule.wc.nw_dst_mask) @_register_make @_set_nxm_headers([ofproto_v1_0.NXM_NX_IP_ECN]) class MFIPECN(MFField): @classmethod def make(cls, header): return cls(header, MF_PACK_STRING_8) def put(self, buf, offset, rule): return self._put(buf, offset, rule.flow.nw_tos & IP_ECN_MASK) @_register_make @_set_nxm_headers([ofproto_v1_0.NXM_NX_IP_TTL]) class MFIPTTL(MFField): @classmethod def make(cls, header): return cls(header, MF_PACK_STRING_8) def put(self, buf, offset, rule): return self._put(buf, offset, rule.flow.nw_ttl) @_register_make @_set_nxm_headers([ofproto_v1_0.NXM_OF_IP_PROTO]) class MFIPProto(MFField): @classmethod def make(cls, header): return cls(header, MF_PACK_STRING_8) def put(self, buf, offset, rule): return self._put(buf, offset, rule.flow.nw_proto) @_register_make @_set_nxm_headers([ofproto_v1_0.NXM_OF_TCP_SRC, ofproto_v1_0.NXM_OF_TCP_SRC_W, ofproto_v1_0.NXM_OF_UDP_SRC, ofproto_v1_0.NXM_OF_UDP_SRC_W]) class MFTPSRC(MFField): @classmethod def make(cls, header): return cls(header, MF_PACK_STRING_BE16) def put(self, buf, offset, rule): return self.putm(buf, offset, rule.flow.tp_src, rule.wc.tp_src_mask) @_register_make @_set_nxm_headers([ofproto_v1_0.NXM_OF_TCP_DST, ofproto_v1_0.NXM_OF_TCP_DST_W, ofproto_v1_0.NXM_OF_UDP_DST, ofproto_v1_0.NXM_OF_UDP_DST_W]) class MFTPDST(MFField): @classmethod def make(cls, header): return cls(header, MF_PACK_STRING_BE16) def put(self, buf, offset, rule): return self.putm(buf, offset, rule.flow.tp_dst, rule.wc.tp_dst_mask) @_register_make @_set_nxm_headers([ofproto_v1_0.NXM_OF_ARP_SPA, ofproto_v1_0.NXM_OF_ARP_SPA_W]) class MFArpSpa(MFField): @classmethod def make(cls, header): return cls(header, MF_PACK_STRING_BE32) def put(self, buf, offset, rule): return self.putm(buf, offset, rule.flow.arp_spa, rule.wc.arp_spa_mask) @_register_make @_set_nxm_headers([ofproto_v1_0.NXM_OF_ARP_TPA, ofproto_v1_0.NXM_OF_ARP_TPA_W]) class MFArpTpa(MFField): @classmethod def make(cls, header): return cls(header, MF_PACK_STRING_BE32) def put(self, buf, offset, rule): return self.putm(buf, offset, rule.flow.arp_tpa, rule.wc.arp_tpa_mask) @_register_make @_set_nxm_headers([ofproto_v1_0.NXM_NX_ARP_SHA]) class MFArpSha(MFField): @classmethod def make(cls, header): return cls(header, MF_PACK_STRING_MAC) def put(self, buf, offset, rule): return self._put(buf, offset, rule.flow.arp_sha) class MFIPV6(object): pack_str = MF_PACK_STRING_IPV6 @classmethod def field_parser(cls, header, buf, offset): hasmask = (header >> 8) & 1 if hasmask: pack_string = '!' + cls.pack_str[1:] * 2 value = struct.unpack_from(pack_string, buf, offset + 4) return cls(header, list(value[:8]), list(value[8:])) else: value = struct.unpack_from(cls.pack_str, buf, offset + 4) return cls(header, list(value)) @_register_make @_set_nxm_headers([ofproto_v1_0.NXM_NX_IPV6_SRC, ofproto_v1_0.NXM_NX_IPV6_SRC_W]) @MFField.register_field_header([ofproto_v1_0.NXM_NX_IPV6_SRC, ofproto_v1_0.NXM_NX_IPV6_SRC_W]) class MFIPV6Src(MFIPV6, MFField): def __init__(self, header, value, mask=None): super(MFIPV6Src, self).__init__(header, MFIPV6Src.pack_str) self.value = value self.mask = mask @classmethod def make(cls, header): return cls(header, cls.pack_str) def put(self, buf, offset, rule): return self.putv6(buf, offset, rule.flow.ipv6_src, rule.wc.ipv6_src_mask) @_register_make @_set_nxm_headers([ofproto_v1_0.NXM_NX_IPV6_DST, ofproto_v1_0.NXM_NX_IPV6_DST_W]) @MFField.register_field_header([ofproto_v1_0.NXM_NX_IPV6_DST, ofproto_v1_0.NXM_NX_IPV6_DST_W]) class MFIPV6Dst(MFIPV6, MFField): def __init__(self, header, value, mask=None): super(MFIPV6Dst, self).__init__(header, MFIPV6Dst.pack_str) self.value = value self.mask = mask @classmethod def make(cls, header): return cls(header, cls.pack_str) def put(self, buf, offset, rule): return self.putv6(buf, offset, rule.flow.ipv6_dst, rule.wc.ipv6_dst_mask) @_register_make @_set_nxm_headers([ofproto_v1_0.NXM_NX_ND_TARGET, ofproto_v1_0.NXM_NX_ND_TARGET_W]) class MFNdTarget(MFField): @classmethod def make(cls, header): return cls(header, '!4I') def put(self, buf, offset, rule): return self.putv6(buf, offset, rule.flow.nd_target, rule.wc.nd_target_mask) @_register_make @_set_nxm_headers([ofproto_v1_0.NXM_NX_IP_FRAG, ofproto_v1_0.NXM_NX_IP_FRAG_W]) class MFIpFrag(MFField): @classmethod def make(cls, header): return cls(header, '!B') def put(self, buf, offset, rule): if rule.wc.nw_frag_mask == FLOW_NW_FRAG_MASK: return self._put(buf, offset, rule.flow.nw_frag) else: return self.putw(buf, offset, rule.flow.nw_frag, rule.wc.nw_frag_mask & FLOW_NW_FRAG_MASK) @_register_make @_set_nxm_headers([ofproto_v1_0.NXM_NX_ARP_THA]) class MFArpTha(MFField): @classmethod def make(cls, header): return cls(header, MF_PACK_STRING_MAC) def put(self, buf, offset, rule): return self._put(buf, offset, rule.flow.arp_tha) @_register_make @_set_nxm_headers([ofproto_v1_0.NXM_OF_ICMP_TYPE]) class MFICMPType(MFField): @classmethod def make(cls, header): return cls(header, MF_PACK_STRING_8) def put(self, buf, offset, rule): return self._put(buf, offset, rule.flow.tp_src) @_register_make @_set_nxm_headers([ofproto_v1_0.NXM_OF_ICMP_CODE]) class MFICMPCode(MFField): @classmethod def make(cls, header): return cls(header, MF_PACK_STRING_8) def put(self, buf, offset, rule): return self._put(buf, offset, rule.flow.tp_dst) @_register_make @_set_nxm_headers([ofproto_v1_0.NXM_NX_ICMPV6_TYPE]) class MFICMPV6Type(MFField): @classmethod def make(cls, header): return cls(header, MF_PACK_STRING_8) def put(self, buf, offset, rule): return self._put(buf, offset, rule.flow.tp_src) @_register_make @_set_nxm_headers([ofproto_v1_0.NXM_NX_ICMPV6_CODE]) class MFICMPV6Code(MFField): @classmethod def make(cls, header): return cls(header, MF_PACK_STRING_8) def put(self, buf, offset, rule): return self._put(buf, offset, rule.flow.tp_dst) @_register_make @_set_nxm_headers([ofproto_v1_0.NXM_NX_IPV6_LABEL]) class MFICMPV6Label(MFField): @classmethod def make(cls, header): return cls(header, MF_PACK_STRING_BE32) def put(self, buf, offset, rule): return self._put(buf, offset, rule.flow.ipv6_label) @_register_make @_set_nxm_headers([ofproto_v1_0.nxm_nx_reg(i) for i in range(FLOW_N_REGS)] + [ofproto_v1_0.nxm_nx_reg_w(i) for i in range(FLOW_N_REGS)]) class MFRegister(MFField): @classmethod def make(cls, header): return cls(header, MF_PACK_STRING_BE32) def put(self, buf, offset, rule): for i in range(FLOW_N_REGS): if (ofproto_v1_0.nxm_nx_reg(i) == self.nxm_header or ofproto_v1_0.nxm_nx_reg_w(i) == self.nxm_header): if rule.wc.regs_mask[i]: return self.putm(buf, offset, rule.flow.regs[i], rule.wc.regs_mask[i]) else: return self._put(buf, offset, rule.flow.regs[i]) @_register_make @_set_nxm_headers([ofproto_v1_0.NXM_NX_PKT_MARK, ofproto_v1_0.NXM_NX_PKT_MARK_W]) class MFPktMark(MFField): @classmethod def make(cls, header): return cls(header, MF_PACK_STRING_BE32) def put(self, buf, offset, rule): return self.putm(buf, offset, rule.flow.pkt_mark, rule.wc.pkt_mark_mask) @_register_make @_set_nxm_headers([ofproto_v1_0.NXM_NX_TCP_FLAGS, ofproto_v1_0.NXM_NX_TCP_FLAGS_W]) class MFTcpFlags(MFField): @classmethod def make(cls, header): return cls(header, MF_PACK_STRING_BE16) def put(self, buf, offset, rule): return self.putm(buf, offset, rule.flow.tcp_flags, rule.wc.tcp_flags_mask) def serialize_nxm_match(rule, buf, offset): old_offset = offset if not rule.wc.wildcards & FWW_IN_PORT: offset += nxm_put(buf, offset, ofproto_v1_0.NXM_OF_IN_PORT, rule) # Ethernet. if rule.flow.dl_dst != mac.DONTCARE: if rule.wc.dl_dst_mask: header = ofproto_v1_0.NXM_OF_ETH_DST_W else: header = ofproto_v1_0.NXM_OF_ETH_DST offset += nxm_put(buf, offset, header, rule) if rule.flow.dl_src != mac.DONTCARE: if rule.wc.dl_src_mask: header = ofproto_v1_0.NXM_OF_ETH_SRC_W else: header = ofproto_v1_0.NXM_OF_ETH_SRC offset += nxm_put(buf, offset, header, rule) if not rule.wc.wildcards & FWW_DL_TYPE: offset += nxm_put(buf, offset, ofproto_v1_0.NXM_OF_ETH_TYPE, rule) # 802.1Q if rule.wc.vlan_tci_mask != 0: if rule.wc.vlan_tci_mask == UINT16_MAX: header = ofproto_v1_0.NXM_OF_VLAN_TCI else: header = ofproto_v1_0.NXM_OF_VLAN_TCI_W offset += nxm_put(buf, offset, header, rule) # L3 if not rule.wc.wildcards & FWW_NW_DSCP: offset += nxm_put(buf, offset, ofproto_v1_0.NXM_OF_IP_TOS, rule) if not rule.wc.wildcards & FWW_NW_ECN: offset += nxm_put(buf, offset, ofproto_v1_0.NXM_NX_IP_ECN, rule) if not rule.wc.wildcards & FWW_NW_TTL: offset += nxm_put(buf, offset, ofproto_v1_0.NXM_NX_IP_TTL, rule) if not rule.wc.wildcards & FWW_NW_PROTO: offset += nxm_put(buf, offset, ofproto_v1_0.NXM_OF_IP_PROTO, rule) if not rule.wc.wildcards & FWW_NW_PROTO and (rule.flow.nw_proto == inet.IPPROTO_ICMP): if rule.wc.tp_src_mask != 0: offset += nxm_put(buf, offset, ofproto_v1_0.NXM_OF_ICMP_TYPE, rule) if rule.wc.tp_dst_mask != 0: offset += nxm_put(buf, offset, ofproto_v1_0.NXM_OF_ICMP_CODE, rule) if rule.flow.tp_src != 0: if rule.flow.nw_proto == 6: if rule.wc.tp_src_mask == UINT16_MAX: header = ofproto_v1_0.NXM_OF_TCP_SRC else: header = ofproto_v1_0.NXM_OF_TCP_SRC_W elif rule.flow.nw_proto == 17: if rule.wc.tp_src_mask == UINT16_MAX: header = ofproto_v1_0.NXM_OF_UDP_SRC else: header = ofproto_v1_0.NXM_OF_UDP_SRC_W else: header = 0 if header != 0: offset += nxm_put(buf, offset, header, rule) if rule.flow.tp_dst != 0: if rule.flow.nw_proto == 6: if rule.wc.tp_dst_mask == UINT16_MAX: header = ofproto_v1_0.NXM_OF_TCP_DST else: header = ofproto_v1_0.NXM_OF_TCP_DST_W elif rule.flow.nw_proto == 17: if rule.wc.tp_dst_mask == UINT16_MAX: header = ofproto_v1_0.NXM_OF_UDP_DST else: header = ofproto_v1_0.NXM_OF_UDP_DST_W else: header = 0 if header != 0: offset += nxm_put(buf, offset, header, rule) if rule.flow.tcp_flags != 0: # TCP Flags can only be used if the ethernet type is IPv4 or IPv6 if rule.flow.dl_type in (ether.ETH_TYPE_IP, ether.ETH_TYPE_IPV6): # TCP Flags can only be used if the ip protocol is TCP if rule.flow.nw_proto == inet.IPPROTO_TCP: if rule.wc.tcp_flags_mask == UINT16_MAX: header = ofproto_v1_0.NXM_NX_TCP_FLAGS else: header = ofproto_v1_0.NXM_NX_TCP_FLAGS_W else: header = 0 else: header = 0 if header != 0: offset += nxm_put(buf, offset, header, rule) # IP Source and Destination if rule.flow.nw_src != 0: if rule.wc.nw_src_mask == UINT32_MAX: header = ofproto_v1_0.NXM_OF_IP_SRC else: header = ofproto_v1_0.NXM_OF_IP_SRC_W offset += nxm_put(buf, offset, header, rule) if rule.flow.nw_dst != 0: if rule.wc.nw_dst_mask == UINT32_MAX: header = ofproto_v1_0.NXM_OF_IP_DST else: header = ofproto_v1_0.NXM_OF_IP_DST_W offset += nxm_put(buf, offset, header, rule) # IPv6 if not rule.wc.wildcards & FWW_NW_PROTO and (rule.flow.nw_proto == inet.IPPROTO_ICMPV6): if rule.wc.tp_src_mask != 0: offset += nxm_put(buf, offset, ofproto_v1_0.NXM_NX_ICMPV6_TYPE, rule) if rule.wc.tp_dst_mask != 0: offset += nxm_put(buf, offset, ofproto_v1_0.NXM_NX_ICMPV6_CODE, rule) if not rule.wc.wildcards & FWW_IPV6_LABEL: offset += nxm_put(buf, offset, ofproto_v1_0.NXM_NX_IPV6_LABEL, rule) if len(rule.flow.ipv6_src): if len(rule.wc.ipv6_src_mask): header = ofproto_v1_0.NXM_NX_IPV6_SRC_W else: header = ofproto_v1_0.NXM_NX_IPV6_SRC offset += nxm_put(buf, offset, header, rule) if len(rule.flow.ipv6_dst): if len(rule.wc.ipv6_dst_mask): header = ofproto_v1_0.NXM_NX_IPV6_DST_W else: header = ofproto_v1_0.NXM_NX_IPV6_DST offset += nxm_put(buf, offset, header, rule) if len(rule.flow.nd_target): if len(rule.wc.nd_target_mask): header = ofproto_v1_0.NXM_NX_ND_TARGET_W else: header = ofproto_v1_0.NXM_NX_ND_TARGET offset += nxm_put(buf, offset, header, rule) # ARP if rule.flow.arp_spa != 0: if rule.wc.arp_spa_mask == UINT32_MAX: header = ofproto_v1_0.NXM_OF_ARP_SPA else: header = ofproto_v1_0.NXM_OF_ARP_SPA_W offset += nxm_put(buf, offset, header, rule) if rule.flow.arp_tpa != 0: if rule.wc.arp_tpa_mask == UINT32_MAX: header = ofproto_v1_0.NXM_OF_ARP_TPA else: header = ofproto_v1_0.NXM_OF_ARP_TPA_W offset += nxm_put(buf, offset, header, rule) if not rule.wc.wildcards & FWW_ARP_SHA: offset += nxm_put(buf, offset, ofproto_v1_0.NXM_NX_ARP_SHA, rule) if not rule.wc.wildcards & FWW_ARP_THA: offset += nxm_put(buf, offset, ofproto_v1_0.NXM_NX_ARP_THA, rule) if rule.flow.nw_frag: if rule.wc.nw_frag_mask == FLOW_NW_FRAG_MASK: header = ofproto_v1_0.NXM_NX_IP_FRAG else: header = ofproto_v1_0.NXM_NX_IP_FRAG_W offset += nxm_put(buf, offset, header, rule) if rule.flow.pkt_mark != 0: if rule.wc.pkt_mark_mask == UINT32_MAX: header = ofproto_v1_0.NXM_NX_PKT_MARK else: header = ofproto_v1_0.NXM_NX_PKT_MARK_W offset += nxm_put(buf, offset, header, rule) # Tunnel Id if rule.wc.tun_id_mask != 0: if rule.wc.tun_id_mask == UINT64_MAX: header = ofproto_v1_0.NXM_NX_TUN_ID else: header = ofproto_v1_0.NXM_NX_TUN_ID_W offset += nxm_put(buf, offset, header, rule) # XXX: Cookie for i in range(FLOW_N_REGS): if rule.wc.regs_bits & (1 << i): if rule.wc.regs_mask[i]: header = ofproto_v1_0.nxm_nx_reg_w(i) else: header = ofproto_v1_0.nxm_nx_reg(i) offset += nxm_put(buf, offset, header, rule) # Pad pad_len = round_up(offset) - offset msg_pack_into("%dx" % pad_len, buf, offset) # The returned length, the match_len, does not include the pad return offset - old_offset def nxm_put(buf, offset, header, rule): nxm = NXMatch(header) len_ = nxm.put_header(buf, offset) mf = mf_from_nxm_header(nxm.header) return len_ + mf.put(buf, offset + len_, rule) def round_up(length): return (length + 7) // 8 * 8 # Round up to a multiple of 8 class NXMatch(object): def __init__(self, header): self.header = header @classmethod def parser(cls, buf, offset, match_len): if match_len < 4: raise exception.OFPMalformedMessage (header,) = struct.unpack_from(ofproto_v1_0.NXM_HEADER_PACK_STRING, buf, offset) instance = cls(header) payload_len = instance.length() if payload_len == 0 or match_len < payload_len + 4: raise exception.OFPMalformedMessage return instance def vendor(self): return self.header >> 16 def field(self): return (self.header >> 9) % 0x7f def type(self): return (self.header >> 9) % 0x7fffff def hasmask(self): return (self.header >> 8) & 1 def length(self): return self.header & 0xff def show(self): return ('%08x (vendor=%x, field=%x, hasmask=%x len=%x)' % (self.header, self.vendor(), self.field(), self.hasmask(), self.length())) def put_header(self, buf, offset): msg_pack_into(ofproto_v1_0.NXM_HEADER_PACK_STRING, buf, offset, self.header) return struct.calcsize(ofproto_v1_0.NXM_HEADER_PACK_STRING) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/ofproto/ofproto_common.py0000664000175000017500000000260000000000000021367 0ustar00zuulzuul00000000000000# Copyright (C) 2011, 2012 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2011 Isaku Yamahata # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. from struct import calcsize OFP_HEADER_PACK_STR = '!BBHI' OFP_HEADER_SIZE = 8 assert calcsize(OFP_HEADER_PACK_STR) == OFP_HEADER_SIZE # Note: IANA assigned port number for OpenFlow is 6653 # from OpenFlow 1.3.3 (EXT-133). # Some applications may still use 6633 as the de facto standard though. OFP_TCP_PORT = 6653 OFP_SSL_PORT = 6653 OFP_TCP_PORT_OLD = 6633 OFP_SSL_PORT_OLD = 6633 # Vendor/Experimenter IDs # https://rs.opennetworking.org/wiki/display/PUBLIC/ONF+Registry NX_EXPERIMENTER_ID = 0x00002320 # Nicira NX_NSH_EXPERIMENTER_ID = 0x005ad650 # Nicira Ext for Network Service Header BSN_EXPERIMENTER_ID = 0x005c16c7 # Big Switch Networks ONF_EXPERIMENTER_ID = 0x4f4e4600 # OpenFlow Extensions for 1.3.X Pack 1 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/ofproto/ofproto_parser.py0000664000175000017500000002203100000000000021373 0ustar00zuulzuul00000000000000# Copyright (C) 2011, 2012 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2011 Isaku Yamahata # # 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. import base64 import collections import logging import struct import functools from os_ken import exception from os_ken import utils from os_ken.lib import stringify from os_ken.ofproto import ofproto_common LOG = logging.getLogger('os_ken.ofproto.ofproto_parser') def header(buf): assert len(buf) >= ofproto_common.OFP_HEADER_SIZE # LOG.debug('len %d bufsize %d', len(buf), ofproto.OFP_HEADER_SIZE) return struct.unpack_from(ofproto_common.OFP_HEADER_PACK_STR, bytes(buf)) _MSG_PARSERS = {} def register_msg_parser(version): def register(msg_parser): _MSG_PARSERS[version] = msg_parser return msg_parser return register def msg(datapath, version, msg_type, msg_len, xid, buf): exp = None try: assert len(buf) >= msg_len except AssertionError as e: exp = e msg_parser = _MSG_PARSERS.get(version) if msg_parser is None: raise exception.OFPUnknownVersion(version=version) try: msg = msg_parser(datapath, version, msg_type, msg_len, xid, buf) except exception.OFPTruncatedMessage as e: raise e except: LOG.exception( 'Encountered an error while parsing OpenFlow packet from switch. ' 'This implies the switch sent a malformed OpenFlow packet. ' 'version 0x%02x msg_type %d msg_len %d xid %d buf %s', version, msg_type, msg_len, xid, utils.hex_array(buf)) msg = None if exp: raise exp return msg def create_list_of_base_attributes(f): @functools.wraps(f) def wrapper(self, *args, **kwargs): ret = f(self, *args, **kwargs) cls = self.__class__ # hasattr(cls, '_base_attributes') doesn't work because super class # may already have the attribute. if '_base_attributes' not in cls.__dict__: cls._base_attributes = set(dir(self)) return ret return wrapper def ofp_msg_from_jsondict(dp, jsondict): """ This function instanticates an appropriate OpenFlow message class from the given JSON style dictionary. The objects created by following two code fragments are equivalent. Code A:: jsonstr = '{ "OFPSetConfig": { "flags": 0, "miss_send_len": 128 } }' jsondict = json.loads(jsonstr) o = ofp_msg_from_jsondict(dp, jsondict) Code B:: o = dp.ofproto_parser.OFPSetConfig(flags=0, miss_send_len=128) This function takes the following arguments. ======== ======================================= Argument Description ======== ======================================= dp An instance of os_ken.controller.Datapath. jsondict A JSON style dict. ======== ======================================= """ parser = dp.ofproto_parser assert len(jsondict) == 1 for k, v in jsondict.items(): cls = getattr(parser, k) assert issubclass(cls, MsgBase) return cls.from_jsondict(v, datapath=dp) def ofp_instruction_from_jsondict(dp, jsonlist, encap=True): """ This function is intended to be used with os_ken.lib.ofctl_string.ofp_instruction_from_str. It is very similar to ofp_msg_from_jsondict, but works on a list of OFPInstructions/OFPActions. It also encapsulates OFPAction into OFPInstructionActions, as >OF1.0 OFPFlowMod requires that. This function takes the following arguments. ======== ================================================== Argument Description ======== ================================================== dp An instance of os_ken.controller.Datapath. jsonlist A list of JSON style dictionaries. encap Encapsulate OFPAction into OFPInstructionActions. Must be false for OF10. ======== ================================================== """ proto = dp.ofproto parser = dp.ofproto_parser actions = [] result = [] for jsondict in jsonlist: assert len(jsondict) == 1 k, v = list(jsondict.items())[0] cls = getattr(parser, k) if issubclass(cls, parser.OFPAction): if encap: actions.append(cls.from_jsondict(v)) continue else: ofpinst = getattr(parser, 'OFPInstruction', None) if not ofpinst or not issubclass(cls, ofpinst): raise ValueError("Supplied jsondict is of wrong type: %s", jsondict) result.append(cls.from_jsondict(v)) if not encap: return result if actions: # Although the OpenFlow spec says Apply Actions is executed first, # let's place it in the head as a precaution. result = [parser.OFPInstructionActions( proto.OFPIT_APPLY_ACTIONS, actions)] + result return result class StringifyMixin(stringify.StringifyMixin): _class_prefixes = ["OFP", "ONF", "MT", "NX"] @classmethod def cls_from_jsondict_key(cls, k): obj_cls = super(StringifyMixin, cls).cls_from_jsondict_key(k) return obj_cls class MsgBase(StringifyMixin): """ This is a base class for OpenFlow message classes. An instance of this class has at least the following attributes. ========= ============================== Attribute Description ========= ============================== datapath A os_ken.controller.controller.Datapath instance for this message version OpenFlow protocol version msg_type Type of OpenFlow message msg_len Length of the message xid Transaction id buf Raw data ========= ============================== """ @create_list_of_base_attributes def __init__(self, datapath): super(MsgBase, self).__init__() self.datapath = datapath self.version = None self.msg_type = None self.msg_len = None self.xid = None self.buf = None def set_headers(self, version, msg_type, msg_len, xid): assert msg_type == self.cls_msg_type self.version = version self.msg_type = msg_type self.msg_len = msg_len self.xid = xid def set_xid(self, xid): assert self.xid is None self.xid = xid def set_buf(self, buf): self.buf = bytes(buf) def __str__(self): def hexify(x): return hex(x) if isinstance(x, int) else x buf = 'version=%s,msg_type=%s,msg_len=%s,xid=%s,' %\ (hexify(self.version), hexify(self.msg_type), hexify(self.msg_len), hexify(self.xid)) return buf + StringifyMixin.__str__(self) @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg_ = cls(datapath) msg_.set_headers(version, msg_type, msg_len, xid) msg_.set_buf(buf) return msg_ def _serialize_pre(self): self.version = self.datapath.ofproto.OFP_VERSION self.msg_type = self.cls_msg_type self.buf = bytearray(self.datapath.ofproto.OFP_HEADER_SIZE) def _serialize_header(self): # buffer length is determined after trailing data is formated. assert self.version is not None assert self.msg_type is not None assert self.buf is not None assert len(self.buf) >= self.datapath.ofproto.OFP_HEADER_SIZE self.msg_len = len(self.buf) if self.xid is None: self.xid = 0 struct.pack_into(self.datapath.ofproto.OFP_HEADER_PACK_STR, self.buf, 0, self.version, self.msg_type, self.msg_len, self.xid) def _serialize_body(self): pass def serialize(self): self._serialize_pre() self._serialize_body() self._serialize_header() class MsgInMsgBase(MsgBase): @classmethod def _decode_value(cls, k, json_value, decode_string=base64.b64decode, **additional_args): return cls._get_decoder(k, decode_string)(json_value, **additional_args) def namedtuple(typename, fields, **kwargs): class _namedtuple(StringifyMixin, collections.namedtuple(typename, fields, **kwargs)): pass return _namedtuple def msg_str_attr(msg_, buf, attr_list=None): if attr_list is None: attr_list = stringify.obj_attrs(msg_) for attr in attr_list: val = getattr(msg_, attr, None) if val is not None: buf += ' %s %s' % (attr, val) return buf ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/ofproto/ofproto_protocol.py0000664000175000017500000000427300000000000021750 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2014 YAMAMOTO Takashi # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. from os_ken.ofproto import ofproto_v1_0 from os_ken.ofproto import ofproto_v1_0_parser from os_ken.ofproto import ofproto_v1_2 from os_ken.ofproto import ofproto_v1_2_parser from os_ken.ofproto import ofproto_v1_3 from os_ken.ofproto import ofproto_v1_3_parser from os_ken.ofproto import ofproto_v1_4 from os_ken.ofproto import ofproto_v1_4_parser from os_ken.ofproto import ofproto_v1_5 from os_ken.ofproto import ofproto_v1_5_parser _versions = { ofproto_v1_0.OFP_VERSION: (ofproto_v1_0, ofproto_v1_0_parser), ofproto_v1_2.OFP_VERSION: (ofproto_v1_2, ofproto_v1_2_parser), ofproto_v1_3.OFP_VERSION: (ofproto_v1_3, ofproto_v1_3_parser), ofproto_v1_4.OFP_VERSION: (ofproto_v1_4, ofproto_v1_4_parser), ofproto_v1_5.OFP_VERSION: (ofproto_v1_5, ofproto_v1_5_parser), } # OF versions supported by every apps in this process (intersection) _supported_versions = set(_versions.keys()) def set_app_supported_versions(vers): global _supported_versions _supported_versions &= set(vers) assert _supported_versions, 'No OpenFlow version is available' class ProtocolDesc(object): """ OpenFlow protocol version flavor descriptor """ def __init__(self, version=None): if version is None: version = max(_supported_versions) self.set_version(version) def set_version(self, version): assert version in _supported_versions (self.ofproto, self.ofproto_parser) = _versions[version] @property def supported_ofp_version(self): return _supported_versions ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/ofproto/ofproto_utils.py0000664000175000017500000000737100000000000021251 0ustar00zuulzuul00000000000000# Copyright (C) 2015 Nippon Telegraph and Telephone 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. import re def generate(modname): import sys import functools mod = sys.modules[modname] def add_attr(k, v): setattr(mod, k, v) add_attr('ofp_msg_type_to_str', functools.partial(_msg_type_to_str, mod)) add_attr('ofp_error_type_to_str', functools.partial(_error_type_to_str, mod)) add_attr('ofp_error_code_to_str', functools.partial(_error_code_to_str, mod)) add_attr('ofp_error_to_jsondict', functools.partial(_error_to_jsondict, mod)) def _get_value_name(mod, value, pattern): for k, v in mod.__dict__.items(): if k.startswith(pattern): if v == value: return k return 'Unknown' def _msg_type_to_str(mod, type_): """ This method is registered as ofp_msg_type_to_str(type_) method into os_ken.ofproto.ofproto_v1_* modules. And this method returns the message type as a string value for given 'type' defined in ofp_type enum. Example:: >>> ofproto.ofp_msg_type_to_str(14) 'OFPT_FLOW_MOD(14)' """ return '%s(%d)' % (_get_value_name(mod, type_, 'OFPT_'), type_) def _error_type_to_str(mod, type_): """ This method is registered as ofp_error_type_to_str(type_) method into os_ken.ofproto.ofproto_v1_* modules. And this method returns the error type as a string value for given 'type' defined in ofp_error_msg structure. Example:: >>> ofproto.ofp_error_type_to_str(4) 'OFPET_BAD_MATCH(4)' """ return '%s(%d)' % (_get_value_name(mod, type_, 'OFPET_'), type_) def _get_error_names(mod, type_, code): t_name = _get_value_name(mod, type_, 'OFPET_') if t_name == 'Unknown': return 'Unknown', 'Unknown' # Construct error code name pattern # e.g.) "OFPET_BAD_MATCH" -> "OFPBMC_" if t_name == 'OFPET_FLOW_MONITOR_FAILED': c_name_p = 'OFPMOFC_' else: c_name_p = 'OFP' for m in re.findall("_(.)", t_name): c_name_p += m.upper() c_name_p += 'C_' c_name = _get_value_name(mod, code, c_name_p) return t_name, c_name def _error_code_to_str(mod, type_, code): """ This method is registered as ofp_error_code_to_str(type_, code) method into os_ken.ofproto.ofproto_v1_* modules. And this method returns the error code as a string value for given 'type' and 'code' defined in ofp_error_msg structure. Example:: >>> ofproto.ofp_error_code_to_str(4, 9) 'OFPBMC_BAD_PREREQ(9)' """ (_, c_name) = _get_error_names(mod, type_, code) return '%s(%d)' % (c_name, code) def _error_to_jsondict(mod, type_, code): """ This method is registered as ofp_error_to_jsondict(type_, code) method into os_ken.ofproto.ofproto_v1_* modules. And this method returns ofp_error_msg as a json format for given 'type' and 'code' defined in ofp_error_msg structure. Example:: >>> ofproto.ofp_error_to_jsondict(4, 9) {'code': 'OFPBMC_BAD_PREREQ(9)', 'type': 'OFPET_BAD_MATCH(4)'} """ (t_name, c_name) = _get_error_names(mod, type_, code) return {'type': '%s(%d)' % (t_name, type_), 'code': '%s(%d)' % (c_name, code)} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/ofproto/ofproto_v1_0.py0000664000175000017500000005054300000000000020655 0ustar00zuulzuul00000000000000# Copyright (C) 2011, 2012 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2011, 2012 Isaku Yamahata # # 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. """ OpenFlow 1.0 definitions. """ from os_ken.ofproto import ofproto_utils from os_ken.ofproto.nicira_ext import * # For API compat MAX_XID = 0xffffffff # define constants OFP_VERSION = 0x01 OFP_MAX_TABLE_NAME_LEN = 32 OFP_MAX_TABLE_NAME_LEN_STR = str(OFP_MAX_TABLE_NAME_LEN) OFP_MAX_PORT_NAME_LEN = 16 OFP_TCP_PORT = 6633 OFP_SSL_PORT = 6633 OFP_ETH_ALEN = 6 OFP_ETH_ALEN_STR = str(OFP_ETH_ALEN) OFP_NO_BUFFER = 0xffffffff # enum ofp_port OFPP_MAX = 0xff00 OFPP_IN_PORT = 0xfff8 # Send the packet out the input port. This # virtual port must be explicitly used # in order to send back out of the input # port. OFPP_TABLE = 0xfff9 # Perform actions in flow table. # NB: This can only be the destination # port for packet-out messages. OFPP_NORMAL = 0xfffa # Process with normal L2/L3 switching. OFPP_FLOOD = 0xfffb # All physical ports except input port and # those disabled by STP. OFPP_ALL = 0xfffc # All physical ports except input port. OFPP_CONTROLLER = 0xfffd # Send to controller. OFPP_LOCAL = 0xfffe # Local openflow "port". OFPP_NONE = 0xffff # Not associated with a physical port. # enum ofp_type OFPT_HELLO = 0 # Symmetric message OFPT_ERROR = 1 # Symmetric message OFPT_ECHO_REQUEST = 2 # Symmetric message OFPT_ECHO_REPLY = 3 # Symmetric message OFPT_VENDOR = 4 # Symmetric message OFPT_FEATURES_REQUEST = 5 # Controller/switch message OFPT_FEATURES_REPLY = 6 # Controller/switch message OFPT_GET_CONFIG_REQUEST = 7 # Controller/switch message OFPT_GET_CONFIG_REPLY = 8 # Controller/switch message OFPT_SET_CONFIG = 9 # Controller/switch message OFPT_PACKET_IN = 10 # Async message OFPT_FLOW_REMOVED = 11 # Async message OFPT_PORT_STATUS = 12 # Async message OFPT_PACKET_OUT = 13 # Controller/switch message OFPT_FLOW_MOD = 14 # Controller/switch message OFPT_PORT_MOD = 15 # Controller/switch message OFPT_STATS_REQUEST = 16 # Controller/switch message OFPT_STATS_REPLY = 17 # Controller/switch message OFPT_BARRIER_REQUEST = 18 # Controller/switch message OFPT_BARRIER_REPLY = 19 # Controller/switch message OFPT_QUEUE_GET_CONFIG_REQUEST = 20 # Controller/switch message OFPT_QUEUE_GET_CONFIG_REPLY = 21 # Controller/switch message OFP_HEADER_PACK_STR = '!BBHI' OFP_HEADER_SIZE = 8 OFP_MSG_SIZE_MAX = 65535 assert calcsize(OFP_HEADER_PACK_STR) == OFP_HEADER_SIZE # define constants OFP_DEFAULT_MISS_SEND_LEN = 128 # enum ofp_config_flags OFPC_FRAG_NORMAL = 0 # No special handling for fragments. OFPC_FRAG_DROP = 1 # Drop fragments. OFPC_FRAG_REASM = 2 # Reassemble (only if OFPC_IP_REASM set). OFPC_FRAG_NX_MATCH = 3 # Make first fragments available for matching. OFPC_FRAG_MASK = 3 OFP_SWITCH_CONFIG_PACK_STR = '!HH' OFP_SWITCH_CONFIG_SIZE = 12 assert (calcsize(OFP_SWITCH_CONFIG_PACK_STR) + OFP_HEADER_SIZE == OFP_SWITCH_CONFIG_SIZE) # enum ofp_capabilities OFPC_FLOW_STATS = 1 << 0 # Flow statistics. OFPC_TABLE_STATS = 1 << 1 # Table statistics. OFPC_PORT_STATS = 1 << 2 # Port statistics. OFPC_STP = 1 << 3 # 802.1d spanning tree. OFPC_RESERVED = 1 << 4 # Reserved, must not be set. OFPC_IP_REASM = 1 << 5 # Can reassemble IP fragments. OFPC_QUEUE_STATS = 1 << 6 # Queue statistics. OFPC_ARP_MATCH_IP = 1 << 7 # Match IP addresses in ARP pkts. # enum ofp_port_config OFPPC_PORT_DOWN = 1 << 0 # Port is administratively down. OFPPC_NO_STP = 1 << 1 # Disable 802.1D spanning tree on port. OFPPC_NO_RECV = 1 << 2 # Drop all packets except 802.1D # spanning tree packets OFPPC_NO_RECV_STP = 1 << 3 # Drop received 802.1D STP packets. OFPPC_NO_FLOOD = 1 << 4 # Do not include this port when flooding. OFPPC_NO_FWD = 1 << 5 # Drop packets forwarded to port. OFPPC_NO_PACKET_IN = 1 << 6 # Do not send packet-in msgs for port. # enum ofp_port_state OFPPS_LINK_DOWN = 1 << 0 # No physical link present. OFPPS_STP_LISTEN = 0 << 8 # Not learning or relaying frames. OFPPS_STP_LEARN = 1 << 8 # Learning but not relaying frames. OFPPS_STP_FORWARD = 2 << 8 # Learning and relaying frames. OFPPS_STP_BLOCK = 3 << 8 # Not part of spanning tree. OFPPS_STP_MASK = 3 << 8 # Bit mask for OFPPS_STP_* values. # enum ofp_port_features OFPPF_10MB_HD = 1 << 0 # 10 Mb half-duplex rate support. OFPPF_10MB_FD = 1 << 1 # 10 Mb full-duplex rate support. OFPPF_100MB_HD = 1 << 2 # 100 Mb half-duplex rate support. OFPPF_100MB_FD = 1 << 3 # 100 Mb full-duplex rate support. OFPPF_1GB_HD = 1 << 4 # 1 Gb half-duplex rate support. OFPPF_1GB_FD = 1 << 5 # 1 Gb full-duplex rate support. OFPPF_10GB_FD = 1 << 6 # 10 Gb full-duplex rate support. OFPPF_COPPER = 1 << 7 # Copper medium. OFPPF_FIBER = 1 << 8 # Fiber medium. OFPPF_AUTONEG = 1 << 9 # Auto-negotiation. OFPPF_PAUSE = 1 << 10 # Pause. OFPPF_PAUSE_ASYM = 1 << 11 # Asymmetric pause. _OFP_PHY_PORT_PACK_STR = 'H' + OFP_ETH_ALEN_STR + 's' + \ str(OFP_MAX_PORT_NAME_LEN) + 'sIIIIII' OFP_PHY_PORT_PACK_STR = '!' + _OFP_PHY_PORT_PACK_STR OFP_PHY_PORT_SIZE = 48 assert calcsize(OFP_PHY_PORT_PACK_STR) == OFP_PHY_PORT_SIZE OFP_SWITCH_FEATURES_PACK_STR = '!QIB3xII' OFP_SWITCH_FEATURES_SIZE = 32 assert (calcsize(OFP_SWITCH_FEATURES_PACK_STR) + OFP_HEADER_SIZE == OFP_SWITCH_FEATURES_SIZE) # enum ofp_port_reason OFPPR_ADD = 0 # The port was added. OFPPR_DELETE = 1 # The port was removed. OFPPR_MODIFY = 2 # Some attribute of the port has changed. OFP_PORT_STATUS_PACK_STR = '!B7x' + _OFP_PHY_PORT_PACK_STR OFP_PORT_STATUS_DESC_OFFSET = OFP_HEADER_SIZE + 8 OFP_PORT_STATUS_SIZE = 64 assert (calcsize(OFP_PORT_STATUS_PACK_STR) + OFP_HEADER_SIZE == OFP_PORT_STATUS_SIZE) OFP_PORT_MOD_PACK_STR = '!H' + OFP_ETH_ALEN_STR + 'sIII4x' OFP_PORT_MOD_SIZE = 32 assert calcsize(OFP_PORT_MOD_PACK_STR) + OFP_HEADER_SIZE == OFP_PORT_MOD_SIZE # enum ofp_packet_in_reason OFPR_NO_MATCH = 0 # No matching flow. OFPR_ACTION = 1 # Action explicitly output to controller. # OF1.0 spec says OFP_ASSERT(sizeof(struct ofp_packet_in) == 20). # It's quite bogus as it assumes a specific class of C implementations. # (well, if it was C. it's unclear from the spec itself.) # We just use the real size of the structure as this is not C. This # agrees with on-wire messages OpenFlow Reference Release and Open vSwitch # produce. OFP_PACKET_IN_PACK_STR = '!IHHBx' OFP_PACKET_IN_SIZE = 18 assert calcsize(OFP_PACKET_IN_PACK_STR) + OFP_HEADER_SIZE == OFP_PACKET_IN_SIZE # enum ofp_action_type OFPAT_OUTPUT = 0 # Output to switch port. OFPAT_SET_VLAN_VID = 1 # Set the 802.1q VLAN id. OFPAT_SET_VLAN_PCP = 2 # Set the 802.1q priority. OFPAT_STRIP_VLAN = 3 # Strip the 802.1q header. OFPAT_SET_DL_SRC = 4 # Ethernet source address. OFPAT_SET_DL_DST = 5 # Ethernet destination address. OFPAT_SET_NW_SRC = 6 # IP source address. OFPAT_SET_NW_DST = 7 # IP destination address. OFPAT_SET_NW_TOS = 8 # IP ToS (DSCP field, 6 bits). OFPAT_SET_TP_SRC = 9 # TCP/UDP source port. OFPAT_SET_TP_DST = 10 # TCP/UDP destination port. OFPAT_ENQUEUE = 11 # Output to queue. OFPAT_VENDOR = 0xffff OFP_ACTION_OUTPUT_PACK_STR = '!HHHH' OFP_ACTION_OUTPUT_SIZE = 8 assert calcsize(OFP_ACTION_OUTPUT_PACK_STR) == OFP_ACTION_OUTPUT_SIZE OFP_ACTION_VLAN_VID_PACK_STR = '!HHH2x' OFP_ACTION_VLAN_VID_SIZE = 8 assert calcsize(OFP_ACTION_VLAN_VID_PACK_STR) == OFP_ACTION_VLAN_VID_SIZE OFP_ACTION_VLAN_PCP_PACK_STR = '!HHB3x' OFP_ACTION_VLAN_PCP_SIZE = 8 assert calcsize(OFP_ACTION_VLAN_PCP_PACK_STR) == OFP_ACTION_VLAN_PCP_SIZE OFP_ACTION_DL_ADDR_PACK_STR = '!HH' + OFP_ETH_ALEN_STR + 's6x' OFP_ACTION_DL_ADDR_SIZE = 16 assert calcsize(OFP_ACTION_DL_ADDR_PACK_STR) == OFP_ACTION_DL_ADDR_SIZE OFP_ACTION_NW_ADDR_PACK_STR = '!HHI' OFP_ACTION_NW_ADDR_SIZE = 8 assert calcsize(OFP_ACTION_NW_ADDR_PACK_STR) == OFP_ACTION_NW_ADDR_SIZE OFP_ACTION_NW_TOS_PACK_STR = '!HHB3x' OFP_ACTION_NW_TOS_SIZE = 8 assert calcsize(OFP_ACTION_NW_TOS_PACK_STR) == OFP_ACTION_NW_TOS_SIZE OFP_ACTION_TP_PORT_PACK_STR = '!HHH2x' OFP_ACTION_TP_PORT_SIZE = 8 assert calcsize(OFP_ACTION_TP_PORT_PACK_STR) == OFP_ACTION_TP_PORT_SIZE OFP_ACTION_VENDOR_HEADER_PACK_STR = '!HHI' OFP_ACTION_VENDOR_HEADER_SIZE = 8 assert (calcsize(OFP_ACTION_VENDOR_HEADER_PACK_STR) == OFP_ACTION_VENDOR_HEADER_SIZE) # OpenFlow1.2 or later compatible OFP_ACTION_EXPERIMENTER_HEADER_SIZE = OFP_ACTION_VENDOR_HEADER_SIZE OFP_ACTION_HEADER_PACK_STR = '!HH4x' OFP_ACTION_HEADER_SIZE = 8 assert calcsize(OFP_ACTION_HEADER_PACK_STR) == OFP_ACTION_HEADER_SIZE OFP_ACTION_ENQUEUE_PACK_STR = '!HHH6xI' OFP_ACTION_ENQUEUE_SIZE = 16 assert calcsize(OFP_ACTION_ENQUEUE_PACK_STR) == OFP_ACTION_ENQUEUE_SIZE OFP_ACTION_PACK_STR = '!H' # because of union ofp_action # OFP_ACTION_SIZE = 8 # assert calcsize(OFP_ACTION_PACK_STR) == OFP_ACTION_SIZE OFP_PACKET_OUT_PACK_STR = '!IHH' OFP_PACKET_OUT_SIZE = 16 assert (calcsize(OFP_PACKET_OUT_PACK_STR) + OFP_HEADER_SIZE == OFP_PACKET_OUT_SIZE) # enum ofp_flow_mod_command OFPFC_ADD = 0 # New flow. OFPFC_MODIFY = 1 # Modify all matching flows. OFPFC_MODIFY_STRICT = 2 # Modify entry strictly matching wildcards OFPFC_DELETE = 3 # Delete all matching flows. OFPFC_DELETE_STRICT = 4 # Strictly match wildcards and priority. # enum ofp_flow_wildcards OFPFW_IN_PORT = 1 << 0 # Switch input port. OFPFW_DL_VLAN = 1 << 1 # VLAN vid. OFPFW_DL_SRC = 1 << 2 # Ethernet source address. OFPFW_DL_DST = 1 << 3 # Ethernet destination address. OFPFW_DL_TYPE = 1 << 4 # Ethernet frame type. OFPFW_NW_PROTO = 1 << 5 # IP protocol. OFPFW_TP_SRC = 1 << 6 # TCP/UDP source port. OFPFW_TP_DST = 1 << 7 # TCP/UDP destination port. OFPFW_NW_SRC_SHIFT = 8 OFPFW_NW_SRC_BITS = 6 OFPFW_NW_SRC_MASK = ((1 << OFPFW_NW_SRC_BITS) - 1) << OFPFW_NW_SRC_SHIFT OFPFW_NW_SRC = OFPFW_NW_SRC_MASK # IP source address (not in OF Spec). OFPFW_NW_SRC_ALL = 32 << OFPFW_NW_SRC_SHIFT OFPFW_NW_DST_SHIFT = 14 OFPFW_NW_DST_BITS = 6 OFPFW_NW_DST_MASK = ((1 << OFPFW_NW_DST_BITS) - 1) << OFPFW_NW_DST_SHIFT OFPFW_NW_DST = OFPFW_NW_DST_MASK # IP destination address (not in OF Spec). OFPFW_NW_DST_ALL = 32 << OFPFW_NW_DST_SHIFT OFPFW_DL_VLAN_PCP = 1 << 20 # VLAN priority. OFPFW_NW_TOS = 1 << 21 # IP ToS (DSCP field, 6 bits). OFPFW_ALL = ((1 << 22) - 1) # define constants OFPFW_ICMP_TYPE = OFPFW_TP_SRC OFPFW_ICMP_CODE = OFPFW_TP_DST OFP_DL_TYPE_ETH2_CUTOFF = 0x0600 OFP_DL_TYPE_NOT_ETH_TYPE = 0x05ff OFP_VLAN_NONE = 0xffff _OFP_MATCH_PACK_STR = 'IH' + OFP_ETH_ALEN_STR + 's' + OFP_ETH_ALEN_STR + \ 'sHBxHBB2xIIHH' OFP_MATCH_PACK_STR = '!' + _OFP_MATCH_PACK_STR OFP_MATCH_SIZE = 40 assert calcsize(OFP_MATCH_PACK_STR) == OFP_MATCH_SIZE OFP_FLOW_PERMANENT = 0 OFP_DEFAULT_PRIORITY = 0x8000 # enum ofp_flow_mod_flags OFPFF_SEND_FLOW_REM = 1 << 0 # Send flow removed message when flow # expires or is deleted. OFPFF_CHECK_OVERLAP = 1 << 1 # Check for overlapping entries first. OFPFF_EMERG = 1 << 2 # Ramark this is for emergency. _OFP_FLOW_MOD_PACK_STR0 = 'QHHHHIHH' OFP_FLOW_MOD_PACK_STR = '!' + _OFP_MATCH_PACK_STR + _OFP_FLOW_MOD_PACK_STR0 OFP_FLOW_MOD_PACK_STR0 = '!' + _OFP_FLOW_MOD_PACK_STR0 OFP_FLOW_MOD_SIZE = 72 assert calcsize(OFP_FLOW_MOD_PACK_STR) + OFP_HEADER_SIZE == OFP_FLOW_MOD_SIZE # enum ofp_flow_removed_reason OFPRR_IDLE_TIMEOUT = 0 # Flow idle time exceeded idle_timeout. OFPRR_HARD_TIMEOUT = 1 # Time exceeded hard_timeout. OFPRR_DELETE = 2 # Evicted by a DELETE flow mod. _OFP_FLOW_REMOVED_PACK_STR0 = 'QHBxIIH2xQQ' OFP_FLOW_REMOVED_PACK_STR = '!' + _OFP_MATCH_PACK_STR + \ _OFP_FLOW_REMOVED_PACK_STR0 OFP_FLOW_REMOVED_PACK_STR0 = '!' + _OFP_FLOW_REMOVED_PACK_STR0 OFP_FLOW_REMOVED_SIZE = 88 assert (calcsize(OFP_FLOW_REMOVED_PACK_STR) + OFP_HEADER_SIZE == OFP_FLOW_REMOVED_SIZE) # enum ofp_error_type OFPET_HELLO_FAILED = 0 # Hello protocol failed. OFPET_BAD_REQUEST = 1 # Request was not understood. OFPET_BAD_ACTION = 2 # Error in action description. OFPET_FLOW_MOD_FAILED = 3 # Problem modifying flow entry. OFPET_PORT_MOD_FAILED = 4 # OFPT_PORT_MOD failed. OFPET_QUEUE_OP_FAILED = 5 # Queue operation failed. # enum ofp_hello_failed_code OFPHFC_INCOMPATIBLE = 0 # No compatible version. OFPHFC_EPERM = 1 # Permissions error. # enum ofp_bad_request_code OFPBRC_BAD_VERSION = 0 # ofp_header.version not supported. OFPBRC_BAD_TYPE = 1 # ofp_header.type not supported. OFPBRC_BAD_STAT = 2 # ofp_stats_msg.type not supported. OFPBRC_BAD_VENDOR = 3 # Vendor not supported (in ofp_vendor_header # or ofp_stats_msg). OFPBRC_BAD_SUBTYPE = 4 # Vendor subtype not supported. OFPBRC_EPERM = 5 # Permissions error. OFPBRC_BAD_LEN = 6 # Wrong request length for type. OFPBRC_BUFFER_EMPTY = 7 # Specified buffer has already been used. OFPBRC_BUFFER_UNKNOWN = 8 # Specified buffer does not exist. # enum ofp_bad_action_code OFPBAC_BAD_TYPE = 0 # Unknown action type. OFPBAC_BAD_LEN = 1 # Length problem in actions. OFPBAC_BAD_VENDOR = 2 # Unknown vendor id specified. OFPBAC_BAD_VENDOR_TYPE = 3 # Unknown action type for vendor id. OFPBAC_BAD_OUT_PORT = 4 # Problem validating output action. OFPBAC_BAD_ARGUMENT = 5 # Bad action argument. OFPBAC_EPERM = 6 # Permissions error. OFPBAC_TOO_MANY = 7 # Can't handle this many actions. OFPBAC_BAD_QUEUE = 8 # Problem validating output queue. # enum ofp_flow_mod_failed_code OFPFMFC_ALL_TABLES_FULL = 0 # Flow not added because of full tables. OFPFMFC_OVERLAP = 1 # Attempted to add overlapping flow with # CHECK_OVERLAP flags set. OFPFMFC_EPERM = 2 # Permissions error. OFPFMFC_BAD_EMERG_TIMEOUT = 3 # Flow not added because of non-zero idle/hard # timeout. OFPFMFC_BAD_COMMAND = 4 # Unknown command. OFPFMFC_UNSUPPORTED = 5 # Unsupported action list - cannot process in # the order specified. # enum ofp_port_mod_failed_code OFPPMFC_BAD_PORT = 0 # Specified port does not exist. OFPPMFC_BAD_HW_ADDR = 1 # Specified hardware address is wrong. # enum ofp_queue_op_failed_code OFPQOFC_BAD_PORT = 0 # Invalid port (or port does not exist). OFPQOFC_BAD_QUEUE = 1 # Queue does not exist. OFPQOFC_EPERM = 2 # Permissions error. OFP_ERROR_MSG_PACK_STR = '!HH' OFP_ERROR_MSG_SIZE = 12 assert calcsize(OFP_ERROR_MSG_PACK_STR) + OFP_HEADER_SIZE == OFP_ERROR_MSG_SIZE # enum ofp_stats_types OFPST_DESC = 0 OFPST_FLOW = 1 OFPST_AGGREGATE = 2 OFPST_TABLE = 3 OFPST_PORT = 4 OFPST_QUEUE = 5 OFPST_VENDOR = 0xffff _OFP_STATS_MSG_PACK_STR = 'HH' OFP_STATS_MSG_PACK_STR = '!' + _OFP_STATS_MSG_PACK_STR OFP_STATS_MSG_SIZE = 12 assert calcsize(OFP_STATS_MSG_PACK_STR) + OFP_HEADER_SIZE == OFP_STATS_MSG_SIZE # enum ofp_stats_reply_flags OFPSF_REPLY_MORE = 1 << 0 # More replies to follow. # define constants DESC_STR_LEN = 256 DESC_STR_LEN_STR = str(DESC_STR_LEN) SERIAL_NUM_LEN = 32 SERIAL_NUM_LEN_STR = str(SERIAL_NUM_LEN) OFP_DESC_STATS_PACK_STR = '!' + \ DESC_STR_LEN_STR + 's' + \ DESC_STR_LEN_STR + 's' + \ DESC_STR_LEN_STR + 's' + \ SERIAL_NUM_LEN_STR + 's' + \ DESC_STR_LEN_STR + 's' OFP_DESC_STATS_SIZE = 1068 assert (calcsize(OFP_DESC_STATS_PACK_STR) + OFP_STATS_MSG_SIZE == OFP_DESC_STATS_SIZE) _OFP_FLOW_STATS_REQUEST_ID_PORT_STR = 'BxH' OFP_FLOW_STATS_REQUEST_ID_PORT_STR = '!' + _OFP_FLOW_STATS_REQUEST_ID_PORT_STR OFP_FLOW_STATS_REQUEST_PACK_STR = '!' + _OFP_MATCH_PACK_STR + \ _OFP_FLOW_STATS_REQUEST_ID_PORT_STR OFP_FLOW_STATS_REQUEST_SIZE = 56 assert (calcsize(OFP_FLOW_STATS_REQUEST_PACK_STR) + OFP_STATS_MSG_SIZE == OFP_FLOW_STATS_REQUEST_SIZE) _OFP_FLOW_STATS_0_PACK_STR = 'HBx' OFP_FLOW_STATS_0_PACK_STR = '!' + _OFP_FLOW_STATS_0_PACK_STR OFP_FLOW_STATS_0_SIZE = 4 assert calcsize(OFP_FLOW_STATS_0_PACK_STR) == OFP_FLOW_STATS_0_SIZE _OFP_FLOW_STATS_1_PACK_STR = 'IIHHH6xQQQ' OFP_FLOW_STATS_1_PACK_STR = '!' + _OFP_FLOW_STATS_1_PACK_STR OFP_FLOW_STATS_1_SIZE = 44 assert calcsize(OFP_FLOW_STATS_1_PACK_STR) == OFP_FLOW_STATS_1_SIZE OFP_FLOW_STATS_PACK_STR = '!' + _OFP_FLOW_STATS_0_PACK_STR +\ _OFP_MATCH_PACK_STR + _OFP_FLOW_STATS_1_PACK_STR OFP_FLOW_STATS_SIZE = 88 assert calcsize(OFP_FLOW_STATS_PACK_STR) == OFP_FLOW_STATS_SIZE OFP_AGGREGATE_STATS_REPLY_PACK_STR = '!QQI4x' OFP_AGGREGATE_STATS_REPLY_SIZE = 36 assert (calcsize(OFP_AGGREGATE_STATS_REPLY_PACK_STR) + OFP_STATS_MSG_SIZE == OFP_AGGREGATE_STATS_REPLY_SIZE) OFP_TABLE_STATS_PACK_STR = '!B3x' + OFP_MAX_TABLE_NAME_LEN_STR + 'sIIIQQ' OFP_TABLE_STATS_SIZE = 64 assert calcsize(OFP_TABLE_STATS_PACK_STR) == OFP_TABLE_STATS_SIZE OFP_PORT_STATS_REQUEST_PACK_STR = '!H6x' OFP_PORT_STATS_REQUEST_SIZE = 20 assert (calcsize(OFP_PORT_STATS_REQUEST_PACK_STR) + OFP_STATS_MSG_SIZE == OFP_PORT_STATS_REQUEST_SIZE) OFP_PORT_STATS_PACK_STR = '!H6xQQQQQQQQQQQQ' OFP_PORT_STATS_SIZE = 104 assert calcsize(OFP_PORT_STATS_PACK_STR) == OFP_PORT_STATS_SIZE OFPQ_ALL = 0xffffffff OFP_QUEUE_STATS_REQUEST_PACK_STR = '!HxxI' OFP_QUEUE_STATS_REQUEST_SIZE = 8 assert (calcsize(OFP_QUEUE_STATS_REQUEST_PACK_STR) == OFP_QUEUE_STATS_REQUEST_SIZE) OFP_QUEUE_STATS_PACK_STR = '!H2xIQQQ' OFP_QUEUE_STATS_SIZE = 32 assert calcsize(OFP_QUEUE_STATS_PACK_STR) == OFP_QUEUE_STATS_SIZE OFP_VENDOR_STATS_MSG_PACK_STR = '!I' OFP_VENDOR_STATS_MSG_SIZE = 16 assert (calcsize(OFP_VENDOR_STATS_MSG_PACK_STR) + OFP_STATS_MSG_SIZE == OFP_VENDOR_STATS_MSG_SIZE) OFP_VENDOR_HEADER_PACK_STR = '!I' OFP_VENDOR_HEADER_SIZE = 12 assert (calcsize(OFP_VENDOR_HEADER_PACK_STR) + OFP_HEADER_SIZE == OFP_VENDOR_HEADER_SIZE) OFP_QUEUE_GET_CONFIG_REQUEST_PACK_STR = '!H2x' OFP_QUEUE_GET_CONFIG_REQUEST_SIZE = 12 assert (calcsize(OFP_QUEUE_GET_CONFIG_REQUEST_PACK_STR) + OFP_HEADER_SIZE == OFP_QUEUE_GET_CONFIG_REQUEST_SIZE) OFP_QUEUE_GET_CONFIG_REPLY_PACK_STR = '!H6x' OFP_QUEUE_GET_CONFIG_REPLY_SIZE = 16 assert (calcsize(OFP_QUEUE_GET_CONFIG_REPLY_PACK_STR) + OFP_HEADER_SIZE == OFP_QUEUE_GET_CONFIG_REPLY_SIZE) OFP_PACKET_QUEUE_PQCK_STR = '!IH2x' OFP_PACKET_QUEUE_SIZE = 8 assert calcsize(OFP_PACKET_QUEUE_PQCK_STR) == OFP_PACKET_QUEUE_SIZE OFPQT_NONE = 0 OFPQT_MIN_RATE = 1 OFP_QUEUE_PROP_HEADER_PACK_STR = '!HH4x' OFP_QUEUE_PROP_HEADER_SIZE = 8 assert calcsize(OFP_QUEUE_PROP_HEADER_PACK_STR) == OFP_QUEUE_PROP_HEADER_SIZE OFP_QUEUE_PROP_MIN_RATE_PACK_STR = '!H6x' OFP_QUEUE_PROP_MIN_RATE_SIZE = 16 assert (calcsize(OFP_QUEUE_PROP_MIN_RATE_PACK_STR) + OFP_QUEUE_PROP_HEADER_SIZE == OFP_QUEUE_PROP_MIN_RATE_SIZE) # OXM # enum ofp_oxm_class OFPXMC_OPENFLOW_BASIC = 0x8000 # Basic class for OpenFlow def _oxm_tlv_header(class_, field, hasmask, length): return (class_ << 16) | (field << 9) | (hasmask << 8) | length def oxm_tlv_header(field, length): return _oxm_tlv_header(OFPXMC_OPENFLOW_BASIC, field, 0, length) def oxm_tlv_header_w(field, length): return _oxm_tlv_header(OFPXMC_OPENFLOW_BASIC, field, 1, length * 2) def oxm_tlv_header_extract_hasmask(header): return (header >> 8) & 1 def oxm_tlv_header_extract_length(header): if oxm_tlv_header_extract_hasmask(header): length = (header & 0xff) // 2 else: length = header & 0xff return length oxm_fields.generate(__name__) # generate utility methods ofproto_utils.generate(__name__) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/ofproto/ofproto_v1_0_parser.py0000664000175000017500000034102500000000000022227 0ustar00zuulzuul00000000000000# Copyright (C) 2011, 2012 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2011, 2012 Isaku Yamahata # # 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. """ Decoder/Encoder implementations of OpenFlow 1.0. """ import struct import base64 import netaddr from os_ken.ofproto.ofproto_parser import StringifyMixin, MsgBase from os_ken.lib import addrconv from os_ken.lib import ip from os_ken.lib import mac from os_ken.lib.packet import packet from os_ken.lib.pack_utils import msg_pack_into from os_ken.ofproto import nx_match from os_ken.ofproto import ofproto_common from os_ken.ofproto import ofproto_parser from os_ken.ofproto import ofproto_v1_0 as ofproto from os_ken.ofproto import nx_actions from os_ken import utils import logging LOG = logging.getLogger('os_ken.ofproto.ofproto_v1_0_parser') _MSG_PARSERS = {} def _set_msg_type(msg_type): '''Annotate corresponding OFP message type''' def _set_cls_msg_type(cls): cls.cls_msg_type = msg_type return cls return _set_cls_msg_type def _register_parser(cls): '''class decorator to register msg parser''' assert cls.cls_msg_type is not None assert cls.cls_msg_type not in _MSG_PARSERS _MSG_PARSERS[cls.cls_msg_type] = cls.parser return cls @ofproto_parser.register_msg_parser(ofproto.OFP_VERSION) def msg_parser(datapath, version, msg_type, msg_len, xid, buf): parser = _MSG_PARSERS.get(msg_type) return parser(datapath, version, msg_type, msg_len, xid, buf) # OFP_MSG_REPLY = { # OFPFeaturesRequest: OFPSwitchFeatures, # OFPBarrierRequest: OFPBarrierReply, # OFPQueueGetConfigRequest: OFPQueueGetConfigReply, # # # ofp_stats_request -> ofp_stats_reply # OFPDescStatsRequest: OFPDescStatsReply, # OFPFlowStatsRequest: OFPFlowStatsReply, # OFPAggregateStatsRequest: OFPAggregateStatsReply, # OFPTableStatsRequest: OFPTableStatsReply, # OFPPortStatsRequest: OFPPortStatsReply, # OFPQueueStatsRequest: OFPQueueStatsReply, # OFPVendorStatsRequest: OFPVendorStatsReply, # } def _set_msg_reply(msg_reply): '''Annotate OFP reply message class''' def _set_cls_msg_reply(cls): cls.cls_msg_reply = msg_reply return cls return _set_cls_msg_reply # # common structures # class OFPPhyPort(ofproto_parser.namedtuple('OFPPhyPort', ( 'port_no', 'hw_addr', 'name', 'config', 'state', 'curr', 'advertised', 'supported', 'peer'))): """ Description of a port ========== ========================================================= Attribute Description ========== ========================================================= port_no Port number and it uniquely identifies a port within a switch. hw_addr MAC address for the port. name Null-terminated string containing a human-readable name for the interface. config Bitmap of port configuration flags. | OFPPC_PORT_DOWN | OFPPC_NO_STP | OFPPC_NO_RECV | OFPPC_NO_RECV_STP | OFPPC_NO_FLOOD | OFPPC_NO_FWD | OFPPC_NO_PACKET_IN state Bitmap of port state flags. | OFPPS_LINK_DOWN | OFPPS_STP_LISTEN | OFPPS_STP_LEARN | OFPPS_STP_FORWARD | OFPPS_STP_BLOCK | OFPPS_STP_MASK curr Current features. advertised Features being advertised by the port. supported Features supported by the port. peer Features advertised by peer. ========== ========================================================= """ _TYPE = { 'ascii': [ 'hw_addr', ], 'utf-8': [ # OF spec is unclear about the encoding of name. # we assumes UTF-8, which is used by OVS. 'name', ] } @classmethod def parser(cls, buf, offset): port = struct.unpack_from(ofproto.OFP_PHY_PORT_PACK_STR, buf, offset) port = list(port) i = cls._fields.index('hw_addr') port[i] = addrconv.mac.bin_to_text(port[i]) i = cls._fields.index('name') port[i] = port[i].rstrip(b'\0') return cls(*port) class OFPMatch(StringifyMixin): """ Flow Match Structure This class is implementation of the flow match structure having compose/query API. ================ ================================================== Attribute Description ================ ================================================== wildcards Wildcard fields. (match fields) For the available match fields, please refer to the following. ================ ================================================== ================ =============== ================================== Argument Value Description ================ =============== ================================== in_port Integer 16bit Switch input port. dl_src MAC address Ethernet source address. dl_dst MAC address Ethernet destination address. dl_vlan Integer 16bit Input VLAN id. dl_vlan_pcp Integer 8bit Input VLAN priority. dl_type Integer 16bit Ethernet frame type. nw_tos Integer 8bit IP ToS (actually DSCP field, 6 bits). nw_proto Integer 8bit IP protocol or lower 8 bits of ARP opcode. nw_src IPv4 address IP source address. nw_dst IPv4 address IP destination address. tp_src Integer 16bit TCP/UDP source port. tp_dst Integer 16bit TCP/UDP destination port. nw_src_mask Integer 8bit IP source address mask specified as IPv4 address prefix. nw_dst_mask Integer 8bit IP destination address mask specified as IPv4 address prefix. ================ =============== ================================== Example:: >>> # compose >>> match = parser.OFPMatch( ... in_port=1, ... dl_type=0x0800, ... dl_src='aa:bb:cc:dd:ee:ff', ... nw_src='192.168.0.1') >>> # query >>> if 'nw_src' in match: ... print match['nw_src'] ... '192.168.0.1' """ def __init__(self, wildcards=None, in_port=None, dl_src=None, dl_dst=None, dl_vlan=None, dl_vlan_pcp=None, dl_type=None, nw_tos=None, nw_proto=None, nw_src=None, nw_dst=None, tp_src=None, tp_dst=None, nw_src_mask=32, nw_dst_mask=32): super(OFPMatch, self).__init__() wc = ofproto.OFPFW_ALL if in_port is None: self.in_port = 0 else: wc &= ~ofproto.OFPFW_IN_PORT self.in_port = in_port if dl_src is None: self.dl_src = mac.DONTCARE else: wc &= ~ofproto.OFPFW_DL_SRC if (isinstance(dl_src, (str, str)) and netaddr.valid_mac(dl_src)): dl_src = addrconv.mac.text_to_bin(dl_src) if dl_src == 0: self.dl_src = mac.DONTCARE else: self.dl_src = dl_src if dl_dst is None: self.dl_dst = mac.DONTCARE else: wc &= ~ofproto.OFPFW_DL_DST if (isinstance(dl_dst, (str, str)) and netaddr.valid_mac(dl_dst)): dl_dst = addrconv.mac.text_to_bin(dl_dst) if dl_dst == 0: self.dl_dst = mac.DONTCARE else: self.dl_dst = dl_dst if dl_vlan is None: self.dl_vlan = 0 else: wc &= ~ofproto.OFPFW_DL_VLAN self.dl_vlan = dl_vlan if dl_vlan_pcp is None: self.dl_vlan_pcp = 0 else: wc &= ~ofproto.OFPFW_DL_VLAN_PCP self.dl_vlan_pcp = dl_vlan_pcp if dl_type is None: self.dl_type = 0 else: wc &= ~ofproto.OFPFW_DL_TYPE self.dl_type = dl_type if nw_tos is None: self.nw_tos = 0 else: wc &= ~ofproto.OFPFW_NW_TOS self.nw_tos = nw_tos if nw_proto is None: self.nw_proto = 0 else: wc &= ~ofproto.OFPFW_NW_PROTO self.nw_proto = nw_proto if nw_src is None: self.nw_src = 0 else: wc &= (32 - nw_src_mask) << ofproto.OFPFW_NW_SRC_SHIFT \ | ~ofproto.OFPFW_NW_SRC_MASK if not isinstance(nw_src, int): nw_src = ip.ipv4_to_int(nw_src) self.nw_src = nw_src if nw_dst is None: self.nw_dst = 0 else: wc &= (32 - nw_dst_mask) << ofproto.OFPFW_NW_DST_SHIFT \ | ~ofproto.OFPFW_NW_DST_MASK if not isinstance(nw_dst, int): nw_dst = ip.ipv4_to_int(nw_dst) self.nw_dst = nw_dst if tp_src is None: self.tp_src = 0 else: wc &= ~ofproto.OFPFW_TP_SRC self.tp_src = tp_src if tp_dst is None: self.tp_dst = 0 else: wc &= ~ofproto.OFPFW_TP_DST self.tp_dst = tp_dst if wildcards is None: self.wildcards = wc else: self.wildcards = wildcards def __getitem__(self, name): if not isinstance(name, str): raise KeyError(name) elif name == 'nw_src_mask': _m = 32 - ((self.wildcards & ofproto.OFPFW_NW_SRC_MASK) >> ofproto.OFPFW_NW_SRC_SHIFT) return 0 if _m < 0 else _m elif name == 'nw_dst_mask': _m = 32 - ((self.wildcards & ofproto.OFPFW_NW_DST_MASK) >> ofproto.OFPFW_NW_DST_SHIFT) return 0 if _m < 0 else _m elif name == 'wildcards': return self.wildcards wc = getattr(ofproto, 'OFPFW_' + name.upper(), 0) if ~self.wildcards & wc: value = getattr(self, name) if name in ['dl_src', 'dl_dst']: value = addrconv.mac.bin_to_text(value) elif name in ['nw_src', 'nw_dst']: value = ip.ipv4_to_str(value) return value else: raise KeyError(name) def __contains__(self, name): wc = getattr(ofproto, 'OFPFW_' + name.upper(), 0) return ~self.wildcards & wc def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_MATCH_PACK_STR, buf, offset, self.wildcards, self.in_port, self.dl_src, self.dl_dst, self.dl_vlan, self.dl_vlan_pcp, self.dl_type, self.nw_tos, self.nw_proto, self.nw_src, self.nw_dst, self.tp_src, self.tp_dst) @classmethod def parse(cls, buf, offset): match = struct.unpack_from(ofproto.OFP_MATCH_PACK_STR, buf, offset) return cls(*match) def to_jsondict(self): fields = {} # copy values to avoid original values conversion for k, v in self.__dict__.items(): if k in ['dl_src', 'dl_dst']: fields[k] = addrconv.mac.bin_to_text(v) elif k in ['nw_src', 'nw_dst']: fields[k] = ip.ipv4_to_str(v) else: fields[k] = v return {self.__class__.__name__: fields} @classmethod def from_jsondict(cls, dict_): return cls(**dict_) class OFPActionHeader(StringifyMixin): _base_attributes = ['type', 'len'] def __init__(self, type_, len_): self.type = type_ self.len = len_ def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_HEADER_PACK_STR, buf, offset, self.type, self.len) class OFPAction(OFPActionHeader): _ACTION_TYPES = {} @staticmethod def register_action_type(type_, len_): def _register_action_type(cls): cls.cls_action_type = type_ cls.cls_action_len = len_ OFPAction._ACTION_TYPES[cls.cls_action_type] = cls return cls return _register_action_type def __init__(self): cls = self.__class__ super(OFPAction, self).__init__(cls.cls_action_type, cls.cls_action_len) @classmethod def parser(cls, buf, offset): type_, len_ = struct.unpack_from( ofproto.OFP_ACTION_HEADER_PACK_STR, buf, offset) cls_ = cls._ACTION_TYPES.get(type_) assert cls_ is not None return cls_.parser(buf, offset) @OFPAction.register_action_type(ofproto.OFPAT_OUTPUT, ofproto.OFP_ACTION_OUTPUT_SIZE) class OFPActionOutput(OFPAction): """ Output action This action indicates output a packet to the switch port. ================ ====================================================== Attribute Description ================ ====================================================== port Output port. max_len Max length to send to controller. ================ ====================================================== Note:: The reason of this magic number (0xffe5) is because there is no good constant in of1.0. The same value as OFPCML_MAX of of1.2 and of1.3 is used. """ def __init__(self, port, max_len=0xffe5): super(OFPActionOutput, self).__init__() self.port = port self.max_len = max_len @classmethod def parser(cls, buf, offset): type_, len_, port, max_len = struct.unpack_from( ofproto.OFP_ACTION_OUTPUT_PACK_STR, buf, offset) assert type_ == ofproto.OFPAT_OUTPUT assert len_ == ofproto.OFP_ACTION_OUTPUT_SIZE return cls(port, max_len) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_OUTPUT_PACK_STR, buf, offset, self.type, self.len, self.port, self.max_len) @OFPAction.register_action_type(ofproto.OFPAT_SET_VLAN_VID, ofproto.OFP_ACTION_VLAN_VID_SIZE) class OFPActionVlanVid(OFPAction): """ Set the 802.1q VLAN id action This action indicates the 802.1q VLAN id to be set. ================ ====================================================== Attribute Description ================ ====================================================== vlan_vid VLAN id. ================ ====================================================== """ def __init__(self, vlan_vid): super(OFPActionVlanVid, self).__init__() self.vlan_vid = vlan_vid @classmethod def parser(cls, buf, offset): type_, len_, vlan_vid = struct.unpack_from( ofproto.OFP_ACTION_VLAN_VID_PACK_STR, buf, offset) assert type_ == ofproto.OFPAT_SET_VLAN_VID assert len_ == ofproto.OFP_ACTION_VLAN_VID_SIZE return cls(vlan_vid) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_VLAN_VID_PACK_STR, buf, offset, self.type, self.len, self.vlan_vid) @OFPAction.register_action_type(ofproto.OFPAT_SET_VLAN_PCP, ofproto.OFP_ACTION_VLAN_PCP_SIZE) class OFPActionVlanPcp(OFPAction): """ Set the 802.1q priority action This action indicates the 802.1q priority to be set. ================ ====================================================== Attribute Description ================ ====================================================== vlan_pcp VLAN priority. ================ ====================================================== """ def __init__(self, vlan_pcp): super(OFPActionVlanPcp, self).__init__() self.vlan_pcp = vlan_pcp @classmethod def parser(cls, buf, offset): type_, len_, vlan_pcp = struct.unpack_from( ofproto.OFP_ACTION_VLAN_PCP_PACK_STR, buf, offset) assert type_ == ofproto.OFPAT_SET_VLAN_PCP assert len_ == ofproto.OFP_ACTION_VLAN_PCP_SIZE return cls(vlan_pcp) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_VLAN_PCP_PACK_STR, buf, offset, self.type, self.len, self.vlan_pcp) @OFPAction.register_action_type(ofproto.OFPAT_STRIP_VLAN, ofproto.OFP_ACTION_HEADER_SIZE) class OFPActionStripVlan(OFPAction): """ Strip the 802.1q header action This action indicates the 802.1q priority to be striped. """ def __init__(self): super(OFPActionStripVlan, self).__init__() @classmethod def parser(cls, buf, offset): type_, len_ = struct.unpack_from( ofproto.OFP_ACTION_HEADER_PACK_STR, buf, offset) assert type_ == ofproto.OFPAT_STRIP_VLAN assert len_ == ofproto.OFP_ACTION_HEADER_SIZE return cls() class OFPActionDlAddr(OFPAction): def __init__(self, dl_addr): super(OFPActionDlAddr, self).__init__() if (isinstance(dl_addr, (str, str)) and netaddr.valid_mac(dl_addr)): dl_addr = addrconv.mac.text_to_bin(dl_addr) self.dl_addr = dl_addr @classmethod def parser(cls, buf, offset): type_, len_, dl_addr = struct.unpack_from( ofproto.OFP_ACTION_DL_ADDR_PACK_STR, buf, offset) assert type_ in (ofproto.OFPAT_SET_DL_SRC, ofproto.OFPAT_SET_DL_DST) assert len_ == ofproto.OFP_ACTION_DL_ADDR_SIZE return cls(dl_addr) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_DL_ADDR_PACK_STR, buf, offset, self.type, self.len, self.dl_addr) def to_jsondict(self): body = {"dl_addr": addrconv.mac.bin_to_text(self.dl_addr)} return {self.__class__.__name__: body} @classmethod def from_jsondict(cls, dict_): return cls(**dict_) @OFPAction.register_action_type(ofproto.OFPAT_SET_DL_SRC, ofproto.OFP_ACTION_DL_ADDR_SIZE) class OFPActionSetDlSrc(OFPActionDlAddr): """ Set the ethernet source address action This action indicates the ethernet source address to be set. ================ ====================================================== Attribute Description ================ ====================================================== dl_addr Ethernet address. ================ ====================================================== """ def __init__(self, dl_addr): super(OFPActionSetDlSrc, self).__init__(dl_addr) @OFPAction.register_action_type(ofproto.OFPAT_SET_DL_DST, ofproto.OFP_ACTION_DL_ADDR_SIZE) class OFPActionSetDlDst(OFPActionDlAddr): """ Set the ethernet destination address action This action indicates the ethernet destination address to be set. ================ ====================================================== Attribute Description ================ ====================================================== dl_addr Ethernet address. ================ ====================================================== """ def __init__(self, dl_addr): super(OFPActionSetDlDst, self).__init__(dl_addr) class OFPActionNwAddr(OFPAction): def __init__(self, nw_addr): super(OFPActionNwAddr, self).__init__() if not isinstance(nw_addr, int): nw_addr = ip.ipv4_to_int(nw_addr) self.nw_addr = nw_addr @classmethod def parser(cls, buf, offset): type_, len_, nw_addr = struct.unpack_from( ofproto.OFP_ACTION_NW_ADDR_PACK_STR, buf, offset) assert type_ in (ofproto.OFPAT_SET_NW_SRC, ofproto.OFPAT_SET_NW_DST) assert len_ == ofproto.OFP_ACTION_NW_ADDR_SIZE return cls(nw_addr) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_NW_ADDR_PACK_STR, buf, offset, self.type, self.len, self.nw_addr) def to_jsondict(self): body = {"nw_addr": ip.ipv4_to_str(self.nw_addr)} return {self.__class__.__name__: body} @classmethod def from_jsondict(cls, dict_): return cls(**dict_) @OFPAction.register_action_type(ofproto.OFPAT_SET_NW_SRC, ofproto.OFP_ACTION_NW_ADDR_SIZE) class OFPActionSetNwSrc(OFPActionNwAddr): """ Set the IP source address action This action indicates the IP source address to be set. ================ ====================================================== Attribute Description ================ ====================================================== nw_addr IP address. ================ ====================================================== """ def __init__(self, nw_addr): super(OFPActionSetNwSrc, self).__init__(nw_addr) @OFPAction.register_action_type(ofproto.OFPAT_SET_NW_DST, ofproto.OFP_ACTION_NW_ADDR_SIZE) class OFPActionSetNwDst(OFPActionNwAddr): """ Set the IP destination address action This action indicates the IP destination address to be set. ================ ====================================================== Attribute Description ================ ====================================================== nw_addr IP address. ================ ====================================================== """ def __init__(self, nw_addr): super(OFPActionSetNwDst, self).__init__(nw_addr) @OFPAction.register_action_type(ofproto.OFPAT_SET_NW_TOS, ofproto.OFP_ACTION_NW_TOS_SIZE) class OFPActionSetNwTos(OFPAction): """ Set the IP ToS action This action indicates the IP ToS (DSCP field, 6 bits) to be set. ================ ====================================================== Attribute Description ================ ====================================================== tos IP ToS (DSCP field, 6 bits). ================ ====================================================== """ def __init__(self, tos): super(OFPActionSetNwTos, self).__init__() self.tos = tos @classmethod def parser(cls, buf, offset): type_, len_, tos = struct.unpack_from( ofproto.OFP_ACTION_NW_TOS_PACK_STR, buf, offset) assert type_ == ofproto.OFPAT_SET_NW_TOS assert len_ == ofproto.OFP_ACTION_NW_TOS_SIZE return cls(tos) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_NW_TOS_PACK_STR, buf, offset, self.type, self.len, self.tos) class OFPActionTpPort(OFPAction): def __init__(self, tp): super(OFPActionTpPort, self).__init__() self.tp = tp @classmethod def parser(cls, buf, offset): type_, len_, tp = struct.unpack_from( ofproto.OFP_ACTION_TP_PORT_PACK_STR, buf, offset) assert type_ in (ofproto.OFPAT_SET_TP_SRC, ofproto.OFPAT_SET_TP_DST) assert len_ == ofproto.OFP_ACTION_TP_PORT_SIZE return cls(tp) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_TP_PORT_PACK_STR, buf, offset, self.type, self.len, self.tp) @OFPAction.register_action_type(ofproto.OFPAT_SET_TP_SRC, ofproto.OFP_ACTION_TP_PORT_SIZE) class OFPActionSetTpSrc(OFPActionTpPort): """ Set the TCP/UDP source port action This action indicates the TCP/UDP source port to be set. ================ ====================================================== Attribute Description ================ ====================================================== tp TCP/UDP port. ================ ====================================================== """ def __init__(self, tp): super(OFPActionSetTpSrc, self).__init__(tp) @OFPAction.register_action_type(ofproto.OFPAT_SET_TP_DST, ofproto.OFP_ACTION_TP_PORT_SIZE) class OFPActionSetTpDst(OFPActionTpPort): """ Set the TCP/UDP destination port action This action indicates the TCP/UDP destination port to be set. ================ ====================================================== Attribute Description ================ ====================================================== tp TCP/UDP port. ================ ====================================================== """ def __init__(self, tp): super(OFPActionSetTpDst, self).__init__(tp) @OFPAction.register_action_type(ofproto.OFPAT_ENQUEUE, ofproto.OFP_ACTION_ENQUEUE_SIZE) class OFPActionEnqueue(OFPAction): """ Output to queue action This action indicates send packets to given queue on port. ================ ====================================================== Attribute Description ================ ====================================================== port Port that queue belongs. queue_id Where to enqueue the packets. ================ ====================================================== """ def __init__(self, port, queue_id): super(OFPActionEnqueue, self).__init__() self.port = port self.queue_id = queue_id @classmethod def parser(cls, buf, offset): type_, len_, port, queue_id = struct.unpack_from( ofproto.OFP_ACTION_ENQUEUE_PACK_STR, buf, offset) assert type_ == ofproto.OFPAT_ENQUEUE assert len_ == ofproto.OFP_ACTION_ENQUEUE_SIZE return cls(port, queue_id) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_ENQUEUE_PACK_STR, buf, offset, self.type, self.len, self.port, self.queue_id) @OFPAction.register_action_type(ofproto.OFPAT_VENDOR, 0) class OFPActionVendor(OFPAction): """ Vendor action This action is an extensible action for the vendor. """ _ACTION_VENDORS = {} @staticmethod def register_action_vendor(vendor): def _register_action_vendor(cls): cls.cls_vendor = vendor OFPActionVendor._ACTION_VENDORS[cls.cls_vendor] = cls return cls return _register_action_vendor def __init__(self, vendor=None): super(OFPActionVendor, self).__init__() self.type = ofproto.OFPAT_VENDOR self.len = None if vendor is None: self.vendor = self.cls_vendor else: self.vendor = vendor @classmethod def parser(cls, buf, offset): type_, len_, vendor = struct.unpack_from( ofproto.OFP_ACTION_VENDOR_HEADER_PACK_STR, buf, offset) data = buf[(offset + ofproto.OFP_ACTION_VENDOR_HEADER_SIZE ): offset + len_] if vendor == ofproto_common.NX_EXPERIMENTER_ID: obj = NXAction.parse(data) # noqa else: cls_ = cls._ACTION_VENDORS.get(vendor, None) if cls_ is None: obj = OFPActionVendorUnknown(vendor, data) else: obj = cls_.parser(buf, offset) obj.len = len_ return obj def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_VENDOR_HEADER_PACK_STR, buf, offset, self.type, self.len, self.vendor) # OpenFlow1.2 or later compatible OFPActionExperimenter = OFPActionVendor class OFPActionVendorUnknown(OFPActionVendor): def __init__(self, vendor, data=None, type_=None, len_=None): super(OFPActionVendorUnknown, self).__init__(vendor=vendor) self.data = data def serialize(self, buf, offset): # fixup data = self.data if data is None: data = bytearray() self.len = (utils.round_up(len(data), 8) + ofproto.OFP_ACTION_VENDOR_HEADER_SIZE) super(OFPActionVendorUnknown, self).serialize(buf, offset) msg_pack_into('!%ds' % len(self.data), buf, offset + ofproto.OFP_ACTION_VENDOR_HEADER_SIZE, self.data) @OFPActionVendor.register_action_vendor(ofproto_common.NX_EXPERIMENTER_ID) class NXActionHeader(OFPActionVendor): _NX_ACTION_SUBTYPES = {} @staticmethod def register_nx_action_subtype(subtype, len_): def _register_nx_action_subtype(cls): cls.cls_action_len = len_ cls.cls_subtype = subtype NXActionHeader._NX_ACTION_SUBTYPES[cls.cls_subtype] = cls return cls return _register_nx_action_subtype def __init__(self): super(NXActionHeader, self).__init__() self.subtype = self.cls_subtype def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_HEADER_PACK_STR, buf, offset, self.type, self.len) @classmethod def parser(cls, buf, offset): type_, len_, vendor, subtype = struct.unpack_from( ofproto.NX_ACTION_HEADER_PACK_STR, buf, offset) cls_ = cls._NX_ACTION_SUBTYPES.get(subtype) return cls_.parser(buf, offset) class OFPDescStats(ofproto_parser.namedtuple('OFPDescStats', ( 'mfr_desc', 'hw_desc', 'sw_desc', 'serial_num', 'dp_desc'))): _TYPE = { 'ascii': [ 'mfr_desc', 'hw_desc', 'sw_desc', 'serial_num', 'dp_desc', ] } @classmethod def parser(cls, buf, offset): desc = struct.unpack_from(ofproto.OFP_DESC_STATS_PACK_STR, buf, offset) desc = list(desc) desc = [x.rstrip(b'\0') for x in desc] stats = cls(*desc) stats.length = ofproto.OFP_DESC_STATS_SIZE return stats class OFPFlowStats(StringifyMixin): def __init__(self): super(OFPFlowStats, self).__init__() self.length = None self.table_id = None self.match = None self.duration_sec = None self.duration_nsec = None self.priority = None self.idle_timeout = None self.hard_timeout = None self.cookie = None self.packet_count = None self.byte_count = None self.actions = None @classmethod def parser(cls, buf, offset): flow_stats = cls() flow_stats.length, flow_stats.table_id = struct.unpack_from( ofproto.OFP_FLOW_STATS_0_PACK_STR, buf, offset) offset += ofproto.OFP_FLOW_STATS_0_SIZE flow_stats.match = OFPMatch.parse(buf, offset) offset += ofproto.OFP_MATCH_SIZE (flow_stats.duration_sec, flow_stats.duration_nsec, flow_stats.priority, flow_stats.idle_timeout, flow_stats.hard_timeout, flow_stats.cookie, flow_stats.packet_count, flow_stats.byte_count) = struct.unpack_from( ofproto.OFP_FLOW_STATS_1_PACK_STR, buf, offset) offset += ofproto.OFP_FLOW_STATS_1_SIZE flow_stats.actions = [] length = ofproto.OFP_FLOW_STATS_SIZE while length < flow_stats.length: action = OFPAction.parser(buf, offset) flow_stats.actions.append(action) offset += action.len length += action.len return flow_stats class OFPAggregateStats(ofproto_parser.namedtuple('OFPAggregateStats', ( 'packet_count', 'byte_count', 'flow_count'))): @classmethod def parser(cls, buf, offset): agg = struct.unpack_from( ofproto.OFP_AGGREGATE_STATS_REPLY_PACK_STR, buf, offset) stats = cls(*agg) stats.length = ofproto.OFP_AGGREGATE_STATS_REPLY_SIZE return stats class OFPTableStats(ofproto_parser.namedtuple('OFPTableStats', ( 'table_id', 'name', 'wildcards', 'max_entries', 'active_count', 'lookup_count', 'matched_count'))): _TYPE = { 'utf-8': [ # OF spec is unclear about the encoding of name. # we assumes UTF-8. 'name', ] } @classmethod def parser(cls, buf, offset): tbl = struct.unpack_from(ofproto.OFP_TABLE_STATS_PACK_STR, buf, offset) tbl = list(tbl) i = cls._fields.index('name') tbl[i] = tbl[i].rstrip(b'\0') stats = cls(*tbl) stats.length = ofproto.OFP_TABLE_STATS_SIZE return stats class OFPPortStats(ofproto_parser.namedtuple('OFPPortStats', ( 'port_no', 'rx_packets', 'tx_packets', 'rx_bytes', 'tx_bytes', 'rx_dropped', 'tx_dropped', 'rx_errors', 'tx_errors', 'rx_frame_err', 'rx_over_err', 'rx_crc_err', 'collisions'))): @classmethod def parser(cls, buf, offset): port = struct.unpack_from(ofproto.OFP_PORT_STATS_PACK_STR, buf, offset) stats = cls(*port) stats.length = ofproto.OFP_PORT_STATS_SIZE return stats class OFPQueueStats(ofproto_parser.namedtuple('OFPQueueStats', ( 'port_no', 'queue_id', 'tx_bytes', 'tx_packets', 'tx_errors'))): @classmethod def parser(cls, buf, offset): queue = struct.unpack_from(ofproto.OFP_QUEUE_STATS_PACK_STR, buf, offset) stats = cls(*queue) stats.length = ofproto.OFP_QUEUE_STATS_SIZE return stats class OFPVendorStats(ofproto_parser.namedtuple('OFPVendorStats', ('specific_data'))): @classmethod def parser(cls, buf, offset): stats = cls(buf[offset:]) stats.length = len(stats.specific_data) return stats class NXFlowStats(StringifyMixin): def __init__(self): super(NXFlowStats, self).__init__() self.length = None self.table_id = None self.duration_sec = None self.duration_nsec = None self.priority = None self.idle_timeout = None self.hard_timeout = None self.match_len = None self.idle_age = None self.hard_age = None self.cookie = None self.packet_count = None self.byte_count = None @classmethod def parser(cls, buf, offset): original_offset = offset nxflow_stats = cls() (nxflow_stats.length, nxflow_stats.table_id, nxflow_stats.duration_sec, nxflow_stats.duration_nsec, nxflow_stats.priority, nxflow_stats.idle_timeout, nxflow_stats.hard_timeout, nxflow_stats.match_len, nxflow_stats.idle_age, nxflow_stats.hard_age, nxflow_stats.cookie, nxflow_stats.packet_count, nxflow_stats.byte_count) = struct.unpack_from( ofproto.NX_FLOW_STATS_PACK_STR, buf, offset) offset += ofproto.NX_FLOW_STATS_SIZE fields = [] match_len = nxflow_stats.match_len match_len -= 4 while match_len > 0: field = nx_match.MFField.parser(buf, offset) offset += field.length match_len -= field.length fields.append(field) nxflow_stats.fields = fields actions = [] total_len = original_offset + nxflow_stats.length match_len = nxflow_stats.match_len offset += utils.round_up(match_len, 8) - match_len while offset < total_len: action = OFPAction.parser(buf, offset) actions.append(action) offset += action.len nxflow_stats.actions = actions return nxflow_stats class NXAggregateStats(ofproto_parser.namedtuple('NXAggregateStats', ( 'packet_count', 'byte_count', 'flow_count'))): @classmethod def parser(cls, buf, offset): agg = struct.unpack_from( ofproto.NX_AGGREGATE_STATS_REPLY_PACK_STR, buf, offset) stats = cls(*agg) stats.length = ofproto.NX_AGGREGATE_STATS_REPLY_SIZE return stats class OFPQueuePropHeader(StringifyMixin): _QUEUE_PROPERTIES = {} @staticmethod def register_queue_property(prop_type, prop_len): def _register_queue_propery(cls): cls.cls_prop_type = prop_type cls.cls_prop_len = prop_len OFPQueuePropHeader._QUEUE_PROPERTIES[prop_type] = cls return cls return _register_queue_propery def __init__(self): self.property = self.cls_prop_type self.len = self.cls_prop_len @classmethod def parser(cls, buf, offset): property_, len_ = struct.unpack_from( ofproto.OFP_QUEUE_PROP_HEADER_PACK_STR, buf, offset) prop_cls = cls._QUEUE_PROPERTIES[property_] assert property_ == prop_cls.cls_prop_type assert len_ == prop_cls.cls_prop_len offset += ofproto.OFP_QUEUE_PROP_HEADER_SIZE return prop_cls.parser(buf, offset) @OFPQueuePropHeader.register_queue_property( ofproto.OFPQT_NONE, ofproto.OFP_QUEUE_PROP_HEADER_SIZE) class OFPQueuePropNone(OFPQueuePropHeader): def __init__(self): super(OFPQueuePropNone, self).__init__() @classmethod def parser(cls, buf, offset): return cls() @OFPQueuePropHeader.register_queue_property( ofproto.OFPQT_MIN_RATE, ofproto.OFP_QUEUE_PROP_MIN_RATE_SIZE) class OFPQueuePropMinRate(OFPQueuePropHeader): def __init__(self, rate): super(OFPQueuePropMinRate, self).__init__() self.rate = rate @classmethod def parser(cls, buf, offset): (rate,) = struct.unpack_from( ofproto.OFP_QUEUE_PROP_MIN_RATE_PACK_STR, buf, offset) return cls(rate) class OFPPacketQueue(StringifyMixin): """ Description of a queue ========== ========================================================= Attribute Description ========== ========================================================= queue_id ID for the specific queue. len Length in bytes of this queue desc. properties List of ``OFPQueueProp*`` instance. ========== ========================================================= """ def __init__(self, queue_id, len_): self.queue_id = queue_id self.len = len_ self.properties = None @classmethod def parser(cls, buf, offset): queue_id, len_ = struct.unpack_from( ofproto.OFP_PACKET_QUEUE_PQCK_STR, buf, offset) packet_queue = cls(queue_id, len_) packet_queue.properties = [] cur_len = ofproto.OFP_PACKET_QUEUE_SIZE offset += ofproto.OFP_PACKET_QUEUE_SIZE while (cur_len + ofproto.OFP_QUEUE_PROP_HEADER_SIZE <= packet_queue.len): prop = OFPQueuePropHeader.parser(buf, offset) packet_queue.properties.append(prop) cur_len += prop.len offset += prop.len return packet_queue # # Symmetric messages # parser + serializer # @_register_parser @_set_msg_type(ofproto.OFPT_HELLO) class OFPHello(MsgBase): """ Hello message When connection is started, the hello message is exchanged between a switch and a controller. This message is handled by the OSKen framework, so the OSKen application do not need to process this typically. """ def __init__(self, datapath): super(OFPHello, self).__init__(datapath) @_register_parser @_set_msg_type(ofproto.OFPT_ERROR) class OFPErrorMsg(MsgBase): """ Error message The switch notifies controller of problems by this message. ========== ========================================================= Attribute Description ========== ========================================================= type High level type of error code Details depending on the type data Variable length data depending on the type and code ========== ========================================================= ``type`` attribute corresponds to ``type_`` parameter of __init__. Types and codes are defined in ``os_ken.ofproto.ofproto``. =========================== =========== Type Code =========================== =========== OFPET_HELLO_FAILED OFPHFC_* OFPET_BAD_REQUEST OFPBRC_* OFPET_BAD_ACTION OFPBAC_* OFPET_FLOW_MOD_FAILED OFPFMFC_* OFPET_PORT_MOD_FAILED OFPPMFC_* OFPET_QUEUE_OP_FAILED OFPQOFC_* =========================== =========== Example:: @set_ev_cls(ofp_event.EventOFPErrorMsg, [HANDSHAKE_DISPATCHER, CONFIG_DISPATCHER, MAIN_DISPATCHER]) def error_msg_handler(self, ev): msg = ev.msg self.logger.debug('OFPErrorMsg received: type=0x%02x code=0x%02x ' 'message=%s', msg.type, msg.code, utils.hex_array(msg.data)) """ def __init__(self, datapath, type_=None, code=None, data=None): super(OFPErrorMsg, self).__init__(datapath) self.type = type_ self.code = code if isinstance(data, str): data = data.encode('ascii') self.data = data @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPErrorMsg, cls).parser(datapath, version, msg_type, msg_len, xid, buf) msg.type, msg.code = struct.unpack_from( ofproto.OFP_ERROR_MSG_PACK_STR, msg.buf, ofproto.OFP_HEADER_SIZE) msg.data = msg.buf[ofproto.OFP_ERROR_MSG_SIZE:] return msg def _serialize_body(self): assert self.data is not None msg_pack_into(ofproto.OFP_ERROR_MSG_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.type, self.code) self.buf += self.data @_register_parser @_set_msg_type(ofproto.OFPT_ECHO_REQUEST) class OFPEchoRequest(MsgBase): """ Echo request message This message is handled by the OSKen framework, so the OSKen application do not need to process this typically. ========== ========================================================= Attribute Description ========== ========================================================= data An arbitrary length data. ========== ========================================================= Example:: def send_echo_request(self, datapath, data): ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPEchoRequest(datapath, data) datapath.send_msg(req) """ def __init__(self, datapath, data=None): super(OFPEchoRequest, self).__init__(datapath) self.data = data @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPEchoRequest, cls).parser(datapath, version, msg_type, msg_len, xid, buf) msg.data = msg.buf[ofproto.OFP_HEADER_SIZE:] return msg def _serialize_body(self): if self.data is not None: self.buf += self.data @_register_parser @_set_msg_type(ofproto.OFPT_ECHO_REPLY) class OFPEchoReply(MsgBase): """ Echo reply message This message is handled by the OSKen framework, so the OSKen application do not need to process this typically. ========== ========================================================= Attribute Description ========== ========================================================= data An arbitrary length data. ========== ========================================================= Example:: @set_ev_cls(ofp_event.EventOFPEchoReply, [HANDSHAKE_DISPATCHER, CONFIG_DISPATCHER, MAIN_DISPATCHER]) def echo_reply_handler(self, ev): self.logger.debug('OFPEchoReply received: data=%s', utils.hex_array(ev.msg.data)) """ def __init__(self, datapath, data=None): super(OFPEchoReply, self).__init__(datapath) self.data = data @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPEchoReply, cls).parser(datapath, version, msg_type, msg_len, xid, buf) msg.data = msg.buf[ofproto.OFP_HEADER_SIZE:] return msg def _serialize_body(self): assert self.data is not None self.buf += self.data @_register_parser @_set_msg_type(ofproto.OFPT_VENDOR) class OFPVendor(MsgBase): """ Vendor message The controller send this message to send the vendor-specific information to a switch. """ _VENDORS = {} @staticmethod def register_vendor(id_): def _register_vendor(cls): OFPVendor._VENDORS[id_] = cls return cls return _register_vendor def __init__(self, datapath): super(OFPVendor, self).__init__(datapath) self.data = None self.vendor = None @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPVendor, cls).parser(datapath, version, msg_type, msg_len, xid, buf) (msg.vendor,) = struct.unpack_from( ofproto.OFP_VENDOR_HEADER_PACK_STR, msg.buf, ofproto.OFP_HEADER_SIZE) cls_ = cls._VENDORS.get(msg.vendor) if cls_: msg.data = cls_.parser(datapath, msg.buf, 0) else: msg.data = msg.buf[ofproto.OFP_VENDOR_HEADER_SIZE:] return msg def serialize_header(self): msg_pack_into(ofproto.OFP_VENDOR_HEADER_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.vendor) def _serialize_body(self): assert self.data is not None self.serialize_header() self.buf += self.data @OFPVendor.register_vendor(ofproto_common.NX_EXPERIMENTER_ID) class NiciraHeader(OFPVendor): _NX_SUBTYPES = {} @staticmethod def register_nx_subtype(subtype): def _register_nx_subtype(cls): cls.cls_subtype = subtype NiciraHeader._NX_SUBTYPES[cls.cls_subtype] = cls return cls return _register_nx_subtype def __init__(self, datapath, subtype): super(NiciraHeader, self).__init__(datapath) self.vendor = ofproto_common.NX_EXPERIMENTER_ID self.subtype = subtype def serialize_header(self): super(NiciraHeader, self).serialize_header() msg_pack_into(ofproto.NICIRA_HEADER_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.vendor, self.subtype) @classmethod def parser(cls, datapath, buf, offset): vendor, subtype = struct.unpack_from( ofproto.NICIRA_HEADER_PACK_STR, buf, offset + ofproto.OFP_HEADER_SIZE) cls_ = cls._NX_SUBTYPES.get(subtype) return cls_.parser(datapath, buf, offset + ofproto.NICIRA_HEADER_SIZE) class NXTSetFlowFormat(NiciraHeader): def __init__(self, datapath, flow_format): super(NXTSetFlowFormat, self).__init__( datapath, ofproto.NXT_SET_FLOW_FORMAT) self.format = flow_format def _serialize_body(self): self.serialize_header() msg_pack_into(ofproto.NX_SET_FLOW_FORMAT_PACK_STR, self.buf, ofproto.NICIRA_HEADER_SIZE, self.format) class NXTFlowMod(NiciraHeader): def __init__(self, datapath, cookie, command, idle_timeout=0, hard_timeout=0, priority=ofproto.OFP_DEFAULT_PRIORITY, buffer_id=0xffffffff, out_port=ofproto.OFPP_NONE, flags=0, rule=None, actions=None): # the argument, rule, is positioned at the one before the last due # to the layout struct nxt_flow_mod. # Although rule must be given, default argument to rule, None, # is given to allow other default value of argument before rule. assert rule is not None if actions is None: actions = [] super(NXTFlowMod, self).__init__(datapath, ofproto.NXT_FLOW_MOD) self.cookie = cookie self.command = command self.idle_timeout = idle_timeout self.hard_timeout = hard_timeout self.priority = priority self.buffer_id = buffer_id self.out_port = out_port self.flags = flags self.rule = rule self.actions = actions def _serialize_body(self): self.serialize_header() offset = ofproto.NX_FLOW_MOD_SIZE match_len = nx_match.serialize_nxm_match(self.rule, self.buf, offset) offset += nx_match.round_up(match_len) msg_pack_into(ofproto.NX_FLOW_MOD_PACK_STR, self.buf, ofproto.NICIRA_HEADER_SIZE, self.cookie, self.command, self.idle_timeout, self.hard_timeout, self.priority, self.buffer_id, self.out_port, self.flags, match_len) if self.actions is not None: for a in self.actions: a.serialize(self.buf, offset) offset += a.len class NXTRoleRequest(NiciraHeader): def __init__(self, datapath, role): super(NXTRoleRequest, self).__init__( datapath, ofproto.NXT_ROLE_REQUEST) self.role = role def _serialize_body(self): self.serialize_header() msg_pack_into(ofproto.NX_ROLE_PACK_STR, self.buf, ofproto.NICIRA_HEADER_SIZE, self.role) @NiciraHeader.register_nx_subtype(ofproto.NXT_ROLE_REPLY) class NXTRoleReply(NiciraHeader): def __init__(self, datapath, role): super(NXTRoleReply, self).__init__( datapath, ofproto.NXT_ROLE_REPLY) self.role = role @classmethod def parser(cls, datapath, buf, offset): (role,) = struct.unpack_from( ofproto.NX_ROLE_PACK_STR, buf, offset) return cls(datapath, role) class NXTFlowModTableId(NiciraHeader): def __init__(self, datapath, set_): super(NXTFlowModTableId, self).__init__( datapath, ofproto.NXT_FLOW_MOD_TABLE_ID) self.set = set_ def _serialize_body(self): self.serialize_header() msg_pack_into(ofproto.NX_FLOW_MOD_TABLE_ID_PACK_STR, self.buf, ofproto.NICIRA_HEADER_SIZE, self.set) @NiciraHeader.register_nx_subtype(ofproto.NXT_FLOW_REMOVED) class NXTFlowRemoved(NiciraHeader): def __init__(self, datapath, cookie, priority, reason, duration_sec, duration_nsec, idle_timeout, match_len, packet_count, byte_count, match): super(NXTFlowRemoved, self).__init__( datapath, ofproto.NXT_FLOW_REMOVED) self.cookie = cookie self.priority = priority self.reason = reason self.duration_sec = duration_sec self.duration_nsec = duration_nsec self.idle_timeout = idle_timeout self.match_len = match_len self.packet_count = packet_count self.byte_count = byte_count self.match = match @classmethod def parser(cls, datapath, buf, offset): (cookie, priority, reason, duration_sec, duration_nsec, idle_timeout, match_len, packet_count, byte_count) = struct.unpack_from( ofproto.NX_FLOW_REMOVED_PACK_STR, buf, offset) offset += (ofproto.NX_FLOW_REMOVED_SIZE - ofproto.NICIRA_HEADER_SIZE) match = nx_match.NXMatch.parser(buf, offset, match_len) return cls(datapath, cookie, priority, reason, duration_sec, duration_nsec, idle_timeout, match_len, packet_count, byte_count, match) class NXTSetPacketInFormat(NiciraHeader): def __init__(self, datapath, packet_in_format): super(NXTSetPacketInFormat, self).__init__( datapath, ofproto.NXT_SET_PACKET_IN_FORMAT) self.format = packet_in_format def _serialize_body(self): self.serialize_header() msg_pack_into(ofproto.NX_SET_PACKET_IN_FORMAT_PACK_STR, self.buf, ofproto.NICIRA_HEADER_SIZE, self.format) @NiciraHeader.register_nx_subtype(ofproto.NXT_PACKET_IN) class NXTPacketIn(NiciraHeader): def __init__(self, datapath, buffer_id, total_len, reason, table_id, cookie, match_len, match, frame): super(NXTPacketIn, self).__init__( datapath, ofproto.NXT_PACKET_IN) self.buffer_id = buffer_id self.total_len = total_len self.reason = reason self.table_id = table_id self.cookie = cookie self.match_len = match_len self.match = match self.frame = frame @classmethod def parser(cls, datapath, buf, offset): (buffer_id, total_len, reason, table_id, cookie, match_len) = struct.unpack_from( ofproto.NX_PACKET_IN_PACK_STR, buf, offset) offset += (ofproto.NX_PACKET_IN_SIZE - ofproto.NICIRA_HEADER_SIZE) match = nx_match.NXMatch.parser(buf, offset, match_len) offset += (match_len + 7) // 8 * 8 frame = buf[offset:] if total_len < len(frame): frame = frame[:total_len] return cls(datapath, buffer_id, total_len, reason, table_id, cookie, match_len, match, frame) class NXTFlowAge(NiciraHeader): def __init__(self, datapath): super(NXTFlowAge, self).__init__( datapath, ofproto.NXT_FLOW_AGE) def _serialize_body(self): self.serialize_header() class NXTSetAsyncConfig(NiciraHeader): def __init__(self, datapath, packet_in_mask, port_status_mask, flow_removed_mask): super(NXTSetAsyncConfig, self).__init__( datapath, ofproto.NXT_SET_ASYNC_CONFIG) self.packet_in_mask = packet_in_mask self.port_status_mask = port_status_mask self.flow_removed_mask = flow_removed_mask def _serialize_body(self): self.serialize_header() msg_pack_into(ofproto.NX_ASYNC_CONFIG_PACK_STR, self.buf, ofproto.NICIRA_HEADER_SIZE, self.packet_in_mask[0], self.packet_in_mask[1], self.port_status_mask[0], self.port_status_mask[1], self.flow_removed_mask[0], self.flow_removed_mask[1]) class NXTSetControllerId(NiciraHeader): def __init__(self, datapath, controller_id): super(NXTSetControllerId, self).__init__( datapath, ofproto.NXT_SET_CONTROLLER_ID) self.controller_id = controller_id def _serialize_body(self): self.serialize_header() msg_pack_into(ofproto.NX_CONTROLLER_ID_PACK_STR, self.buf, ofproto.NICIRA_HEADER_SIZE, self.controller_id) # # asymmetric message (datapath -> controller) # parser only # @_register_parser @_set_msg_type(ofproto.OFPT_FEATURES_REPLY) class OFPSwitchFeatures(MsgBase): """ Features reply message The switch responds with a features reply message to a features request. This message is handled by the OSKen framework, so the OSKen application do not need to process this typically. ================ ====================================================== Attribute Description ================ ====================================================== datapath_id Datapath unique ID. n_buffers Max packets buffered at once. n_tables Number of tables supported by datapath. capabilities Bitmap of capabilities flag. | OFPC_FLOW_STATS | OFPC_TABLE_STATS | OFPC_PORT_STATS | OFPC_STP | OFPC_RESERVED | OFPC_IP_REASM | OFPC_QUEUE_STATS | OFPC_ARP_MATCH_IP actions Bitmap of supported OFPAT_*. ports List of ``OFPPhyPort`` instances. ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER) def switch_features_handler(self, ev): msg = ev.msg self.logger.debug('OFPSwitchFeatures received: ' 'datapath_id=0x%016x n_buffers=%d ' 'n_tables=%d capabilities=0x%08x ports=%s', msg.datapath_id, msg.n_buffers, msg.n_tables, msg.capabilities, msg.ports) """ def __init__(self, datapath, datapath_id=None, n_buffers=None, n_tables=None, capabilities=None, actions=None, ports=None): super(OFPSwitchFeatures, self).__init__(datapath) self.datapath_id = datapath_id self.n_buffers = n_buffers self.n_tables = n_tables self.capabilities = capabilities self.actions = actions self.ports = ports @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPSwitchFeatures, cls).parser(datapath, version, msg_type, msg_len, xid, buf) (msg.datapath_id, msg.n_buffers, msg.n_tables, msg.capabilities, msg.actions) = struct.unpack_from( ofproto.OFP_SWITCH_FEATURES_PACK_STR, msg.buf, ofproto.OFP_HEADER_SIZE) msg.ports = {} n_ports = ((msg_len - ofproto.OFP_SWITCH_FEATURES_SIZE) // ofproto.OFP_PHY_PORT_SIZE) offset = ofproto.OFP_SWITCH_FEATURES_SIZE for _i in range(n_ports): port = OFPPhyPort.parser(msg.buf, offset) # print 'port = %s' % str(port) msg.ports[port.port_no] = port offset += ofproto.OFP_PHY_PORT_SIZE return msg @_register_parser @_set_msg_type(ofproto.OFPT_PORT_STATUS) class OFPPortStatus(MsgBase): """ Port status message The switch notifies controller of change of ports. ================ ====================================================== Attribute Description ================ ====================================================== reason One of the following values. | OFPPR_ADD | OFPPR_DELETE | OFPPR_MODIFY desc instance of ``OFPPhyPort`` ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPPortStatus, MAIN_DISPATCHER) def port_status_handler(self, ev): msg = ev.msg dp = msg.datapath ofp = dp.ofproto if msg.reason == ofp.OFPPR_ADD: reason = 'ADD' elif msg.reason == ofp.OFPPR_DELETE: reason = 'DELETE' elif msg.reason == ofp.OFPPR_MODIFY: reason = 'MODIFY' else: reason = 'unknown' self.logger.debug('OFPPortStatus received: reason=%s desc=%s', reason, msg.desc) """ def __init__(self, datapath, reason=None, desc=None): super(OFPPortStatus, self).__init__(datapath) self.reason = reason self.desc = desc @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPPortStatus, cls).parser(datapath, version, msg_type, msg_len, xid, buf) msg.reason = struct.unpack_from( ofproto.OFP_PORT_STATUS_PACK_STR, msg.buf, ofproto.OFP_HEADER_SIZE)[0] msg.desc = OFPPhyPort.parser(msg.buf, ofproto.OFP_PORT_STATUS_DESC_OFFSET) return msg @_register_parser @_set_msg_type(ofproto.OFPT_PACKET_IN) class OFPPacketIn(MsgBase): """ Packet-In message The switch sends the packet that received to the controller by this message. ============= ========================================================= Attribute Description ============= ========================================================= buffer_id ID assigned by datapath. total_len Full length of frame. in_port Port on which frame was received. reason Reason packet is being sent. | OFPR_NO_MATCH | OFPR_ACTION | OFPR_INVALID_TTL data Ethernet frame. ============= ========================================================= Example:: @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER) def packet_in_handler(self, ev): msg = ev.msg dp = msg.datapath ofp = dp.ofproto if msg.reason == ofp.OFPR_NO_MATCH: reason = 'NO MATCH' elif msg.reason == ofp.OFPR_ACTION: reason = 'ACTION' elif msg.reason == ofp.OFPR_INVALID_TTL: reason = 'INVALID TTL' else: reason = 'unknown' self.logger.debug('OFPPacketIn received: ' 'buffer_id=%x total_len=%d in_port=%d, ' 'reason=%s data=%s', msg.buffer_id, msg.total_len, msg.in_port, reason, utils.hex_array(msg.data)) """ def __init__(self, datapath, buffer_id=None, total_len=None, in_port=None, reason=None, data=None): super(OFPPacketIn, self).__init__(datapath) self.buffer_id = buffer_id self.total_len = total_len self.in_port = in_port self.reason = reason self.data = data @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPPacketIn, cls).parser(datapath, version, msg_type, msg_len, xid, buf) (msg.buffer_id, msg.total_len, msg.in_port, msg.reason) = struct.unpack_from( ofproto.OFP_PACKET_IN_PACK_STR, msg.buf, ofproto.OFP_HEADER_SIZE) msg.data = msg.buf[ofproto.OFP_PACKET_IN_SIZE:] if msg.total_len < len(msg.data): # discard padding for 8-byte alignment of OFP packet msg.data = msg.data[:msg.total_len] return msg @_register_parser @_set_msg_type(ofproto.OFPT_GET_CONFIG_REPLY) class OFPGetConfigReply(MsgBase): """ Get config reply message The switch responds to a configuration request with a get config reply message. ============= ========================================================= Attribute Description ============= ========================================================= flags One of the following configuration flags. | OFPC_FRAG_NORMAL | OFPC_FRAG_DROP | OFPC_FRAG_REASM | OFPC_FRAG_MASK miss_send_len Max bytes of new flow that datapath should send to the controller. ============= ========================================================= Example:: @set_ev_cls(ofp_event.EventOFPGetConfigReply, MAIN_DISPATCHER) def get_config_reply_handler(self, ev): msg = ev.msg dp = msg.datapath ofp = dp.ofproto if msg.flags == ofp.OFPC_FRAG_NORMAL: flags = 'NORMAL' elif msg.flags == ofp.OFPC_FRAG_DROP: flags = 'DROP' elif msg.flags == ofp.OFPC_FRAG_REASM: flags = 'REASM' elif msg.flags == ofp.OFPC_FRAG_MASK: flags = 'MASK' else: flags = 'unknown' self.logger.debug('OFPGetConfigReply received: ' 'flags=%s miss_send_len=%d', flags, msg.miss_send_len) """ def __init__(self, datapath): super(OFPGetConfigReply, self).__init__(datapath) @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPGetConfigReply, cls).parser(datapath, version, msg_type, msg_len, xid, buf) (msg.flags, msg.miss_send_len) = struct.unpack_from( ofproto.OFP_SWITCH_CONFIG_PACK_STR, msg.buf, ofproto.OFP_HEADER_SIZE) return msg @_register_parser @_set_msg_type(ofproto.OFPT_BARRIER_REPLY) class OFPBarrierReply(MsgBase): """ Barrier reply message The switch responds with this message to a barrier request. Example:: @set_ev_cls(ofp_event.EventOFPBarrierReply, MAIN_DISPATCHER) def barrier_reply_handler(self, ev): self.logger.debug('OFPBarrierReply received') """ def __init__(self, datapath): super(OFPBarrierReply, self).__init__(datapath) @_register_parser @_set_msg_type(ofproto.OFPT_FLOW_REMOVED) class OFPFlowRemoved(MsgBase): """ Flow removed message When flow entries time out or are deleted, the switch notifies controller with this message. ================ ====================================================== Attribute Description ================ ====================================================== match Instance of ``OFPMatch``. cookie Opaque controller-issued identifier. priority Priority level of flow entry. reason One of the following values. | OFPRR_IDLE_TIMEOUT | OFPRR_HARD_TIMEOUT | OFPRR_DELETE duration_sec Time flow was alive in seconds. duration_nsec Time flow was alive in nanoseconds beyond duration_sec. idle_timeout Idle timeout from original flow mod. packet_count Number of packets that was associated with the flow. byte_count Number of bytes that was associated with the flow. ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPFlowRemoved, MAIN_DISPATCHER) def flow_removed_handler(self, ev): msg = ev.msg dp = msg.datapath ofp = dp.ofproto if msg.reason == ofp.OFPRR_IDLE_TIMEOUT: reason = 'IDLE TIMEOUT' elif msg.reason == ofp.OFPRR_HARD_TIMEOUT: reason = 'HARD TIMEOUT' elif msg.reason == ofp.OFPRR_DELETE: reason = 'DELETE' elif msg.reason == ofp.OFPRR_GROUP_DELETE: reason = 'GROUP DELETE' else: reason = 'unknown' self.logger.debug('OFPFlowRemoved received: ' 'match=%s cookie=%d priority=%d reason=%s ' 'duration_sec=%d duration_nsec=%d ' 'idle_timeout=%d packet_count=%d byte_count=%d', msg.match, msg.cookie, msg.priority, reason, msg.duration_sec, msg.duration_nsec, msg.idle_timeout, msg.packet_count, msg.byte_count) """ def __init__(self, datapath): super(OFPFlowRemoved, self).__init__(datapath) @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPFlowRemoved, cls).parser(datapath, version, msg_type, msg_len, xid, buf) msg.match = OFPMatch.parse(msg.buf, ofproto.OFP_HEADER_SIZE) (msg.cookie, msg.priority, msg.reason, msg.duration_sec, msg.duration_nsec, msg.idle_timeout, msg.packet_count, msg.byte_count) = struct.unpack_from( ofproto.OFP_FLOW_REMOVED_PACK_STR0, msg.buf, ofproto.OFP_HEADER_SIZE + ofproto.OFP_MATCH_SIZE) return msg @_register_parser @_set_msg_type(ofproto.OFPT_QUEUE_GET_CONFIG_REPLY) class OFPQueueGetConfigReply(MsgBase): """ Queue configuration reply message The switch responds with this message to a queue configuration request. ================ ====================================================== Attribute Description ================ ====================================================== port Port to be queried. queues List of ``OFPPacketQueue`` instance. ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPQueueGetConfigReply, MAIN_DISPATCHER) def queue_get_config_reply_handler(self, ev): msg = ev.msg self.logger.debug('OFPQueueGetConfigReply received: ' 'port=%s queues=%s', msg.port, msg.queues) """ def __init__(self, datapath): super(OFPQueueGetConfigReply, self).__init__(datapath) @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPQueueGetConfigReply, cls).parser( datapath, version, msg_type, msg_len, xid, buf) offset = ofproto.OFP_HEADER_SIZE (msg.port,) = struct.unpack_from( ofproto.OFP_QUEUE_GET_CONFIG_REPLY_PACK_STR, msg.buf, offset) msg.queues = [] offset = ofproto.OFP_QUEUE_GET_CONFIG_REPLY_SIZE while offset + ofproto.OFP_PACKET_QUEUE_SIZE <= msg_len: queue = OFPPacketQueue.parser(msg.buf, offset) msg.queues.append(queue) offset += queue.len return msg def _set_stats_type(stats_type, stats_body_cls): def _set_cls_stats_type(cls): cls.cls_stats_type = stats_type cls.cls_stats_body_cls = stats_body_cls return cls return _set_cls_stats_type @_register_parser @_set_msg_type(ofproto.OFPT_STATS_REPLY) class OFPStatsReply(MsgBase): _STATS_MSG_TYPES = {} @staticmethod def register_stats_type(body_single_struct=False): def _register_stats_type(cls): assert cls.cls_stats_type is not None assert cls.cls_stats_type not in OFPStatsReply._STATS_MSG_TYPES assert cls.cls_stats_body_cls is not None cls.cls_body_single_struct = body_single_struct OFPStatsReply._STATS_MSG_TYPES[cls.cls_stats_type] = cls return cls return _register_stats_type def __init__(self, datapath): super(OFPStatsReply, self).__init__(datapath) self.type = None self.flags = None self.body = None @classmethod def parser_stats_body(cls, buf, msg_len, offset): body_cls = cls.cls_stats_body_cls body = [] while offset < msg_len: entry = body_cls.parser(buf, offset) body.append(entry) offset += entry.length if cls.cls_body_single_struct: return body[0] return body @classmethod def parser_stats(cls, datapath, version, msg_type, msg_len, xid, buf): # call MsgBase::parser, not OFPStatsReply::parser msg = MsgBase.parser.__func__( cls, datapath, version, msg_type, msg_len, xid, buf) msg.body = msg.parser_stats_body(msg.buf, msg.msg_len, ofproto.OFP_STATS_MSG_SIZE) return msg @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): type_, flags = struct.unpack_from(ofproto.OFP_STATS_MSG_PACK_STR, bytes(buf), ofproto.OFP_HEADER_SIZE) stats_type_cls = cls._STATS_MSG_TYPES.get(type_) msg = stats_type_cls.parser_stats( datapath, version, msg_type, msg_len, xid, buf) msg.type = type_ msg.flags = flags return msg @OFPStatsReply.register_stats_type(body_single_struct=True) @_set_stats_type(ofproto.OFPST_DESC, OFPDescStats) @_set_msg_type(ofproto.OFPT_STATS_REPLY) class OFPDescStatsReply(OFPStatsReply): """ Description statistics reply message The switch responds with a stats reply that include this message to a description statistics request. ================ ====================================================== Attribute Description ================ ====================================================== mfr_desc Manufacturer description. hw_desc Hardware description. sw_desc Software description. serial_num Serial number. dp_desc Human readable description of datapath. ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPDescStatsReply, MAIN_DISPATCHER) def desc_stats_reply_handler(self, ev): msg = ev.msg ofp = msg.datapath.ofproto body = ev.msg.body self.logger.debug('DescStats: mfr_desc=%s hw_desc=%s sw_desc=%s ' 'serial_num=%s dp_desc=%s', body.mfr_desc, body.hw_desc, body.sw_desc, body.serial_num, body.dp_desc) """ def __init__(self, datapath): super(OFPDescStatsReply, self).__init__(datapath) @OFPStatsReply.register_stats_type() @_set_stats_type(ofproto.OFPST_FLOW, OFPFlowStats) @_set_msg_type(ofproto.OFPT_STATS_REPLY) class OFPFlowStatsReply(OFPStatsReply): """ Individual flow statistics reply message The switch responds with a stats reply that include this message to an individual flow statistics request. ================ ====================================================== Attribute Description ================ ====================================================== table_id ID of table flow came from. match Instance of ``OFPMatch``. duration_sec Time flow has been alive in seconds. duration_nsec Time flow has been alive in nanoseconds beyond duration_sec. priority Priority of the entry. Only meaningful when this is not an exact-match entry. idle_timeout Number of seconds idle before expiration. hard_timeout Number of seconds before expiration. cookie Opaque controller-issued identifier. packet_count Number of packets in flow. byte_count Number of bytes in flow. actions List of ``OFPAction*`` instance ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPFlowStatsReply, MAIN_DISPATCHER) def flow_stats_reply_handler(self, ev): msg = ev.msg ofp = msg.datapath.ofproto body = ev.msg.body flows = [] for stat in body: flows.append('table_id=%s match=%s ' 'duration_sec=%d duration_nsec=%d ' 'priority=%d ' 'idle_timeout=%d hard_timeout=%d ' 'cookie=%d packet_count=%d byte_count=%d ' 'actions=%s' % (stat.table_id, stat.match, stat.duration_sec, stat.duration_nsec, stat.priority, stat.idle_timeout, stat.hard_timeout, stat.cookie, stat.packet_count, stat.byte_count, stat.actions)) self.logger.debug('FlowStats: %s', flows) """ def __init__(self, datapath): super(OFPFlowStatsReply, self).__init__(datapath) @OFPStatsReply.register_stats_type() @_set_stats_type(ofproto.OFPST_AGGREGATE, OFPAggregateStats) @_set_msg_type(ofproto.OFPT_STATS_REPLY) class OFPAggregateStatsReply(OFPStatsReply): """ Aggregate flow statistics reply message The switch responds with a stats reply that include this message to an aggregate flow statistics request. ================ ====================================================== Attribute Description ================ ====================================================== packet_count Number of packets in flows. byte_count Number of bytes in flows. flow_count Number of flows. ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPAggregateStatsReply, MAIN_DISPATCHER) def aggregate_stats_reply_handler(self, ev): msg = ev.msg ofp = msg.datapath.ofproto body = ev.msg.body self.logger.debug('AggregateStats: packet_count=%d byte_count=%d ' 'flow_count=%d', body.packet_count, body.byte_count, body.flow_count) """ def __init__(self, datapath): super(OFPAggregateStatsReply, self).__init__(datapath) @OFPStatsReply.register_stats_type() @_set_stats_type(ofproto.OFPST_TABLE, OFPTableStats) @_set_msg_type(ofproto.OFPT_STATS_REPLY) class OFPTableStatsReply(OFPStatsReply): """ Table statistics reply message The switch responds with a stats reply that include this message to a table statistics request. ================ ====================================================== Attribute Description ================ ====================================================== table_id ID of table. name table name. wildcards Bitmap of OFPFW_* wildcards that are supported by the table. max_entries Max number of entries supported active_count Number of active entries lookup_count Number of packets looked up in table matched_count Number of packets that hit table ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPTableStatsReply, MAIN_DISPATCHER) def stats_reply_handler(self, ev): msg = ev.msg ofp = msg.datapath.ofproto body = ev.msg.body tables = [] for stat in body: tables.append('table_id=%d name=%s wildcards=0x%02x ' 'max_entries=%d active_count=%d ' 'lookup_count=%d matched_count=%d' % (stat.table_id, stat.name, stat.wildcards, stat.max_entries, stat.active_count, stat.lookup_count, stat.matched_count)) self.logger.debug('TableStats: %s', tables) """ def __init__(self, datapath): super(OFPTableStatsReply, self).__init__(datapath) @OFPStatsReply.register_stats_type() @_set_stats_type(ofproto.OFPST_PORT, OFPPortStats) @_set_msg_type(ofproto.OFPT_STATS_REPLY) class OFPPortStatsReply(OFPStatsReply): """ Port statistics reply message The switch responds with a stats reply that include this message to a port statistics request. ================ ====================================================== Attribute Description ================ ====================================================== port_no Port number. rx_packets Number of received packets. tx_packets Number of transmitted packets. rx_bytes Number of received bytes. tx_bytes Number of transmitted bytes. rx_dropped Number of packets dropped by RX. tx_dropped Number of packets dropped by TX. rx_errors Number of receive errors. tx_errors Number of transmit errors. rx_frame_err Number of frame alignment errors. rx_over_err Number of packet with RX overrun. rx_crc_err Number of CRC errors. collisions Number of collisions. ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPPortStatsReply, MAIN_DISPATCHER) def port_stats_reply_handler(self, ev): msg = ev.msg ofp = msg.datapath.ofproto body = ev.msg.body ports = [] for stat in body: ports.append('port_no=%d ' 'rx_packets=%d tx_packets=%d ' 'rx_bytes=%d tx_bytes=%d ' 'rx_dropped=%d tx_dropped=%d ' 'rx_errors=%d tx_errors=%d ' 'rx_frame_err=%d rx_over_err=%d rx_crc_err=%d ' 'collisions=%d' % (stat.port_no, stat.rx_packets, stat.tx_packets, stat.rx_bytes, stat.tx_bytes, stat.rx_dropped, stat.tx_dropped, stat.rx_errors, stat.tx_errors, stat.rx_frame_err, stat.rx_over_err, stat.rx_crc_err, stat.collisions)) self.logger.debug('PortStats: %s', ports) """ def __init__(self, datapath): super(OFPPortStatsReply, self).__init__(datapath) @OFPStatsReply.register_stats_type() @_set_stats_type(ofproto.OFPST_QUEUE, OFPQueueStats) @_set_msg_type(ofproto.OFPT_STATS_REPLY) class OFPQueueStatsReply(OFPStatsReply): """ Queue statistics reply message The switch responds with a stats reply that include this message to an aggregate flow statistics request. ================ ====================================================== Attribute Description ================ ====================================================== port_no Port number. queue_id ID of queue. tx_bytes Number of transmitted bytes. tx_packets Number of transmitted packets. tx_errors Number of packets dropped due to overrun. ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPQueueStatsReply, MAIN_DISPATCHER) def stats_reply_handler(self, ev): msg = ev.msg ofp = msg.datapath.ofproto body = ev.msg.body queues = [] for stat in body: queues.append('port_no=%d queue_id=%d ' 'tx_bytes=%d tx_packets=%d tx_errors=%d ' % (stat.port_no, stat.queue_id, stat.tx_bytes, stat.tx_packets, stat.tx_errors)) self.logger.debug('QueueStats: %s', queues) """ def __init__(self, datapath): super(OFPQueueStatsReply, self).__init__(datapath) @OFPStatsReply.register_stats_type() @_set_stats_type(ofproto.OFPST_VENDOR, OFPVendorStats) @_set_msg_type(ofproto.OFPT_STATS_REPLY) class OFPVendorStatsReply(OFPStatsReply): """ Vendor statistics reply message The switch responds with a stats reply that include this message to an vendor statistics request. """ _STATS_VENDORS = {} @staticmethod def register_stats_vendor(vendor): def _register_stats_vendor(cls): cls.cls_vendor = vendor OFPVendorStatsReply._STATS_VENDORS[cls.cls_vendor] = cls return cls return _register_stats_vendor def __init__(self, datapath): super(OFPVendorStatsReply, self).__init__(datapath) @classmethod def parser_stats(cls, datapath, version, msg_type, msg_len, xid, buf): (type_,) = struct.unpack_from( ofproto.OFP_VENDOR_STATS_MSG_PACK_STR, bytes(buf), ofproto.OFP_STATS_MSG_SIZE) cls_ = cls._STATS_VENDORS.get(type_) if cls_ is None: msg = MsgBase.parser.__func__( cls, datapath, version, msg_type, msg_len, xid, buf) body_cls = cls.cls_stats_body_cls body = body_cls.parser(buf, ofproto.OFP_STATS_MSG_SIZE) msg.body = body return msg return cls_.parser( datapath, version, msg_type, msg_len, xid, buf, ofproto.OFP_VENDOR_STATS_MSG_SIZE) @OFPVendorStatsReply.register_stats_vendor(ofproto_common.NX_EXPERIMENTER_ID) class NXStatsReply(OFPStatsReply): _NX_STATS_TYPES = {} @staticmethod def register_nx_stats_type(body_single_struct=False): def _register_nx_stats_type(cls): assert cls.cls_stats_type is not None assert cls.cls_stats_type not in \ NXStatsReply._NX_STATS_TYPES assert cls.cls_stats_body_cls is not None cls.cls_body_single_struct = body_single_struct NXStatsReply._NX_STATS_TYPES[cls.cls_stats_type] = cls return cls return _register_nx_stats_type @classmethod def parser_stats_body(cls, buf, msg_len, offset): body_cls = cls.cls_stats_body_cls body = [] while offset < msg_len: entry = body_cls.parser(buf, offset) body.append(entry) offset += entry.length if cls.cls_body_single_struct: return body[0] return body @classmethod def parser_stats(cls, datapath, version, msg_type, msg_len, xid, buf, offset): msg = MsgBase.parser.__func__( cls, datapath, version, msg_type, msg_len, xid, buf) msg.body = msg.parser_stats_body(msg.buf, msg.msg_len, offset) return msg @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf, offset): (type_,) = struct.unpack_from( ofproto.NX_STATS_MSG_PACK_STR, bytes(buf), offset) offset += ofproto.NX_STATS_MSG0_SIZE cls_ = cls._NX_STATS_TYPES.get(type_) msg = cls_.parser_stats( datapath, version, msg_type, msg_len, xid, buf, offset) return msg @NXStatsReply.register_nx_stats_type() @_set_stats_type(ofproto.NXST_FLOW, NXFlowStats) class NXFlowStatsReply(NXStatsReply): def __init__(self, datapath): super(NXFlowStatsReply, self).__init__(datapath) @NXStatsReply.register_nx_stats_type() @_set_stats_type(ofproto.NXST_AGGREGATE, NXAggregateStats) class NXAggregateStatsReply(NXStatsReply): def __init__(self, datapath): super(NXAggregateStatsReply, self).__init__(datapath) # # controller-to-switch message # serializer only # @_set_msg_reply(OFPSwitchFeatures) @_set_msg_type(ofproto.OFPT_FEATURES_REQUEST) class OFPFeaturesRequest(MsgBase): """ Features request message The controller sends a feature request to the switch upon session establishment. This message is handled by the OSKen framework, so the OSKen application do not need to process this typically. Example:: def send_features_request(self, datapath): ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPFeaturesRequest(datapath) datapath.send_msg(req) """ def __init__(self, datapath): super(OFPFeaturesRequest, self).__init__(datapath) @_set_msg_type(ofproto.OFPT_GET_CONFIG_REQUEST) class OFPGetConfigRequest(MsgBase): """ Get config request message The controller sends a get config request to query configuration parameters in the switch. Example:: def send_get_config_request(self, datapath): ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPGetConfigRequest(datapath) datapath.send_msg(req) """ def __init__(self, datapath): super(OFPGetConfigRequest, self).__init__(datapath) @_set_msg_type(ofproto.OFPT_SET_CONFIG) class OFPSetConfig(MsgBase): """ Set config request message The controller sends a set config request message to set configuraion parameters. ============= ========================================================= Attribute Description ============= ========================================================= flags One of the following configuration flags. | OFPC_FRAG_NORMAL | OFPC_FRAG_DROP | OFPC_FRAG_REASM | OFPC_FRAG_MASK miss_send_len Max bytes of new flow that datapath should send to the controller. ============= ========================================================= Example:: def send_set_config(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPSetConfig(datapath, ofp.OFPC_FRAG_NORMAL, 256) datapath.send_msg(req) """ def __init__(self, datapath, flags=None, miss_send_len=None): super(OFPSetConfig, self).__init__(datapath) self.flags = flags self.miss_send_len = miss_send_len def _serialize_body(self): assert self.flags is not None assert self.miss_send_len is not None msg_pack_into(ofproto.OFP_SWITCH_CONFIG_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.flags, self.miss_send_len) @_set_msg_type(ofproto.OFPT_PACKET_OUT) class OFPPacketOut(MsgBase): """ Packet-Out message The controller uses this message to send a packet out throught the switch. ================ ====================================================== Attribute Description ================ ====================================================== buffer_id ID assigned by datapath (0xffffffff if none). in_port Packet's input port (OFPP_NONE if none). actions ist of ``OFPAction*`` instance. data Packet data of a binary type value or an instances of packet.Packet. ================ ====================================================== Example:: def send_packet_out(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser buffer_id = 0xffffffff in_port = ofp.OFPP_NONE actions = [ofp_parser.OFPActionOutput(ofp.OFPP_FLOOD, 0)] req = ofp_parser.OFPPacketOut(datapath, buffer_id, in_port, actions) datapath.send_msg(req) """ def __init__(self, datapath, buffer_id=None, in_port=None, actions=None, data=None): super(OFPPacketOut, self).__init__(datapath) self.buffer_id = buffer_id self.in_port = in_port self._actions_len = None self.actions = actions self.data = data def _serialize_body(self): assert self.buffer_id is not None assert self.in_port is not None assert self.actions is not None self._actions_len = 0 offset = ofproto.OFP_PACKET_OUT_SIZE for a in self.actions: a.serialize(self.buf, offset) offset += a.len self._actions_len += a.len if self.data is not None: assert self.buffer_id == 0xffffffff if isinstance(self.data, packet.Packet): self.data.serialize() self.buf += self.data.data else: self.buf += self.data msg_pack_into(ofproto.OFP_PACKET_OUT_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.buffer_id, self.in_port, self._actions_len) @classmethod def from_jsondict(cls, dict_, decode_string=base64.b64decode, **additional_args): if isinstance(dict_['data'], dict): data = dict_.pop('data') ins = super(OFPPacketOut, cls).from_jsondict(dict_, decode_string, **additional_args) ins.data = packet.Packet.from_jsondict(data['Packet']) dict_['data'] = data else: ins = super(OFPPacketOut, cls).from_jsondict(dict_, decode_string, **additional_args) return ins @_register_parser @_set_msg_type(ofproto.OFPT_FLOW_MOD) class OFPFlowMod(MsgBase): """ Modify Flow entry message The controller sends this message to modify the flow table. ================ ====================================================== Attribute Description ================ ====================================================== match Instance of ``OFPMatch``. cookie Opaque controller-issued identifier. command One of the following values. | OFPFC_ADD | OFPFC_MODIFY | OFPFC_MODIFY_STRICT | OFPFC_DELETE | OFPFC_DELETE_STRICT idle_timeout Idle time before discarding (seconds). hard_timeout Max time before discarding (seconds). priority Priority level of flow entry. buffer_id Buffered packet to apply to (or 0xffffffff). Not meaningful for OFPFC_DELETE*. out_port For OFPFC_DELETE* commands, require matching entries to include this as an output port. A value of OFPP_NONE indicates no restriction. flags One of the following values. | OFPFF_SEND_FLOW_REM | OFPFF_CHECK_OVERLAP | OFPFF_EMERG actions List of ``OFPAction*`` instance. ================ ====================================================== Example:: def send_flow_mod(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser match = ofp_parser.OFPMatch(in_port=1) cookie = 0 command = ofp.OFPFC_ADD idle_timeout = hard_timeout = 0 priority = 32768 buffer_id = 0xffffffff out_port = ofproto.OFPP_NONE flags = 0 actions = [ofp_parser.OFPActionOutput(ofp.OFPP_NORMAL, 0)] req = ofp_parser.OFPFlowMod( datapath, match, cookie, command, idle_timeout, hard_timeout, priority, buffer_id, out_port, flags, actions) datapath.send_msg(req) """ def __init__(self, datapath, match=None, cookie=0, command=ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=0, priority=ofproto.OFP_DEFAULT_PRIORITY, buffer_id=0xffffffff, out_port=ofproto.OFPP_NONE, flags=0, actions=None): super(OFPFlowMod, self).__init__(datapath) self.match = OFPMatch() if match is None else match self.cookie = cookie self.command = command self.idle_timeout = idle_timeout self.hard_timeout = hard_timeout self.priority = priority self.buffer_id = buffer_id self.out_port = out_port self.flags = flags self.actions = [] if actions is None else actions def _serialize_body(self): offset = ofproto.OFP_HEADER_SIZE self.match.serialize(self.buf, offset) offset += ofproto.OFP_MATCH_SIZE msg_pack_into(ofproto.OFP_FLOW_MOD_PACK_STR0, self.buf, offset, self.cookie, self.command, self.idle_timeout, self.hard_timeout, self.priority, self.buffer_id, self.out_port, self.flags) offset = ofproto.OFP_FLOW_MOD_SIZE if self.actions is not None: for a in self.actions: a.serialize(self.buf, offset) offset += a.len @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPFlowMod, cls).parser( datapath, version, msg_type, msg_len, xid, buf) offset = ofproto.OFP_HEADER_SIZE msg.match = OFPMatch.parse(msg.buf, offset) offset += ofproto.OFP_MATCH_SIZE (msg.cookie, msg.command, msg.idle_timeout, msg.hard_timeout, msg.priority, msg.buffer_id, msg.out_port, msg.flags) = struct.unpack_from( ofproto.OFP_FLOW_MOD_PACK_STR0, msg.buf, offset) offset = ofproto.OFP_FLOW_MOD_SIZE actions = [] while offset < msg_len: a = OFPAction.parser(buf, offset) actions.append(a) offset += a.len msg.actions = actions return msg @_set_msg_type(ofproto.OFPT_PORT_MOD) class OFPPortMod(MsgBase): """ Port modification message The controller send this message to modify the behavior of the port. ================ ====================================================== Attribute Description ================ ====================================================== port_no Port number to modify. hw_addr The hardware address that must be the same as hw_addr of ``OFPPhyPort`` of ``OFPSwitchFeatures``. config Bitmap of configuration flags. | OFPPC_PORT_DOWN | OFPPC_NO_STP | OFPPC_NO_RECV | OFPPC_NO_RECV_STP | OFPPC_NO_FLOOD | OFPPC_NO_FWD | OFPPC_NO_PACKET_IN mask Bitmap of configuration flags above to be changed advertise Bitmap of the following flags. | OFPPF_10MB_HD | OFPPF_10MB_FD | OFPPF_100MB_HD | OFPPF_100MB_FD | OFPPF_1GB_HD | OFPPF_1GB_FD | OFPPF_10GB_FD | OFPPF_COPPER | OFPPF_FIBER | OFPPF_AUTONEG | OFPPF_PAUSE | OFPPF_PAUSE_ASYM ================ ====================================================== Example:: def send_port_mod(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser port_no = 3 hw_addr = 'fa:c8:e8:76:1d:7e' config = 0 mask = (ofp.OFPPC_PORT_DOWN | ofp.OFPPC_NO_RECV | ofp.OFPPC_NO_FWD | ofp.OFPPC_NO_PACKET_IN) advertise = (ofp.OFPPF_10MB_HD | ofp.OFPPF_100MB_FD | ofp.OFPPF_1GB_FD | ofp.OFPPF_COPPER | ofp.OFPPF_AUTONEG | ofp.OFPPF_PAUSE | ofp.OFPPF_PAUSE_ASYM) req = ofp_parser.OFPPortMod(datapath, port_no, hw_addr, config, mask, advertise) datapath.send_msg(req) """ _TYPE = { 'ascii': [ 'hw_addr', ] } def __init__(self, datapath, port_no=0, hw_addr='00:00:00:00:00:00', config=0, mask=0, advertise=0): super(OFPPortMod, self).__init__(datapath) self.port_no = port_no self.hw_addr = hw_addr self.config = config self.mask = mask self.advertise = advertise def _serialize_body(self): msg_pack_into(ofproto.OFP_PORT_MOD_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.port_no, addrconv.mac.text_to_bin(self.hw_addr), self.config, self.mask, self.advertise) @_set_msg_reply(OFPBarrierReply) @_set_msg_type(ofproto.OFPT_BARRIER_REQUEST) class OFPBarrierRequest(MsgBase): """ Barrier request message The controller sends this message to ensure message dependencies have been met or receive notifications for completed operations. Example:: def send_barrier_request(self, datapath): ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPBarrierRequest(datapath) datapath.send_msg(req) """ def __init__(self, datapath): super(OFPBarrierRequest, self).__init__(datapath) @_set_msg_reply(OFPQueueGetConfigReply) @_set_msg_type(ofproto.OFPT_QUEUE_GET_CONFIG_REQUEST) class OFPQueueGetConfigRequest(MsgBase): """ Queue configuration request message ================ ====================================================== Attribute Description ================ ====================================================== port Port to be queried. Should refer to a valid physical port (i.e. < OFPP_MAX). ================ ====================================================== Example:: def send_queue_get_config_request(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPQueueGetConfigRequest(datapath, ofp.OFPP_NONE) datapath.send_msg(req) """ def __init__(self, datapath, port): super(OFPQueueGetConfigRequest, self).__init__(datapath) self.port = port def _serialize_body(self): msg_pack_into(ofproto.OFP_QUEUE_GET_CONFIG_REQUEST_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.port) class OFPStatsRequest(MsgBase): def __init__(self, datapath, flags): assert flags == 0 # none yet defined super(OFPStatsRequest, self).__init__(datapath) self.type = self.__class__.cls_stats_type self.flags = flags def _serialize_stats_body(self): pass def _serialize_body(self): msg_pack_into(ofproto.OFP_STATS_MSG_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.type, self.flags) self._serialize_stats_body() @_set_msg_reply(OFPDescStatsReply) @_set_stats_type(ofproto.OFPST_DESC, OFPDescStats) @_set_msg_type(ofproto.OFPT_STATS_REQUEST) class OFPDescStatsRequest(OFPStatsRequest): """ Description statistics request message The controller uses this message to query description of the switch. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero (none yet defined in the spec). ================ ====================================================== Example:: def send_desc_stats_request(self, datapath): ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPDescStatsRequest(datapath) datapath.send_msg(req) """ def __init__(self, datapath, flags): super(OFPDescStatsRequest, self).__init__(datapath, flags) class OFPFlowStatsRequestBase(OFPStatsRequest): def __init__(self, datapath, flags, match, table_id, out_port): super(OFPFlowStatsRequestBase, self).__init__(datapath, flags) self.match = match self.table_id = table_id self.out_port = out_port def _serialize_stats_body(self): offset = ofproto.OFP_STATS_MSG_SIZE self.match.serialize(self.buf, offset) offset += ofproto.OFP_MATCH_SIZE msg_pack_into(ofproto.OFP_FLOW_STATS_REQUEST_ID_PORT_STR, self.buf, offset, self.table_id, self.out_port) @_set_msg_reply(OFPFlowStatsReply) @_set_stats_type(ofproto.OFPST_FLOW, OFPFlowStats) @_set_msg_type(ofproto.OFPT_STATS_REQUEST) class OFPFlowStatsRequest(OFPFlowStatsRequestBase): """ Individual flow statistics request message The controller uses this message to query individual flow statistics. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero (none yet defined in the spec). match Instance of ``OFPMatch``. table_id ID of table to read (from ofp_table_stats), 0xff for all tables or 0xfe for emergency. out_port Require matching entries to include this as an output port. A value of OFPP_NONE indicates no restriction. ================ ====================================================== Example:: def send_flow_stats_request(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser match = ofp_parser.OFPMatch(in_port=1) table_id = 0xff out_port = ofp.OFPP_NONE req = ofp_parser.OFPFlowStatsRequest( datapath, 0, match, table_id, out_port) datapath.send_msg(req) """ def __init__(self, datapath, flags, match, table_id, out_port): super(OFPFlowStatsRequest, self).__init__( datapath, flags, match, table_id, out_port) @_set_msg_reply(OFPAggregateStatsReply) @_set_stats_type(ofproto.OFPST_AGGREGATE, OFPAggregateStats) @_set_msg_type(ofproto.OFPT_STATS_REQUEST) class OFPAggregateStatsRequest(OFPFlowStatsRequestBase): """ Aggregate flow statistics request message The controller uses this message to query aggregate flow statictics. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero (none yet defined in the spec). match Fields to match. table_id ID of table to read (from ofp_table_stats) 0xff for all tables or 0xfe for emergency. out_port Require matching entries to include this as an output port. A value of OFPP_NONE indicates no restriction. ================ ====================================================== Example:: def send_aggregate_stats_request(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser cookie = cookie_mask = 0 match = ofp_parser.OFPMatch(in_port=1) req = ofp_parser.OFPAggregateStatsRequest( datapath, 0, match, 0xff, ofp.OFPP_NONE) datapath.send_msg(req) """ def __init__(self, datapath, flags, match, table_id, out_port): super(OFPAggregateStatsRequest, self).__init__( datapath, flags, match, table_id, out_port) @_set_msg_reply(OFPTableStatsReply) @_set_stats_type(ofproto.OFPST_TABLE, OFPTableStats) @_set_msg_type(ofproto.OFPT_STATS_REQUEST) class OFPTableStatsRequest(OFPStatsRequest): """ Table statistics request message The controller uses this message to query flow table statictics. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero (none yet defined in the spec). ================ ====================================================== Example:: def send_table_stats_request(self, datapath): ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPTableStatsRequest(datapath) datapath.send_msg(req) """ def __init__(self, datapath, flags): super(OFPTableStatsRequest, self).__init__(datapath, flags) @_set_msg_reply(OFPPortStatsReply) @_set_stats_type(ofproto.OFPST_PORT, OFPPortStats) @_set_msg_type(ofproto.OFPT_STATS_REQUEST) class OFPPortStatsRequest(OFPStatsRequest): """ Port statistics request message The controller uses this message to query information about ports statistics. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero (none yet defined in the spec). port_no Port number to read (OFPP_NONE to all ports). ================ ====================================================== Example:: def send_port_stats_request(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPPortStatsRequest(datapath, 0, ofp.OFPP_ANY) datapath.send_msg(req) """ def __init__(self, datapath, flags, port_no): super(OFPPortStatsRequest, self).__init__(datapath, flags) self.port_no = port_no def _serialize_stats_body(self): msg_pack_into(ofproto.OFP_PORT_STATS_REQUEST_PACK_STR, self.buf, ofproto.OFP_STATS_MSG_SIZE, self.port_no) @_set_msg_reply(OFPQueueStatsReply) @_set_stats_type(ofproto.OFPST_QUEUE, OFPQueueStats) @_set_msg_type(ofproto.OFPT_STATS_REQUEST) class OFPQueueStatsRequest(OFPStatsRequest): """ Queue statistics request message The controller uses this message to query queue statictics. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero (none yet defined in the spec) port_no Port number to read (All ports if OFPT_ALL). queue_id ID of queue to read (All queues if OFPQ_ALL). ================ ====================================================== Example:: def send_queue_stats_request(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPQueueStatsRequest(datapath, 0, ofp.OFPT_ALL, ofp.OFPQ_ALL) datapath.send_msg(req) """ def __init__(self, datapath, flags, port_no, queue_id): super(OFPQueueStatsRequest, self).__init__(datapath, flags) self.port_no = port_no self.queue_id = queue_id def _serialize_stats_body(self): msg_pack_into(ofproto.OFP_QUEUE_STATS_REQUEST_PACK_STR, self.buf, ofproto.OFP_STATS_MSG_SIZE, self.port_no, self.queue_id) @_set_msg_reply(OFPVendorStatsReply) @_set_stats_type(ofproto.OFPST_VENDOR, OFPVendorStats) @_set_msg_type(ofproto.OFPT_STATS_REQUEST) class OFPVendorStatsRequest(OFPStatsRequest): """ Vendor statistics request message The controller uses this message to query vendor-specific information of a switch. """ def __init__(self, datapath, flags, vendor, specific_data=None): super(OFPVendorStatsRequest, self).__init__(datapath, flags) self.vendor = vendor self.specific_data = specific_data def _serialize_vendor_stats(self): self.buf += self.specific_data def _serialize_stats_body(self): msg_pack_into(ofproto.OFP_VENDOR_STATS_MSG_PACK_STR, self.buf, ofproto.OFP_STATS_MSG_SIZE, self.vendor) self._serialize_vendor_stats() class NXStatsRequest(OFPVendorStatsRequest): def __init__(self, datapath, flags, subtype): super(NXStatsRequest, self).__init__(datapath, flags, ofproto_common.NX_EXPERIMENTER_ID) self.subtype = subtype def _serialize_vendor_stats_body(self): pass def _serialize_vendor_stats(self): msg_pack_into(ofproto.NX_STATS_MSG_PACK_STR, self.buf, ofproto.OFP_VENDOR_STATS_MSG_SIZE, self.subtype) self._serialize_vendor_stats_body() class NXFlowStatsRequest(NXStatsRequest): def __init__(self, datapath, flags, out_port, table_id, rule=None): super(NXFlowStatsRequest, self).__init__(datapath, flags, ofproto.NXST_FLOW) self.out_port = out_port self.table_id = table_id self.rule = rule self.match_len = 0 def _serialize_vendor_stats_body(self): if self.rule is not None: offset = ofproto.NX_STATS_MSG_SIZE + \ ofproto.NX_FLOW_STATS_REQUEST_SIZE self.match_len = nx_match.serialize_nxm_match( self.rule, self.buf, offset) msg_pack_into( ofproto.NX_FLOW_STATS_REQUEST_PACK_STR, self.buf, ofproto.NX_STATS_MSG_SIZE, self.out_port, self.match_len, self.table_id) class NXAggregateStatsRequest(NXStatsRequest): def __init__(self, datapath, flags, out_port, table_id, rule=None): super(NXAggregateStatsRequest, self).__init__( datapath, flags, ofproto.NXST_AGGREGATE) self.out_port = out_port self.table_id = table_id self.rule = rule self.match_len = 0 def _serialize_vendor_stats_body(self): if self.rule is not None: offset = ofproto.NX_STATS_MSG_SIZE + \ ofproto.NX_AGGREGATE_STATS_REQUEST_SIZE self.match_len = nx_match.serialize_nxm_match( self.rule, self.buf, offset) msg_pack_into( ofproto.NX_AGGREGATE_STATS_REQUEST_PACK_STR, self.buf, ofproto.NX_STATS_MSG_SIZE, self.out_port, self.match_len, self.table_id) nx_actions.generate( 'os_ken.ofproto.ofproto_v1_0', 'os_ken.ofproto.ofproto_v1_0_parser' ) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/ofproto/ofproto_v1_2.py0000664000175000017500000010434300000000000020655 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2012 Isaku Yamahata # # 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. """ OpenFlow 1.2 definitions. """ from os_ken.lib import type_desc from os_ken.ofproto import nicira_ext from os_ken.ofproto import ofproto_utils from os_ken.ofproto import oxm_fields from struct import calcsize # struct ofp_header OFP_HEADER_PACK_STR = '!BBHI' OFP_HEADER_SIZE = 8 assert calcsize(OFP_HEADER_PACK_STR) == OFP_HEADER_SIZE # enum ofp_type OFPT_HELLO = 0 # Symmetric message OFPT_ERROR = 1 # Symmetric message OFPT_ECHO_REQUEST = 2 # Symmetric message OFPT_ECHO_REPLY = 3 # Symmetric message OFPT_EXPERIMENTER = 4 # Symmetric message # Immutable message OFPT_FEATURES_REQUEST = 5 # Controller/switch message OFPT_FEATURES_REPLY = 6 # Controller/switch message OFPT_GET_CONFIG_REQUEST = 7 # Controller/switch message OFPT_GET_CONFIG_REPLY = 8 # Controller/switch message OFPT_SET_CONFIG = 9 # Controller/switch message OFPT_PACKET_IN = 10 # Async message OFPT_FLOW_REMOVED = 11 # Async message OFPT_PORT_STATUS = 12 # Async message OFPT_PACKET_OUT = 13 # Controller/switch message OFPT_FLOW_MOD = 14 # Controller/switch message OFPT_GROUP_MOD = 15 # Controller/switch message OFPT_PORT_MOD = 16 # Controller/switch message OFPT_TABLE_MOD = 17 # Controller/switch message OFPT_STATS_REQUEST = 18 # Controller/switch message OFPT_STATS_REPLY = 19 # Controller/switch message OFPT_BARRIER_REQUEST = 20 # Controller/switch message OFPT_BARRIER_REPLY = 21 # Controller/switch message OFPT_QUEUE_GET_CONFIG_REQUEST = 22 # Controller/switch message OFPT_QUEUE_GET_CONFIG_REPLY = 23 # Controller/switch message OFPT_ROLE_REQUEST = 24 # Controller/switch message OFPT_ROLE_REPLY = 25 # Controller/switch message # struct ofp_port OFP_MAX_PORT_NAME_LEN = 16 OFP_ETH_ALEN = 6 OFP_ETH_ALEN_STR = str(OFP_ETH_ALEN) _OFP_PORT_PACK_STR = 'I4x' + OFP_ETH_ALEN_STR + 's' + '2x' + \ str(OFP_MAX_PORT_NAME_LEN) + 's' + 'IIIIIIII' OFP_PORT_PACK_STR = '!' + _OFP_PORT_PACK_STR OFP_PORT_SIZE = 64 assert calcsize(OFP_PORT_PACK_STR) == OFP_PORT_SIZE # enum ofp_port_config OFPPC_PORT_DOWN = 1 << 0 # Port is administratively down. OFPPC_NO_RECV = 1 << 2 # Drop all packets recieved by port. OFPPC_NO_FWD = 1 << 5 # Drop packets forwarded to port. OFPPC_NO_PACKET_IN = 1 << 6 # Do not send packet-in msgs for port. # enum ofp_port_state OFPPS_LINK_DOWN = 1 << 0 # No physical link present. OFPPS_BLOCKED = 1 << 1 # Port is blocked. OFPPS_LIVE = 1 << 2 # Live for Fast Failover Group. # enum ofp_port_no OFPP_MAX = 0xffffff00 OFPP_IN_PORT = 0xfffffff8 # Send the packet out the input port. This # virtual port must be explicitly used # in order to send back out of the input # port. OFPP_TABLE = 0xfffffff9 # Perform actions in flow table. # NB: This can only be the destination # port for packet-out messages. OFPP_NORMAL = 0xfffffffa # Process with normal L2/L3 switching. OFPP_FLOOD = 0xfffffffb # All physical ports except input port and # those disabled by STP. OFPP_ALL = 0xfffffffc # All physical ports except input port. OFPP_CONTROLLER = 0xfffffffd # Send to controller. OFPP_LOCAL = 0xfffffffe # Local openflow "port". OFPP_ANY = 0xffffffff # Not associated with a physical port. # All ones is used to indicate all queues in a port (for stats retrieval). OFPQ_ALL = 0xffffffff # enum ofp_port_features OFPPF_10MB_HD = 1 << 0 # 10 Mb half-duplex rate support. OFPPF_10MB_FD = 1 << 1 # 10 Mb full-duplex rate support. OFPPF_100MB_HD = 1 << 2 # 100 Mb half-duplex rate support. OFPPF_100MB_FD = 1 << 3 # 100 Mb full-duplex rate support. OFPPF_1GB_HD = 1 << 4 # 1 Gb half-duplex rate support. OFPPF_1GB_FD = 1 << 5 # 1 Gb full-duplex rate support. OFPPF_10GB_FD = 1 << 6 # 10 Gb full-duplex rate support. OFPPF_40GB_FD = 1 << 7 # 40 Gb full-duplex rate support. OFPPF_100GB_FD = 1 << 8 # 100 Gb full-duplex rate support. OFPPF_1TB_FD = 1 << 9 # 1 Tb full-duplex rate support. OFPPF_OTHER = 1 << 10 # Other rate, not in the list. OFPPF_COPPER = 1 << 11 # Copper medium. OFPPF_FIBER = 1 << 12 # Fiber medium. OFPPF_AUTONEG = 1 << 13 # Auto-negotiation. OFPPF_PAUSE = 1 << 14 # Pause. OFPPF_PAUSE_ASYM = 1 << 15 # Asymmetric pause. # struct ofp_packet_queue OFP_PACKET_QUEUE_PACK_STR = '!IIH6x' OFP_PACKET_QUEUE_SIZE = 16 assert calcsize(OFP_PACKET_QUEUE_PACK_STR) == OFP_PACKET_QUEUE_SIZE # enum ofp_queue_properties OFPQT_MIN_RATE = 1 # Minimum datarate guaranteed. OFPQT_MAX_RATE = 2 # Maximum datarate. OFPQT_EXPERIMENTER = 0xffff # Experimenter defined property. # struct ofp_queue_prop_header OFP_QUEUE_PROP_HEADER_PACK_STR = '!HH4x' OFP_QUEUE_PROP_HEADER_SIZE = 8 assert calcsize(OFP_QUEUE_PROP_HEADER_PACK_STR) == OFP_QUEUE_PROP_HEADER_SIZE # struct ofp_queue_prop_min_rate OFP_QUEUE_PROP_MIN_RATE_PACK_STR = '!H6x' OFP_QUEUE_PROP_MIN_RATE_SIZE = 16 assert (calcsize(OFP_QUEUE_PROP_MIN_RATE_PACK_STR) + OFP_QUEUE_PROP_HEADER_SIZE) == OFP_QUEUE_PROP_MIN_RATE_SIZE # struct ofp_queue_prop_max_rate OFP_QUEUE_PROP_MAX_RATE_PACK_STR = '!H6x' OFP_QUEUE_PROP_MAX_RATE_SIZE = 16 assert (calcsize(OFP_QUEUE_PROP_MAX_RATE_PACK_STR) + OFP_QUEUE_PROP_HEADER_SIZE) == OFP_QUEUE_PROP_MAX_RATE_SIZE # struct ofp_queue_prop_experimenter OFP_QUEUE_PROP_EXPERIMENTER_PACK_STR = '!I4x' OFP_QUEUE_PROP_EXPERIMENTER_SIZE = 16 assert (calcsize(OFP_QUEUE_PROP_EXPERIMENTER_PACK_STR) + OFP_QUEUE_PROP_HEADER_SIZE) == OFP_QUEUE_PROP_EXPERIMENTER_SIZE # struct ofp_match _OFP_MATCH_PACK_STR = 'HHBBBB' OFP_MATCH_PACK_STR = '!' + _OFP_MATCH_PACK_STR OFP_MATCH_SIZE = 8 assert calcsize(OFP_MATCH_PACK_STR) == OFP_MATCH_SIZE # enum ofp_match_type OFPMT_STANDARD = 0 # Deprecated OFPMT_OXM = 1 # OpenFlow Extensible Match # enum ofp_oxm_class OFPXMC_NXM_0 = 0x0000 # Backward compatibility with NXM OFPXMC_NXM_1 = 0x0001 # Backward compatibility with NXM OFPXMC_OPENFLOW_BASIC = 0x8000 # Basic class for OpenFlow OFPXMC_EXPERIMENTER = 0xFFFF # Experimenter class # enum ofp_vlan_id OFPVID_PRESENT = 0x1000 # bit that indicate that a VLAN id is set. OFPVID_NONE = 0x0000 # No VLAN id was set. # struct ofp_oxm_experimenter_header OFP_OXM_EXPERIMENTER_HEADER_PACK_STR = '!II' OFP_OXM_EXPERIMENTER_HEADER_SIZE = 8 assert (calcsize(OFP_OXM_EXPERIMENTER_HEADER_PACK_STR) == OFP_OXM_EXPERIMENTER_HEADER_SIZE) # enum ofp_instruction_type OFPIT_GOTO_TABLE = 1 # Setup the next table in the lookup pipeline. OFPIT_WRITE_METADATA = 2 # Setup the metadata field for use later in # pipeline. OFPIT_WRITE_ACTIONS = 3 # Write the action(s) onto the datapath # action set OFPIT_APPLY_ACTIONS = 4 # Applies the action(s) immediately OFPIT_CLEAR_ACTIONS = 5 # Clears all actions from the datapath action # set OFPIT_EXPERIMENTER = 0xFFFF # Experimenter instruction # struct ofp_instruction_goto_table OFP_INSTRUCTION_GOTO_TABLE_PACK_STR = '!HHB3x' OFP_INSTRUCTION_GOTO_TABLE_SIZE = 8 assert (calcsize(OFP_INSTRUCTION_GOTO_TABLE_PACK_STR) == OFP_INSTRUCTION_GOTO_TABLE_SIZE) # struct ofp_instruction_write_metadata OFP_INSTRUCTION_WRITE_METADATA_PACK_STR = '!HH4xQQ' OFP_INSTRUCTION_WRITE_METADATA_SIZE = 24 assert (calcsize(OFP_INSTRUCTION_WRITE_METADATA_PACK_STR) == OFP_INSTRUCTION_WRITE_METADATA_SIZE) # struct ofp_instaruction_actions OFP_INSTRUCTION_ACTIONS_PACK_STR = '!HH4x' OFP_INSTRUCTION_ACTIONS_SIZE = 8 assert (calcsize(OFP_INSTRUCTION_ACTIONS_PACK_STR) == OFP_INSTRUCTION_ACTIONS_SIZE) # enum ofp_action_type OFPAT_OUTPUT = 0 # Output to switch port. OFPAT_COPY_TTL_OUT = 11 # Copy TTL "outwards" -- from # next-to-outermost to outermost OFPAT_COPY_TTL_IN = 12 # Copy TTL "inwards" -- from outermost to # next-to-outermost OFPAT_SET_MPLS_TTL = 15 # MPLS TTL. OFPAT_DEC_MPLS_TTL = 16 # Decrement MPLS TTL OFPAT_PUSH_VLAN = 17 # Push a new VLAN tag OFPAT_POP_VLAN = 18 # Pop the outer VLAN tag OFPAT_PUSH_MPLS = 19 # Push a new MPLS tag OFPAT_POP_MPLS = 20 # Pop the outer MPLS tag OFPAT_SET_QUEUE = 21 # Set queue id when outputting to a port OFPAT_GROUP = 22 # Apply group OFPAT_SET_NW_TTL = 23 # IP TTL. OFPAT_DEC_NW_TTL = 24 # Decrement IP TTL. OFPAT_SET_FIELD = 25 # Set a header field using OXM TLV format. OFPAT_EXPERIMENTER = 0xffff # struct ofp_action_header OFP_ACTION_HEADER_PACK_STR = '!HH4x' OFP_ACTION_HEADER_SIZE = 8 assert calcsize(OFP_ACTION_HEADER_PACK_STR) == OFP_ACTION_HEADER_SIZE # struct ofp_action_output OFP_ACTION_OUTPUT_PACK_STR = '!HHIH6x' OFP_ACTION_OUTPUT_SIZE = 16 assert calcsize(OFP_ACTION_OUTPUT_PACK_STR) == OFP_ACTION_OUTPUT_SIZE # enum ofp_controller_max_len OFPCML_MAX = 0xffe5 # maximum max_len value which can be used to # request a specific byte length. OFPCML_NO_BUFFER = 0xffff # indicates that no buffering should be # applied and the whole packet is to be # sent to the controller. # struct ofp_action_group OFP_ACTION_GROUP_PACK_STR = '!HHI' OFP_ACTION_GROUP_SIZE = 8 assert calcsize(OFP_ACTION_GROUP_PACK_STR) == OFP_ACTION_GROUP_SIZE # struct ofp_action_set_queue OFP_ACTION_SET_QUEUE_PACK_STR = '!HHI' OFP_ACTION_SET_QUEUE_SIZE = 8 assert calcsize(OFP_ACTION_SET_QUEUE_PACK_STR) == OFP_ACTION_SET_QUEUE_SIZE # struct ofp_aciton_mpls_ttl OFP_ACTION_MPLS_TTL_PACK_STR = '!HHB3x' OFP_ACTION_MPLS_TTL_SIZE = 8 assert calcsize(OFP_ACTION_MPLS_TTL_PACK_STR) == OFP_ACTION_MPLS_TTL_SIZE # struct ofp_action_nw_ttl OFP_ACTION_NW_TTL_PACK_STR = '!HHB3x' OFP_ACTION_NW_TTL_SIZE = 8 assert calcsize(OFP_ACTION_NW_TTL_PACK_STR) == OFP_ACTION_NW_TTL_SIZE # struct ofp_action_push OFP_ACTION_PUSH_PACK_STR = '!HHH2x' OFP_ACTION_PUSH_SIZE = 8 assert calcsize(OFP_ACTION_PUSH_PACK_STR) == OFP_ACTION_PUSH_SIZE # struct ofp_action_pop_mpls OFP_ACTION_POP_MPLS_PACK_STR = '!HHH2x' OFP_ACTION_POP_MPLS_SIZE = 8 assert calcsize(OFP_ACTION_POP_MPLS_PACK_STR) == OFP_ACTION_POP_MPLS_SIZE # struct ofp_action_set_field OFP_ACTION_SET_FIELD_PACK_STR = '!HH4B' OFP_ACTION_SET_FIELD_SIZE = 8 assert calcsize(OFP_ACTION_SET_FIELD_PACK_STR) == OFP_ACTION_SET_FIELD_SIZE # struct ofp_action_experimenter_header OFP_ACTION_EXPERIMENTER_HEADER_PACK_STR = '!HHI' OFP_ACTION_EXPERIMENTER_HEADER_SIZE = 8 assert (calcsize(OFP_ACTION_EXPERIMENTER_HEADER_PACK_STR) == OFP_ACTION_EXPERIMENTER_HEADER_SIZE) # struct ofp_switch_feature OFP_SWITCH_FEATURES_PACK_STR = '!QIB3xII' OFP_SWITCH_FEATURES_SIZE = 32 assert (calcsize(OFP_SWITCH_FEATURES_PACK_STR) + OFP_HEADER_SIZE == OFP_SWITCH_FEATURES_SIZE) # enum ofp_capabilities OFPC_FLOW_STATS = 1 << 0 # Flow statistics. OFPC_TABLE_STATS = 1 << 1 # Table statistics. OFPC_PORT_STATS = 1 << 2 # Port statistics. OFPC_GROUP_STATS = 1 << 3 # Group statistics. OFPC_IP_REASM = 1 << 5 # Can reassemble IP fragments. OFPC_QUEUE_STATS = 1 << 6 # Queue statistics. OFPC_PORT_BLOCKED = 1 << 8 # Switch will block looping ports. # struct ofp_switch_config OFP_SWITCH_CONFIG_PACK_STR = '!HH' OFP_SWITCH_CONFIG_SIZE = 12 assert (calcsize(OFP_SWITCH_CONFIG_PACK_STR) + OFP_HEADER_SIZE == OFP_SWITCH_CONFIG_SIZE) # enum ofp_config_flags OFPC_FRAG_NORMAL = 0 # No special handling for fragments. OFPC_FRAG_DROP = 1 # Drop fragments. OFPC_FRAG_REASM = 2 # Reassemble (only if OFPC_IP_REASM set). OFPC_FRAG_MASK = 3 OFPC_INVALID_TTL_TO_CONTROLLER = 1 << 2 # Send packets with invalid # TTL to the controller. # enum ofp_table OFPTT_MAX = 0xfe OFPTT_ALL = 0xff # struct ofp_table_mod OFP_TABLE_MOD_PACK_STR = '!B3xI' OFP_TABLE_MOD_SIZE = 16 assert (calcsize(OFP_TABLE_MOD_PACK_STR) + OFP_HEADER_SIZE == OFP_TABLE_MOD_SIZE) # enum ofp_table_config OFPTC_TABLE_MISS_CONTROLLER = 0 OFPTC_TABLE_MISS_CONTINUE = 1 << 0 OFPTC_TABLE_MISS_DROP = 1 << 1 OFPTC_TABLE_MISS_MASK = 3 # struct ofp_flow_mod _OFP_FLOW_MOD_PACK_STR0 = 'QQBBHHHIIIH2x' OFP_FLOW_MOD_PACK_STR = '!' + _OFP_FLOW_MOD_PACK_STR0 + _OFP_MATCH_PACK_STR OFP_FLOW_MOD_PACK_STR0 = '!' + _OFP_FLOW_MOD_PACK_STR0 OFP_FLOW_MOD_SIZE = 56 assert (calcsize(OFP_FLOW_MOD_PACK_STR) + OFP_HEADER_SIZE == OFP_FLOW_MOD_SIZE) # enum ofp_flow_mod_command OFPFC_ADD = 0 # New flow. OFPFC_MODIFY = 1 # Modify all matching flows. OFPFC_MODIFY_STRICT = 2 # Modify entry strictly matching wildcards OFPFC_DELETE = 3 # Delete all matching flows. OFPFC_DELETE_STRICT = 4 # Strictly match wildcards and priority. # enum ofp_flow_mod_flags OFPFF_SEND_FLOW_REM = 1 << 0 # Send flow removed message when flow # expires or is deleted. OFPFF_CHECK_OVERLAP = 1 << 1 # Check for overlapping entries first. OFPFF_RESET_COUNTS = 1 << 2 # Reset flow packet and byte counts. # struct ofp_group_mod OFP_GROUP_MOD_PACK_STR = '!HBxI' OFP_GROUP_MOD_SIZE = 16 assert (calcsize(OFP_GROUP_MOD_PACK_STR) + OFP_HEADER_SIZE == OFP_GROUP_MOD_SIZE) # enum ofp_group OFPG_MAX = 0xffffff00 OFPG_ALL = 0xfffffffc OFPG_ANY = 0xffffffff # enum ofp_group_mod_command OFPGC_ADD = 0 # New group. OFPGC_MODIFY = 1 # Modify all matching groups. OFPGC_DELETE = 2 # Deletes all matching groups. # enum ofp_group_type OFPGT_ALL = 0 # All (multicast/broadcast) group. OFPGT_SELECT = 1 # Select group. OFPGT_INDIRECT = 2 # Indirect group. OFPGT_FF = 3 # Fast failover group. # struct ofp_bucket OFP_BUCKET_PACK_STR = '!HHII4x' OFP_BUCKET_SIZE = 16 assert calcsize(OFP_BUCKET_PACK_STR) == OFP_BUCKET_SIZE # struct ofp_port_mod OFP_PORT_MOD_PACK_STR = '!I4x' + OFP_ETH_ALEN_STR + 's' + '2xIII4x' OFP_PORT_MOD_SIZE = 40 assert calcsize(OFP_PORT_MOD_PACK_STR) + OFP_HEADER_SIZE == OFP_PORT_MOD_SIZE # sturct ofp_stats_request OFP_STATS_REQUEST_PACK_STR = '!HH4x' OFP_STATS_REQUEST_SIZE = 16 assert (calcsize(OFP_STATS_REQUEST_PACK_STR) + OFP_HEADER_SIZE == OFP_STATS_REQUEST_SIZE) # enum ofp_stats_reply_flags OFPSF_REPLY_MORE = 1 << 0 # More replies to follow. # struct ofp_stats_reply OFP_STATS_REPLY_PACK_STR = '!HH4x' OFP_STATS_REPLY_SIZE = 16 assert (calcsize(OFP_STATS_REPLY_PACK_STR) + OFP_HEADER_SIZE == OFP_STATS_REPLY_SIZE) # enum ofp_stats_types OFPST_DESC = 0 OFPST_FLOW = 1 OFPST_AGGREGATE = 2 OFPST_TABLE = 3 OFPST_PORT = 4 OFPST_QUEUE = 5 OFPST_GROUP = 6 OFPST_GROUP_DESC = 7 OFPST_GROUP_FEATURES = 8 OFPST_EXPERIMENTER = 0xffff # struct ofp_desc_stats DESC_STR_LEN = 256 DESC_STR_LEN_STR = str(DESC_STR_LEN) SERIAL_NUM_LEN = 32 SERIAL_NUM_LEN_STR = str(SERIAL_NUM_LEN) OFP_DESC_STATS_PACK_STR = '!' + \ DESC_STR_LEN_STR + 's' + \ DESC_STR_LEN_STR + 's' + \ DESC_STR_LEN_STR + 's' + \ SERIAL_NUM_LEN_STR + 's' + \ DESC_STR_LEN_STR + 's' OFP_DESC_STATS_SIZE = 1056 assert calcsize(OFP_DESC_STATS_PACK_STR) == OFP_DESC_STATS_SIZE # struct ofp_flow_stats_request OFP_FLOW_STATS_REQUEST_PACK_STR = '!B3xII4xQQ' OFP_FLOW_STATS_REQUEST_SIZE = 40 assert (calcsize(OFP_FLOW_STATS_REQUEST_PACK_STR) + OFP_MATCH_SIZE == OFP_FLOW_STATS_REQUEST_SIZE) # struct ofp_flow_stats OFP_FLOW_STATS_PACK_STR = '!HBxIIHHH6xQQQ' OFP_FLOW_STATS_SIZE = 56 assert (calcsize(OFP_FLOW_STATS_PACK_STR) + OFP_MATCH_SIZE == OFP_FLOW_STATS_SIZE) # struct ofp_aggregate_stats_request OFP_AGGREGATE_STATS_REQUEST_PACK_STR = '!B3xII4xQQ' OFP_AGGREGATE_STATS_REQUEST_SIZE = 40 assert (calcsize(OFP_AGGREGATE_STATS_REQUEST_PACK_STR) + OFP_MATCH_SIZE == OFP_AGGREGATE_STATS_REQUEST_SIZE) # struct ofp_aggregate_stats_reply OFP_AGGREGATE_STATS_REPLY_PACK_STR = '!QQI4x' OFP_AGGREGATE_STATS_REPLY_SIZE = 24 assert (calcsize(OFP_AGGREGATE_STATS_REPLY_PACK_STR) == OFP_AGGREGATE_STATS_REPLY_SIZE) # sturct ofp_table_stats OFP_TABLE_STATS_SIZE = 128 OFP_MAX_TABLE_NAME_LEN = 32 OFP_MAX_TABLE_NAME_LEN_STR = str(OFP_MAX_TABLE_NAME_LEN) OFP_TABLE_STATS_PACK_STR = '!B7x' + OFP_MAX_TABLE_NAME_LEN_STR + \ 'sQQIIQQQQIIIIQQ' assert calcsize(OFP_TABLE_STATS_PACK_STR) == OFP_TABLE_STATS_SIZE # struct ofp_port_stats_request OFP_PORT_STATS_REQUEST_PACK_STR = '!I4x' OFP_PORT_STATS_REQUEST_SIZE = 8 assert calcsize(OFP_PORT_STATS_REQUEST_PACK_STR) == OFP_PORT_STATS_REQUEST_SIZE # struct ofp_port_stats OFP_PORT_STATS_PACK_STR = '!I4xQQQQQQQQQQQQ' OFP_PORT_STATS_SIZE = 104 assert calcsize(OFP_PORT_STATS_PACK_STR) == OFP_PORT_STATS_SIZE # struct ofp_queue_stats_request OFP_QUEUE_STATS_REQUEST_PACK_STR = '!II' OFP_QUEUE_STATS_REQUEST_SIZE = 8 assert (calcsize(OFP_QUEUE_STATS_REQUEST_PACK_STR) == OFP_QUEUE_STATS_REQUEST_SIZE) # struct ofp_queue_stats OFP_QUEUE_STATS_PACK_STR = '!IIQQQ' OFP_QUEUE_STATS_SIZE = 32 assert calcsize(OFP_QUEUE_STATS_PACK_STR) == OFP_QUEUE_STATS_SIZE # struct ofp_group_stats_request OFP_GROUP_STATS_REQUEST_PACK_STR = '!I4x' OFP_GROUP_STATS_REQUEST_SIZE = 8 assert (calcsize(OFP_GROUP_STATS_REQUEST_PACK_STR) == OFP_GROUP_STATS_REQUEST_SIZE) # struct ofp_group_stats OFP_GROUP_STATS_PACK_STR = '!H2xII4xQQ' OFP_GROUP_STATS_SIZE = 32 assert calcsize(OFP_GROUP_STATS_PACK_STR) == OFP_GROUP_STATS_SIZE # struct ofp_bucket_counter OFP_BUCKET_COUNTER_PACK_STR = '!QQ' OFP_BUCKET_COUNTER_SIZE = 16 assert calcsize(OFP_BUCKET_COUNTER_PACK_STR) == OFP_BUCKET_COUNTER_SIZE # struct ofp_group_desc_stats OFP_GROUP_DESC_STATS_PACK_STR = '!HBxI' OFP_GROUP_DESC_STATS_SIZE = 8 assert calcsize(OFP_GROUP_DESC_STATS_PACK_STR) == OFP_GROUP_DESC_STATS_SIZE # struct ofp_group_features_stats OFP_GROUP_FEATURES_STATS_PACK_STR = '!II4I4I' OFP_GROUP_FEATURES_STATS_SIZE = 40 assert (calcsize(OFP_GROUP_FEATURES_STATS_PACK_STR) == OFP_GROUP_FEATURES_STATS_SIZE) # enmu ofp_group_capabilities OFPGFC_SELECT_WEIGHT = 1 << 0 # Support weight for select groups. OFPGFC_SELECT_LIVENESS = 1 << 1 # Support liveness for select groups. OFPGFC_CHAINING = 1 << 2 # Support chaining groups. OFPGFC_CHAINING_CHECKS = 1 << 3 # Check chaining for loops and delete # struct ofp_experimenter_stats_header OFP_EXPERIMENTER_STATS_HEADER_PACK_STR = '!II' OFP_EXPERIMENTER_STATS_HEADER_SIZE = 8 assert (calcsize(OFP_EXPERIMENTER_STATS_HEADER_PACK_STR) == OFP_EXPERIMENTER_STATS_HEADER_SIZE) # struct opf_queue_get_config_request OFP_QUEUE_GET_CONFIG_REQUEST_PACK_STR = '!I4x' OFP_QUEUE_GET_CONFIG_REQUEST_SIZE = 16 assert (calcsize(OFP_QUEUE_GET_CONFIG_REQUEST_PACK_STR) + OFP_HEADER_SIZE == OFP_QUEUE_GET_CONFIG_REQUEST_SIZE) # struct ofp_queue_get_config_reply OFP_QUEUE_GET_CONFIG_REPLY_PACK_STR = '!I4x' OFP_QUEUE_GET_CONFIG_REPLY_SIZE = 16 assert (calcsize(OFP_QUEUE_GET_CONFIG_REPLY_PACK_STR) + OFP_HEADER_SIZE == OFP_QUEUE_GET_CONFIG_REPLY_SIZE) # struct ofp_packet_out OFP_PACKET_OUT_PACK_STR = '!IIH6x' OFP_PACKET_OUT_SIZE = 24 assert (calcsize(OFP_PACKET_OUT_PACK_STR) + OFP_HEADER_SIZE == OFP_PACKET_OUT_SIZE) # struct ofp_role_request OFP_ROLE_REQUEST_PACK_STR = '!I4xQ' OFP_ROLE_REQUEST_SIZE = 24 assert (calcsize(OFP_ROLE_REQUEST_PACK_STR) + OFP_HEADER_SIZE == OFP_ROLE_REQUEST_SIZE) # enum ofp_controller_role OFPCR_ROLE_NOCHANGE = 0 # Don't change current role. OFPCR_ROLE_EQUAL = 1 # Default role, full access. OFPCR_ROLE_MASTER = 2 # Full access, at most one master. OFPCR_ROLE_SLAVE = 3 # Read-only access. # struct ofp_packet_in OFP_PACKET_IN_PACK_STR = '!IHBB' OFP_PACKET_IN_SIZE = 24 assert (calcsize(OFP_PACKET_IN_PACK_STR) + OFP_MATCH_SIZE + OFP_HEADER_SIZE == OFP_PACKET_IN_SIZE) # enum ofp_packet_in_reason OFPR_NO_MATCH = 0 # No matching flow. OFPR_ACTION = 1 # Action explicitly output to controller. OFPR_INVALID_TTL = 2 # Packet has invalid TTL. # struct ofp_flow_removed _OFP_FLOW_REMOVED_PACK_STR0 = 'QHBBIIHHQQ' OFP_FLOW_REMOVED_PACK_STR = '!' + _OFP_FLOW_REMOVED_PACK_STR0 + \ _OFP_MATCH_PACK_STR OFP_FLOW_REMOVED_PACK_STR0 = '!' + _OFP_FLOW_REMOVED_PACK_STR0 OFP_FLOW_REMOVED_SIZE = 56 assert (calcsize(OFP_FLOW_REMOVED_PACK_STR) + OFP_HEADER_SIZE == OFP_FLOW_REMOVED_SIZE) # enum ofp_flow_removed_reason OFPRR_IDLE_TIMEOUT = 0 # Flow idle time exceeded idle_timeout. OFPRR_HARD_TIMEOUT = 1 # Time exceeded hard_timeout. OFPRR_DELETE = 2 # Evicted by a DELETE flow mod. OFPRR_GROUP_DELETE = 3 # Group was removed. # struct ofp_port_status OFP_PORT_STATUS_PACK_STR = '!B7x' + _OFP_PORT_PACK_STR OFP_PORT_STATUS_DESC_OFFSET = OFP_HEADER_SIZE + 8 OFP_PORT_STATUS_SIZE = 80 assert (calcsize(OFP_PORT_STATUS_PACK_STR) + OFP_HEADER_SIZE == OFP_PORT_STATUS_SIZE) # enum ofp_port_reason OFPPR_ADD = 0 # The port was added. OFPPR_DELETE = 1 # The port was removed. OFPPR_MODIFY = 2 # Some attribute of the port has changed. # struct ofp_error_msg OFP_ERROR_MSG_PACK_STR = '!HH' OFP_ERROR_MSG_SIZE = 12 assert calcsize(OFP_ERROR_MSG_PACK_STR) + OFP_HEADER_SIZE == OFP_ERROR_MSG_SIZE # enum ofp_error_type OFPET_HELLO_FAILED = 0 # Hello protocol failed. OFPET_BAD_REQUEST = 1 # Request was not understood. OFPET_BAD_ACTION = 2 # Error in action description. OFPET_BAD_INSTRUCTION = 3 # Error in instruction list. OFPET_BAD_MATCH = 4 # Error in match. OFPET_FLOW_MOD_FAILED = 5 # Problem modifying flow entry. OFPET_GROUP_MOD_FAILED = 6 # Problem modifying group entry. OFPET_PORT_MOD_FAILED = 7 # OFPT_PORT_MOD failed. OFPET_TABLE_MOD_FAILED = 8 # Table mod request failed. OFPET_QUEUE_OP_FAILED = 9 # Queue operation failed. OFPET_SWITCH_CONFIG_FAILED = 10 # Switch config request failed. OFPET_ROLE_REQUEST_FAILED = 11 # Controller Role request failed. OFPET_EXPERIMENTER = 0xffff # Experimenter error messages. # enum ofp_hello_failed_code OFPHFC_INCOMPATIBLE = 0 # No compatible version. OFPHFC_EPERM = 1 # Permissions error. # enum ofp_bad_request_code OFPBRC_BAD_VERSION = 0 # ofp_header.version not supported. OFPBRC_BAD_TYPE = 1 # ofp_header.type not supported. OFPBRC_BAD_STAT = 2 # ofp_stats_msg.type not supported. OFPBRC_BAD_EXPERIMENTER = 3 # Experimenter id not supported # (in ofp_experimenter_header # or ofp_stats_request or ofp_stats_reply). OFPBRC_BAD_EXP_TYPE = 4 # Experimenter type not supported. OFPBRC_EPERM = 5 # Permissions error. OFPBRC_BAD_LEN = 6 # Wrong request length for type. OFPBRC_BUFFER_EMPTY = 7 # Specified buffer has already been used. OFPBRC_BUFFER_UNKNOWN = 8 # Specified buffer does not exist. OFPBRC_BAD_TABLE_ID = 9 # Specified table-id invalid or does not exist. OFPBRC_IS_SLAVE = 10 # Denied because controller is slave. OFPBRC_BAD_PORT = 11 # Invalid port. OFPBRC_BAD_PACKET = 12 # Invalid packet in packet-out # enum ofp_bad_action_code OFPBAC_BAD_TYPE = 0 # Unknown action type. OFPBAC_BAD_LEN = 1 # Length problem in actions. OFPBAC_BAD_EXPERIMENTER = 2 # Unknown experimenter id specified. OFPBAC_BAD_EXP_TYPE = 3 # Unknown action type for experimenter id. OFPBAC_BAD_OUT_PORT = 4 # Problem validating output action. OFPBAC_BAD_ARGUMENT = 5 # Bad action argument. OFPBAC_EPERM = 6 # Permissions error. OFPBAC_TOO_MANY = 7 # Can't handle this many actions. OFPBAC_BAD_QUEUE = 8 # Problem validating output queue. OFPBAC_BAD_OUT_GROUP = 9 # Invalid group id in forward action. OFPBAC_MATCH_INCONSISTENT = 10 # Action can't apply for this match, # or Set-Field missing prerequisite. OFPBAC_UNSUPPORTED_ORDER = 11 # Action order is unsupported for # the action list in an Apply-Actions # instruction OFPBAC_BAD_TAG = 12 # Actions uses an unsupported tag/encap. OFPBAC_BAD_SET_TYPE = 13 # Unsupported type in SET_FIELD action. OFPBAC_BAD_SET_LEN = 14 # Length problem in SET_FIELD action. OFPBAC_BAD_SET_ARGUMENT = 15 # Bad arguement in SET_FIELD action. # enum ofp_bad_instruction_code OFPBIC_UNKNOWN_INST = 0 # Unknown instruction. OFPBIC_UNSUP_INST = 1 # Switch or table does not support # the instruction. OFPBIC_BAD_TABLE_ID = 2 # Invalid Table-Id specified OFPBIC_UNSUP_METADATA = 3 # Metadata value unsupported by datapath. OFPBIC_UNSUP_METADATA_MASK = 4 # Metadata mask value unsupported by # datapath. OFPBIC_BAD_EXPERIMENTER = 5 # Unknown experimenter id specified. OFPBIC_BAD_EXP_TYPE = 6 # Unknown instruction for experimenter id. OFPBIC_BAD_LEN = 7 # Length problem in instrucitons. OFPBIC_EPERM = 8 # Permissions error. # enum ofp_bad_match_code OFPBMC_BAD_TYPE = 0 # Unsupported match type apecified by # the match. OFPBMC_BAD_LEN = 1 # Length problem in math. OFPBMC_BAD_TAG = 2 # Match uses an unsupported tag/encap. OFPBMC_BAD_DL_ADDR_MASK = 3 # Unsupported datalink addr mask - # switch does not support arbitrary # datalink address mask. OFPBMC_BAD_NW_ADDR_MASK = 4 # Unsupported network addr mask - # switch does not support arbitrary # network addres mask. OFPBMC_BAD_WILDCARDS = 5 # Unsupported combination of fields # masked or omitted in the match. OFPBMC_BAD_FIELD = 6 # Unsupported field type in the match. OFPBMC_BAD_VALUE = 7 # Unsupported value in a match field. OFPBMC_BAD_MASK = 8 # Unsupported mask specified in the # match. OFPBMC_BAD_PREREQ = 9 # A prerequisite was not met. OFPBMC_DUP_FIELD = 10 # A field type was duplicated. OFPBMC_EPERM = 11 # Permissions error. # enum ofp_flow_mod_failed_code OFPFMFC_UNKNOWN = 0 # Unspecified error. OFPFMFC_TABLE_FULL = 1 # Flow not added because table was full. OFPFMFC_BAD_TABLE_ID = 2 # Table does not exist OFPFMFC_OVERLAP = 3 # Attempted to add overlapping flow # with CHECK_OVERLAP flag set. OFPFMFC_EPERM = 4 # Permissions error. OFPFMFC_BAD_TIMEOUT = 5 # Flow not added because of # unsupported idle/hard timeout. OFPFMFC_BAD_COMMAND = 6 # Unsupported or unknown command. OFPFMFC_BAD_FLAGS = 7 # Unsupported or unknown flags. # enum ofp_group_mod_failed_code OFPGMFC_GROUP_EXISTS = 0 OFPGMFC_INVALID_GROUP = 1 OFPGMFC_WEIGHT_UNSUPPORTED = 2 # Switch does not support unequal load # sharing with select groups. OFPGMFC_OUT_OF_GROUPS = 3 # The group table is full. OFPGMFC_OUT_OF_BUCKETS = 4 # The maximum number of action buckets # for a group has been exceeded. OFPGMFC_CHAINING_UNSUPPORTED = 5 # Switch does not support groups that # forward to groups. OFPGMFC_WATCH_UNSUPPORTED = 6 # This group cannot watch the # watch_port or watch_group specified. OFPGMFC_LOOP = 7 # Group entry would cause a loop. OFPGMFC_UNKNOWN_GROUP = 8 # Group not modified because a group # MODIFY attempted to modify a # non-existent group. OFPGMFC_CHAINED_GROUP = 9 # Group not deleted because another # group is forwarding to it. OFPGMFC_BAD_TYPE = 10 # Unsupported or unknown group type. OFPGMFC_BAD_COMMAND = 11 # Unsupported or unknown command. OFPGMFC_BAD_BUCKET = 12 # Error in bucket. OFPGMFC_BAD_WATCH = 13 # Error in watch port/group. OFPGMFC_EPERM = 14 # Permissions error. # enum ofp_port_mod_failed_code OFPPMFC_BAD_PORT = 0 # Specified port does not exist. OFPPMFC_BAD_HW_ADDR = 1 # Specified hardware address does not # match the port number. OFPPMFC_BAD_CONFIG = 2 # Specified config is invalid. OFPPMFC_BAD_ADVERTISE = 3 # Specified advertise is invalid. OFPPMFC_EPERM = 4 # Permissions error. # enum ofp_table_mod_failed_code OFPTMFC_BAD_TABLE = 0 # Specified table does not exist. OFPTMFC_BAD_CONFIG = 1 # Specified config is invalid. OFPTMFC_EPERM = 2 # Permissions error # enum ofp_queue_op_failed_code OFPQOFC_BAD_PORT = 0 # Invalid port (or port does not exist). OFPQOFC_BAD_QUEUE = 1 # Queue does not exist. OFPQOFC_EPERM = 2 # Permissions error. # enum ofp_switch_config_failed_code OFPSCFC_BAD_FLAGS = 0 # Specified flags is invalid. OFPSCFC_BAD_LEN = 1 # Specified len is invalid. OFPQCFC_EPERM = 2 # Permissions error (depracated). # New or updated OSKen applications shall use # OFPSCFC_EPERM. The variable name is a typo of # in specifications before v1.3.1 (EXT-208). OFPSCFC_EPERM = 2 # Permissions error. # Ported back to ofproto_v1_2 for consistency with # later OF specs (EXT-208). # enum ofp_role_request_failed_code OFPRRFC_STALE = 0 # Stale Message: old generation_id. OFPRRFC_UNSUP = 1 # Controller role change unsupported. OFPRRFC_BAD_ROLE = 2 # Invalid role. # struct ofp_error_experimenter_msg OFP_ERROR_EXPERIMENTER_MSG_PACK_STR = '!HHI' OFP_ERROR_EXPERIMENTER_MSG_SIZE = 16 assert (calcsize(OFP_ERROR_EXPERIMENTER_MSG_PACK_STR) + OFP_HEADER_SIZE == OFP_ERROR_EXPERIMENTER_MSG_SIZE) # struct ofp_experimenter_header OFP_EXPERIMENTER_HEADER_PACK_STR = '!II' OFP_EXPERIMENTER_HEADER_SIZE = 16 assert (calcsize(OFP_EXPERIMENTER_HEADER_PACK_STR) + OFP_HEADER_SIZE == OFP_EXPERIMENTER_HEADER_SIZE) # OXM def _oxm_tlv_header(class_, field, hasmask, length): return (class_ << 16) | (field << 9) | (hasmask << 8) | length def oxm_tlv_header(field, length): return _oxm_tlv_header(OFPXMC_OPENFLOW_BASIC, field, 0, length) def oxm_tlv_header_w(field, length): return _oxm_tlv_header(OFPXMC_OPENFLOW_BASIC, field, 1, length * 2) def oxm_tlv_header_extract_hasmask(header): return (header >> 8) & 1 def oxm_tlv_header_extract_length(header): if oxm_tlv_header_extract_hasmask(header): length = (header & 0xff) // 2 else: length = header & 0xff return length oxm_types = [ oxm_fields.OpenFlowBasic('in_port', 0, type_desc.Int4), oxm_fields.OpenFlowBasic('in_phy_port', 1, type_desc.Int4), oxm_fields.OpenFlowBasic('metadata', 2, type_desc.Int8), oxm_fields.OpenFlowBasic('eth_dst', 3, type_desc.MacAddr), oxm_fields.OpenFlowBasic('eth_src', 4, type_desc.MacAddr), oxm_fields.OpenFlowBasic('eth_type', 5, type_desc.Int2), oxm_fields.OpenFlowBasic('vlan_vid', 6, type_desc.Int2), oxm_fields.OpenFlowBasic('vlan_pcp', 7, type_desc.Int1), oxm_fields.OpenFlowBasic('ip_dscp', 8, type_desc.Int1), oxm_fields.OpenFlowBasic('ip_ecn', 9, type_desc.Int1), oxm_fields.OpenFlowBasic('ip_proto', 10, type_desc.Int1), oxm_fields.OpenFlowBasic('ipv4_src', 11, type_desc.IPv4Addr), oxm_fields.OpenFlowBasic('ipv4_dst', 12, type_desc.IPv4Addr), oxm_fields.OpenFlowBasic('tcp_src', 13, type_desc.Int2), oxm_fields.OpenFlowBasic('tcp_dst', 14, type_desc.Int2), oxm_fields.OpenFlowBasic('udp_src', 15, type_desc.Int2), oxm_fields.OpenFlowBasic('udp_dst', 16, type_desc.Int2), oxm_fields.OpenFlowBasic('sctp_src', 17, type_desc.Int2), oxm_fields.OpenFlowBasic('sctp_dst', 18, type_desc.Int2), oxm_fields.OpenFlowBasic('icmpv4_type', 19, type_desc.Int1), oxm_fields.OpenFlowBasic('icmpv4_code', 20, type_desc.Int1), oxm_fields.OpenFlowBasic('arp_op', 21, type_desc.Int2), oxm_fields.OpenFlowBasic('arp_spa', 22, type_desc.IPv4Addr), oxm_fields.OpenFlowBasic('arp_tpa', 23, type_desc.IPv4Addr), oxm_fields.OpenFlowBasic('arp_sha', 24, type_desc.MacAddr), oxm_fields.OpenFlowBasic('arp_tha', 25, type_desc.MacAddr), oxm_fields.OpenFlowBasic('ipv6_src', 26, type_desc.IPv6Addr), oxm_fields.OpenFlowBasic('ipv6_dst', 27, type_desc.IPv6Addr), oxm_fields.OpenFlowBasic('ipv6_flabel', 28, type_desc.Int4), oxm_fields.OpenFlowBasic('icmpv6_type', 29, type_desc.Int1), oxm_fields.OpenFlowBasic('icmpv6_code', 30, type_desc.Int1), oxm_fields.OpenFlowBasic('ipv6_nd_target', 31, type_desc.IPv6Addr), oxm_fields.OpenFlowBasic('ipv6_nd_sll', 32, type_desc.MacAddr), oxm_fields.OpenFlowBasic('ipv6_nd_tll', 33, type_desc.MacAddr), oxm_fields.OpenFlowBasic('mpls_label', 34, type_desc.Int4), oxm_fields.OpenFlowBasic('mpls_tc', 35, type_desc.Int1), # EXT-256 Old version of ONF Extension oxm_fields.OldONFExperimenter('pbb_uca', 2560, type_desc.Int1), # EXT-109 TCP flags match field Extension oxm_fields.ONFExperimenter('tcp_flags', 42, type_desc.Int2), # EXT-233 Output match Extension # NOTE(yamamoto): The spec says uint64_t but I assume it's an error. oxm_fields.ONFExperimenter('actset_output', 43, type_desc.Int4), ] + nicira_ext.oxm_types oxm_fields.generate(__name__) # generate utility methods ofproto_utils.generate(__name__) # define constants OFP_VERSION = 0x03 OFP_TCP_PORT = 6633 MAX_XID = 0xffffffff OFP_NO_BUFFER = 0xffffffff ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/ofproto/ofproto_v1_2_parser.py0000664000175000017500000050273000000000000022233 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2012 Isaku Yamahata # # 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. """ Decoder/Encoder implementations of OpenFlow 1.2. """ import struct import base64 from os_ken.lib import addrconv from os_ken.lib import mac from os_ken.lib.pack_utils import msg_pack_into from os_ken.lib.packet import packet from os_ken import utils from os_ken.ofproto.ofproto_parser import StringifyMixin, MsgBase from os_ken.ofproto import ether from os_ken.ofproto import ofproto_parser from os_ken.ofproto import ofproto_v1_2 as ofproto import logging LOG = logging.getLogger('os_ken.ofproto.ofproto_v1_2_parser') _MSG_PARSERS = {} def _set_msg_type(msg_type): def _set_cls_msg_type(cls): cls.cls_msg_type = msg_type return cls return _set_cls_msg_type def _register_parser(cls): '''class decorator to register msg parser''' assert cls.cls_msg_type is not None assert cls.cls_msg_type not in _MSG_PARSERS _MSG_PARSERS[cls.cls_msg_type] = cls.parser return cls @ofproto_parser.register_msg_parser(ofproto.OFP_VERSION) def msg_parser(datapath, version, msg_type, msg_len, xid, buf): parser = _MSG_PARSERS.get(msg_type) return parser(datapath, version, msg_type, msg_len, xid, buf) @_register_parser @_set_msg_type(ofproto.OFPT_HELLO) class OFPHello(MsgBase): """ Hello message When connection is started, the hello message is exchanged between a switch and a controller. This message is handled by the OSKen framework, so the OSKen application do not need to process this typically. """ def __init__(self, datapath): super(OFPHello, self).__init__(datapath) @_register_parser @_set_msg_type(ofproto.OFPT_ERROR) class OFPErrorMsg(MsgBase): """ Error message The switch notifies controller of problems by this message. ========== ========================================================= Attribute Description ========== ========================================================= type High level type of error code Details depending on the type data Variable length data depending on the type and code ========== ========================================================= ``type`` attribute corresponds to ``type_`` parameter of __init__. Types and codes are defined in ``os_ken.ofproto.ofproto``. ============================= =========== Type Code ============================= =========== OFPET_HELLO_FAILED OFPHFC_* OFPET_BAD_REQUEST OFPBRC_* OFPET_BAD_ACTION OFPBAC_* OFPET_BAD_INSTRUCTION OFPBIC_* OFPET_BAD_MATCH OFPBMC_* OFPET_FLOW_MOD_FAILED OFPFMFC_* OFPET_GROUP_MOD_FAILED OFPGMFC_* OFPET_PORT_MOD_FAILED OFPPMFC_* OFPET_TABLE_MOD_FAILED OFPTMFC_* OFPET_QUEUE_OP_FAILED OFPQOFC_* OFPET_SWITCH_CONFIG_FAILED OFPSCFC_* OFPET_ROLE_REQUEST_FAILED OFPRRFC_* OFPET_EXPERIMENTER N/A ============================= =========== If ``type == OFPET_EXPERIMENTER``, this message has also the following attributes. ============= ====================================================== Attribute Description ============= ====================================================== exp_type Experimenter defined type experimenter Experimenter ID ============= ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPErrorMsg, [HANDSHAKE_DISPATCHER, CONFIG_DISPATCHER, MAIN_DISPATCHER]) def error_msg_handler(self, ev): msg = ev.msg self.logger.debug('OFPErrorMsg received: type=0x%02x code=0x%02x ' 'message=%s', msg.type, msg.code, utils.hex_array(msg.data)) """ def __init__(self, datapath, type_=None, code=None, data=None, **kwargs): super(OFPErrorMsg, self).__init__(datapath) self.type = type_ self.code = code if isinstance(data, str): data = data.encode('ascii') self.data = data if self.type == ofproto.OFPET_EXPERIMENTER: self.exp_type = kwargs.get('exp_type', None) self.experimenter = kwargs.get('experimenter', None) @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): type_, = struct.unpack_from('!H', bytes(buf), ofproto.OFP_HEADER_SIZE) msg = super(OFPErrorMsg, cls).parser(datapath, version, msg_type, msg_len, xid, buf) if type_ == ofproto.OFPET_EXPERIMENTER: (msg.type, msg.exp_type, msg.experimenter, msg.data) = cls.parse_experimenter_body(buf) else: (msg.type, msg.code, msg.data) = cls.parse_body(buf) return msg @classmethod def parse_body(cls, buf): type_, code = struct.unpack_from( ofproto.OFP_ERROR_MSG_PACK_STR, buf, ofproto.OFP_HEADER_SIZE) data = buf[ofproto.OFP_ERROR_MSG_SIZE:] return type_, code, data @classmethod def parse_experimenter_body(cls, buf): type_, exp_type, experimenter = struct.unpack_from( ofproto.OFP_ERROR_EXPERIMENTER_MSG_PACK_STR, buf, ofproto.OFP_HEADER_SIZE) data = buf[ofproto.OFP_ERROR_EXPERIMENTER_MSG_SIZE:] return type_, exp_type, experimenter, data def _serialize_body(self): assert self.data is not None if self.type == ofproto.OFPET_EXPERIMENTER: msg_pack_into(ofproto.OFP_ERROR_EXPERIMENTER_MSG_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.type, self.exp_type, self.experimenter) self.buf += self.data else: msg_pack_into(ofproto.OFP_ERROR_MSG_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.type, self.code) self.buf += self.data # For the backward compatibility def OFPErrorExperimenterMsg(datapath, type_=None, exp_type=None, experimenter=None, data=None): msg = OFPErrorMsg(datapath, data=data) msg.type = ofproto.OFPET_EXPERIMENTER msg.exp_type = exp_type msg.experimenter = experimenter return msg @_register_parser @_set_msg_type(ofproto.OFPT_ECHO_REQUEST) class OFPEchoRequest(MsgBase): """ Echo request message This message is handled by the OSKen framework, so the OSKen application do not need to process this typically. ========== ========================================================= Attribute Description ========== ========================================================= data An arbitrary length data ========== ========================================================= Example:: def send_echo_request(self, datapath, data): ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPEchoRequest(datapath, data) datapath.send_msg(req) @set_ev_cls(ofp_event.EventOFPEchoRequest, [HANDSHAKE_DISPATCHER, CONFIG_DISPATCHER, MAIN_DISPATCHER]) def echo_request_handler(self, ev): self.logger.debug('OFPEchoRequest received: data=%s', utils.hex_array(ev.msg.data)) """ def __init__(self, datapath, data=None): super(OFPEchoRequest, self).__init__(datapath) self.data = data @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPEchoRequest, cls).parser(datapath, version, msg_type, msg_len, xid, buf) msg.data = msg.buf[ofproto.OFP_HEADER_SIZE:] return msg def _serialize_body(self): if self.data is not None: self.buf += self.data @_register_parser @_set_msg_type(ofproto.OFPT_ECHO_REPLY) class OFPEchoReply(MsgBase): """ Echo reply message This message is handled by the OSKen framework, so the OSKen application do not need to process this typically. ========== ========================================================= Attribute Description ========== ========================================================= data An arbitrary length data ========== ========================================================= Example:: def send_echo_reply(self, datapath, data): ofp_parser = datapath.ofproto_parser reply = ofp_parser.OFPEchoReply(datapath, data) datapath.send_msg(reply) @set_ev_cls(ofp_event.EventOFPEchoReply, [HANDSHAKE_DISPATCHER, CONFIG_DISPATCHER, MAIN_DISPATCHER]) def echo_reply_handler(self, ev): self.logger.debug('OFPEchoReply received: data=%s', utils.hex_array(ev.msg.data)) """ def __init__(self, datapath, data=None): super(OFPEchoReply, self).__init__(datapath) self.data = data @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPEchoReply, cls).parser(datapath, version, msg_type, msg_len, xid, buf) msg.data = msg.buf[ofproto.OFP_HEADER_SIZE:] return msg def _serialize_body(self): assert self.data is not None self.buf += self.data @_register_parser @_set_msg_type(ofproto.OFPT_EXPERIMENTER) class OFPExperimenter(MsgBase): """ Experimenter extension message ============= ========================================================= Attribute Description ============= ========================================================= experimenter Experimenter ID exp_type Experimenter defined data Experimenter defined arbitrary additional data ============= ========================================================= """ def __init__(self, datapath, experimenter=None, exp_type=None, data=None): super(OFPExperimenter, self).__init__(datapath) self.experimenter = experimenter self.exp_type = exp_type self.data = data @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPExperimenter, cls).parser(datapath, version, msg_type, msg_len, xid, buf) (msg.experimenter, msg.exp_type) = struct.unpack_from( ofproto.OFP_EXPERIMENTER_HEADER_PACK_STR, msg.buf, ofproto.OFP_HEADER_SIZE) msg.data = msg.buf[ofproto.OFP_EXPERIMENTER_HEADER_SIZE:] return msg def _serialize_body(self): assert self.data is not None msg_pack_into(ofproto.OFP_EXPERIMENTER_HEADER_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.experimenter, self.exp_type) self.buf += self.data class OFPPort(ofproto_parser.namedtuple('OFPPort', ( 'port_no', 'hw_addr', 'name', 'config', 'state', 'curr', 'advertised', 'supported', 'peer', 'curr_speed', 'max_speed'))): """ Description of a port ========== ========================================================= Attribute Description ========== ========================================================= port_no Port number and it uniquely identifies a port within a switch. hw_addr MAC address for the port. name Null-terminated string containing a human-readable name for the interface. config Bitmap of port configuration flags. | OFPPC_PORT_DOWN | OFPPC_NO_RECV | OFPPC_NO_FWD | OFPPC_NO_PACKET_IN state Bitmap of port state flags. | OFPPS_LINK_DOWN | OFPPS_BLOCKED | OFPPS_LIVE curr Current features. advertised Features being advertised by the port. supported Features supported by the port. peer Features advertised by peer. curr_speed Current port bitrate in kbps. max_speed Max port bitrate in kbps. ========== ========================================================= """ _TYPE = { 'ascii': [ 'hw_addr', ], 'utf-8': [ # OF spec is unclear about the encoding of name. # we assumes UTF-8, which is used by OVS. 'name', ] } @classmethod def parser(cls, buf, offset): port = struct.unpack_from(ofproto.OFP_PORT_PACK_STR, buf, offset) port = list(port) i = cls._fields.index('hw_addr') port[i] = addrconv.mac.bin_to_text(port[i]) i = cls._fields.index('name') port[i] = port[i].rstrip(b'\0') return cls(*port) @_set_msg_type(ofproto.OFPT_FEATURES_REQUEST) class OFPFeaturesRequest(MsgBase): """ Features request message The controller sends a feature request to the switch upon session establishment. This message is handled by the OSKen framework, so the OSKen application do not need to process this typically. Example:: def send_features_request(self, datapath): ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPFeaturesRequest(datapath) datapath.send_msg(req) """ def __init__(self, datapath): super(OFPFeaturesRequest, self).__init__(datapath) @_register_parser @_set_msg_type(ofproto.OFPT_FEATURES_REPLY) class OFPSwitchFeatures(MsgBase): """ Features reply message The switch responds with a features reply message to a features request. This message is handled by the OSKen framework, so the OSKen application do not need to process this typically. Example:: @set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER) def switch_features_handler(self, ev): msg = ev.msg self.logger.debug('OFPSwitchFeatures received: ' 'datapath_id=0x%016x n_buffers=%d ' 'n_tables=%d capabilities=0x%08x ports=%s', msg.datapath_id, msg.n_buffers, msg.n_tables, msg.capabilities, msg.ports) """ def __init__(self, datapath, datapath_id=None, n_buffers=None, n_tables=None, capabilities=None, ports=None): super(OFPSwitchFeatures, self).__init__(datapath) self.datapath_id = datapath_id self.n_buffers = n_buffers self.n_tables = n_tables self.capabilities = capabilities self.ports = ports @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPSwitchFeatures, cls).parser(datapath, version, msg_type, msg_len, xid, buf) (msg.datapath_id, msg.n_buffers, msg.n_tables, msg.capabilities, msg._reserved) = struct.unpack_from( ofproto.OFP_SWITCH_FEATURES_PACK_STR, msg.buf, ofproto.OFP_HEADER_SIZE) msg.ports = {} n_ports = ((msg_len - ofproto.OFP_SWITCH_FEATURES_SIZE) // ofproto.OFP_PORT_SIZE) offset = ofproto.OFP_SWITCH_FEATURES_SIZE for i in range(n_ports): port = OFPPort.parser(msg.buf, offset) msg.ports[port.port_no] = port offset += ofproto.OFP_PORT_SIZE return msg @_set_msg_type(ofproto.OFPT_GET_CONFIG_REQUEST) class OFPGetConfigRequest(MsgBase): """ Get config request message The controller sends a get config request to query configuration parameters in the switch. Example:: def send_get_config_request(self, datapath): ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPGetConfigRequest(datapath) datapath.send_msg(req) """ def __init__(self, datapath): super(OFPGetConfigRequest, self).__init__(datapath) @_register_parser @_set_msg_type(ofproto.OFPT_GET_CONFIG_REPLY) class OFPGetConfigReply(MsgBase): """ Get config reply message The switch responds to a configuration request with a get config reply message. ============= ========================================================= Attribute Description ============= ========================================================= flags One of the following configuration flags. | OFPC_FRAG_NORMAL | OFPC_FRAG_DROP | OFPC_FRAG_REASM | OFPC_FRAG_MASK | OFPC_INVALID_TTL_TO_CONTROLLER miss_send_len Max bytes of new flow that datapath should send to the controller ============= ========================================================= Example:: @set_ev_cls(ofp_event.EventOFPGetConfigReply, MAIN_DISPATCHER) def get_config_reply_handler(self, ev): msg = ev.msg dp = msg.datapath ofp = dp.ofproto if msg.flags == ofp.OFPC_FRAG_NORMAL: flags = 'NORMAL' elif msg.flags == ofp.OFPC_FRAG_DROP: flags = 'DROP' elif msg.flags == ofp.OFPC_FRAG_REASM: flags = 'REASM' elif msg.flags == ofp.OFPC_FRAG_MASK: flags = 'MASK' elif msg.flags == ofp.OFPC_INVALID_TTL_TO_CONTROLLER: flags = 'INVALID TTL TO CONTROLLER' else: flags = 'unknown' self.logger.debug('OFPGetConfigReply received: ' 'flags=%s miss_send_len=%d', flags, msg.miss_send_len) """ def __init__(self, datapath, flags=None, miss_send_len=None): super(OFPGetConfigReply, self).__init__(datapath) self.flags = flags self.miss_send_len = miss_send_len @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPGetConfigReply, cls).parser(datapath, version, msg_type, msg_len, xid, buf) msg.flags, msg.miss_send_len = struct.unpack_from( ofproto.OFP_SWITCH_CONFIG_PACK_STR, msg.buf, ofproto.OFP_HEADER_SIZE) return msg @_set_msg_type(ofproto.OFPT_SET_CONFIG) class OFPSetConfig(MsgBase): """ Set config request message The controller sends a set config request message to set configuraion parameters. ============= ========================================================= Attribute Description ============= ========================================================= flags One of the following configuration flags. | OFPC_FRAG_NORMAL | OFPC_FRAG_DROP | OFPC_FRAG_REASM | OFPC_FRAG_MASK | OFPC_INVALID_TTL_TO_CONTROLLER miss_send_len Max bytes of new flow that datapath should send to the controller ============= ========================================================= Example:: def send_set_config(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPSetConfig(datapath, ofp.OFPC_FRAG_NORMAL, 256) datapath.send_msg(req) """ def __init__(self, datapath, flags=0, miss_send_len=0): super(OFPSetConfig, self).__init__(datapath) self.flags = flags self.miss_send_len = miss_send_len def _serialize_body(self): assert self.flags is not None assert self.miss_send_len is not None msg_pack_into(ofproto.OFP_SWITCH_CONFIG_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.flags, self.miss_send_len) @_register_parser @_set_msg_type(ofproto.OFPT_PACKET_IN) class OFPPacketIn(MsgBase): """ Packet-In message The switch sends the packet that received to the controller by this message. ============= ========================================================= Attribute Description ============= ========================================================= buffer_id ID assigned by datapath total_len Full length of frame reason Reason packet is being sent. | OFPR_NO_MATCH | OFPR_ACTION | OFPR_INVALID_TTL table_id ID of the table that was looked up match Instance of ``OFPMatch`` data Ethernet frame ============= ========================================================= Example:: @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER) def packet_in_handler(self, ev): msg = ev.msg dp = msg.datapath ofp = dp.ofproto if msg.reason == ofp.OFPR_NO_MATCH: reason = 'NO MATCH' elif msg.reason == ofp.OFPR_ACTION: reason = 'ACTION' elif msg.reason == ofp.OFPR_INVALID_TTL: reason = 'INVALID TTL' else: reason = 'unknown' self.logger.debug('OFPPacketIn received: ' 'buffer_id=%x total_len=%d reason=%s ' 'table_id=%d match=%s data=%s', msg.buffer_id, msg.total_len, reason, msg.table_id, msg.match, utils.hex_array(msg.data)) """ def __init__(self, datapath, buffer_id=None, total_len=None, reason=None, table_id=None, match=None, data=None): super(OFPPacketIn, self).__init__(datapath) self.buffer_id = buffer_id self.total_len = total_len self.reason = reason self.table_id = table_id self.match = match self.data = data @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPPacketIn, cls).parser(datapath, version, msg_type, msg_len, xid, buf) (msg.buffer_id, msg.total_len, msg.reason, msg.table_id) = struct.unpack_from( ofproto.OFP_PACKET_IN_PACK_STR, msg.buf, ofproto.OFP_HEADER_SIZE) msg.match = OFPMatch.parser(msg.buf, ofproto.OFP_PACKET_IN_SIZE - ofproto.OFP_MATCH_SIZE) match_len = utils.round_up(msg.match.length, 8) msg.data = msg.buf[(ofproto.OFP_PACKET_IN_SIZE - ofproto.OFP_MATCH_SIZE + match_len + 2):] if msg.total_len < len(msg.data): # discard padding for 8-byte alignment of OFP packet msg.data = msg.data[:msg.total_len] return msg @_register_parser @_set_msg_type(ofproto.OFPT_FLOW_REMOVED) class OFPFlowRemoved(MsgBase): """ Flow removed message When flow entries time out or are deleted, the switch notifies controller with this message. ================ ====================================================== Attribute Description ================ ====================================================== cookie Opaque controller-issued identifier priority Priority level of flow entry reason One of the following values. | OFPRR_IDLE_TIMEOUT | OFPRR_HARD_TIMEOUT | OFPRR_DELETE | OFPRR_GROUP_DELETE table_id ID of the table duration_sec Time flow was alive in seconds duration_nsec Time flow was alive in nanoseconds beyond duration_sec idle_timeout Idle timeout from original flow mod hard_timeout Hard timeout from original flow mod packet_count Number of packets that was associated with the flow byte_count Number of bytes that was associated with the flow match Instance of ``OFPMatch`` ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPFlowRemoved, MAIN_DISPATCHER) def flow_removed_handler(self, ev): msg = ev.msg dp = msg.datapath ofp = dp.ofproto if msg.reason == ofp.OFPRR_IDLE_TIMEOUT: reason = 'IDLE TIMEOUT' elif msg.reason == ofp.OFPRR_HARD_TIMEOUT: reason = 'HARD TIMEOUT' elif msg.reason == ofp.OFPRR_DELETE: reason = 'DELETE' elif msg.reason == ofp.OFPRR_GROUP_DELETE: reason = 'GROUP DELETE' else: reason = 'unknown' self.logger.debug('OFPFlowRemoved received: ' 'cookie=%d priority=%d reason=%s table_id=%d ' 'duration_sec=%d duration_nsec=%d ' 'idle_timeout=%d hard_timeout=%d ' 'packet_count=%d byte_count=%d match.fields=%s', msg.cookie, msg.priority, reason, msg.table_id, msg.duration_sec, msg.duration_nsec, msg.idle_timeout, msg.hard_timeout, msg.packet_count, msg.byte_count, msg.match) """ def __init__(self, datapath, cookie=None, priority=None, reason=None, table_id=None, duration_sec=None, duration_nsec=None, idle_timeout=None, hard_timeout=None, packet_count=None, byte_count=None, match=None): super(OFPFlowRemoved, self).__init__(datapath) self.cookie = cookie self.priority = priority self.reason = reason self.table_id = table_id self.duration_sec = duration_sec self.duration_nsec = duration_nsec self.idle_timeout = idle_timeout self.hard_timeout = hard_timeout self.packet_count = packet_count self.byte_count = byte_count self.match = match @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPFlowRemoved, cls).parser(datapath, version, msg_type, msg_len, xid, buf) (msg.cookie, msg.priority, msg.reason, msg.table_id, msg.duration_sec, msg.duration_nsec, msg.idle_timeout, msg.hard_timeout, msg.packet_count, msg.byte_count) = struct.unpack_from( ofproto.OFP_FLOW_REMOVED_PACK_STR0, msg.buf, ofproto.OFP_HEADER_SIZE) offset = (ofproto.OFP_FLOW_REMOVED_SIZE - ofproto.OFP_MATCH_SIZE) msg.match = OFPMatch.parser(msg.buf, offset) return msg @_register_parser @_set_msg_type(ofproto.OFPT_PORT_STATUS) class OFPPortStatus(MsgBase): """ Port status message The switch notifies controller of change of ports. ================ ====================================================== Attribute Description ================ ====================================================== reason One of the following values. | OFPPR_ADD | OFPPR_DELETE | OFPPR_MODIFY desc instance of ``OFPPort`` ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPPortStatus, MAIN_DISPATCHER) def port_status_handler(self, ev): msg = ev.msg dp = msg.datapath ofp = dp.ofproto if msg.reason == ofp.OFPPR_ADD: reason = 'ADD' elif msg.reason == ofp.OFPPR_DELETE: reason = 'DELETE' elif msg.reason == ofp.OFPPR_MODIFY: reason = 'MODIFY' else: reason = 'unknown' self.logger.debug('OFPPortStatus received: reason=%s desc=%s', reason, msg.desc) """ def __init__(self, datapath, reason=None, desc=None): super(OFPPortStatus, self).__init__(datapath) self.reason = reason self.desc = desc @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPPortStatus, cls).parser(datapath, version, msg_type, msg_len, xid, buf) msg.reason = struct.unpack_from( ofproto.OFP_PORT_STATUS_PACK_STR, msg.buf, ofproto.OFP_HEADER_SIZE)[0] msg.desc = OFPPort.parser(msg.buf, ofproto.OFP_PORT_STATUS_DESC_OFFSET) return msg @_set_msg_type(ofproto.OFPT_PACKET_OUT) class OFPPacketOut(MsgBase): """ Packet-Out message The controller uses this message to send a packet out throught the switch. ================ ====================================================== Attribute Description ================ ====================================================== buffer_id ID assigned by datapath (OFP_NO_BUFFER if none) in_port Packet's input port or ``OFPP_CONTROLLER`` actions list of OpenFlow action class data Packet data of a binary type value or an instances of packet.Packet. ================ ====================================================== Example:: def send_packet_out(self, datapath, buffer_id, in_port): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser actions = [ofp_parser.OFPActionOutput(ofp.OFPP_FLOOD, 0)] req = ofp_parser.OFPPacketOut(datapath, buffer_id, in_port, actions) datapath.send_msg(req) """ def __init__(self, datapath, buffer_id=None, in_port=None, actions=None, data=None, actions_len=None): # The in_port field is the ingress port that must be associated # with the packet for OpenFlow processing. assert in_port is not None super(OFPPacketOut, self).__init__(datapath) self.buffer_id = buffer_id self.in_port = in_port self.actions_len = 0 self.actions = actions self.data = data def _serialize_body(self): self.actions_len = 0 offset = ofproto.OFP_PACKET_OUT_SIZE for a in self.actions: a.serialize(self.buf, offset) offset += a.len self.actions_len += a.len if self.data is not None: assert self.buffer_id == 0xffffffff if isinstance(self.data, packet.Packet): self.data.serialize() self.buf += self.data.data else: self.buf += self.data msg_pack_into(ofproto.OFP_PACKET_OUT_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.buffer_id, self.in_port, self.actions_len) @classmethod def from_jsondict(cls, dict_, decode_string=base64.b64decode, **additional_args): if isinstance(dict_['data'], dict): data = dict_.pop('data') ins = super(OFPPacketOut, cls).from_jsondict(dict_, decode_string, **additional_args) ins.data = packet.Packet.from_jsondict(data['Packet']) dict_['data'] = data else: ins = super(OFPPacketOut, cls).from_jsondict(dict_, decode_string, **additional_args) return ins @_register_parser @_set_msg_type(ofproto.OFPT_FLOW_MOD) class OFPFlowMod(MsgBase): """ Modify Flow entry message The controller sends this message to modify the flow table. ================ ====================================================== Attribute Description ================ ====================================================== cookie Opaque controller-issued identifier cookie_mask Mask used to restrict the cookie bits that must match when the command is ``OPFFC_MODIFY*`` or ``OFPFC_DELETE*`` table_id ID of the table to put the flow in command One of the following values. | OFPFC_ADD | OFPFC_MODIFY | OFPFC_MODIFY_STRICT | OFPFC_DELETE | OFPFC_DELETE_STRICT idle_timeout Idle time before discarding (seconds) hard_timeout Max time before discarding (seconds) priority Priority level of flow entry buffer_id Buffered packet to apply to (or OFP_NO_BUFFER) out_port For ``OFPFC_DELETE*`` commands, require matching entries to include this as an output port out_group For ``OFPFC_DELETE*`` commands, require matching entries to include this as an output group flags One of the following values. | OFPFF_SEND_FLOW_REM | OFPFF_CHECK_OVERLAP | OFPFF_RESET_COUNTS match Instance of ``OFPMatch`` instructions list of ``OFPInstruction*`` instance ================ ====================================================== Example:: def send_flow_mod(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser cookie = cookie_mask = 0 table_id = 0 idle_timeout = hard_timeout = 0 priority = 32768 buffer_id = ofp.OFP_NO_BUFFER match = ofp_parser.OFPMatch(in_port=1, eth_dst='ff:ff:ff:ff:ff:ff') actions = [ofp_parser.OFPActionOutput(ofp.OFPP_NORMAL, 0)] inst = [ofp_parser.OFPInstructionActions(ofp.OFPIT_APPLY_ACTIONS, actions)] req = ofp_parser.OFPFlowMod(datapath, cookie, cookie_mask, table_id, ofp.OFPFC_ADD, idle_timeout, hard_timeout, priority, buffer_id, ofp.OFPP_ANY, ofp.OFPG_ANY, ofp.OFPFF_SEND_FLOW_REM, match, inst) datapath.send_msg(req) """ def __init__(self, datapath, cookie=0, cookie_mask=0, table_id=0, command=ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=0, priority=0, buffer_id=ofproto.OFP_NO_BUFFER, out_port=0, out_group=0, flags=0, match=None, instructions=None): instructions = instructions if instructions else [] super(OFPFlowMod, self).__init__(datapath) self.cookie = cookie self.cookie_mask = cookie_mask self.table_id = table_id self.command = command self.idle_timeout = idle_timeout self.hard_timeout = hard_timeout self.priority = priority self.buffer_id = buffer_id self.out_port = out_port self.out_group = out_group self.flags = flags if match is None: match = OFPMatch() assert isinstance(match, OFPMatch) self.match = match for i in instructions: assert isinstance(i, OFPInstruction) self.instructions = instructions def _serialize_body(self): msg_pack_into(ofproto.OFP_FLOW_MOD_PACK_STR0, self.buf, ofproto.OFP_HEADER_SIZE, self.cookie, self.cookie_mask, self.table_id, self.command, self.idle_timeout, self.hard_timeout, self.priority, self.buffer_id, self.out_port, self.out_group, self.flags) offset = (ofproto.OFP_FLOW_MOD_SIZE - ofproto.OFP_MATCH_SIZE) match_len = self.match.serialize(self.buf, offset) offset += match_len for inst in self.instructions: inst.serialize(self.buf, offset) offset += inst.len @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPFlowMod, cls).parser( datapath, version, msg_type, msg_len, xid, buf) (msg.cookie, msg.cookie_mask, msg.table_id, msg.command, msg.idle_timeout, msg.hard_timeout, msg.priority, msg.buffer_id, msg.out_port, msg.out_group, msg.flags) = struct.unpack_from( ofproto.OFP_FLOW_MOD_PACK_STR0, msg.buf, ofproto.OFP_HEADER_SIZE) offset = ofproto.OFP_FLOW_MOD_SIZE - ofproto.OFP_HEADER_SIZE msg.match = OFPMatch.parser(buf, offset) offset += utils.round_up(msg.match.length, 8) instructions = [] while offset < msg_len: i = OFPInstruction.parser(buf, offset) instructions.append(i) offset += i.len msg.instructions = instructions return msg class OFPInstruction(StringifyMixin): _INSTRUCTION_TYPES = {} @staticmethod def register_instruction_type(types): def _register_instruction_type(cls): for type_ in types: OFPInstruction._INSTRUCTION_TYPES[type_] = cls return cls return _register_instruction_type @classmethod def parser(cls, buf, offset): (type_, len_) = struct.unpack_from('!HH', buf, offset) cls_ = cls._INSTRUCTION_TYPES.get(type_) return cls_.parser(buf, offset) @OFPInstruction.register_instruction_type([ofproto.OFPIT_GOTO_TABLE]) class OFPInstructionGotoTable(OFPInstruction): """ Goto table instruction This instruction indicates the next table in the processing pipeline. ================ ====================================================== Attribute Description ================ ====================================================== table_id Next table ================ ====================================================== """ def __init__(self, table_id, type_=None, len_=None): super(OFPInstructionGotoTable, self).__init__() self.type = ofproto.OFPIT_GOTO_TABLE self.len = ofproto.OFP_INSTRUCTION_GOTO_TABLE_SIZE self.table_id = table_id @classmethod def parser(cls, buf, offset): (type_, len_, table_id) = struct.unpack_from( ofproto.OFP_INSTRUCTION_GOTO_TABLE_PACK_STR, buf, offset) return cls(table_id) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_INSTRUCTION_GOTO_TABLE_PACK_STR, buf, offset, self.type, self.len, self.table_id) @OFPInstruction.register_instruction_type([ofproto.OFPIT_WRITE_METADATA]) class OFPInstructionWriteMetadata(OFPInstruction): """ Write metadata instruction This instruction writes the masked metadata value into the metadata field. ================ ====================================================== Attribute Description ================ ====================================================== metadata Metadata value to write metadata_mask Metadata write bitmask ================ ====================================================== """ def __init__(self, metadata, metadata_mask, type_=None, len_=None): super(OFPInstructionWriteMetadata, self).__init__() self.type = ofproto.OFPIT_WRITE_METADATA self.len = ofproto.OFP_INSTRUCTION_WRITE_METADATA_SIZE self.metadata = metadata self.metadata_mask = metadata_mask @classmethod def parser(cls, buf, offset): (type_, len_, metadata, metadata_mask) = struct.unpack_from( ofproto.OFP_INSTRUCTION_WRITE_METADATA_PACK_STR, buf, offset) return cls(metadata, metadata_mask) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_INSTRUCTION_WRITE_METADATA_PACK_STR, buf, offset, self.type, self.len, self.metadata, self.metadata_mask) @OFPInstruction.register_instruction_type([ofproto.OFPIT_WRITE_ACTIONS, ofproto.OFPIT_APPLY_ACTIONS, ofproto.OFPIT_CLEAR_ACTIONS]) class OFPInstructionActions(OFPInstruction): """ Actions instruction This instruction writes/applies/clears the actions. ================ ====================================================== Attribute Description ================ ====================================================== type One of following values. | OFPIT_WRITE_ACTIONS | OFPIT_APPLY_ACTIONS | OFPIT_CLEAR_ACTIONS actions list of OpenFlow action class ================ ====================================================== ``type`` attribute corresponds to ``type_`` parameter of __init__. """ def __init__(self, type_, actions=None, len_=None): super(OFPInstructionActions, self).__init__() self.type = type_ for a in actions: assert isinstance(a, OFPAction) self.actions = actions @classmethod def parser(cls, buf, offset): (type_, len_) = struct.unpack_from( ofproto.OFP_INSTRUCTION_ACTIONS_PACK_STR, buf, offset) offset += ofproto.OFP_INSTRUCTION_ACTIONS_SIZE actions = [] actions_len = len_ - ofproto.OFP_INSTRUCTION_ACTIONS_SIZE while actions_len > 0: a = OFPAction.parser(buf, offset) actions.append(a) actions_len -= a.len offset += a.len inst = cls(type_, actions) inst.len = len_ return inst def serialize(self, buf, offset): action_offset = offset + ofproto.OFP_INSTRUCTION_ACTIONS_SIZE if self.actions: for a in self.actions: assert isinstance(a, OFPAction) a.serialize(buf, action_offset) action_offset += a.len self.len = action_offset - offset pad_len = utils.round_up(self.len, 8) - self.len msg_pack_into("%dx" % pad_len, buf, action_offset) self.len += pad_len msg_pack_into(ofproto.OFP_INSTRUCTION_ACTIONS_PACK_STR, buf, offset, self.type, self.len) class OFPActionHeader(StringifyMixin): def __init__(self, type_, len_): self.type = type_ self.len = len_ def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_HEADER_PACK_STR, buf, offset, self.type, self.len) class OFPAction(OFPActionHeader): _ACTION_TYPES = {} @staticmethod def register_action_type(type_, len_): def _register_action_type(cls): cls.cls_action_type = type_ cls.cls_action_len = len_ OFPAction._ACTION_TYPES[cls.cls_action_type] = cls return cls return _register_action_type def __init__(self): cls = self.__class__ super(OFPAction, self).__init__(cls.cls_action_type, cls.cls_action_len) @classmethod def parser(cls, buf, offset): type_, len_ = struct.unpack_from( ofproto.OFP_ACTION_HEADER_PACK_STR, buf, offset) cls_ = cls._ACTION_TYPES.get(type_) assert cls_ is not None return cls_.parser(buf, offset) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_HEADER_PACK_STR, buf, offset, self.type, self.len) @OFPAction.register_action_type(ofproto.OFPAT_OUTPUT, ofproto.OFP_ACTION_OUTPUT_SIZE) class OFPActionOutput(OFPAction): """ Output action This action indicates output a packet to the switch port. ================ ====================================================== Attribute Description ================ ====================================================== port Output port max_len Max length to send to controller ================ ====================================================== """ def __init__(self, port, max_len=ofproto.OFPCML_MAX, type_=None, len_=None): super(OFPActionOutput, self).__init__() self.port = port self.max_len = max_len @classmethod def parser(cls, buf, offset): type_, len_, port, max_len = struct.unpack_from( ofproto.OFP_ACTION_OUTPUT_PACK_STR, buf, offset) return cls(port, max_len) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_OUTPUT_PACK_STR, buf, offset, self.type, self.len, self.port, self.max_len) @OFPAction.register_action_type(ofproto.OFPAT_GROUP, ofproto.OFP_ACTION_GROUP_SIZE) class OFPActionGroup(OFPAction): """ Group action This action indicates the group used to process the packet. ================ ====================================================== Attribute Description ================ ====================================================== group_id Group identifier ================ ====================================================== """ def __init__(self, group_id=0, type_=None, len_=None): super(OFPActionGroup, self).__init__() self.group_id = group_id @classmethod def parser(cls, buf, offset): (type_, len_, group_id) = struct.unpack_from( ofproto.OFP_ACTION_GROUP_PACK_STR, buf, offset) return cls(group_id) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_GROUP_PACK_STR, buf, offset, self.type, self.len, self.group_id) @OFPAction.register_action_type(ofproto.OFPAT_SET_QUEUE, ofproto.OFP_ACTION_SET_QUEUE_SIZE) class OFPActionSetQueue(OFPAction): """ Set queue action This action sets the queue id that will be used to map a flow to an already-configured queue on a port. ================ ====================================================== Attribute Description ================ ====================================================== queue_id Queue ID for the packets ================ ====================================================== """ def __init__(self, queue_id, type_=None, len_=None): super(OFPActionSetQueue, self).__init__() self.queue_id = queue_id @classmethod def parser(cls, buf, offset): (type_, len_, queue_id) = struct.unpack_from( ofproto.OFP_ACTION_SET_QUEUE_PACK_STR, buf, offset) return cls(queue_id) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_SET_QUEUE_PACK_STR, buf, offset, self.type, self.len, self.queue_id) @OFPAction.register_action_type(ofproto.OFPAT_SET_MPLS_TTL, ofproto.OFP_ACTION_MPLS_TTL_SIZE) class OFPActionSetMplsTtl(OFPAction): """ Set MPLS TTL action This action sets the MPLS TTL. ================ ====================================================== Attribute Description ================ ====================================================== mpls_ttl MPLS TTL ================ ====================================================== """ def __init__(self, mpls_ttl, type_=None, len_=None): super(OFPActionSetMplsTtl, self).__init__() self.mpls_ttl = mpls_ttl @classmethod def parser(cls, buf, offset): (type_, len_, mpls_ttl) = struct.unpack_from( ofproto.OFP_ACTION_MPLS_TTL_PACK_STR, buf, offset) return cls(mpls_ttl) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_MPLS_TTL_PACK_STR, buf, offset, self.type, self.len, self.mpls_ttl) @OFPAction.register_action_type(ofproto.OFPAT_DEC_MPLS_TTL, ofproto.OFP_ACTION_HEADER_SIZE) class OFPActionDecMplsTtl(OFPAction): """ Decrement MPLS TTL action This action decrements the MPLS TTL. """ def __init__(self, type_=None, len_=None): super(OFPActionDecMplsTtl, self).__init__() @classmethod def parser(cls, buf, offset): (type_, len_) = struct.unpack_from( ofproto.OFP_ACTION_HEADER_PACK_STR, buf, offset) return cls() @OFPAction.register_action_type(ofproto.OFPAT_SET_NW_TTL, ofproto.OFP_ACTION_NW_TTL_SIZE) class OFPActionSetNwTtl(OFPAction): """ Set IP TTL action This action sets the IP TTL. ================ ====================================================== Attribute Description ================ ====================================================== nw_ttl IP TTL ================ ====================================================== """ def __init__(self, nw_ttl, type_=None, len_=None): super(OFPActionSetNwTtl, self).__init__() self.nw_ttl = nw_ttl @classmethod def parser(cls, buf, offset): (type_, len_, nw_ttl) = struct.unpack_from( ofproto.OFP_ACTION_NW_TTL_PACK_STR, buf, offset) return cls(nw_ttl) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_NW_TTL_PACK_STR, buf, offset, self.type, self.len, self.nw_ttl) @OFPAction.register_action_type(ofproto.OFPAT_DEC_NW_TTL, ofproto.OFP_ACTION_HEADER_SIZE) class OFPActionDecNwTtl(OFPAction): """ Decrement IP TTL action This action decrements the IP TTL. """ def __init__(self, type_=None, len_=None): super(OFPActionDecNwTtl, self).__init__() @classmethod def parser(cls, buf, offset): (type_, len_) = struct.unpack_from( ofproto.OFP_ACTION_HEADER_PACK_STR, buf, offset) return cls() @OFPAction.register_action_type(ofproto.OFPAT_COPY_TTL_OUT, ofproto.OFP_ACTION_HEADER_SIZE) class OFPActionCopyTtlOut(OFPAction): """ Copy TTL Out action This action copies the TTL from the next-to-outermost header with TTL to the outermost header with TTL. """ def __init__(self, type_=None, len_=None): super(OFPActionCopyTtlOut, self).__init__() @classmethod def parser(cls, buf, offset): (type_, len_) = struct.unpack_from( ofproto.OFP_ACTION_HEADER_PACK_STR, buf, offset) return cls() @OFPAction.register_action_type(ofproto.OFPAT_COPY_TTL_IN, ofproto.OFP_ACTION_HEADER_SIZE) class OFPActionCopyTtlIn(OFPAction): """ Copy TTL In action This action copies the TTL from the outermost header with TTL to the next-to-outermost header with TTL. """ def __init__(self, type_=None, len_=None): super(OFPActionCopyTtlIn, self).__init__() @classmethod def parser(cls, buf, offset): (type_, len_) = struct.unpack_from( ofproto.OFP_ACTION_HEADER_PACK_STR, buf, offset) return cls() @OFPAction.register_action_type(ofproto.OFPAT_PUSH_VLAN, ofproto.OFP_ACTION_PUSH_SIZE) class OFPActionPushVlan(OFPAction): """ Push VLAN action This action pushes a new VLAN tag to the packet. ================ ====================================================== Attribute Description ================ ====================================================== ethertype Ether type. The default is 802.1Q. (0x8100) ================ ====================================================== """ def __init__(self, ethertype=ether.ETH_TYPE_8021Q, type_=None, len_=None): super(OFPActionPushVlan, self).__init__() self.ethertype = ethertype @classmethod def parser(cls, buf, offset): (type_, len_, ethertype) = struct.unpack_from( ofproto.OFP_ACTION_PUSH_PACK_STR, buf, offset) return cls(ethertype) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_PUSH_PACK_STR, buf, offset, self.type, self.len, self.ethertype) @OFPAction.register_action_type(ofproto.OFPAT_PUSH_MPLS, ofproto.OFP_ACTION_PUSH_SIZE) class OFPActionPushMpls(OFPAction): """ Push MPLS action This action pushes a new MPLS header to the packet. ================ ====================================================== Attribute Description ================ ====================================================== ethertype Ether type ================ ====================================================== """ def __init__(self, ethertype=ether.ETH_TYPE_MPLS, type_=None, len_=None): super(OFPActionPushMpls, self).__init__() self.ethertype = ethertype @classmethod def parser(cls, buf, offset): (type_, len_, ethertype) = struct.unpack_from( ofproto.OFP_ACTION_PUSH_PACK_STR, buf, offset) return cls(ethertype) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_PUSH_PACK_STR, buf, offset, self.type, self.len, self.ethertype) @OFPAction.register_action_type(ofproto.OFPAT_POP_VLAN, ofproto.OFP_ACTION_HEADER_SIZE) class OFPActionPopVlan(OFPAction): """ Pop VLAN action This action pops the outermost VLAN tag from the packet. """ def __init__(self, type_=None, len_=None): super(OFPActionPopVlan, self).__init__() @classmethod def parser(cls, buf, offset): (type_, len_) = struct.unpack_from( ofproto.OFP_ACTION_HEADER_PACK_STR, buf, offset) return cls() @OFPAction.register_action_type(ofproto.OFPAT_POP_MPLS, ofproto.OFP_ACTION_POP_MPLS_SIZE) class OFPActionPopMpls(OFPAction): """ Pop MPLS action This action pops the MPLS header from the packet. """ def __init__(self, ethertype=ether.ETH_TYPE_IP, type_=None, len_=None): super(OFPActionPopMpls, self).__init__() self.ethertype = ethertype @classmethod def parser(cls, buf, offset): (type_, len_, ethertype) = struct.unpack_from( ofproto.OFP_ACTION_POP_MPLS_PACK_STR, buf, offset) return cls(ethertype) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_POP_MPLS_PACK_STR, buf, offset, self.type, self.len, self.ethertype) @OFPAction.register_action_type(ofproto.OFPAT_SET_FIELD, ofproto.OFP_ACTION_SET_FIELD_SIZE) class OFPActionSetField(OFPAction): """ Set field action This action modifies a header field in the packet. The set of keywords available for this is same as OFPMatch. Example:: set_field = OFPActionSetField(eth_src="00:00:00:00:00:00") """ def __init__(self, field=None, **kwargs): # old api # OFPActionSetField(field) # new api # OFPActionSetField(eth_src="00:00:00:00:00") super(OFPActionSetField, self).__init__() if isinstance(field, OFPMatchField): # old api compat assert len(kwargs) == 0 self.field = field else: # new api assert len(kwargs) == 1 key = list(kwargs.keys())[0] value = kwargs[key] assert isinstance(key, (str, str)) assert not isinstance(value, tuple) # no mask self.key = key self.value = value @classmethod def parser(cls, buf, offset): (type_, len_) = struct.unpack_from('!HH', buf, offset) (n, value, mask, _len) = ofproto.oxm_parse(buf, offset + 4) k, uv = ofproto.oxm_to_user(n, value, mask) action = cls(**{k: uv}) action.len = len_ # old api compat action.field = OFPMatchField.parser(buf, offset + 4) return action def serialize(self, buf, offset): # old api compat if self._composed_with_old_api(): return self.serialize_old(buf, offset) n, value, mask = ofproto.oxm_from_user(self.key, self.value) len_ = ofproto.oxm_serialize(n, value, mask, buf, offset + 4) self.len = utils.round_up(4 + len_, 8) msg_pack_into('!HH', buf, offset, self.type, self.len) pad_len = self.len - (4 + len_) msg_pack_into("%dx" % pad_len, buf, offset + 4 + len_) # XXX old api compat def serialize_old(self, buf, offset): len_ = ofproto.OFP_ACTION_SET_FIELD_SIZE + self.field.oxm_len() self.len = utils.round_up(len_, 8) pad_len = self.len - len_ msg_pack_into('!HH', buf, offset, self.type, self.len) self.field.serialize(buf, offset + 4) offset += len_ msg_pack_into("%dx" % pad_len, buf, offset) # XXX old api compat def _composed_with_old_api(self): return not hasattr(self, 'value') def to_jsondict(self): return { self.__class__.__name__: { 'field': ofproto.oxm_to_jsondict(self.key, self.value), "len": self.len, "type": self.type } } @classmethod def from_jsondict(cls, dict_): k, v = ofproto.oxm_from_jsondict(dict_['field']) o = OFPActionSetField(**{k: v}) # XXX old api compat # serialize and parse to fill old attributes buf = bytearray() o.serialize(buf, 0) return OFPActionSetField.parser(bytes(buf), 0) # XXX old api compat def __str__(self): # XXX old api compat if self._composed_with_old_api(): # copy object first because serialize_old is destructive o2 = OFPActionSetField(self.field) # serialize and parse to fill new fields buf = bytearray() o2.serialize(buf, 0) o = OFPActionSetField.parser(bytes(buf), 0) else: o = self return super(OFPActionSetField, o).__str__() __repr__ = __str__ def stringify_attrs(self): yield (self.key, self.value) @OFPAction.register_action_type( ofproto.OFPAT_EXPERIMENTER, ofproto.OFP_ACTION_EXPERIMENTER_HEADER_SIZE) class OFPActionExperimenter(OFPAction): """ Experimenter action This action is an extensible action for the experimenter. ================ ====================================================== Attribute Description ================ ====================================================== experimenter Experimenter ID ================ ====================================================== .. Note:: For the list of the supported Nicira experimenter actions, please refer to :ref:`os_ken.ofproto.nx_actions `. """ def __init__(self, experimenter, type_=None, len_=None): super(OFPActionExperimenter, self).__init__() self.experimenter = experimenter @classmethod def parser(cls, buf, offset): (type_, len_, experimenter) = struct.unpack_from( ofproto.OFP_ACTION_EXPERIMENTER_HEADER_PACK_STR, buf, offset) ex = cls(experimenter) ex.len = len_ return ex def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_EXPERIMENTER_HEADER_PACK_STR, buf, offset, self.type, self.len, self.experimenter) class OFPBucket(StringifyMixin): def __init__(self, weight=0, watch_port=ofproto.OFPP_ANY, watch_group=ofproto.OFPG_ANY, actions=None, len_=None): super(OFPBucket, self).__init__() self.weight = weight self.watch_port = watch_port self.watch_group = watch_group self.actions = actions @classmethod def parser(cls, buf, offset): (len_, weigth, watch_port, watch_group) = struct.unpack_from( ofproto.OFP_BUCKET_PACK_STR, buf, offset) length = ofproto.OFP_BUCKET_SIZE offset += ofproto.OFP_BUCKET_SIZE actions = [] while length < len_: action = OFPAction.parser(buf, offset) actions.append(action) offset += action.len length += action.len m = cls(weigth, watch_port, watch_group, actions) m.len = len_ return m def serialize(self, buf, offset): action_offset = offset + ofproto.OFP_BUCKET_SIZE action_len = 0 for a in self.actions: a.serialize(buf, action_offset) action_offset += a.len action_len += a.len self.len = utils.round_up(ofproto.OFP_BUCKET_SIZE + action_len, 8) msg_pack_into(ofproto.OFP_BUCKET_PACK_STR, buf, offset, self.len, self.weight, self.watch_port, self.watch_group) @_set_msg_type(ofproto.OFPT_GROUP_MOD) class OFPGroupMod(MsgBase): """ Modify group entry message The controller sends this message to modify the group table. ================ ====================================================== Attribute Description ================ ====================================================== command One of the following values. | OFPGC_ADD | OFPGC_MODIFY | OFPGC_DELETE type One of the following values. | OFPGT_ALL | OFPGT_SELECT | OFPGT_INDIRECT | OFPGT_FF group_id Group identifier buckets list of ``OFPBucket`` ================ ====================================================== ``type`` attribute corresponds to ``type_`` parameter of __init__. Example:: def send_group_mod(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser port = 1 max_len = 2000 actions = [ofp_parser.OFPActionOutput(port, max_len)] weight = 100 watch_port = 0 watch_group = 0 buckets = [ofp_parser.OFPBucket(weight, watch_port, watch_group, actions)] group_id = 1 req = ofp_parser.OFPGroupMod(datapath, ofp.OFPGC_ADD, ofp.OFPGT_SELECT, group_id, buckets) datapath.send_msg(req) """ def __init__(self, datapath, command=ofproto.OFPGC_ADD, type_=ofproto.OFPGT_ALL, group_id=0, buckets=None): buckets = buckets if buckets else [] super(OFPGroupMod, self).__init__(datapath) self.command = command self.type = type_ self.group_id = group_id self.buckets = buckets def _serialize_body(self): msg_pack_into(ofproto.OFP_GROUP_MOD_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.command, self.type, self.group_id) offset = ofproto.OFP_GROUP_MOD_SIZE for b in self.buckets: b.serialize(self.buf, offset) offset += b.len @_set_msg_type(ofproto.OFPT_PORT_MOD) class OFPPortMod(MsgBase): """ Port modification message The controller sneds this message to modify the behavior of the port. ================ ====================================================== Attribute Description ================ ====================================================== port_no Port number to modify hw_addr The hardware address that must be the same as hw_addr of ``OFPPort`` of ``OFPSwitchFeatures`` config Bitmap of configuration flags. | OFPPC_PORT_DOWN | OFPPC_NO_RECV | OFPPC_NO_FWD | OFPPC_NO_PACKET_IN mask Bitmap of configuration flags above to be changed advertise Bitmap of the following flags. | OFPPF_10MB_HD | OFPPF_10MB_FD | OFPPF_100MB_HD | OFPPF_100MB_FD | OFPPF_1GB_HD | OFPPF_1GB_FD | OFPPF_10GB_FD | OFPPF_40GB_FD | OFPPF_100GB_FD | OFPPF_1TB_FD | OFPPF_OTHER | OFPPF_COPPER | OFPPF_FIBER | OFPPF_AUTONEG | OFPPF_PAUSE | OFPPF_PAUSE_ASYM ================ ====================================================== Example:: def send_port_mod(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser port_no = 3 hw_addr = 'fa:c8:e8:76:1d:7e' config = 0 mask = (ofp.OFPPC_PORT_DOWN | ofp.OFPPC_NO_RECV | ofp.OFPPC_NO_FWD | ofp.OFPPC_NO_PACKET_IN) advertise = (ofp.OFPPF_10MB_HD | ofp.OFPPF_100MB_FD | ofp.OFPPF_1GB_FD | ofp.OFPPF_COPPER | ofp.OFPPF_AUTONEG | ofp.OFPPF_PAUSE | ofp.OFPPF_PAUSE_ASYM) req = ofp_parser.OFPPortMod(datapath, port_no, hw_addr, config, mask, advertise) datapath.send_msg(req) """ _TYPE = { 'ascii': [ 'hw_addr', ] } def __init__(self, datapath, port_no=0, hw_addr='00:00:00:00:00:00', config=0, mask=0, advertise=0): super(OFPPortMod, self).__init__(datapath) self.port_no = port_no self.hw_addr = hw_addr self.config = config self.mask = mask self.advertise = advertise def _serialize_body(self): msg_pack_into(ofproto.OFP_PORT_MOD_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.port_no, addrconv.mac.text_to_bin(self.hw_addr), self.config, self.mask, self.advertise) @_set_msg_type(ofproto.OFPT_TABLE_MOD) class OFPTableMod(MsgBase): """ Flow table configuration message The controller sends this message to configure table state. ================ ====================================================== Attribute Description ================ ====================================================== table_id ID of the table (OFPTT_ALL indicates all tables) config Bitmap of the following flags. | OFPTC_TABLE_MISS_CONTROLLER | OFPTC_TABLE_MISS_CONTINUE | OFPTC_TABLE_MISS_DROP | OFPTC_TABLE_MISS_MASK ================ ====================================================== Example:: def send_table_mod(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPTableMod(datapath, ofp.OFPTT_ALL, ofp.OFPTC_TABLE_MISS_DROP) datapath.send_msg(req) """ def __init__(self, datapath, table_id, config): super(OFPTableMod, self).__init__(datapath) self.table_id = table_id self.config = config def _serialize_body(self): msg_pack_into(ofproto.OFP_TABLE_MOD_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.table_id, self.config) class OFPStatsRequest(MsgBase): def __init__(self, datapath, type_, flags=0): super(OFPStatsRequest, self).__init__(datapath) self.type = type_ self.flags = flags def to_jsondict(self): # remove some redundant attributes d = super(OFPStatsRequest, self).to_jsondict() v = d[self.__class__.__name__] del v['type'] # implied by subclass return d def _serialize_stats_body(self): pass def _serialize_body(self): msg_pack_into(ofproto.OFP_STATS_REQUEST_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.type, self.flags) self._serialize_stats_body() @_register_parser @_set_msg_type(ofproto.OFPT_STATS_REPLY) class OFPStatsReply(MsgBase): _STATS_TYPES = {} @staticmethod def register_stats_reply_type(type_, body_single_struct=False): def _register_stats_reply_type(cls): OFPStatsReply._STATS_TYPES[type_] = cls cls.cls_body_single_struct = body_single_struct return cls return _register_stats_reply_type def __init__(self, datapath, type_=None, flags=None, body=None): super(OFPStatsReply, self).__init__(datapath) self.type = type_ self.flags = flags self.body = body @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPStatsReply, cls).parser(datapath, version, msg_type, msg_len, xid, buf) msg.type, msg.flags = struct.unpack_from( ofproto.OFP_STATS_REPLY_PACK_STR, msg.buf, ofproto.OFP_HEADER_SIZE) stats_type_cls = cls._STATS_TYPES.get(msg.type) offset = ofproto.OFP_STATS_REPLY_SIZE body = [] while offset < msg_len: r = stats_type_cls.parser(msg.buf, offset) body.append(r) offset += r.length if stats_type_cls.cls_body_single_struct: msg.body = body[0] else: msg.body = body return msg @_set_msg_type(ofproto.OFPT_STATS_REQUEST) class OFPDescStatsRequest(OFPStatsRequest): """ Description statistics request message The controller uses this message to query description of the switch. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero (none yet defined in the spec) ================ ====================================================== Example:: def send_desc_stats_request(self, datapath): ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPDescStatsRequest(datapath) datapath.send_msg(req) """ def __init__(self, datapath, flags=0): super(OFPDescStatsRequest, self).__init__(datapath, ofproto.OFPST_DESC, flags) @OFPStatsReply.register_stats_reply_type(ofproto.OFPST_DESC, body_single_struct=True) class OFPDescStats(ofproto_parser.namedtuple('OFPDescStats', ( 'mfr_desc', 'hw_desc', 'sw_desc', 'serial_num', 'dp_desc'))): """ Description statistics reply message The switch responds with a stats reply that include this message to a description statistics request. ================ ====================================================== Attribute Description ================ ====================================================== mfr_desc Manufacturer description hw_desc Hardware description sw_desc Software description serial_num Serial number dp_desc Human readable description of datapath ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPStatsReply, MAIN_DISPATCHER) def stats_reply_handler(self, ev): msg = ev.msg ofp = msg.datapath.ofproto body = ev.msg.body if msg.type == ofp.OFPST_DESC: self.desc_stats_reply_handler(body) def desc_stats_reply_handler(self, body): self.logger.debug('DescStats: mfr_desc=%s hw_desc=%s sw_desc=%s ' 'serial_num=%s dp_desc=%s', body.mfr_desc, body.hw_desc, body.sw_desc, body.serial_num, body.dp_desc) """ _TYPE = { 'ascii': [ 'mfr_desc', 'hw_desc', 'sw_desc', 'serial_num', 'dp_desc', ] } @classmethod def parser(cls, buf, offset): desc = struct.unpack_from(ofproto.OFP_DESC_STATS_PACK_STR, buf, offset) desc = list(desc) desc = [x.rstrip(b'\0') for x in desc] stats = cls(*desc) stats.length = ofproto.OFP_DESC_STATS_SIZE return stats @_set_msg_type(ofproto.OFPT_STATS_REQUEST) class OFPFlowStatsRequest(OFPStatsRequest): """ Individual flow statistics request message The controller uses this message to query individual flow statistics. ================ ====================================================== Attribute Description ================ ====================================================== table_id ID of table to read out_port Require matching entries to include this as an output port out_group Require matching entries to include this as an output group cookie Require matching entries to contain this cookie value cookie_mask Mask used to restrict the cookie bits that must match match Instance of ``OFPMatch`` flags Zero (none yet defined in the spec) ================ ====================================================== Example:: def send_flow_stats_request(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser cookie = cookie_mask = 0 match = ofp_parser.OFPMatch(in_port=1) req = ofp_parser.OFPFlowStatsRequest(datapath, ofp.OFPTT_ALL, ofp.OFPP_ANY, ofp.OFPG_ANY, cookie, cookie_mask, match) datapath.send_msg(req) """ def __init__(self, datapath, table_id=ofproto.OFPTT_ALL, out_port=ofproto.OFPP_ANY, out_group=ofproto.OFPG_ANY, cookie=0, cookie_mask=0, match=None, flags=0): super(OFPFlowStatsRequest, self).__init__(datapath, ofproto.OFPST_FLOW, flags) self.table_id = table_id self.out_port = out_port self.out_group = out_group self.cookie = cookie self.cookie_mask = cookie_mask if match is None: match = OFPMatch() self.match = match def _serialize_stats_body(self): msg_pack_into(ofproto.OFP_FLOW_STATS_REQUEST_PACK_STR, self.buf, ofproto.OFP_STATS_REQUEST_SIZE, self.table_id, self.out_port, self.out_group, self.cookie, self.cookie_mask) offset = (ofproto.OFP_STATS_REQUEST_SIZE + ofproto.OFP_FLOW_STATS_REQUEST_SIZE - ofproto.OFP_MATCH_SIZE) self.match.serialize(self.buf, offset) @OFPStatsReply.register_stats_reply_type(ofproto.OFPST_FLOW) class OFPFlowStats(StringifyMixin): """ Individual flow statistics reply message The switch responds with a stats reply that include this message to an individual flow statistics request. ================ ====================================================== Attribute Description ================ ====================================================== table_id ID of table flow came from duration_sec Time flow has been alive in seconds duration_nsec Time flow has been alive in nanoseconds beyond duration_sec priority Priority of the entry idle_timeout Number of seconds idle before expiration hard_timeout Number of seconds before expiration cookie Opaque controller-issued identifier packet_count Number of packets in flow byte_count Number of bytes in flow match Instance of ``OFPMatch`` instructions list of ``OFPInstruction*`` instance ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPStatsReply, MAIN_DISPATCHER) def stats_reply_handler(self, ev): msg = ev.msg ofp = msg.datapath.ofproto body = ev.msg.body if msg.type == ofp.OFPST_FLOW: self.flow_stats_reply_handler(body) def flow_stats_reply_handler(self, body): flows = [] for stat in body: flows.append('table_id=%s ' 'duration_sec=%d duration_nsec=%d ' 'priority=%d ' 'idle_timeout=%d hard_timeout=%d ' 'cookie=%d packet_count=%d byte_count=%d ' 'match=%s instructions=%s' % (stat.table_id, stat.duration_sec, stat.duration_nsec, stat.priority, stat.idle_timeout, stat.hard_timeout, stat.cookie, stat.packet_count, stat.byte_count, stat.match, stat.instructions)) self.logger.debug('FlowStats: %s', flows) """ def __init__(self, table_id, duration_sec, duration_nsec, priority, idle_timeout, hard_timeout, cookie, packet_count, byte_count, match, instructions=None, length=None): super(OFPFlowStats, self).__init__() self.table_id = table_id self.duration_sec = duration_sec self.duration_nsec = duration_nsec self.priority = priority self.idle_timeout = idle_timeout self.hard_timeout = hard_timeout self.cookie = cookie self.packet_count = packet_count self.byte_count = byte_count self.match = match self.instructions = instructions self.length = length @classmethod def parser(cls, buf, offset): (length, table_id, duration_sec, duration_nsec, priority, idle_timeout, hard_timeout, cookie, packet_count, byte_count) = struct.unpack_from( ofproto.OFP_FLOW_STATS_PACK_STR, buf, offset) offset += (ofproto.OFP_FLOW_STATS_SIZE - ofproto.OFP_MATCH_SIZE) match = OFPMatch.parser(buf, offset) match_length = utils.round_up(match.length, 8) inst_length = (length - (ofproto.OFP_FLOW_STATS_SIZE - ofproto.OFP_MATCH_SIZE + match_length)) offset += match_length instructions = [] while inst_length > 0: inst = OFPInstruction.parser(buf, offset) instructions.append(inst) offset += inst.len inst_length -= inst.len o = cls(table_id, duration_sec, duration_nsec, priority, idle_timeout, hard_timeout, cookie, packet_count, byte_count, match, instructions) o.length = length return o @_set_msg_type(ofproto.OFPT_STATS_REQUEST) class OFPAggregateStatsRequest(OFPStatsRequest): """ Aggregate flow statistics request message The controller uses this message to query aggregate flow statictics. ================ ====================================================== Attribute Description ================ ====================================================== table_id ID of table to read out_port Require matching entries to include this as an output port out_group Require matching entries to include this as an output group cookie Require matching entries to contain this cookie value cookie_mask Mask used to restrict the cookie bits that must match match Instance of ``OFPMatch`` flags Zero (none yet defined in the spec) ================ ====================================================== Example:: def send_aggregate_stats_request(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser cookie = cookie_mask = 0 match = ofp_parser.OFPMatch(in_port=1) req = ofp_parser.OFPAggregateStatsRequest(datapath, 0, ofp.OFPTT_ALL, ofp.OFPP_ANY, ofp.OFPG_ANY, cookie, cookie_mask, match) datapath.send_msg(req) """ def __init__(self, datapath, table_id=ofproto.OFPTT_ALL, out_port=ofproto.OFPP_ANY, out_group=ofproto.OFPP_ANY, cookie=0, cookie_mask=0, match=None, flags=0): super(OFPAggregateStatsRequest, self).__init__( datapath, ofproto.OFPST_AGGREGATE, flags) self.table_id = table_id self.out_port = out_port self.out_group = out_group self.cookie = cookie self.cookie_mask = cookie_mask if match is None: match = OFPMatch() self.match = match def _serialize_stats_body(self): msg_pack_into(ofproto.OFP_AGGREGATE_STATS_REQUEST_PACK_STR, self.buf, ofproto.OFP_STATS_REQUEST_SIZE, self.table_id, self.out_port, self.out_group, self.cookie, self.cookie_mask) offset = (ofproto.OFP_STATS_REQUEST_SIZE + ofproto.OFP_AGGREGATE_STATS_REQUEST_SIZE - ofproto.OFP_MATCH_SIZE) self.match.serialize(self.buf, offset) @OFPStatsReply.register_stats_reply_type(ofproto.OFPST_AGGREGATE, body_single_struct=True) class OFPAggregateStatsReply(ofproto_parser.namedtuple('OFPAggregateStats', ( 'packet_count', 'byte_count', 'flow_count'))): """ Aggregate flow statistics reply message The switch responds with a stats reply that include this message to an aggregate flow statistics request. ================ ====================================================== Attribute Description ================ ====================================================== packet_count Number of packets in flows byte_count Number of bytes in flows flow_count Number of flows ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPStatsReply, MAIN_DISPATCHER) def stats_reply_handler(self, ev): msg = ev.msg ofp = msg.datapath.ofproto body = ev.msg.body if msg.type == ofp.OFPST_AGGREGATE: self.aggregate_stats_reply_handler(body) def aggregate_stats_reply_handler(self, body): self.logger.debug('AggregateStats: packet_count=%d byte_count=%d ' 'flow_count=%d', body.packet_count, body.byte_count, body.flow_count) """ @classmethod def parser(cls, buf, offset): desc = struct.unpack_from( ofproto.OFP_AGGREGATE_STATS_REPLY_PACK_STR, buf, offset) stats = cls(*desc) stats.length = ofproto.OFP_AGGREGATE_STATS_REPLY_SIZE return stats @_set_msg_type(ofproto.OFPT_STATS_REQUEST) class OFPTableStatsRequest(OFPStatsRequest): """ Table statistics request message The controller uses this message to query flow table statictics. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero (none yet defined in the spec) ================ ====================================================== Example:: def send_table_stats_request(self, datapath): ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPTableStatsRequest(datapath) datapath.send_msg(req) """ def __init__(self, datapath, flags=0): super(OFPTableStatsRequest, self).__init__(datapath, ofproto.OFPST_TABLE, flags) @OFPStatsReply.register_stats_reply_type(ofproto.OFPST_TABLE) class OFPTableStats( ofproto_parser.namedtuple('OFPTableStats', ('table_id', 'name', 'match', 'wildcards', 'write_actions', 'apply_actions', 'write_setfields', 'apply_setfields', 'metadata_match', 'metadata_write', 'instructions', 'config', 'max_entries', 'active_count', 'lookup_count', 'matched_count'))): """ Table statistics reply message The switch responds with a stats reply that include this message to a table statistics request. ================ ====================================================== Attribute Description ================ ====================================================== table_id ID of table name table name match Bitmap of (1 << OFPXMT_*) that indicate the fields the table can match on wildcards Bitmap of (1 << OFPXMT_*) wildcards that are supported by the table write_actions Bitmap of OFPAT_* that are supported by the table with OFPIT_WRITE_ACTIONS apply_actions Bitmap of OFPAT_* that are supported by the table with OFPIT_APPLY_ACTIONS write_setfields Bitmap of (1 << OFPXMT_*) header fields that can be set with OFPIT_WRITE_ACTIONS apply_setfields Bitmap of (1 << OFPXMT_*) header fields that can be set with OFPIT_APPLY_ACTIONS metadata_match Bits of metadata table can match metadata_write Bits of metadata table can write instructions Bitmap of OFPIT_* values supported config Bitmap of OFPTC_* values max_entries Max number of entries supported active_count Number of active entries lookup_count Number of packets looked up in table matched_count Number of packets that hit table ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPStatsReply, MAIN_DISPATCHER) def stats_reply_handler(self, ev): msg = ev.msg ofp = msg.datapath.ofproto body = ev.msg.body if msg.type == ofp.OFPST_TABLE: self.table_stats_reply_handler(body) def table_stats_reply_handler(self, body): tables = [] for stat in body: tables.append('table_id=%d active_count=%d lookup_count=%d ' ' matched_count=%d' % (stat.table_id, stat.active_count, stat.lookup_count, stat.matched_count)) self.logger.debug('TableStats: %s', tables) """ _TYPE = { 'utf-8': [ # OF spec is unclear about the encoding of name. # we assumes UTF-8. 'name', ] } @classmethod def parser(cls, buf, offset): table = struct.unpack_from( ofproto.OFP_TABLE_STATS_PACK_STR, buf, offset) table = list(table) i = cls._fields.index('name') table[i] = table[i].rstrip(b'\0') stats = cls(*table) stats.length = ofproto.OFP_TABLE_STATS_SIZE return stats @_set_msg_type(ofproto.OFPT_STATS_REQUEST) class OFPPortStatsRequest(OFPStatsRequest): """ Port statistics request message The controller uses this message to query information about ports statistics. ================ ====================================================== Attribute Description ================ ====================================================== port_no Port number to read (OFPP_ANY to all ports) flags Zero (none yet defined in the spec) ================ ====================================================== Example:: def send_port_stats_request(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPPortStatsRequest(datapath, ofp.OFPP_ANY) datapath.send_msg(req) """ def __init__(self, datapath, port_no=ofproto.OFPP_ANY, flags=0): super(OFPPortStatsRequest, self).__init__(datapath, ofproto.OFPST_PORT, flags) self.port_no = port_no def _serialize_stats_body(self): msg_pack_into(ofproto.OFP_PORT_STATS_REQUEST_PACK_STR, self.buf, ofproto.OFP_STATS_REQUEST_SIZE, self.port_no) @OFPStatsReply.register_stats_reply_type(ofproto.OFPST_PORT) class OFPPortStats( ofproto_parser.namedtuple('OFPPortStats', ('port_no', 'rx_packets', 'tx_packets', 'rx_bytes', 'tx_bytes', 'rx_dropped', 'tx_dropped', 'rx_errors', 'tx_errors', 'rx_frame_err', 'rx_over_err', 'rx_crc_err', 'collisions'))): """ Port statistics reply message The switch responds with a stats reply that include this message to a port statistics request. ================ ====================================================== Attribute Description ================ ====================================================== port_no Port number rx_packets Number of received packets tx_packets Number of transmitted packets rx_bytes Number of received bytes tx_bytes Number of transmitted bytes rx_dropped Number of packets dropped by RX tx_dropped Number of packets dropped by TX rx_errors Number of receive errors tx_errors Number of transmit errors rx_frame_err Number of frame alignment errors rx_over_err Number of packet with RX overrun rx_crc_err Number of CRC errors collisions Number of collisions ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPStatsReply, MAIN_DISPATCHER) def stats_reply_handler(self, ev): msg = ev.msg ofp = msg.datapath.ofproto body = ev.msg.body if msg.type == ofp.OFPST_PORT: self.port_stats_reply_handler(body) def port_stats_reply_handler(self, body): ports = [] for stat in body: ports.append('port_no=%d ' 'rx_packets=%d tx_packets=%d ' 'rx_bytes=%d tx_bytes=%d ' 'rx_dropped=%d tx_dropped=%d ' 'rx_errors=%d tx_errors=%d ' 'rx_frame_err=%d rx_over_err=%d rx_crc_err=%d ' 'collisions=%d' % (stat.port_no, stat.rx_packets, stat.tx_packets, stat.rx_bytes, stat.tx_bytes, stat.rx_dropped, stat.tx_dropped, stat.rx_errors, stat.tx_errors, stat.rx_frame_err, stat.rx_over_err, stat.rx_crc_err, stat.collisions)) self.logger.debug('PortStats: %s', ports) """ @classmethod def parser(cls, buf, offset): port = struct.unpack_from(ofproto.OFP_PORT_STATS_PACK_STR, buf, offset) stats = cls(*port) stats.length = ofproto.OFP_PORT_STATS_SIZE return stats @_set_msg_type(ofproto.OFPT_STATS_REQUEST) class OFPQueueStatsRequest(OFPStatsRequest): """ Queue statistics request message The controller uses this message to query queue statictics. ================ ====================================================== Attribute Description ================ ====================================================== port_no Port number to read queue_id ID of queue to read flags Zero (none yet defined in the spec) ================ ====================================================== Example:: def send_queue_stats_request(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPQueueStatsRequest(datapath, ofp.OFPP_ANY, ofp.OFPQ_ALL) datapath.send_msg(req) """ def __init__(self, datapath, port_no=ofproto.OFPP_ANY, queue_id=ofproto.OFPQ_ALL, flags=0): super(OFPQueueStatsRequest, self).__init__(datapath, ofproto.OFPST_QUEUE, flags) self.port_no = port_no self.queue_id = queue_id def _serialize_stats_body(self): msg_pack_into(ofproto.OFP_QUEUE_STATS_REQUEST_PACK_STR, self.buf, ofproto.OFP_STATS_REQUEST_SIZE, self.port_no, self.queue_id) @OFPStatsReply.register_stats_reply_type(ofproto.OFPST_QUEUE) class OFPQueueStats( ofproto_parser.namedtuple('OFPQueueStats', ('port_no', 'queue_id', 'tx_bytes', 'tx_packets', 'tx_errors'))): """ Queue statistics reply message The switch responds with a stats reply that include this message to an aggregate flow statistics request. ================ ====================================================== Attribute Description ================ ====================================================== port_no Port number queue_id ID of queue tx_bytes Number of transmitted bytes tx_packets Number of transmitted packets tx_errors Number of packets dropped due to overrun ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPStatsReply, MAIN_DISPATCHER) def stats_reply_handler(self, ev): msg = ev.msg ofp = msg.datapath.ofproto body = ev.msg.body if msg.type == ofp.OFPST_QUEUE: self.queue_stats_reply_handler(body) def queue_stats_reply_handler(self, body): queues = [] for stat in body: queues.append('port_no=%d queue_id=%d ' 'tx_bytes=%d tx_packets=%d tx_errors=%d ' % (stat.port_no, stat.queue_id, stat.tx_bytes, stat.tx_packets, stat.tx_errors)) self.logger.debug('QueueStats: %s', queues) """ @classmethod def parser(cls, buf, offset): queue = struct.unpack_from(ofproto.OFP_QUEUE_STATS_PACK_STR, buf, offset) stats = cls(*queue) stats.length = ofproto.OFP_QUEUE_STATS_SIZE return stats class OFPBucketCounter(StringifyMixin): def __init__(self, packet_count, byte_count): super(OFPBucketCounter, self).__init__() self.packet_count = packet_count self.byte_count = byte_count @classmethod def parser(cls, buf, offset): packet, byte = struct.unpack_from( ofproto.OFP_BUCKET_COUNTER_PACK_STR, buf, offset) return cls(packet, byte) @_set_msg_type(ofproto.OFPT_STATS_REQUEST) class OFPGroupStatsRequest(OFPStatsRequest): """ Group statistics request message The controller uses this message to query statistics of one or more groups. ================ ====================================================== Attribute Description ================ ====================================================== group_id ID of group to read (OFPG_ALL to all groups) flags Zero (none yet defined in the spec) ================ ====================================================== Example:: def send_group_stats_request(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPGroupStatsRequest(datapath, ofp.OFPG_ALL) datapath.send_msg(req) """ def __init__(self, datapath, group_id=ofproto.OFPG_ALL, flags=0): super(OFPGroupStatsRequest, self).__init__(datapath, ofproto.OFPST_GROUP, flags) self.group_id = group_id def _serialize_stats_body(self): msg_pack_into(ofproto.OFP_GROUP_STATS_REQUEST_PACK_STR, self.buf, ofproto.OFP_STATS_REQUEST_SIZE, self.group_id) @OFPStatsReply.register_stats_reply_type(ofproto.OFPST_GROUP) class OFPGroupStats(StringifyMixin): """ Group statistics reply message The switch responds with a stats reply that include this message to a group statistics request. ================ ====================================================== Attribute Description ================ ====================================================== group_id Group identifier ref_count Number of flows or groups that directly forward to this group packet_count Number of packets processed by group byte_count Number of bytes processed by group bucket_counters List of ``OFPBucketCounter`` instance ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPStatsReply, MAIN_DISPATCHER) def stats_reply_handler(self, ev): msg = ev.msg ofp = msg.datapath.ofproto body = ev.msg.body if msg.type == ofp.OFPST_GROUP: self.group_stats_reply_handler(body) def group_stats_reply_handler(self, body): groups = [] for stat in body: groups.append('group_id=%d ref_count=%d packet_count=%d ' 'byte_count=%d bucket_counters=%s' % (stat.group_id, stat.ref_count, stat.packet_count, stat.byte_count, stat.bucket_counters)) self.logger.debug('GroupStats: %s', groups) """ def __init__(self, group_id, ref_count, packet_count, byte_count, bucket_counters, length=None): super(OFPGroupStats, self).__init__() self.group_id = group_id self.ref_count = ref_count self.packet_count = packet_count self.byte_count = byte_count self.bucket_counters = bucket_counters self.length = length @classmethod def parser(cls, buf, offset): (length, group_id, ref_count, packet_count, byte_count) = struct.unpack_from( ofproto.OFP_GROUP_STATS_PACK_STR, buf, offset) bucket_len = length - ofproto.OFP_GROUP_STATS_SIZE offset += ofproto.OFP_GROUP_STATS_SIZE bucket_counters = [] while bucket_len > 0: bucket_counters.append(OFPBucketCounter.parser(buf, offset)) offset += ofproto.OFP_BUCKET_COUNTER_SIZE bucket_len -= ofproto.OFP_BUCKET_COUNTER_SIZE o = cls(group_id, ref_count, packet_count, byte_count, bucket_counters) o.length = length return o @_set_msg_type(ofproto.OFPT_STATS_REQUEST) class OFPGroupDescStatsRequest(OFPStatsRequest): """ Group description request message The controller uses this message to list the set of groups on a switch. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero (none yet defined in the spec) ================ ====================================================== Example:: def send_group_desc_stats_request(self, datapath): ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPGroupDescStatsRequest(datapath) datapath.send_msg(req) """ def __init__(self, datapath, flags=0): super(OFPGroupDescStatsRequest, self).__init__( datapath, ofproto.OFPST_GROUP_DESC, flags) @OFPStatsReply.register_stats_reply_type(ofproto.OFPST_GROUP_DESC) class OFPGroupDescStats(StringifyMixin): """ Group description reply message The switch responds with a stats reply that include this message to a group description request. ================ ====================================================== Attribute Description ================ ====================================================== type One of OFPGT_* group_id Group identifier buckets List of ``OFPBucket`` instance ================ ====================================================== ``type`` attribute corresponds to ``type_`` parameter of __init__. Example:: @set_ev_cls(ofp_event.EventOFPStatsReply, MAIN_DISPATCHER) def stats_reply_handler(self, ev): msg = ev.msg ofp = msg.datapath.ofproto body = ev.msg.body if msg.type == ofp.OFPST_GROUP_DESC: self.group_desc_stats_reply_handler(body) def group_desc_stats_reply_handler(self, body): descs = [] for stat in body: descs.append('type=%d group_id=%d buckets=%s' % (stat.type, stat.group_id, stat.buckets)) self.logger.debug('GroupDescStats: %s', descs) """ def __init__(self, type_, group_id, buckets, length=None): self.type = type_ self.group_id = group_id self.buckets = buckets @classmethod def parser(cls, buf, offset): (length, type_, group_id) = struct.unpack_from( ofproto.OFP_GROUP_DESC_STATS_PACK_STR, buf, offset) bucket_len = length - ofproto.OFP_GROUP_DESC_STATS_SIZE offset += ofproto.OFP_GROUP_DESC_STATS_SIZE buckets = [] while bucket_len > 0: bucket = OFPBucket.parser(buf, offset) buckets.append(bucket) offset += bucket.len bucket_len -= bucket.len o = cls(type_, group_id, buckets) o.length = length return o @_set_msg_type(ofproto.OFPT_STATS_REQUEST) class OFPGroupFeaturesStatsRequest(OFPStatsRequest): """ Group features request message The controller uses this message to list the capabilities of groups on a switch. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero (none yet defined in the spec) ================ ====================================================== Example:: def send_group_features_stats_request(self, datapath): ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPGroupFeaturesStatsRequest(datapath) datapath.send_msg(req) """ def __init__(self, datapath, flags=0): super(OFPGroupFeaturesStatsRequest, self).__init__( datapath, ofproto.OFPST_GROUP_FEATURES, flags) @OFPStatsReply.register_stats_reply_type(ofproto.OFPST_GROUP_FEATURES, body_single_struct=True) class OFPGroupFeaturesStats(StringifyMixin): """ Group features reply message The switch responds with a stats reply that include this message to a group features request. ================ ====================================================== Attribute Description ================ ====================================================== types Bitmap of OFPGT_* values supported capabilities Bitmap of OFPGFC_* capability supported max_groups Maximum number of groups for each type actions Bitmaps of OFPAT_* that are supported ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPStatsReply, MAIN_DISPATCHER) def stats_reply_handler(self, ev): msg = ev.msg ofp = msg.datapath.ofproto body = ev.msg.body if msg.type == ofp.OFPST_GROUP_FEATURES: self.group_features_stats_reply_handler(body) def group_features_stats_reply_handler(self, body): self.logger.debug('GroupFeaturesStats: types=%d ' 'capabilities=0x%08x max_groups=%s ' 'actions=%s', body.types, body.capabilities, body.max_groups, body.actions) """ def __init__(self, types, capabilities, max_groups, actions, length=None): self.types = types self.capabilities = capabilities self.max_groups = max_groups self.actions = actions @classmethod def parser(cls, buf, offset): stats = struct.unpack_from( ofproto.OFP_GROUP_FEATURES_STATS_PACK_STR, buf, offset) types = stats[0] capabilities = stats[1] max_groups = list(stats[2:6]) actions = list(stats[6:10]) o = cls(types, capabilities, max_groups, actions) o.length = ofproto.OFP_GROUP_FEATURES_STATS_SIZE return o @_set_msg_type(ofproto.OFPT_QUEUE_GET_CONFIG_REQUEST) class OFPQueueGetConfigRequest(MsgBase): """ Queue configuration request message ================ ====================================================== Attribute Description ================ ====================================================== port Port to be queried (OFPP_ANY to all configured queues) ================ ====================================================== Example:: def send_queue_get_config_request(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPQueueGetConfigRequest(datapath, ofp.OFPP_ANY) datapath.send_msg(req) """ def __init__(self, datapath, port): super(OFPQueueGetConfigRequest, self).__init__(datapath) self.port = port def _serialize_body(self): msg_pack_into(ofproto.OFP_QUEUE_GET_CONFIG_REQUEST_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.port) class OFPQueuePropHeader(StringifyMixin): def __init__(self, property_, len_=None): self.property = property_ self.len = len_ def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_QUEUE_PROP_HEADER_PACK_STR, buf, offset, self.property, self.len) class OFPQueueProp(OFPQueuePropHeader): _QUEUE_PROP_PROPERTIES = {} @staticmethod def register_property(property_, len_): def _register_property(cls): cls.cls_property = property_ cls.cls_len = len_ OFPQueueProp._QUEUE_PROP_PROPERTIES[cls.cls_property] = cls return cls return _register_property def __init__(self): cls = self.__class__ super(OFPQueueProp, self).__init__(cls.cls_property, cls.cls_len) @classmethod def parser(cls, buf, offset): (property_, len_) = struct.unpack_from( ofproto.OFP_QUEUE_PROP_HEADER_PACK_STR, buf, offset) cls_ = cls._QUEUE_PROP_PROPERTIES.get(property_) offset += ofproto.OFP_QUEUE_PROP_HEADER_SIZE return cls_.parser(buf, offset) class OFPPacketQueue(StringifyMixin): def __init__(self, queue_id, port, properties, len_=None): super(OFPPacketQueue, self).__init__() self.queue_id = queue_id self.port = port self.len = len_ self.properties = properties @classmethod def parser(cls, buf, offset): (queue_id, port, len_) = struct.unpack_from( ofproto.OFP_PACKET_QUEUE_PACK_STR, buf, offset) length = ofproto.OFP_PACKET_QUEUE_SIZE offset += ofproto.OFP_PACKET_QUEUE_SIZE properties = [] while length < len_: queue_prop = OFPQueueProp.parser(buf, offset) properties.append(queue_prop) offset += queue_prop.len length += queue_prop.len o = cls(queue_id, port, properties) o.len = len_ return o @OFPQueueProp.register_property(ofproto.OFPQT_MIN_RATE, ofproto.OFP_QUEUE_PROP_MIN_RATE_SIZE) class OFPQueuePropMinRate(OFPQueueProp): def __init__(self, rate, property_=None, len_=None): super(OFPQueuePropMinRate, self).__init__() self.rate = rate @classmethod def parser(cls, buf, offset): (rate,) = struct.unpack_from( ofproto.OFP_QUEUE_PROP_MIN_RATE_PACK_STR, buf, offset) return cls(rate) @OFPQueueProp.register_property(ofproto.OFPQT_MAX_RATE, ofproto.OFP_QUEUE_PROP_MAX_RATE_SIZE) class OFPQueuePropMaxRate(OFPQueueProp): def __init__(self, rate, property_=None, len_=None): super(OFPQueuePropMaxRate, self).__init__() self.rate = rate @classmethod def parser(cls, buf, offset): (rate,) = struct.unpack_from( ofproto.OFP_QUEUE_PROP_MAX_RATE_PACK_STR, buf, offset) return cls(rate) @_register_parser @_set_msg_type(ofproto.OFPT_QUEUE_GET_CONFIG_REPLY) class OFPQueueGetConfigReply(MsgBase): """ Queue configuration reply message The switch responds with this message to a queue configuration request. ================ ====================================================== Attribute Description ================ ====================================================== port Port which was queried queues list of ``OFPPacketQueue`` instance ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPQueueGetConfigReply, MAIN_DISPATCHER) def queue_get_config_reply_handler(self, ev): msg = ev.msg self.logger.debug('OFPQueueGetConfigReply received: ' 'port=%s queues=%s', msg.port, msg.queues) """ def __init__(self, datapath, port=None, queues=None): super(OFPQueueGetConfigReply, self).__init__(datapath) self.port = port self.queues = queues @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPQueueGetConfigReply, cls).parser(datapath, version, msg_type, msg_len, xid, buf) (msg.port,) = struct.unpack_from( ofproto.OFP_QUEUE_GET_CONFIG_REPLY_PACK_STR, msg.buf, ofproto.OFP_HEADER_SIZE) msg.queues = [] length = ofproto.OFP_QUEUE_GET_CONFIG_REPLY_SIZE offset = ofproto.OFP_QUEUE_GET_CONFIG_REPLY_SIZE while length < msg.msg_len: queue = OFPPacketQueue.parser(msg.buf, offset) msg.queues.append(queue) offset += queue.len length += queue.len return msg @_set_msg_type(ofproto.OFPT_BARRIER_REQUEST) class OFPBarrierRequest(MsgBase): """ Barrier request message The controller sends this message to ensure message dependencies have been met or receive notifications for completed operations. Example:: def send_barrier_request(self, datapath): ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPBarrierRequest(datapath) datapath.send_msg(req) """ def __init__(self, datapath): super(OFPBarrierRequest, self).__init__(datapath) @_register_parser @_set_msg_type(ofproto.OFPT_BARRIER_REPLY) class OFPBarrierReply(MsgBase): """ Barrier reply message The switch responds with this message to a barrier request. Example:: @set_ev_cls(ofp_event.EventOFPBarrierReply, MAIN_DISPATCHER) def barrier_reply_handler(self, ev): self.logger.debug('OFPBarrierReply received') """ def __init__(self, datapath): super(OFPBarrierReply, self).__init__(datapath) @_set_msg_type(ofproto.OFPT_ROLE_REQUEST) class OFPRoleRequest(MsgBase): """ Role request message The controller uses this message to change its role. ================ ====================================================== Attribute Description ================ ====================================================== role One of the following values. | OFPCR_ROLE_NOCHANGE | OFPCR_ROLE_EQUAL | OFPCR_ROLE_MASTER | OFPCR_ROLE_SLAVE generation_id Master Election Generation ID ================ ====================================================== Example:: def send_role_request(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPRoleRequest(datapath, ofp.OFPCR_ROLE_EQUAL, 0) datapath.send_msg(req) """ def __init__(self, datapath, role, generation_id): super(OFPRoleRequest, self).__init__(datapath) self.role = role self.generation_id = generation_id def _serialize_body(self): msg_pack_into(ofproto.OFP_ROLE_REQUEST_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.role, self.generation_id) @_register_parser @_set_msg_type(ofproto.OFPT_ROLE_REPLY) class OFPRoleReply(MsgBase): """ Role reply message The switch responds with this message to a role request. ================ ====================================================== Attribute Description ================ ====================================================== role One of the following values. | OFPCR_ROLE_NOCHANGE | OFPCR_ROLE_EQUAL | OFPCR_ROLE_MASTER | OFPCR_ROLE_SLAVE generation_id Master Election Generation ID ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPRoleReply, MAIN_DISPATCHER) def role_reply_handler(self, ev): msg = ev.msg dp = msg.datapath ofp = dp.ofproto if msg.role == ofp.OFPCR_ROLE_NOCHANGE: role = 'NOCHANGE' elif msg.role == ofp.OFPCR_ROLE_EQUAL: role = 'EQUAL' elif msg.role == ofp.OFPCR_ROLE_MASTER: role = 'MASTER' elif msg.role == ofp.OFPCR_ROLE_SLAVE: role = 'SLAVE' else: role = 'unknown' self.logger.debug('OFPRoleReply received: ' 'role=%s generation_id=%d', role, msg.generation_id) """ def __init__(self, datapath, role=None, generation_id=None): super(OFPRoleReply, self).__init__(datapath) self.role = role self.generation_id = generation_id @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPRoleReply, cls).parser(datapath, version, msg_type, msg_len, xid, buf) (msg.role, msg.generation_id) = struct.unpack_from( ofproto.OFP_ROLE_REQUEST_PACK_STR, msg.buf, ofproto.OFP_HEADER_SIZE) return msg UINT64_MAX = (1 << 64) - 1 UINT32_MAX = (1 << 32) - 1 UINT16_MAX = (1 << 16) - 1 class Flow(object): def __init__(self): self.in_port = 0 self.in_phy_port = 0 self.metadata = 0 self.dl_dst = mac.DONTCARE self.dl_src = mac.DONTCARE self.dl_type = 0 self.vlan_vid = 0 self.vlan_pcp = 0 self.ip_dscp = 0 self.ip_ecn = 0 self.ip_proto = 0 self.ipv4_src = 0 self.ipv4_dst = 0 self.tcp_src = 0 self.tcp_dst = 0 self.udp_src = 0 self.udp_dst = 0 self.sctp_src = 0 self.sctp_dst = 0 self.icmpv4_type = 0 self.icmpv4_code = 0 self.arp_op = 0 self.arp_spa = 0 self.arp_tpa = 0 self.arp_sha = 0 self.arp_tha = 0 self.ipv6_src = [] self.ipv6_dst = [] self.ipv6_flabel = 0 self.icmpv6_type = 0 self.icmpv6_code = 0 self.ipv6_nd_target = [] self.ipv6_nd_sll = 0 self.ipv6_nd_tll = 0 self.mpls_label = 0 self.mpls_tc = 0 class FlowWildcards(object): def __init__(self): self.metadata_mask = 0 self.dl_dst_mask = 0 self.dl_src_mask = 0 self.vlan_vid_mask = 0 self.ipv4_src_mask = 0 self.ipv4_dst_mask = 0 self.arp_spa_mask = 0 self.arp_tpa_mask = 0 self.arp_sha_mask = 0 self.arp_tha_mask = 0 self.ipv6_src_mask = [] self.ipv6_dst_mask = [] self.ipv6_flabel_mask = 0 self.wildcards = (1 << 64) - 1 def ft_set(self, shift): self.wildcards &= ~(1 << shift) def ft_test(self, shift): return not self.wildcards & (1 << shift) class OFPMatch(StringifyMixin): """ Flow Match Structure This class is implementation of the flow match structure having compose/query API. There are new API and old API for compatibility. the old API is supposed to be removed later. You can define the flow match by the keyword arguments. The following arguments are available. ================ =============== ================================== Argument Value Description ================ =============== ================================== in_port Integer 32bit Switch input port in_phy_port Integer 32bit Switch physical input port metadata Integer 64bit Metadata passed between tables eth_dst MAC address Ethernet destination address eth_src MAC address Ethernet source address eth_type Integer 16bit Ethernet frame type vlan_vid Integer 16bit VLAN id vlan_pcp Integer 8bit VLAN priority ip_dscp Integer 8bit IP DSCP (6 bits in ToS field) ip_ecn Integer 8bit IP ECN (2 bits in ToS field) ip_proto Integer 8bit IP protocol ipv4_src IPv4 address IPv4 source address ipv4_dst IPv4 address IPv4 destination address tcp_src Integer 16bit TCP source port tcp_dst Integer 16bit TCP destination port udp_src Integer 16bit UDP source port udp_dst Integer 16bit UDP destination port sctp_src Integer 16bit SCTP source port sctp_dst Integer 16bit SCTP destination port icmpv4_type Integer 8bit ICMP type icmpv4_code Integer 8bit ICMP code arp_op Integer 16bit ARP opcode arp_spa IPv4 address ARP source IPv4 address arp_tpa IPv4 address ARP target IPv4 address arp_sha MAC address ARP source hardware address arp_tha MAC address ARP target hardware address ipv6_src IPv6 address IPv6 source address ipv6_dst IPv6 address IPv6 destination address ipv6_flabel Integer 32bit IPv6 Flow Label icmpv6_type Integer 8bit ICMPv6 type icmpv6_code Integer 8bit ICMPv6 code ipv6_nd_target IPv6 address Target address for ND ipv6_nd_sll MAC address Source link-layer for ND ipv6_nd_tll MAC address Target link-layer for ND mpls_label Integer 32bit MPLS label mpls_tc Integer 8bit MPLS TC pbb_uca Integer 8bit PBB UCA header field (EXT-256 Old version of ONF Extension) tcp_flags Integer 16bit TCP flags (EXT-109 ONF Extension) actset_output Integer 32bit Output port from action set metadata (EXT-233 ONF Extension) ================ =============== ================================== Example:: >>> # compose >>> match = parser.OFPMatch( ... in_port=1, ... eth_type=0x86dd, ... ipv6_src=('2001:db8:bd05:1d2:288a:1fc0:1:10ee', ... 'ffff:ffff:ffff:ffff::'), ... ipv6_dst='2001:db8:bd05:1d2:288a:1fc0:1:10ee') >>> # query >>> if 'ipv6_src' in match: ... print match['ipv6_src'] ... ('2001:db8:bd05:1d2:288a:1fc0:1:10ee', 'ffff:ffff:ffff:ffff::') .. Note:: For the list of the supported Nicira experimenter matches, please refer to :ref:`os_ken.ofproto.nx_match `. .. Note:: For VLAN id match field, special values are defined in OpenFlow Spec. 1) Packets with and without a VLAN tag - Example:: match = parser.OFPMatch() - Packet Matching ====================== ===== non-VLAN-tagged MATCH VLAN-tagged(vlan_id=3) MATCH VLAN-tagged(vlan_id=5) MATCH ====================== ===== 2) Only packets without a VLAN tag - Example:: match = parser.OFPMatch(vlan_vid=0x0000) - Packet Matching ====================== ===== non-VLAN-tagged MATCH VLAN-tagged(vlan_id=3) x VLAN-tagged(vlan_id=5) x ====================== ===== 3) Only packets with a VLAN tag regardless of its value - Example:: match = parser.OFPMatch(vlan_vid=(0x1000, 0x1000)) - Packet Matching ====================== ===== non-VLAN-tagged x VLAN-tagged(vlan_id=3) MATCH VLAN-tagged(vlan_id=5) MATCH ====================== ===== 4) Only packets with VLAN tag and VID equal - Example:: match = parser.OFPMatch(vlan_vid=(0x1000 | 3)) - Packet Matching ====================== ===== non-VLAN-tagged x VLAN-tagged(vlan_id=3) MATCH VLAN-tagged(vlan_id=5) x ====================== ===== """ def __init__(self, type_=None, length=None, _ordered_fields=None, **kwargs): super(OFPMatch, self).__init__() self._wc = FlowWildcards() self._flow = Flow() self.fields = [] self.type = ofproto.OFPMT_OXM self.length = length if _ordered_fields is not None: assert not kwargs self._fields2 = _ordered_fields else: # eg. # OFPMatch(eth_src=('ff:ff:ff:00:00:00'), eth_type=0x800, # ipv4_src='10.0.0.1') kwargs = dict(ofproto.oxm_normalize_user(k, v) for (k, v) in kwargs.items()) fields = [ofproto.oxm_from_user(k, v) for (k, v) in kwargs.items()] # assumption: sorting by OXM type values makes fields # meet ordering requirements (eg. eth_type before ipv4_src) fields.sort( key=lambda x: x[0][0] if isinstance(x[0], tuple) else x[0]) self._fields2 = [ofproto.oxm_to_user(n, v, m) for (n, v, m) in fields] def __getitem__(self, key): return dict(self._fields2)[key] def __contains__(self, key): return key in dict(self._fields2) def iteritems(self): return iter(dict(self._fields2).items()) def items(self): return self._fields2 def get(self, key, default=None): return dict(self._fields2).get(key, default) def stringify_attrs(self): yield "oxm_fields", dict(self._fields2) def to_jsondict(self): """ Returns a dict expressing the flow match. """ # XXX old api compat if self._composed_with_old_api(): # copy object first because serialize_old is destructive o2 = OFPMatch() o2.fields = self.fields[:] # serialize and parse to fill OFPMatch._fields2 buf = bytearray() o2.serialize(buf, 0) o = OFPMatch.parser(bytes(buf), 0) else: o = self body = {"oxm_fields": [ofproto.oxm_to_jsondict(k, uv) for k, uv in o._fields2], "length": o.length, "type": o.type} return {self.__class__.__name__: body} @classmethod def from_jsondict(cls, dict_): """ Returns an object which is generated from a dict. Exception raises: KeyError -- Unknown match field is defined in dict """ fields = [ofproto.oxm_from_jsondict(f) for f in dict_['oxm_fields']] o = OFPMatch(_ordered_fields=fields) # XXX old api compat # serialize and parse to fill OFPMatch.fields buf = bytearray() o.serialize(buf, 0) return OFPMatch.parser(bytes(buf), 0) def __str__(self): # XXX old api compat if self._composed_with_old_api(): # copy object first because serialize_old is destructive o2 = OFPMatch() o2.fields = self.fields[:] # serialize and parse to fill OFPMatch._fields2 buf = bytearray() o2.serialize(buf, 0) o = OFPMatch.parser(bytes(buf), 0) else: o = self return super(OFPMatch, o).__str__() __repr__ = __str__ def append_field(self, header, value, mask=None): """ Append a match field. ========= ======================================================= Argument Description ========= ======================================================= header match field header ID which is defined automatically in ``ofproto_v1_3`` value match field value mask mask value to the match field ========= ======================================================= The available ``header`` is as follows. ====================== =================================== Header ID Description ====================== =================================== OXM_OF_IN_PORT Switch input port OXM_OF_IN_PHY_PORT Switch physical input port OXM_OF_METADATA Metadata passed between tables OXM_OF_ETH_DST Ethernet destination address OXM_OF_ETH_SRC Ethernet source address OXM_OF_ETH_TYPE Ethernet frame type OXM_OF_VLAN_VID VLAN id OXM_OF_VLAN_PCP VLAN priority OXM_OF_IP_DSCP IP DSCP (6 bits in ToS field) OXM_OF_IP_ECN IP ECN (2 bits in ToS field) OXM_OF_IP_PROTO IP protocol OXM_OF_IPV4_SRC IPv4 source address OXM_OF_IPV4_DST IPv4 destination address OXM_OF_TCP_SRC TCP source port OXM_OF_TCP_DST TCP destination port OXM_OF_UDP_SRC UDP source port OXM_OF_UDP_DST UDP destination port OXM_OF_SCTP_SRC SCTP source port OXM_OF_SCTP_DST SCTP destination port OXM_OF_ICMPV4_TYPE ICMP type OXM_OF_ICMPV4_CODE ICMP code OXM_OF_ARP_OP ARP opcode OXM_OF_ARP_SPA ARP source IPv4 address OXM_OF_ARP_TPA ARP target IPv4 address OXM_OF_ARP_SHA ARP source hardware address OXM_OF_ARP_THA ARP target hardware address OXM_OF_IPV6_SRC IPv6 source address OXM_OF_IPV6_DST IPv6 destination address OXM_OF_IPV6_FLABEL IPv6 Flow Label OXM_OF_ICMPV6_TYPE ICMPv6 type OXM_OF_ICMPV6_CODE ICMPv6 code OXM_OF_IPV6_ND_TARGET Target address for ND OXM_OF_IPV6_ND_SLL Source link-layer for ND OXM_OF_IPV6_ND_TLL Target link-layer for ND OXM_OF_MPLS_LABEL MPLS label OXM_OF_MPLS_TC MPLS TC ====================== =================================== """ self.fields.append(OFPMatchField.make(header, value, mask)) def _composed_with_old_api(self): return (self.fields and not self._fields2) or \ self._wc.__dict__ != FlowWildcards().__dict__ def serialize(self, buf, offset): """ Outputs the expression of the wire protocol of the flow match into the buf. Returns the output length. """ # XXX compat if self._composed_with_old_api(): return self.serialize_old(buf, offset) fields = [ofproto.oxm_from_user(k, uv) for (k, uv) in self._fields2] hdr_pack_str = '!HH' field_offset = offset + struct.calcsize(hdr_pack_str) for (n, value, mask) in fields: field_offset += ofproto.oxm_serialize(n, value, mask, buf, field_offset) length = field_offset - offset msg_pack_into(hdr_pack_str, buf, offset, ofproto.OFPMT_OXM, length) self.length = length pad_len = utils.round_up(length, 8) - length msg_pack_into("%dx" % pad_len, buf, field_offset) return length + pad_len def serialize_old(self, buf, offset): if hasattr(self, '_serialized'): raise Exception('serializing an OFPMatch composed with ' 'old API multiple times is not supported') self._serialized = True if self._wc.ft_test(ofproto.OFPXMT_OFB_IN_PORT): self.append_field(ofproto.OXM_OF_IN_PORT, self._flow.in_port) if self._wc.ft_test(ofproto.OFPXMT_OFB_IN_PHY_PORT): self.append_field(ofproto.OXM_OF_IN_PHY_PORT, self._flow.in_phy_port) if self._wc.ft_test(ofproto.OFPXMT_OFB_METADATA): if self._wc.metadata_mask == UINT64_MAX: header = ofproto.OXM_OF_METADATA else: header = ofproto.OXM_OF_METADATA_W self.append_field(header, self._flow.metadata, self._wc.metadata_mask) if self._wc.ft_test(ofproto.OFPXMT_OFB_ETH_DST): if self._wc.dl_dst_mask: header = ofproto.OXM_OF_ETH_DST_W else: header = ofproto.OXM_OF_ETH_DST self.append_field(header, self._flow.dl_dst, self._wc.dl_dst_mask) if self._wc.ft_test(ofproto.OFPXMT_OFB_ETH_SRC): if self._wc.dl_src_mask: header = ofproto.OXM_OF_ETH_SRC_W else: header = ofproto.OXM_OF_ETH_SRC self.append_field(header, self._flow.dl_src, self._wc.dl_src_mask) if self._wc.ft_test(ofproto.OFPXMT_OFB_ETH_TYPE): self.append_field(ofproto.OXM_OF_ETH_TYPE, self._flow.dl_type) if self._wc.ft_test(ofproto.OFPXMT_OFB_VLAN_VID): if self._wc.vlan_vid_mask == UINT16_MAX: header = ofproto.OXM_OF_VLAN_VID else: header = ofproto.OXM_OF_VLAN_VID_W self.append_field(header, self._flow.vlan_vid, self._wc.vlan_vid_mask) if self._wc.ft_test(ofproto.OFPXMT_OFB_VLAN_PCP): self.append_field(ofproto.OXM_OF_VLAN_PCP, self._flow.vlan_pcp) if self._wc.ft_test(ofproto.OFPXMT_OFB_IP_DSCP): self.append_field(ofproto.OXM_OF_IP_DSCP, self._flow.ip_dscp) if self._wc.ft_test(ofproto.OFPXMT_OFB_IP_ECN): self.append_field(ofproto.OXM_OF_IP_ECN, self._flow.ip_ecn) if self._wc.ft_test(ofproto.OFPXMT_OFB_IP_PROTO): self.append_field(ofproto.OXM_OF_IP_PROTO, self._flow.ip_proto) if self._wc.ft_test(ofproto.OFPXMT_OFB_IPV4_SRC): if self._wc.ipv4_src_mask == UINT32_MAX: header = ofproto.OXM_OF_IPV4_SRC else: header = ofproto.OXM_OF_IPV4_SRC_W self.append_field(header, self._flow.ipv4_src, self._wc.ipv4_src_mask) if self._wc.ft_test(ofproto.OFPXMT_OFB_IPV4_DST): if self._wc.ipv4_dst_mask == UINT32_MAX: header = ofproto.OXM_OF_IPV4_DST else: header = ofproto.OXM_OF_IPV4_DST_W self.append_field(header, self._flow.ipv4_dst, self._wc.ipv4_dst_mask) if self._wc.ft_test(ofproto.OFPXMT_OFB_TCP_SRC): self.append_field(ofproto.OXM_OF_TCP_SRC, self._flow.tcp_src) if self._wc.ft_test(ofproto.OFPXMT_OFB_TCP_DST): self.append_field(ofproto.OXM_OF_TCP_DST, self._flow.tcp_dst) if self._wc.ft_test(ofproto.OFPXMT_OFB_UDP_SRC): self.append_field(ofproto.OXM_OF_UDP_SRC, self._flow.udp_src) if self._wc.ft_test(ofproto.OFPXMT_OFB_UDP_DST): self.append_field(ofproto.OXM_OF_UDP_DST, self._flow.udp_dst) if self._wc.ft_test(ofproto.OFPXMT_OFB_SCTP_SRC): self.append_field(ofproto.OXM_OF_SCTP_SRC, self._flow.sctp_src) if self._wc.ft_test(ofproto.OFPXMT_OFB_SCTP_DST): self.append_field(ofproto.OXM_OF_SCTP_DST, self._flow.sctp_dst) if self._wc.ft_test(ofproto.OFPXMT_OFB_ICMPV4_TYPE): self.append_field(ofproto.OXM_OF_ICMPV4_TYPE, self._flow.icmpv4_type) if self._wc.ft_test(ofproto.OFPXMT_OFB_ICMPV4_CODE): self.append_field(ofproto.OXM_OF_ICMPV4_CODE, self._flow.icmpv4_code) if self._wc.ft_test(ofproto.OFPXMT_OFB_ARP_OP): self.append_field(ofproto.OXM_OF_ARP_OP, self._flow.arp_op) if self._wc.ft_test(ofproto.OFPXMT_OFB_ARP_SPA): if self._wc.arp_spa_mask == UINT32_MAX: header = ofproto.OXM_OF_ARP_SPA else: header = ofproto.OXM_OF_ARP_SPA_W self.append_field(header, self._flow.arp_spa, self._wc.arp_spa_mask) if self._wc.ft_test(ofproto.OFPXMT_OFB_ARP_TPA): if self._wc.arp_tpa_mask == UINT32_MAX: header = ofproto.OXM_OF_ARP_TPA else: header = ofproto.OXM_OF_ARP_TPA_W self.append_field(header, self._flow.arp_tpa, self._wc.arp_tpa_mask) if self._wc.ft_test(ofproto.OFPXMT_OFB_ARP_SHA): if self._wc.arp_sha_mask: header = ofproto.OXM_OF_ARP_SHA_W else: header = ofproto.OXM_OF_ARP_SHA self.append_field(header, self._flow.arp_sha, self._wc.arp_sha_mask) if self._wc.ft_test(ofproto.OFPXMT_OFB_ARP_THA): if self._wc.arp_tha_mask: header = ofproto.OXM_OF_ARP_THA_W else: header = ofproto.OXM_OF_ARP_THA self.append_field(header, self._flow.arp_tha, self._wc.arp_tha_mask) if self._wc.ft_test(ofproto.OFPXMT_OFB_IPV6_SRC): if len(self._wc.ipv6_src_mask): header = ofproto.OXM_OF_IPV6_SRC_W else: header = ofproto.OXM_OF_IPV6_SRC self.append_field(header, self._flow.ipv6_src, self._wc.ipv6_src_mask) if self._wc.ft_test(ofproto.OFPXMT_OFB_IPV6_DST): if len(self._wc.ipv6_dst_mask): header = ofproto.OXM_OF_IPV6_DST_W else: header = ofproto.OXM_OF_IPV6_DST self.append_field(header, self._flow.ipv6_dst, self._wc.ipv6_dst_mask) if self._wc.ft_test(ofproto.OFPXMT_OFB_IPV6_FLABEL): if self._wc.ipv6_flabel_mask == UINT32_MAX: header = ofproto.OXM_OF_IPV6_FLABEL else: header = ofproto.OXM_OF_IPV6_FLABEL_W self.append_field(header, self._flow.ipv6_flabel, self._wc.ipv6_flabel_mask) if self._wc.ft_test(ofproto.OFPXMT_OFB_ICMPV6_TYPE): self.append_field(ofproto.OXM_OF_ICMPV6_TYPE, self._flow.icmpv6_type) if self._wc.ft_test(ofproto.OFPXMT_OFB_ICMPV6_CODE): self.append_field(ofproto.OXM_OF_ICMPV6_CODE, self._flow.icmpv6_code) if self._wc.ft_test(ofproto.OFPXMT_OFB_IPV6_ND_TARGET): self.append_field(ofproto.OXM_OF_IPV6_ND_TARGET, self._flow.ipv6_nd_target) if self._wc.ft_test(ofproto.OFPXMT_OFB_IPV6_ND_SLL): self.append_field(ofproto.OXM_OF_IPV6_ND_SLL, self._flow.ipv6_nd_sll) if self._wc.ft_test(ofproto.OFPXMT_OFB_IPV6_ND_TLL): self.append_field(ofproto.OXM_OF_IPV6_ND_TLL, self._flow.ipv6_nd_tll) if self._wc.ft_test(ofproto.OFPXMT_OFB_MPLS_LABEL): self.append_field(ofproto.OXM_OF_MPLS_LABEL, self._flow.mpls_label) if self._wc.ft_test(ofproto.OFPXMT_OFB_MPLS_TC): self.append_field(ofproto.OXM_OF_MPLS_TC, self._flow.mpls_tc) field_offset = offset + 4 for f in self.fields: f.serialize(buf, field_offset) field_offset += f.length length = field_offset - offset msg_pack_into('!HH', buf, offset, ofproto.OFPMT_OXM, length) pad_len = utils.round_up(length, 8) - length msg_pack_into("%dx" % pad_len, buf, field_offset) return length + pad_len @classmethod def parser(cls, buf, offset): """ Returns an object which is generated from a buffer including the expression of the wire protocol of the flow match. """ match = OFPMatch() type_, length = struct.unpack_from('!HH', buf, offset) match.type = type_ match.length = length # ofp_match adjustment offset += 4 length -= 4 # XXXcompat cls.parser_old(match, buf, offset, length) fields = [] while length > 0: n, value, mask, field_len = ofproto.oxm_parse(buf, offset) k, uv = ofproto.oxm_to_user(n, value, mask) fields.append((k, uv)) offset += field_len length -= field_len match._fields2 = fields return match @staticmethod def parser_old(match, buf, offset, length): while length > 0: field = OFPMatchField.parser(buf, offset) offset += field.length length -= field.length match.fields.append(field) def set_in_port(self, port): self._wc.ft_set(ofproto.OFPXMT_OFB_IN_PORT) self._flow.in_port = port def set_in_phy_port(self, phy_port): self._wc.ft_set(ofproto.OFPXMT_OFB_IN_PHY_PORT) self._flow.in_phy_port = phy_port def set_metadata(self, metadata): self.set_metadata_masked(metadata, UINT64_MAX) def set_metadata_masked(self, metadata, mask): self._wc.ft_set(ofproto.OFPXMT_OFB_METADATA) self._wc.metadata_mask = mask self._flow.metadata = metadata & mask def set_dl_dst(self, dl_dst): self._wc.ft_set(ofproto.OFPXMT_OFB_ETH_DST) self._flow.dl_dst = dl_dst def set_dl_dst_masked(self, dl_dst, mask): self._wc.ft_set(ofproto.OFPXMT_OFB_ETH_DST) self._wc.dl_dst_mask = mask # bit-wise and of the corresponding elements of dl_dst and mask self._flow.dl_dst = mac.haddr_bitand(dl_dst, mask) def set_dl_src(self, dl_src): self._wc.ft_set(ofproto.OFPXMT_OFB_ETH_SRC) self._flow.dl_src = dl_src def set_dl_src_masked(self, dl_src, mask): self._wc.ft_set(ofproto.OFPXMT_OFB_ETH_SRC) self._wc.dl_src_mask = mask self._flow.dl_src = mac.haddr_bitand(dl_src, mask) def set_dl_type(self, dl_type): self._wc.ft_set(ofproto.OFPXMT_OFB_ETH_TYPE) self._flow.dl_type = dl_type def set_vlan_vid_none(self): self._wc.ft_set(ofproto.OFPXMT_OFB_VLAN_VID) self._wc.vlan_vid_mask = UINT16_MAX self._flow.vlan_vid = ofproto.OFPVID_NONE def set_vlan_vid(self, vid): self.set_vlan_vid_masked(vid, UINT16_MAX) def set_vlan_vid_masked(self, vid, mask): vid |= ofproto.OFPVID_PRESENT self._wc.ft_set(ofproto.OFPXMT_OFB_VLAN_VID) self._wc.vlan_vid_mask = mask self._flow.vlan_vid = vid def set_vlan_pcp(self, pcp): self._wc.ft_set(ofproto.OFPXMT_OFB_VLAN_PCP) self._flow.vlan_pcp = pcp def set_ip_dscp(self, ip_dscp): self._wc.ft_set(ofproto.OFPXMT_OFB_IP_DSCP) self._flow.ip_dscp = ip_dscp def set_ip_ecn(self, ip_ecn): self._wc.ft_set(ofproto.OFPXMT_OFB_IP_ECN) self._flow.ip_ecn = ip_ecn def set_ip_proto(self, ip_proto): self._wc.ft_set(ofproto.OFPXMT_OFB_IP_PROTO) self._flow.ip_proto = ip_proto def set_ipv4_src(self, ipv4_src): self.set_ipv4_src_masked(ipv4_src, UINT32_MAX) def set_ipv4_src_masked(self, ipv4_src, mask): self._wc.ft_set(ofproto.OFPXMT_OFB_IPV4_SRC) self._flow.ipv4_src = ipv4_src self._wc.ipv4_src_mask = mask def set_ipv4_dst(self, ipv4_dst): self.set_ipv4_dst_masked(ipv4_dst, UINT32_MAX) def set_ipv4_dst_masked(self, ipv4_dst, mask): self._wc.ft_set(ofproto.OFPXMT_OFB_IPV4_DST) self._flow.ipv4_dst = ipv4_dst self._wc.ipv4_dst_mask = mask def set_tcp_src(self, tcp_src): self._wc.ft_set(ofproto.OFPXMT_OFB_TCP_SRC) self._flow.tcp_src = tcp_src def set_tcp_dst(self, tcp_dst): self._wc.ft_set(ofproto.OFPXMT_OFB_TCP_DST) self._flow.tcp_dst = tcp_dst def set_udp_src(self, udp_src): self._wc.ft_set(ofproto.OFPXMT_OFB_UDP_SRC) self._flow.udp_src = udp_src def set_udp_dst(self, udp_dst): self._wc.ft_set(ofproto.OFPXMT_OFB_UDP_DST) self._flow.udp_dst = udp_dst def set_sctp_src(self, sctp_src): self._wc.ft_set(ofproto.OFPXMT_OFB_SCTP_SRC) self._flow.sctp_src = sctp_src def set_sctp_dst(self, sctp_dst): self._wc.ft_set(ofproto.OFPXMT_OFB_SCTP_DST) self._flow.sctp_dst = sctp_dst def set_icmpv4_type(self, icmpv4_type): self._wc.ft_set(ofproto.OFPXMT_OFB_ICMPV4_TYPE) self._flow.icmpv4_type = icmpv4_type def set_icmpv4_code(self, icmpv4_code): self._wc.ft_set(ofproto.OFPXMT_OFB_ICMPV4_CODE) self._flow.icmpv4_code = icmpv4_code def set_arp_opcode(self, arp_op): self._wc.ft_set(ofproto.OFPXMT_OFB_ARP_OP) self._flow.arp_op = arp_op def set_arp_spa(self, arp_spa): self.set_arp_spa_masked(arp_spa, UINT32_MAX) def set_arp_spa_masked(self, arp_spa, mask): self._wc.ft_set(ofproto.OFPXMT_OFB_ARP_SPA) self._wc.arp_spa_mask = mask self._flow.arp_spa = arp_spa def set_arp_tpa(self, arp_tpa): self.set_arp_tpa_masked(arp_tpa, UINT32_MAX) def set_arp_tpa_masked(self, arp_tpa, mask): self._wc.ft_set(ofproto.OFPXMT_OFB_ARP_TPA) self._wc.arp_tpa_mask = mask self._flow.arp_tpa = arp_tpa def set_arp_sha(self, arp_sha): self._wc.ft_set(ofproto.OFPXMT_OFB_ARP_SHA) self._flow.arp_sha = arp_sha def set_arp_sha_masked(self, arp_sha, mask): self._wc.ft_set(ofproto.OFPXMT_OFB_ARP_SHA) self._wc.arp_sha_mask = mask self._flow.arp_sha = mac.haddr_bitand(arp_sha, mask) def set_arp_tha(self, arp_tha): self._wc.ft_set(ofproto.OFPXMT_OFB_ARP_THA) self._flow.arp_tha = arp_tha def set_arp_tha_masked(self, arp_tha, mask): self._wc.ft_set(ofproto.OFPXMT_OFB_ARP_THA) self._wc.arp_tha_mask = mask self._flow.arp_tha = mac.haddr_bitand(arp_tha, mask) def set_ipv6_src(self, src): self._wc.ft_set(ofproto.OFPXMT_OFB_IPV6_SRC) self._flow.ipv6_src = src def set_ipv6_src_masked(self, src, mask): self._wc.ft_set(ofproto.OFPXMT_OFB_IPV6_SRC) self._wc.ipv6_src_mask = mask self._flow.ipv6_src = [x & y for (x, y) in zip(src, mask)] def set_ipv6_dst(self, dst): self._wc.ft_set(ofproto.OFPXMT_OFB_IPV6_DST) self._flow.ipv6_dst = dst def set_ipv6_dst_masked(self, dst, mask): self._wc.ft_set(ofproto.OFPXMT_OFB_IPV6_DST) self._wc.ipv6_dst_mask = mask self._flow.ipv6_dst = [x & y for (x, y) in zip(dst, mask)] def set_ipv6_flabel(self, flabel): self.set_ipv6_flabel_masked(flabel, UINT32_MAX) def set_ipv6_flabel_masked(self, flabel, mask): self._wc.ft_set(ofproto.OFPXMT_OFB_IPV6_FLABEL) self._wc.ipv6_flabel_mask = mask self._flow.ipv6_flabel = flabel def set_icmpv6_type(self, icmpv6_type): self._wc.ft_set(ofproto.OFPXMT_OFB_ICMPV6_TYPE) self._flow.icmpv6_type = icmpv6_type def set_icmpv6_code(self, icmpv6_code): self._wc.ft_set(ofproto.OFPXMT_OFB_ICMPV6_CODE) self._flow.icmpv6_code = icmpv6_code def set_ipv6_nd_target(self, target): self._wc.ft_set(ofproto.OFPXMT_OFB_IPV6_ND_TARGET) self._flow.ipv6_nd_target = target def set_ipv6_nd_sll(self, ipv6_nd_sll): self._wc.ft_set(ofproto.OFPXMT_OFB_IPV6_ND_SLL) self._flow.ipv6_nd_sll = ipv6_nd_sll def set_ipv6_nd_tll(self, ipv6_nd_tll): self._wc.ft_set(ofproto.OFPXMT_OFB_IPV6_ND_TLL) self._flow.ipv6_nd_tll = ipv6_nd_tll def set_mpls_label(self, mpls_label): self._wc.ft_set(ofproto.OFPXMT_OFB_MPLS_LABEL) self._flow.mpls_label = mpls_label def set_mpls_tc(self, mpls_tc): self._wc.ft_set(ofproto.OFPXMT_OFB_MPLS_TC) self._flow.mpls_tc = mpls_tc class OFPMatchField(StringifyMixin): _FIELDS_HEADERS = {} @staticmethod def register_field_header(headers): def _register_field_header(cls): for header in headers: OFPMatchField._FIELDS_HEADERS[header] = cls return cls return _register_field_header def __init__(self, header): self.header = header self.n_bytes = ofproto.oxm_tlv_header_extract_length(header) self.length = 0 @classmethod def cls_to_header(cls, cls_, hasmask): # XXX efficiency inv = dict((v, k) for k, v in cls._FIELDS_HEADERS.items() if (((k >> 8) & 1) != 0) == hasmask) return inv[cls_] @staticmethod def make(header, value, mask=None): cls_ = OFPMatchField._FIELDS_HEADERS.get(header) return cls_(header, value, mask) @classmethod def parser(cls, buf, offset): (header,) = struct.unpack_from('!I', buf, offset) cls_ = OFPMatchField._FIELDS_HEADERS.get(header) if cls_: field = cls_.field_parser(header, buf, offset) else: field = OFPMatchField(header) field.length = (header & 0xff) + 4 return field @classmethod def field_parser(cls, header, buf, offset): mask = None if ofproto.oxm_tlv_header_extract_hasmask(header): pack_str = '!' + cls.pack_str[1:] * 2 (value, mask) = struct.unpack_from(pack_str, buf, offset + 4) else: (value,) = struct.unpack_from(cls.pack_str, buf, offset + 4) return cls(header, value, mask) def serialize(self, buf, offset): if ofproto.oxm_tlv_header_extract_hasmask(self.header): self.put_w(buf, offset, self.value, self.mask) else: self.put(buf, offset, self.value) def _put_header(self, buf, offset): msg_pack_into('!I', buf, offset, self.header) self.length = 4 def _put(self, buf, offset, value): msg_pack_into(self.pack_str, buf, offset, value) self.length += self.n_bytes def put_w(self, buf, offset, value, mask): self._put_header(buf, offset) self._put(buf, offset + self.length, value) self._put(buf, offset + self.length, mask) def put(self, buf, offset, value): self._put_header(buf, offset) self._put(buf, offset + self.length, value) def _putv6(self, buf, offset, value): msg_pack_into(self.pack_str, buf, offset, *value) self.length += self.n_bytes def putv6(self, buf, offset, value, mask=None): self._put_header(buf, offset) self._putv6(buf, offset + self.length, value) if mask and len(mask): self._putv6(buf, offset + self.length, mask) def oxm_len(self): return self.header & 0xff def to_jsondict(self): # remove some redundant attributes d = super(OFPMatchField, self).to_jsondict() v = d[self.__class__.__name__] del v['header'] del v['length'] del v['n_bytes'] return d @classmethod def from_jsondict(cls, dict_): # just pass the dict around. # it will be converted by OFPMatch.__init__(). return {cls.__name__: dict_} def stringify_attrs(self): f = super(OFPMatchField, self).stringify_attrs if not ofproto.oxm_tlv_header_extract_hasmask(self.header): # something like the following, but yield two values (k,v) # return itertools.ifilter(lambda k, v: k != 'mask', iter()) def g(): for k, v in f(): if k != 'mask': yield (k, v) return g() else: return f() @OFPMatchField.register_field_header([ofproto.OXM_OF_IN_PORT]) class MTInPort(OFPMatchField): pack_str = '!I' def __init__(self, header, value, mask=None): super(MTInPort, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto.OXM_OF_METADATA, ofproto.OXM_OF_METADATA_W]) class MTMetadata(OFPMatchField): pack_str = '!Q' def __init__(self, header, value, mask=None): super(MTMetadata, self).__init__(header) self.value = value self.mask = mask @OFPMatchField.register_field_header([ofproto.OXM_OF_IN_PHY_PORT]) class MTInPhyPort(OFPMatchField): pack_str = '!I' def __init__(self, header, value, mask=None): super(MTInPhyPort, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto.OXM_OF_ETH_DST, ofproto.OXM_OF_ETH_DST_W]) class MTEthDst(OFPMatchField): pack_str = '!6s' def __init__(self, header, value, mask=None): super(MTEthDst, self).__init__(header) self.value = value self.mask = mask @OFPMatchField.register_field_header([ofproto.OXM_OF_ETH_SRC, ofproto.OXM_OF_ETH_SRC_W]) class MTEthSrc(OFPMatchField): pack_str = '!6s' def __init__(self, header, value, mask=None): super(MTEthSrc, self).__init__(header) self.value = value self.mask = mask @OFPMatchField.register_field_header([ofproto.OXM_OF_ETH_TYPE]) class MTEthType(OFPMatchField): pack_str = '!H' def __init__(self, header, value, mask=None): super(MTEthType, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto.OXM_OF_VLAN_VID, ofproto.OXM_OF_VLAN_VID_W]) class MTVlanVid(OFPMatchField): pack_str = '!H' def __init__(self, header, value, mask=None): super(MTVlanVid, self).__init__(header) self.value = value self.mask = mask @classmethod def field_parser(cls, header, buf, offset): m = super(MTVlanVid, cls).field_parser(header, buf, offset) m.value &= ~ofproto.OFPVID_PRESENT return m @OFPMatchField.register_field_header([ofproto.OXM_OF_VLAN_PCP]) class MTVlanPcp(OFPMatchField): pack_str = '!B' def __init__(self, header, value, mask=None): super(MTVlanPcp, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto.OXM_OF_IP_DSCP]) class MTIPDscp(OFPMatchField): pack_str = '!B' def __init__(self, header, value, mask=None): super(MTIPDscp, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto.OXM_OF_IP_ECN]) class MTIPECN(OFPMatchField): pack_str = '!B' def __init__(self, header, value, mask=None): super(MTIPECN, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto.OXM_OF_IP_PROTO]) class MTIPProto(OFPMatchField): pack_str = '!B' def __init__(self, header, value, mask=None): super(MTIPProto, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto.OXM_OF_IPV4_SRC, ofproto.OXM_OF_IPV4_SRC_W]) class MTIPV4Src(OFPMatchField): pack_str = '!I' def __init__(self, header, value, mask=None): super(MTIPV4Src, self).__init__(header) self.value = value self.mask = mask @OFPMatchField.register_field_header([ofproto.OXM_OF_IPV4_DST, ofproto.OXM_OF_IPV4_DST_W]) class MTIPV4Dst(OFPMatchField): pack_str = '!I' def __init__(self, header, value, mask=None): super(MTIPV4Dst, self).__init__(header) self.value = value self.mask = mask @OFPMatchField.register_field_header([ofproto.OXM_OF_TCP_SRC]) class MTTCPSrc(OFPMatchField): pack_str = '!H' def __init__(self, header, value, mask=None): super(MTTCPSrc, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto.OXM_OF_TCP_DST]) class MTTCPDst(OFPMatchField): pack_str = '!H' def __init__(self, header, value, mask=None): super(MTTCPDst, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto.OXM_OF_UDP_SRC]) class MTUDPSrc(OFPMatchField): pack_str = '!H' def __init__(self, header, value, mask=None): super(MTUDPSrc, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto.OXM_OF_UDP_DST]) class MTUDPDst(OFPMatchField): pack_str = '!H' def __init__(self, header, value, mask=None): super(MTUDPDst, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto.OXM_OF_SCTP_SRC]) class MTSCTPSrc(OFPMatchField): pack_str = '!H' def __init__(self, header, value, mask=None): super(MTSCTPSrc, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto.OXM_OF_SCTP_DST]) class MTSCTPDst(OFPMatchField): pack_str = '!H' def __init__(self, header, value, mask=None): super(MTSCTPDst, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto.OXM_OF_ICMPV4_TYPE]) class MTICMPV4Type(OFPMatchField): pack_str = '!B' def __init__(self, header, value, mask=None): super(MTICMPV4Type, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto.OXM_OF_ICMPV4_CODE]) class MTICMPV4Code(OFPMatchField): pack_str = '!B' def __init__(self, header, value, mask=None): super(MTICMPV4Code, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto.OXM_OF_ARP_OP]) class MTArpOp(OFPMatchField): pack_str = '!H' def __init__(self, header, value, mask=None): super(MTArpOp, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto.OXM_OF_ARP_SPA, ofproto.OXM_OF_ARP_SPA_W]) class MTArpSpa(OFPMatchField): pack_str = '!I' def __init__(self, header, value, mask=None): super(MTArpSpa, self).__init__(header) self.value = value self.mask = mask @OFPMatchField.register_field_header([ofproto.OXM_OF_ARP_TPA, ofproto.OXM_OF_ARP_TPA_W]) class MTArpTpa(OFPMatchField): pack_str = '!I' def __init__(self, header, value, mask=None): super(MTArpTpa, self).__init__(header) self.value = value self.mask = mask @OFPMatchField.register_field_header([ofproto.OXM_OF_ARP_SHA, ofproto.OXM_OF_ARP_SHA_W]) class MTArpSha(OFPMatchField): pack_str = '!6s' def __init__(self, header, value, mask=None): super(MTArpSha, self).__init__(header) self.value = value self.mask = mask @OFPMatchField.register_field_header([ofproto.OXM_OF_ARP_THA, ofproto.OXM_OF_ARP_THA_W]) class MTArpTha(OFPMatchField): pack_str = '!6s' def __init__(self, header, value, mask=None): super(MTArpTha, self).__init__(header) self.value = value self.mask = mask class MTIPv6(object): @classmethod def field_parser(cls, header, buf, offset): if ofproto.oxm_tlv_header_extract_hasmask(header): pack_str = '!' + cls.pack_str[1:] * 2 value = struct.unpack_from(pack_str, buf, offset + 4) return cls(header, list(value[:8]), list(value[8:])) else: value = struct.unpack_from(cls.pack_str, buf, offset + 4) return cls(header, list(value)) def serialize(self, buf, offset): self.putv6(buf, offset, self.value, self.mask) @OFPMatchField.register_field_header([ofproto.OXM_OF_IPV6_SRC, ofproto.OXM_OF_IPV6_SRC_W]) class MTIPv6Src(MTIPv6, OFPMatchField): pack_str = '!8H' def __init__(self, header, value, mask=None): super(MTIPv6Src, self).__init__(header) self.value = value self.mask = mask @OFPMatchField.register_field_header([ofproto.OXM_OF_IPV6_DST, ofproto.OXM_OF_IPV6_DST_W]) class MTIPv6Dst(MTIPv6, OFPMatchField): pack_str = '!8H' def __init__(self, header, value, mask=None): super(MTIPv6Dst, self).__init__(header) self.value = value self.mask = mask @OFPMatchField.register_field_header([ofproto.OXM_OF_IPV6_FLABEL, ofproto.OXM_OF_IPV6_FLABEL_W]) class MTIPv6Flabel(OFPMatchField): pack_str = '!I' def __init__(self, header, value, mask=None): super(MTIPv6Flabel, self).__init__(header) self.value = value self.mask = mask @OFPMatchField.register_field_header([ofproto.OXM_OF_MPLS_LABEL]) class MTMplsLabel(OFPMatchField): pack_str = '!I' def __init__(self, header, value, mask=None): super(MTMplsLabel, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto.OXM_OF_ICMPV6_TYPE]) class MTICMPV6Type(OFPMatchField): pack_str = '!B' def __init__(self, header, value, mask=None): super(MTICMPV6Type, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto.OXM_OF_ICMPV6_CODE]) class MTICMPV6Code(OFPMatchField): pack_str = '!B' def __init__(self, header, value, mask=None): super(MTICMPV6Code, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto.OXM_OF_IPV6_ND_TARGET]) class MTIPv6NdTarget(MTIPv6, OFPMatchField): pack_str = '!8H' def __init__(self, header, value, mask=None): super(MTIPv6NdTarget, self).__init__(header) self.value = value def serialize(self, buf, offset): self.putv6(buf, offset, self.value) @OFPMatchField.register_field_header([ofproto.OXM_OF_IPV6_ND_SLL]) class MTIPv6NdSll(OFPMatchField): pack_str = '!6s' def __init__(self, header, value, mask=None): super(MTIPv6NdSll, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto.OXM_OF_IPV6_ND_TLL]) class MTIPv6NdTll(OFPMatchField): pack_str = '!6s' def __init__(self, header, value, mask=None): super(MTIPv6NdTll, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto.OXM_OF_MPLS_TC]) class MTMplsTc(OFPMatchField): pack_str = '!B' def __init__(self, header, value, mask=None): super(MTMplsTc, self).__init__(header) self.value = value ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/ofproto/ofproto_v1_3.py0000664000175000017500000014411400000000000020656 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2012 Isaku Yamahata # # 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. """ OpenFlow 1.3 definitions. """ from os_ken.lib import type_desc from os_ken.ofproto import nicira_ext from os_ken.ofproto import ofproto_utils from os_ken.ofproto import oxm_fields from struct import calcsize # struct ofp_header OFP_HEADER_PACK_STR = '!BBHI' OFP_HEADER_SIZE = 8 assert calcsize(OFP_HEADER_PACK_STR) == OFP_HEADER_SIZE # enum ofp_type OFPT_HELLO = 0 # Symmetric message OFPT_ERROR = 1 # Symmetric message OFPT_ECHO_REQUEST = 2 # Symmetric message OFPT_ECHO_REPLY = 3 # Symmetric message OFPT_EXPERIMENTER = 4 # Symmetric message OFPT_FEATURES_REQUEST = 5 # Controller/switch message OFPT_FEATURES_REPLY = 6 # Controller/switch message OFPT_GET_CONFIG_REQUEST = 7 # Controller/switch message OFPT_GET_CONFIG_REPLY = 8 # Controller/switch message OFPT_SET_CONFIG = 9 # Controller/switch message OFPT_PACKET_IN = 10 # Async message OFPT_FLOW_REMOVED = 11 # Async message OFPT_PORT_STATUS = 12 # Async message OFPT_PACKET_OUT = 13 # Controller/switch message OFPT_FLOW_MOD = 14 # Controller/switch message OFPT_GROUP_MOD = 15 # Controller/switch message OFPT_PORT_MOD = 16 # Controller/switch message OFPT_TABLE_MOD = 17 # Controller/switch message OFPT_MULTIPART_REQUEST = 18 # Controller/switch message OFPT_MULTIPART_REPLY = 19 # Controller/switch message OFPT_BARRIER_REQUEST = 20 # Controller/switch message OFPT_BARRIER_REPLY = 21 # Controller/switch message OFPT_QUEUE_GET_CONFIG_REQUEST = 22 # Controller/switch message OFPT_QUEUE_GET_CONFIG_REPLY = 23 # Controller/switch message OFPT_ROLE_REQUEST = 24 # Controller/switch message OFPT_ROLE_REPLY = 25 # Controller/switch message OFPT_GET_ASYNC_REQUEST = 26 # Controller/switch message OFPT_GET_ASYNC_REPLY = 27 # Controller/switch message OFPT_SET_ASYNC = 28 # Controller/switch message OFPT_METER_MOD = 29 # Controller/switch message # struct ofp_port OFP_MAX_PORT_NAME_LEN = 16 OFP_ETH_ALEN = 6 OFP_ETH_ALEN_STR = str(OFP_ETH_ALEN) _OFP_PORT_PACK_STR = 'I4x' + OFP_ETH_ALEN_STR + 's' + '2x' + \ str(OFP_MAX_PORT_NAME_LEN) + 's' + 'IIIIIIII' OFP_PORT_PACK_STR = '!' + _OFP_PORT_PACK_STR OFP_PORT_SIZE = 64 assert calcsize(OFP_PORT_PACK_STR) == OFP_PORT_SIZE # enum ofp_port_config OFPPC_PORT_DOWN = 1 << 0 # Port is administratively down. OFPPC_NO_RECV = 1 << 2 # Drop all packets recieved by port. OFPPC_NO_FWD = 1 << 5 # Drop packets forwarded to port. OFPPC_NO_PACKET_IN = 1 << 6 # Do not send packet-in msgs for port. # enum ofp_port_state OFPPS_LINK_DOWN = 1 << 0 # No physical link present. OFPPS_BLOCKED = 1 << 1 # Port is blocked. OFPPS_LIVE = 1 << 2 # Live for Fast Failover Group. # enum ofp_port_no OFPP_MAX = 0xffffff00 OFPP_IN_PORT = 0xfffffff8 # Send the packet out the input port. This # virtual port must be explicitly used # in order to send back out of the input # port. OFPP_TABLE = 0xfffffff9 # Perform actions in flow table. # NB: This can only be the destination # port for packet-out messages. OFPP_NORMAL = 0xfffffffa # Process with normal L2/L3 switching. OFPP_FLOOD = 0xfffffffb # All physical ports except input port and # those disabled by STP. OFPP_ALL = 0xfffffffc # All physical ports except input port. OFPP_CONTROLLER = 0xfffffffd # Send to controller. OFPP_LOCAL = 0xfffffffe # Local openflow "port". OFPP_ANY = 0xffffffff # Not associated with a physical port. # All ones is used to indicate all queues in a port (for stats retrieval). OFPQ_ALL = 0xffffffff # enum ofp_port_features OFPPF_10MB_HD = 1 << 0 # 10 Mb half-duplex rate support. OFPPF_10MB_FD = 1 << 1 # 10 Mb full-duplex rate support. OFPPF_100MB_HD = 1 << 2 # 100 Mb half-duplex rate support. OFPPF_100MB_FD = 1 << 3 # 100 Mb full-duplex rate support. OFPPF_1GB_HD = 1 << 4 # 1 Gb half-duplex rate support. OFPPF_1GB_FD = 1 << 5 # 1 Gb full-duplex rate support. OFPPF_10GB_FD = 1 << 6 # 10 Gb full-duplex rate support. OFPPF_40GB_FD = 1 << 7 # 40 Gb full-duplex rate support. OFPPF_100GB_FD = 1 << 8 # 100 Gb full-duplex rate support. OFPPF_1TB_FD = 1 << 9 # 1 Tb full-duplex rate support. OFPPF_OTHER = 1 << 10 # Other rate, not in the list. OFPPF_COPPER = 1 << 11 # Copper medium. OFPPF_FIBER = 1 << 12 # Fiber medium. OFPPF_AUTONEG = 1 << 13 # Auto-negotiation. OFPPF_PAUSE = 1 << 14 # Pause. OFPPF_PAUSE_ASYM = 1 << 15 # Asymmetric pause. # struct ofp_packet_queue OFP_PACKET_QUEUE_PACK_STR = '!IIH6x' OFP_PACKET_QUEUE_SIZE = 16 assert calcsize(OFP_PACKET_QUEUE_PACK_STR) == OFP_PACKET_QUEUE_SIZE # enum ofp_queue_properties OFPQT_MIN_RATE = 1 # Minimum datarate guaranteed. OFPQT_MAX_RATE = 2 # Maximum datarate. OFPQT_EXPERIMENTER = 0xffff # Experimenter defined property. # struct ofp_queue_prop_header OFP_QUEUE_PROP_HEADER_PACK_STR = '!HH4x' OFP_QUEUE_PROP_HEADER_SIZE = 8 assert calcsize(OFP_QUEUE_PROP_HEADER_PACK_STR) == OFP_QUEUE_PROP_HEADER_SIZE # struct ofp_queue_prop_min_rate OFP_QUEUE_PROP_MIN_RATE_PACK_STR = '!H6x' OFP_QUEUE_PROP_MIN_RATE_SIZE = 16 assert (calcsize(OFP_QUEUE_PROP_MIN_RATE_PACK_STR) + OFP_QUEUE_PROP_HEADER_SIZE) == OFP_QUEUE_PROP_MIN_RATE_SIZE # struct ofp_queue_prop_max_rate OFP_QUEUE_PROP_MAX_RATE_PACK_STR = '!H6x' OFP_QUEUE_PROP_MAX_RATE_SIZE = 16 assert (calcsize(OFP_QUEUE_PROP_MAX_RATE_PACK_STR) + OFP_QUEUE_PROP_HEADER_SIZE) == OFP_QUEUE_PROP_MAX_RATE_SIZE # struct ofp_queue_prop_experimenter OFP_QUEUE_PROP_EXPERIMENTER_PACK_STR = '!I4x' OFP_QUEUE_PROP_EXPERIMENTER_SIZE = 16 assert (calcsize(OFP_QUEUE_PROP_EXPERIMENTER_PACK_STR) + OFP_QUEUE_PROP_HEADER_SIZE) == OFP_QUEUE_PROP_EXPERIMENTER_SIZE # struct ofp_match _OFP_MATCH_PACK_STR = 'HHBBBB' OFP_MATCH_PACK_STR = '!' + _OFP_MATCH_PACK_STR OFP_MATCH_SIZE = 8 assert calcsize(OFP_MATCH_PACK_STR) == OFP_MATCH_SIZE # enum ofp_match_type OFPMT_STANDARD = 0 # Deprecated OFPMT_OXM = 1 # OpenFlow Extensible Match # enum ofp_oxm_class OFPXMC_NXM_0 = 0x0000 # Backward compatibility with NXM OFPXMC_NXM_1 = 0x0001 # Backward compatibility with NXM OFPXMC_OPENFLOW_BASIC = 0x8000 # Basic class for OpenFlow OFPXMC_EXPERIMENTER = 0xFFFF # Experimenter class # enum ofp_vlan_id OFPVID_PRESENT = 0x1000 # bit that indicate that a VLAN id is set. OFPVID_NONE = 0x0000 # No VLAN id was set. # enum ofp_ipv6exthdr_flags OFPIEH_NONEXT = 1 << 0 # "No next header" encountered. OFPIEH_ESP = 1 << 1 # Encrypted Sec Payload header present. OFPIEH_AUTH = 1 << 2 # Authentication header present. OFPIEH_DEST = 1 << 3 # 1 or 2 dest headers present. OFPIEH_FRAG = 1 << 4 # Fragment header present. OFPIEH_ROUTER = 1 << 5 # Router header present. OFPIEH_HOP = 1 << 6 # Hop-by-hop header present. OFPIEH_UNREP = 1 << 7 # Unexpected repeats encountered. OFPIEH_UNSEQ = 1 << 8 # Unexpected sequencing encountered. # ofp_oxm_experimenter_header OFP_OXM_EXPERIMENTER_HEADER_PACK_STR = '!II' OFP_OXM_EXPERIMENTER_HEADER_SIZE = 8 assert (calcsize(OFP_OXM_EXPERIMENTER_HEADER_PACK_STR) == OFP_OXM_EXPERIMENTER_HEADER_SIZE) # enum ofp_instruction_type OFPIT_GOTO_TABLE = 1 # Setup the next table in the lookup pipeline. OFPIT_WRITE_METADATA = 2 # Setup the metadata field for use later in # pipeline. OFPIT_WRITE_ACTIONS = 3 # Write the action(s) onto the datapath # action set OFPIT_APPLY_ACTIONS = 4 # Applies the action(s) immediately OFPIT_CLEAR_ACTIONS = 5 # Clears all actions from the datapath action # set OFPIT_METER = 6 # Apply meter (rate limiter) OFPIT_EXPERIMENTER = 0xFFFF # Experimenter instruction # struct ofp_instruction_goto_table OFP_INSTRUCTION_GOTO_TABLE_PACK_STR = '!HHB3x' OFP_INSTRUCTION_GOTO_TABLE_SIZE = 8 assert (calcsize(OFP_INSTRUCTION_GOTO_TABLE_PACK_STR) == OFP_INSTRUCTION_GOTO_TABLE_SIZE) # struct ofp_instruction_write_metadata OFP_INSTRUCTION_WRITE_METADATA_PACK_STR = '!HH4xQQ' OFP_INSTRUCTION_WRITE_METADATA_SIZE = 24 assert (calcsize(OFP_INSTRUCTION_WRITE_METADATA_PACK_STR) == OFP_INSTRUCTION_WRITE_METADATA_SIZE) # struct ofp_instruction_actions OFP_INSTRUCTION_ACTIONS_PACK_STR = '!HH4x' OFP_INSTRUCTION_ACTIONS_SIZE = 8 assert (calcsize(OFP_INSTRUCTION_ACTIONS_PACK_STR) == OFP_INSTRUCTION_ACTIONS_SIZE) # struct ofp_instruction_meter OFP_INSTRUCTION_METER_PACK_STR = '!HHI' OFP_INSTRUCTION_METER_SIZE = 8 assert calcsize(OFP_INSTRUCTION_METER_PACK_STR) == OFP_INSTRUCTION_METER_SIZE # enum ofp_action_type OFPAT_OUTPUT = 0 # Output to switch port. OFPAT_COPY_TTL_OUT = 11 # Copy TTL "outwards" -- from # next-to-outermost to outermost OFPAT_COPY_TTL_IN = 12 # Copy TTL "inwards" -- from outermost to # next-to-outermost OFPAT_SET_MPLS_TTL = 15 # MPLS TTL. OFPAT_DEC_MPLS_TTL = 16 # Decrement MPLS TTL OFPAT_PUSH_VLAN = 17 # Push a new VLAN tag OFPAT_POP_VLAN = 18 # Pop the outer VLAN tag OFPAT_PUSH_MPLS = 19 # Push a new MPLS tag OFPAT_POP_MPLS = 20 # Pop the outer MPLS tag OFPAT_SET_QUEUE = 21 # Set queue id when outputting to a port OFPAT_GROUP = 22 # Apply group OFPAT_SET_NW_TTL = 23 # IP TTL. OFPAT_DEC_NW_TTL = 24 # Decrement IP TTL. OFPAT_SET_FIELD = 25 # Set a header field using OXM TLV format. OFPAT_PUSH_PBB = 26 # Push a new PBB service tag (I-TAG) OFPAT_POP_PBB = 27 # Pop the outer PBB service tag (I-TAG) OFPAT_EXPERIMENTER = 0xffff # struct ofp_action_header OFP_ACTION_HEADER_PACK_STR = '!HH4x' OFP_ACTION_HEADER_SIZE = 8 assert calcsize(OFP_ACTION_HEADER_PACK_STR) == OFP_ACTION_HEADER_SIZE # struct ofp_action_output OFP_ACTION_OUTPUT_PACK_STR = '!HHIH6x' OFP_ACTION_OUTPUT_SIZE = 16 assert calcsize(OFP_ACTION_OUTPUT_PACK_STR) == OFP_ACTION_OUTPUT_SIZE # enum ofp_controller_max_len OFPCML_MAX = 0xffe5 # maximum max_len value which can be used to # request a specific byte length. OFPCML_NO_BUFFER = 0xffff # indicates that no buffering should be # applied and the whole packet is to be # sent to the controller. # struct ofp_action_group OFP_ACTION_GROUP_PACK_STR = '!HHI' OFP_ACTION_GROUP_SIZE = 8 assert calcsize(OFP_ACTION_GROUP_PACK_STR) == OFP_ACTION_GROUP_SIZE # struct ofp_action_set_queue OFP_ACTION_SET_QUEUE_PACK_STR = '!HHI' OFP_ACTION_SET_QUEUE_SIZE = 8 assert calcsize(OFP_ACTION_SET_QUEUE_PACK_STR) == OFP_ACTION_SET_QUEUE_SIZE # struct ofp_action_mpls_ttl OFP_ACTION_MPLS_TTL_PACK_STR = '!HHB3x' OFP_ACTION_MPLS_TTL_SIZE = 8 assert calcsize(OFP_ACTION_MPLS_TTL_PACK_STR) == OFP_ACTION_MPLS_TTL_SIZE # struct ofp_action_nw_ttl OFP_ACTION_NW_TTL_PACK_STR = '!HHB3x' OFP_ACTION_NW_TTL_SIZE = 8 assert calcsize(OFP_ACTION_NW_TTL_PACK_STR) == OFP_ACTION_NW_TTL_SIZE # struct ofp_action_push OFP_ACTION_PUSH_PACK_STR = '!HHH2x' OFP_ACTION_PUSH_SIZE = 8 assert calcsize(OFP_ACTION_PUSH_PACK_STR) == OFP_ACTION_PUSH_SIZE # struct ofp_action_pop_mpls OFP_ACTION_POP_MPLS_PACK_STR = '!HHH2x' OFP_ACTION_POP_MPLS_SIZE = 8 assert calcsize(OFP_ACTION_POP_MPLS_PACK_STR) == OFP_ACTION_POP_MPLS_SIZE # struct ofp_action_set_field OFP_ACTION_SET_FIELD_PACK_STR = '!HH4x' OFP_ACTION_SET_FIELD_SIZE = 8 assert calcsize(OFP_ACTION_SET_FIELD_PACK_STR) == OFP_ACTION_SET_FIELD_SIZE # struct ofp_action_experimenter_header OFP_ACTION_EXPERIMENTER_HEADER_PACK_STR = '!HHI' OFP_ACTION_EXPERIMENTER_HEADER_SIZE = 8 assert (calcsize(OFP_ACTION_EXPERIMENTER_HEADER_PACK_STR) == OFP_ACTION_EXPERIMENTER_HEADER_SIZE) # ofp_switch_features OFP_SWITCH_FEATURES_PACK_STR = '!QIBB2xII' OFP_SWITCH_FEATURES_SIZE = 32 assert (calcsize(OFP_SWITCH_FEATURES_PACK_STR) + OFP_HEADER_SIZE == OFP_SWITCH_FEATURES_SIZE) # enum ofp_capabilities OFPC_FLOW_STATS = 1 << 0 # Flow statistics. OFPC_TABLE_STATS = 1 << 1 # Table statistics. OFPC_PORT_STATS = 1 << 2 # Port statistics. OFPC_GROUP_STATS = 1 << 3 # Group statistics. OFPC_IP_REASM = 1 << 5 # Can reassemble IP fragments. OFPC_QUEUE_STATS = 1 << 6 # Queue statistics. OFPC_PORT_BLOCKED = 1 << 8 # Switch will block looping ports. # struct ofp_switch_config OFP_SWITCH_CONFIG_PACK_STR = '!HH' OFP_SWITCH_CONFIG_SIZE = 12 assert (calcsize(OFP_SWITCH_CONFIG_PACK_STR) + OFP_HEADER_SIZE == OFP_SWITCH_CONFIG_SIZE) # enum ofp_config_flags OFPC_FRAG_NORMAL = 0 # No special handling for fragments. OFPC_FRAG_DROP = 1 # Drop fragments. OFPC_FRAG_REASM = 2 # Reassemble (only if OFPC_IP_REASM set). OFPC_FRAG_MASK = 3 # enum ofp_table OFPTT_MAX = 0xfe OFPTT_ALL = 0xff # struct ofp_table_mod OFP_TABLE_MOD_PACK_STR = '!B3xI' OFP_TABLE_MOD_SIZE = 16 assert (calcsize(OFP_TABLE_MOD_PACK_STR) + OFP_HEADER_SIZE == OFP_TABLE_MOD_SIZE) _OFP_FLOW_MOD_PACK_STR0 = 'QQBBHHHIIIH2x' OFP_FLOW_MOD_PACK_STR = '!' + _OFP_FLOW_MOD_PACK_STR0 + _OFP_MATCH_PACK_STR OFP_FLOW_MOD_PACK_STR0 = '!' + _OFP_FLOW_MOD_PACK_STR0 OFP_FLOW_MOD_SIZE = 56 assert (calcsize(OFP_FLOW_MOD_PACK_STR) + OFP_HEADER_SIZE == OFP_FLOW_MOD_SIZE) # enum ofp_flow_mod_command OFPFC_ADD = 0 # New flow. OFPFC_MODIFY = 1 # Modify all matching flows. OFPFC_MODIFY_STRICT = 2 # Modify entry strictly matching wildcards OFPFC_DELETE = 3 # Delete all matching flows. OFPFC_DELETE_STRICT = 4 # Strictly match wildcards and priority. # By default, choose a priority in the middle. OFP_DEFAULT_PRIORITY = 0x8000 # enum ofp_flow_mod_flags OFPFF_SEND_FLOW_REM = 1 << 0 # Send flow removed message when flow # expires or is deleted. OFPFF_CHECK_OVERLAP = 1 << 1 # Check for overlapping entries first. OFPFF_RESET_COUNTS = 1 << 2 # Reset flow packet and byte counts. OFPFF_NO_PKT_COUNTS = 1 << 3 # Don't keep track of packet count. OFPFF_NO_BYT_COUNTS = 1 << 4 # Don't keep track of byte count. # struct ofp_group_mod OFP_GROUP_MOD_PACK_STR = '!HBxI' OFP_GROUP_MOD_SIZE = 16 assert (calcsize(OFP_GROUP_MOD_PACK_STR) + OFP_HEADER_SIZE == OFP_GROUP_MOD_SIZE) # enum ofp_group_mod_command OFPGC_ADD = 0 # New group. OFPGC_MODIFY = 1 # Modify all matching groups. OFPGC_DELETE = 2 # Delete all matching groups. # enum ofp_group OFPG_MAX = 0xffffff00 # Last usable group number. # Fake groups OFPG_ALL = 0xfffffffc # Represents all groups for group delete commands. OFPG_ANY = 0xffffffff # Wildcard group used only for flow stats requests. # Selects all flows regardless of group # (including flows with no group). # enum ofp_group_type OFPGT_ALL = 0 # All (multicast/broadcast) group. OFPGT_SELECT = 1 # Select group. OFPGT_INDIRECT = 2 # Indirect group. OFPGT_FF = 3 # Fast failover group. # struct ofp_bucket OFP_BUCKET_PACK_STR = '!HHII4x' OFP_BUCKET_SIZE = 16 assert calcsize(OFP_BUCKET_PACK_STR) == OFP_BUCKET_SIZE # struct ofp_port_mod OFP_PORT_MOD_PACK_STR = '!I4x' + OFP_ETH_ALEN_STR + 's2xIII4x' OFP_PORT_MOD_SIZE = 40 assert (calcsize(OFP_PORT_MOD_PACK_STR) + OFP_HEADER_SIZE == OFP_PORT_MOD_SIZE) # struct ofp_meter_mod OFP_METER_MOD_PACK_STR = '!HHI' OFP_METER_MOD_SIZE = 16 assert (calcsize(OFP_METER_MOD_PACK_STR) + OFP_HEADER_SIZE == OFP_METER_MOD_SIZE) # enum ofp_meter OFPM_MAX = 0xffff0000 OFPM_SLOWPATH = 0xfffffffd # Meter for slow datapath, if any. OFPM_CONTROLLER = 0xfffffffe # Meter for controller connection. OFPM_ALL = 0xffffffff # Represents all meters for stat requests # commands. # enum ofp_meter_mod_command OFPMC_ADD = 0 # New meter. OFPMC_MODIFY = 1 # Modify specified meter. OFPMC_DELETE = 2 # Delete specified meter. # enum ofp_meter_flags OFPMF_KBPS = 1 << 0 # Rate value in kb/s (kilo-bit per second). OFPMF_PKTPS = 1 << 1 # Rate value in packet/sec. OFPMF_BURST = 1 << 2 # Do burst size. OFPMF_STATS = 1 << 3 # Collect statistics. # struct ofp_meter_band_header OFP_METER_BAND_HEADER_PACK_STR = '!HHII' OFP_METER_BAND_HEADER_SIZE = 12 assert (calcsize(OFP_METER_BAND_HEADER_PACK_STR) == OFP_METER_BAND_HEADER_SIZE) # enum ofp_meter_band_type OFPMBT_DROP = 1 # Drop packet. OFPMBT_DSCP_REMARK = 2 # Remark DSCP in the IP header. OFPMBT_EXPERIMENTER = 0xFFFF # Experimenter meter band. # struct ofp_meter_band_drop OFP_METER_BAND_DROP_PACK_STR = '!HHII4x' OFP_METER_BAND_DROP_SIZE = 16 assert (calcsize(OFP_METER_BAND_DROP_PACK_STR) == OFP_METER_BAND_DROP_SIZE) # struct ofp_meter_band_dscp_remark OFP_METER_BAND_DSCP_REMARK_PACK_STR = '!HHIIB3x' OFP_METER_BAND_DSCP_REMARK_SIZE = 16 assert (calcsize(OFP_METER_BAND_DSCP_REMARK_PACK_STR) == OFP_METER_BAND_DSCP_REMARK_SIZE) # struct ofp_meter_band_experimenter OFP_METER_BAND_EXPERIMENTER_PACK_STR = '!HHIII' OFP_METER_BAND_EXPERIMENTER_SIZE = 16 assert (calcsize(OFP_METER_BAND_EXPERIMENTER_PACK_STR) == OFP_METER_BAND_EXPERIMENTER_SIZE) # struct ofp_multipart_request OFP_MULTIPART_REQUEST_PACK_STR = '!HH4x' OFP_MULTIPART_REQUEST_SIZE = 16 assert (calcsize(OFP_MULTIPART_REQUEST_PACK_STR) + OFP_HEADER_SIZE == OFP_MULTIPART_REQUEST_SIZE) # enum ofp_multipart_request_flags OFPMPF_REQ_MORE = 1 << 0 # More requests to follow. # struct ofp_multipart_reply OFP_MULTIPART_REPLY_PACK_STR = '!HH4x' OFP_MULTIPART_REPLY_SIZE = 16 assert (calcsize(OFP_MULTIPART_REPLY_PACK_STR) + OFP_HEADER_SIZE == OFP_MULTIPART_REPLY_SIZE) # enum ofp_multipart_reply_flags OFPMPF_REPLY_MORE = 1 << 0 # More replies to follow. # enum ofp_multipart_types OFPMP_DESC = 0 OFPMP_FLOW = 1 OFPMP_AGGREGATE = 2 OFPMP_TABLE = 3 OFPMP_PORT_STATS = 4 OFPMP_QUEUE = 5 OFPMP_GROUP = 6 OFPMP_GROUP_DESC = 7 OFPMP_GROUP_FEATURES = 8 OFPMP_METER = 9 OFPMP_METER_CONFIG = 10 OFPMP_METER_FEATURES = 11 OFPMP_TABLE_FEATURES = 12 OFPMP_PORT_DESC = 13 OFPMP_EXPERIMENTER = 0xffff # struct ofp_desc DESC_STR_LEN = 256 DESC_STR_LEN_STR = str(DESC_STR_LEN) SERIAL_NUM_LEN = 32 SERIAL_NUM_LEN_STR = str(SERIAL_NUM_LEN) OFP_DESC_PACK_STR = '!' + \ DESC_STR_LEN_STR + 's' + \ DESC_STR_LEN_STR + 's' + \ DESC_STR_LEN_STR + 's' + \ SERIAL_NUM_LEN_STR + 's' + \ DESC_STR_LEN_STR + 's' OFP_DESC_SIZE = 1056 assert calcsize(OFP_DESC_PACK_STR) == OFP_DESC_SIZE # struct ofp_flow_stats_request _OFP_FLOW_STATS_REQUEST_0_PACK_STR = 'B3xII4xQQ' OFP_FLOW_STATS_REQUEST_0_PACK_STR = '!' + _OFP_FLOW_STATS_REQUEST_0_PACK_STR OFP_FLOW_STATS_REQUEST_0_SIZE = 32 assert (calcsize(OFP_FLOW_STATS_REQUEST_0_PACK_STR) == OFP_FLOW_STATS_REQUEST_0_SIZE) OFP_FLOW_STATS_REQUEST_PACK_STR = (OFP_FLOW_STATS_REQUEST_0_PACK_STR + _OFP_MATCH_PACK_STR) OFP_FLOW_STATS_REQUEST_SIZE = 40 assert (calcsize(OFP_FLOW_STATS_REQUEST_PACK_STR) == OFP_FLOW_STATS_REQUEST_SIZE) # struct ofp_flow_stats _OFP_FLOW_STATS_0_PACK_STR = 'HBxIIHHHH4xQQQ' OFP_FLOW_STATS_0_PACK_STR = '!' + _OFP_FLOW_STATS_0_PACK_STR OFP_FLOW_STATS_0_SIZE = 48 assert calcsize(OFP_FLOW_STATS_0_PACK_STR) == OFP_FLOW_STATS_0_SIZE OFP_FLOW_STATS_PACK_STR = (OFP_FLOW_STATS_0_PACK_STR + _OFP_MATCH_PACK_STR) OFP_FLOW_STATS_SIZE = 56 assert calcsize(OFP_FLOW_STATS_PACK_STR) == OFP_FLOW_STATS_SIZE # struct ofp_flow_stats_request _OFP_AGGREGATE_STATS_REQUEST_0_PACK_STR = 'B3xII4xQQ' OFP_AGGREGATE_STATS_REQUEST_0_PACK_STR = '!' + \ _OFP_AGGREGATE_STATS_REQUEST_0_PACK_STR OFP_AGGREGATE_STATS_REQUEST_0_SIZE = 32 assert (calcsize(OFP_AGGREGATE_STATS_REQUEST_0_PACK_STR) == OFP_AGGREGATE_STATS_REQUEST_0_SIZE) OFP_AGGREGATE_STATS_REQUEST_PACK_STR = \ OFP_AGGREGATE_STATS_REQUEST_0_PACK_STR + _OFP_MATCH_PACK_STR OFP_AGGREGATE_STATS_REQUEST_SIZE = 40 assert (calcsize(OFP_AGGREGATE_STATS_REQUEST_PACK_STR) == OFP_AGGREGATE_STATS_REQUEST_SIZE) # struct ofp_aggregate_stats_request OFP_AGGREGATE_STATS_REQUEST_PACK_STR = '!B3xII4xQQ' + _OFP_MATCH_PACK_STR OFP_AGGREGATE_STATS_REQUEST_SIZE = 40 assert (calcsize(OFP_AGGREGATE_STATS_REQUEST_PACK_STR) == OFP_AGGREGATE_STATS_REQUEST_SIZE) # struct ofp_aggregate_stats_reply OFP_AGGREGATE_STATS_REPLY_PACK_STR = '!QQI4x' OFP_AGGREGATE_STATS_REPLY_SIZE = 24 assert (calcsize(OFP_AGGREGATE_STATS_REPLY_PACK_STR) == OFP_AGGREGATE_STATS_REPLY_SIZE) # struct ofp_table_stats OFP_TABLE_STATS_PACK_STR = '!B3xIQQ' OFP_TABLE_STATS_SIZE = 24 assert calcsize(OFP_TABLE_STATS_PACK_STR) == OFP_TABLE_STATS_SIZE # struct ofp_table_features OFP_MAX_TABLE_NAME_LEN = 32 OFP_MAX_TABLE_NAME_LEN_STR = str(OFP_MAX_TABLE_NAME_LEN) OFP_TABLE_FEATURES_PACK_STR = '!HB5x' + OFP_MAX_TABLE_NAME_LEN_STR + \ 's' + 'QQII' OFP_TABLE_FEATURES_SIZE = 64 assert (calcsize(OFP_TABLE_FEATURES_PACK_STR) == OFP_TABLE_FEATURES_SIZE) # enum ofp_table_feature_prop_type OFPTFPT_INSTRUCTIONS = 0 OFPTFPT_INSTRUCTIONS_MISS = 1 OFPTFPT_NEXT_TABLES = 2 OFPTFPT_NEXT_TABLES_MISS = 3 OFPTFPT_WRITE_ACTIONS = 4 OFPTFPT_WRITE_ACTIONS_MISS = 5 OFPTFPT_APPLY_ACTIONS = 6 OFPTFPT_APPLY_ACTIONS_MISS = 7 OFPTFPT_MATCH = 8 OFPTFPT_WILDCARDS = 10 OFPTFPT_WRITE_SETFIELD = 12 OFPTFPT_WRITE_SETFIELD_MISS = 13 OFPTFPT_APPLY_SETFIELD = 14 OFPTFPT_APPLY_SETFIELD_MISS = 15 OFPTFPT_EXPERIMENTER = 0xFFFE OFPTFPT_EXPERIMENTER_MISS = 0xFFFF # struct ofp_table_feature_prop_instructions OFP_TABLE_FEATURE_PROP_INSTRUCTIONS_PACK_STR = '!HH' OFP_TABLE_FEATURE_PROP_INSTRUCTIONS_SIZE = 4 assert (calcsize(OFP_TABLE_FEATURE_PROP_INSTRUCTIONS_PACK_STR) == OFP_TABLE_FEATURE_PROP_INSTRUCTIONS_SIZE) # struct ofp_table_feature_prop_next_tables OFP_TABLE_FEATURE_PROP_NEXT_TABLES_PACK_STR = '!HH' OFP_TABLE_FEATURE_PROP_NEXT_TABLES_SIZE = 4 assert (calcsize(OFP_TABLE_FEATURE_PROP_NEXT_TABLES_PACK_STR) == OFP_TABLE_FEATURE_PROP_NEXT_TABLES_SIZE) # struct ofp_table_feature_prop_actions OFP_TABLE_FEATURE_PROP_ACTIONS_PACK_STR = '!HH' OFP_TABLE_FEATURE_PROP_ACTIONS_SIZE = 4 assert (calcsize(OFP_TABLE_FEATURE_PROP_ACTIONS_PACK_STR) == OFP_TABLE_FEATURE_PROP_ACTIONS_SIZE) # struct ofp_table_feature_prop_oxm OFP_TABLE_FEATURE_PROP_OXM_PACK_STR = '!HH' OFP_TABLE_FEATURE_PROP_OXM_SIZE = 4 assert (calcsize(OFP_TABLE_FEATURE_PROP_OXM_PACK_STR) == OFP_TABLE_FEATURE_PROP_OXM_SIZE) # struct ofp_port_stats_request OFP_PORT_STATS_REQUEST_PACK_STR = '!I4x' OFP_PORT_STATS_REQUEST_SIZE = 8 assert (calcsize(OFP_PORT_STATS_REQUEST_PACK_STR) == OFP_PORT_STATS_REQUEST_SIZE) # struct ofp_port_stats OFP_PORT_STATS_PACK_STR = '!I4xQQQQQQQQQQQQII' OFP_PORT_STATS_SIZE = 112 assert calcsize(OFP_PORT_STATS_PACK_STR) == OFP_PORT_STATS_SIZE # struct ofp_queue_stats_request OFP_QUEUE_STATS_REQUEST_PACK_STR = '!II' OFP_QUEUE_STATS_REQUEST_SIZE = 8 assert (calcsize(OFP_QUEUE_STATS_REQUEST_PACK_STR) == OFP_QUEUE_STATS_REQUEST_SIZE) # struct ofp_queue_stats OFP_QUEUE_STATS_PACK_STR = '!IIQQQII' OFP_QUEUE_STATS_SIZE = 40 assert calcsize(OFP_QUEUE_STATS_PACK_STR) == OFP_QUEUE_STATS_SIZE # struct ofp_group_stats_request OFP_GROUP_STATS_REQUEST_PACK_STR = '!I4x' OFP_GROUP_STATS_REQUEST_SIZE = 8 assert (calcsize(OFP_GROUP_STATS_REQUEST_PACK_STR) == OFP_GROUP_STATS_REQUEST_SIZE) # struct ofp_group_stats OFP_GROUP_STATS_PACK_STR = '!H2xII4xQQII' OFP_GROUP_STATS_SIZE = 40 assert calcsize(OFP_GROUP_STATS_PACK_STR) == OFP_GROUP_STATS_SIZE # struct ofp_bucket_counter OFP_BUCKET_COUNTER_PACK_STR = '!QQ' OFP_BUCKET_COUNTER_SIZE = 16 assert calcsize(OFP_BUCKET_COUNTER_PACK_STR) == OFP_BUCKET_COUNTER_SIZE # struct ofp_group_desc OFP_GROUP_DESC_PACK_STR = '!HBxI' OFP_GROUP_DESC_SIZE = 8 assert calcsize(OFP_GROUP_DESC_PACK_STR) == OFP_GROUP_DESC_SIZE # struct ofp_group_desc_stats OFP_GROUP_DESC_STATS_PACK_STR = OFP_GROUP_DESC_PACK_STR OFP_GROUP_DESC_STATS_SIZE = OFP_GROUP_DESC_SIZE assert calcsize(OFP_GROUP_DESC_STATS_PACK_STR) == OFP_GROUP_DESC_STATS_SIZE # struct ofp_group_features OFP_GROUP_FEATURES_PACK_STR = '!II4I4I' OFP_GROUP_FEATURES_SIZE = 40 assert calcsize(OFP_GROUP_FEATURES_PACK_STR) == OFP_GROUP_FEATURES_SIZE # enum ofp_group_capabilities OFPGFC_SELECT_WEIGHT = 1 << 0 # Support weight for select groups. OFPGFC_SELECT_LIVENESS = 1 << 1 # Support liveness for select groups. OFPGFC_CHAINING = 1 << 2 # Support chaining groups. OFPGFC_CHAINING_CHECKS = 1 << 3 # Check chaining for loops and delete # struct ofp_meter_multipart_request OFP_METER_MULTIPART_REQUEST_PACK_STR = '!I4x' OFP_METER_MULTIPART_REQUEST_SIZE = 8 assert (calcsize(OFP_METER_MULTIPART_REQUEST_PACK_STR) == OFP_METER_MULTIPART_REQUEST_SIZE) # struct ofp_meter_stats OFP_METER_STATS_PACK_STR = '!IH6xIQQII' OFP_METER_STATS_SIZE = 40 assert calcsize(OFP_METER_STATS_PACK_STR) == OFP_METER_STATS_SIZE # struct ofp_meter_band_stats OFP_METER_BAND_STATS_PACK_STR = '!QQ' OFP_METER_BAND_STATS_SIZE = 16 assert (calcsize(OFP_METER_BAND_STATS_PACK_STR) == OFP_METER_BAND_STATS_SIZE) # struct ofp_meter_config OFP_METER_CONFIG_PACK_STR = '!HHI' OFP_METER_CONFIG_SIZE = 8 assert calcsize(OFP_METER_CONFIG_PACK_STR) == OFP_METER_CONFIG_SIZE # struct ofp_meter_features OFP_METER_FEATURES_PACK_STR = '!IIIBB2x' OFP_METER_FEATURES_SIZE = 16 assert (calcsize(OFP_METER_FEATURES_PACK_STR) == OFP_METER_FEATURES_SIZE) # struct ofp_experimenter_multipart_header OFP_EXPERIMENTER_MULTIPART_HEADER_PACK_STR = '!II' OFP_EXPERIMENTER_MULTIPART_HEADER_SIZE = 8 assert (calcsize(OFP_EXPERIMENTER_MULTIPART_HEADER_PACK_STR) == OFP_EXPERIMENTER_MULTIPART_HEADER_SIZE) # struct ofp_queue_get_config_request OFP_QUEUE_GET_CONFIG_REQUEST_PACK_STR = '!I4x' OFP_QUEUE_GET_CONFIG_REQUEST_SIZE = 16 assert (calcsize(OFP_QUEUE_GET_CONFIG_REQUEST_PACK_STR) + OFP_HEADER_SIZE) == OFP_QUEUE_GET_CONFIG_REQUEST_SIZE # struct ofp_queue_get_config_reply OFP_QUEUE_GET_CONFIG_REPLY_PACK_STR = '!I4x' OFP_QUEUE_GET_CONFIG_REPLY_SIZE = 16 assert (calcsize(OFP_QUEUE_GET_CONFIG_REPLY_PACK_STR) + OFP_HEADER_SIZE) == OFP_QUEUE_GET_CONFIG_REPLY_SIZE # struct ofp_packet_out OFP_PACKET_OUT_PACK_STR = '!IIH6x' OFP_PACKET_OUT_SIZE = 24 assert (calcsize(OFP_PACKET_OUT_PACK_STR) + OFP_HEADER_SIZE == OFP_PACKET_OUT_SIZE) # struct ofp_role_request OFP_ROLE_REQUEST_PACK_STR = '!I4xQ' OFP_ROLE_REQUEST_SIZE = 24 assert (calcsize(OFP_ROLE_REQUEST_PACK_STR) + OFP_HEADER_SIZE == OFP_ROLE_REQUEST_SIZE) # enum ofp_controller_role OFPCR_ROLE_NOCHANGE = 0 # Don't change current role. OFPCR_ROLE_EQUAL = 1 # Default role, full access. OFPCR_ROLE_MASTER = 2 # Full access, at most one master. OFPCR_ROLE_SLAVE = 3 # Read-only access. # struct ofp_async_config OFP_ASYNC_CONFIG_PACK_STR = '!2I2I2I' OFP_ASYNC_CONFIG_SIZE = 32 assert (calcsize(OFP_ASYNC_CONFIG_PACK_STR) + OFP_HEADER_SIZE == OFP_ASYNC_CONFIG_SIZE) # struct ofp_packet_in OFP_PACKET_IN_PACK_STR = '!IHBBQ' OFP_PACKET_IN_SIZE = 32 assert (calcsize(OFP_PACKET_IN_PACK_STR) + OFP_MATCH_SIZE + OFP_HEADER_SIZE == OFP_PACKET_IN_SIZE) # enum ofp_packet_in_reason OFPR_NO_MATCH = 0 # No matching flow. OFPR_ACTION = 1 # Action explicitly output to controller. OFPR_INVALID_TTL = 2 # Packet has invalid TTL. # struct ofp_flow_removed _OFP_FLOW_REMOVED_PACK_STR0 = 'QHBBIIHHQQ' OFP_FLOW_REMOVED_PACK_STR = '!' + _OFP_FLOW_REMOVED_PACK_STR0 + \ _OFP_MATCH_PACK_STR OFP_FLOW_REMOVED_PACK_STR0 = '!' + _OFP_FLOW_REMOVED_PACK_STR0 OFP_FLOW_REMOVED_SIZE = 56 assert (calcsize(OFP_FLOW_REMOVED_PACK_STR) + OFP_HEADER_SIZE == OFP_FLOW_REMOVED_SIZE) # enum ofp_flow_removed_reason OFPRR_IDLE_TIMEOUT = 0 # Flow idle time exceeded idle_timeout. OFPRR_HARD_TIMEOUT = 1 # Time exceeded hard_timeout. OFPRR_DELETE = 2 # Evicted by a DELETE flow mod. OFPRR_GROUP_DELETE = 3 # Group was removed. # struct ofp_port_status OFP_PORT_STATUS_PACK_STR = '!B7x' + _OFP_PORT_PACK_STR OFP_PORT_STATUS_DESC_OFFSET = OFP_HEADER_SIZE + 8 OFP_PORT_STATUS_SIZE = 80 assert (calcsize(OFP_PORT_STATUS_PACK_STR) + OFP_HEADER_SIZE == OFP_PORT_STATUS_SIZE) # enum ofp_port_reason OFPPR_ADD = 0 # The port was added. OFPPR_DELETE = 1 # The port was removed. OFPPR_MODIFY = 2 # Some attribute of the port has changed. # OFPMP_EXPERIMENTER # struct onf_experimenter_multipart_msg # (experimenter == ONF_EXPERIMENTER_ID) ONFMP_FLOW_MONITOR = 1870 # EXT-187 seems to have a lot of flaws. # XXX the spec mentions ONFST_FLOW_MONITOR in some places. # we assume it's same as ONFMP_FLOW_MONITOR. # XXX the spec uses OFPP_NONE. we assume it means OFPP_ANY. # XXX onf_flow_update_full.length is commented to be 24. # but it needs to tell the actual length of instructions. # we assume it's variable. # XXX the spec seems confused between instructions and actions # for onf_flow_update_full/ONFFMF_ACTIONS. we assume they all # are instructions. # XXX the spec does not define payload structures for any of # ONFT_FLOW_MONITOR_CANCEL, ONFT_FLOW_MONITOR_PAUSED, or # ONFT_FLOW_MONITOR_RESUMED. we assume they are same as NX. # according to NX spec (OVS nicira-ext.h and ofp-msg.h): # NXT_FLOW_MONITOR_CANCEL: a single u32 'id'. # NXT_FLOW_MONITOR_PAUSED/RESUMED: empty payload # (OF1.4 uses something different; OFPFMC_DELETE for CANCEL and # OFPFME_ for PAUSED/RESUMED.) # XXX onf_flow_monitor_request and onf_flow_update_full use # match_len + oxm_fields instead of ofp_match. this pointless # diverge from OF1.4 looks like a botch when updating from OF1.0. # XXX the spec mentions "the current implementation of Open vSwitch" # but, as of writing this, it doesn't have this extension implemented # at all. we assume that it is about OF1.0 NX. # XXX the spec mentions nx13_flow_monitor_request but i couldn't find # it in OVS nicira-ext.h. # onf_flow_monitor_request # ONFMP_FLOW_MONITOR request's body is zero or more instances of this. # id, flags, match_len, out_put, table_id, zeros[3] ONF_FLOW_MONITOR_REQUEST_PACK_STR = '!IHHIB3x' ONF_FLOW_MONITOR_REQUEST_SIZE = 16 assert (calcsize(ONF_FLOW_MONITOR_REQUEST_PACK_STR) == ONF_FLOW_MONITOR_REQUEST_SIZE) # onf_flow_monitor_request.flags ONFFMF_INITIAL = 1 << 0 ONFFMF_ADD = 1 << 1 ONFFMF_DELETE = 1 << 2 ONFFMF_MODIFY = 1 << 3 ONFFMF_ACTIONS = 1 << 4 ONFFMF_OWN = 1 << 5 # onf_flow_update_header # ONFMP_FLOW_MONITOR request's body is an array of this # length, event ONF_FLOW_UPDATE_HEADER_PACK_STR = '!HH' ONF_FLOW_UPDATE_HEADER_SIZE = 4 assert (calcsize(ONF_FLOW_UPDATE_HEADER_PACK_STR) == ONF_FLOW_UPDATE_HEADER_SIZE) # onf_flow_update_full, excluding onf_flow_update_header # reason, priority, idle_timeout, hard_timeout, match_len, table_id, # pad, cookie ONF_FLOW_UPDATE_FULL_PACK_STR = '!HHHHHBxQ' ONF_FLOW_UPDATE_FULL_SIZE = 24 - ONF_FLOW_UPDATE_HEADER_SIZE assert (calcsize(ONF_FLOW_UPDATE_FULL_PACK_STR) == ONF_FLOW_UPDATE_FULL_SIZE) # onf_flow_update_abbrev, excluding onf_flow_update_header # xid ONF_FLOW_UPDATE_ABBREV_PACK_STR = '!I' ONF_FLOW_UPDATE_ABBREV_SIZE = 8 - ONF_FLOW_UPDATE_HEADER_SIZE assert (calcsize(ONF_FLOW_UPDATE_ABBREV_PACK_STR) == ONF_FLOW_UPDATE_ABBREV_SIZE) # enum onf_flow_udpate_event ONFFME_ADDED = 0 # some variations in the spec; ONFMFE_ADD, ONFFME_ADD ONFFME_DELETED = 1 ONFFME_MODIFIED = 2 ONFFME_ABBREV = 3 # enum onf_flow_monitor_msg_type ONFT_FLOW_MONITOR_CANCEL = 1870 # controller -> switch ONFT_FLOW_MONITOR_PAUSED = 1871 # switch -> controller ONFT_FLOW_MONITOR_RESUMED = 1872 # switch -> controller # EXT-230 Bundle extension # enum onf_exp_type ONF_ET_BUNDLE_CONTROL = 2300 ONF_ET_BUNDLE_ADD_MESSAGE = 2301 ONF_BUNDLE_CTRL_PACK_STR = '!IHH' ONF_BUNDLE_CTRL_SIZE = 8 assert (calcsize(ONF_BUNDLE_CTRL_PACK_STR) == ONF_BUNDLE_CTRL_SIZE) ONF_BUNDLE_ADD_MSG_PACK_STR = '!I2xH' ONF_BUNDLE_ADD_MSG_SIZE = 16 - OFP_HEADER_SIZE assert (calcsize(ONF_BUNDLE_ADD_MSG_PACK_STR) == ONF_BUNDLE_ADD_MSG_SIZE) # enum onf_bundle_ctrl_type ONF_BCT_OPEN_REQUEST = 0 ONF_BCT_OPEN_REPLY = 1 ONF_BCT_CLOSE_REQUEST = 2 ONF_BCT_CLOSE_REPLY = 3 ONF_BCT_COMMIT_REQUEST = 4 ONF_BCT_COMMIT_REPLY = 5 ONF_BCT_DISCARD_REQUEST = 6 ONF_BCT_DISCARD_REPLY = 7 # enum onf_bundle_flags ONF_BF_ATOMIC = 1 << 0 ONF_BF_ORDERED = 1 << 1 # enum onf_bundle_prop_type ONF_ET_BPT_EXPERIMENTER = 0xffff # struct ofp_error_msg OFP_ERROR_MSG_PACK_STR = '!HH' OFP_ERROR_MSG_SIZE = 12 assert (calcsize(OFP_ERROR_MSG_PACK_STR) + OFP_HEADER_SIZE == OFP_ERROR_MSG_SIZE) # enum ofp_error_type OFPET_HELLO_FAILED = 0 # Hello protocol failed. OFPET_BAD_REQUEST = 1 # Request was not understood. OFPET_BAD_ACTION = 2 # Error in action description. OFPET_BAD_INSTRUCTION = 3 # Error in instruction list. OFPET_BAD_MATCH = 4 # Error in match. OFPET_FLOW_MOD_FAILED = 5 # Problem modifying flow entry. OFPET_GROUP_MOD_FAILED = 6 # Problem modifying group entry. OFPET_PORT_MOD_FAILED = 7 # OFPT_PORT_MOD failed. OFPET_TABLE_MOD_FAILED = 8 # Table mod request failed. OFPET_QUEUE_OP_FAILED = 9 # Queue operation failed. OFPET_SWITCH_CONFIG_FAILED = 10 # Switch config request failed. OFPET_ROLE_REQUEST_FAILED = 11 # Controller Role request failed. OFPET_METER_MOD_FAILED = 12 # Error in meter. OFPET_TABLE_FEATURES_FAILED = 13 # Setting table features failed. OFPET_EXPERIMENTER = 0xffff # Experimenter error messages. # enum ofp_hello_failed_code OFPHFC_INCOMPATIBLE = 0 # No compatible version. OFPHFC_EPERM = 1 # Permissions error. # enum ofp_bad_request_code OFPBRC_BAD_VERSION = 0 # ofp_header.version not supported. OFPBRC_BAD_TYPE = 1 # ofp_header.type not supported. OFPBRC_BAD_MULTIPART = 2 # ofp_multipart_request.type not # supported. OFPBRC_BAD_EXPERIMENTER = 3 # Experimenter id not supported # (in ofp_experimenter_header # or ofp_multipart_request or # ofp_multipart_reply). OFPBRC_BAD_EXP_TYPE = 4 # Experimenter type not supported. OFPBRC_EPERM = 5 # Permissions error. OFPBRC_BAD_LEN = 6 # Wrong request length for type. OFPBRC_BUFFER_EMPTY = 7 # Specified buffer has already been # used. OFPBRC_BUFFER_UNKNOWN = 8 # Specified buffer does not exist. OFPBRC_BAD_TABLE_ID = 9 # Specified table-id invalid or does # not exist. OFPBRC_IS_SLAVE = 10 # Denied because controller is slave. OFPBRC_BAD_PORT = 11 # Invalid port. OFPBRC_BAD_PACKET = 12 # Invalid packet in packet-out OFPBRC_MULTIPART_BUFFER_OVERFLOW = 13 # ofp_multipart_request # overflowed the assigned buffer. # enum ofp_bad_action_code OFPBAC_BAD_TYPE = 0 # Unknown action type. OFPBAC_BAD_LEN = 1 # Length problem in actions. OFPBAC_BAD_EXPERIMENTER = 2 # Unknown experimenter id specified. OFPBAC_BAD_EXP_TYPE = 3 # Unknown action type for experimenter id. OFPBAC_BAD_OUT_PORT = 4 # Problem validating output action. OFPBAC_BAD_ARGUMENT = 5 # Bad action argument. OFPBAC_EPERM = 6 # Permissions error. OFPBAC_TOO_MANY = 7 # Can't handle this many actions. OFPBAC_BAD_QUEUE = 8 # Problem validating output queue. OFPBAC_BAD_OUT_GROUP = 9 # Invalid group id in forward action. OFPBAC_MATCH_INCONSISTENT = 10 # Action can't apply for this match, # or Set-Field missing prerequisite. OFPBAC_UNSUPPORTED_ORDER = 11 # Action order is unsupported for # the action list in an Apply-Actions # instruction OFPBAC_BAD_TAG = 12 # Actions uses an unsupported tag/encap. OFPBAC_BAD_SET_TYPE = 13 # Unsupported type in SET_FIELD action. OFPBAC_BAD_SET_LEN = 14 # Length problem in SET_FIELD action. OFPBAC_BAD_SET_ARGUMENT = 15 # Bad arguement in SET_FIELD action. # enum ofp_bad_instruction_code OFPBIC_UNKNOWN_INST = 0 # Unknown instruction. OFPBIC_UNSUP_INST = 1 # Switch or table does not support # the instruction. OFPBIC_BAD_TABLE_ID = 2 # Invalid Table-Id specified OFPBIC_UNSUP_METADATA = 3 # Metadata value unsupported by datapath. OFPBIC_UNSUP_METADATA_MASK = 4 # Metadata mask value unsupported by # datapath. OFPBIC_BAD_EXPERIMENTER = 5 # Unknown experimenter id specified. OFPBIC_BAD_EXP_TYPE = 6 # Unknown instruction for experimenter id. OFPBIC_BAD_LEN = 7 # Length problem in instrucitons. OFPBIC_EPERM = 8 # Permissions error. # enum ofp_bad_match_code OFPBMC_BAD_TYPE = 0 # Unsupported match type apecified by # the match. OFPBMC_BAD_LEN = 1 # Length problem in math. OFPBMC_BAD_TAG = 2 # Match uses an unsupported tag/encap. OFPBMC_BAD_DL_ADDR_MASK = 3 # Unsupported datalink addr mask - # switch does not support arbitrary # datalink address mask. OFPBMC_BAD_NW_ADDR_MASK = 4 # Unsupported network addr mask - # switch does not support arbitrary # network addres mask. OFPBMC_BAD_WILDCARDS = 5 # Unsupported combination of fields # masked or omitted in the match. OFPBMC_BAD_FIELD = 6 # Unsupported field type in the match. OFPBMC_BAD_VALUE = 7 # Unsupported value in a match field. OFPBMC_BAD_MASK = 8 # Unsupported mask specified in the # match. OFPBMC_BAD_PREREQ = 9 # A prerequisite was not met. OFPBMC_DUP_FIELD = 10 # A field type was duplicated. OFPBMC_EPERM = 11 # Permissions error. # enum ofp_flow_mod_failed_code OFPFMFC_UNKNOWN = 0 # Unspecified error. OFPFMFC_TABLE_FULL = 1 # Flow not added because table was full. OFPFMFC_BAD_TABLE_ID = 2 # Table does not exist OFPFMFC_OVERLAP = 3 # Attempted to add overlapping flow # with CHECK_OVERLAP flag set. OFPFMFC_EPERM = 4 # Permissions error. OFPFMFC_BAD_TIMEOUT = 5 # Flow not added because of # unsupported idle/hard timeout. OFPFMFC_BAD_COMMAND = 6 # Unsupported or unknown command. OFPFMFC_BAD_FLAGS = 7 # Unsupported or unknown flags. # enum ofp_group_mod_failed_code OFPGMFC_GROUP_EXISTS = 0 OFPGMFC_INVALID_GROUP = 1 OFPGMFC_WEIGHT_UNSUPPORTED = 2 # Switch does not support unequal load # sharing with select groups. OFPGMFC_OUT_OF_GROUPS = 3 # The group table is full. OFPGMFC_OUT_OF_BUCKETS = 4 # The maximum number of action buckets # for a group has been exceeded. OFPGMFC_CHAINING_UNSUPPORTED = 5 # Switch does not support groups that # forward to groups. OFPGMFC_WATCH_UNSUPPORTED = 6 # This group cannot watch the # watch_port or watch_group specified. OFPGMFC_LOOP = 7 # Group entry would cause a loop. OFPGMFC_UNKNOWN_GROUP = 8 # Group not modified because a group # MODIFY attempted to modify a # non-existent group. OFPGMFC_CHAINED_GROUP = 9 # Group not deleted because another # group is forwarding to it. OFPGMFC_BAD_TYPE = 10 # Unsupported or unknown group type. OFPGMFC_BAD_COMMAND = 11 # Unsupported or unknown command. OFPGMFC_BAD_BUCKET = 12 # Error in bucket. OFPGMFC_BAD_WATCH = 13 # Error in watch port/group. OFPGMFC_EPERM = 14 # Permissions error. # enum ofp_port_mod_failed_code OFPPMFC_BAD_PORT = 0 # Specified port does not exist. OFPPMFC_BAD_HW_ADDR = 1 # Specified hardware address does not # match the port number. OFPPMFC_BAD_CONFIG = 2 # Specified config is invalid. OFPPMFC_BAD_ADVERTISE = 3 # Specified advertise is invalid. OFPPMFC_EPERM = 4 # Permissions error. # enum ofp_table_mod_failed_code OFPTMFC_BAD_TABLE = 0 # Specified table does not exist. OFPTMFC_BAD_CONFIG = 1 # Specified config is invalid. OFPTMFC_EPERM = 2 # Permissions error # enum ofp_queue_op_failed_code OFPQOFC_BAD_PORT = 0 # Invalid port (or port does not exist). OFPQOFC_BAD_QUEUE = 1 # Queue does not exist. OFPQOFC_EPERM = 2 # Permissions error. # enum ofp_switch_config_failed_code OFPSCFC_BAD_FLAGS = 0 # Specified flags is invalid. OFPSCFC_BAD_LEN = 1 # Specified len is invalid. OFPQCFC_EPERM = 2 # Permissions error (depracated). # New or updated OSKen applications shall use # OFPSCFC_EPERM. The variable name is a typo of # in specifications before v1.3.1 (EXT-208). OFPSCFC_EPERM = 2 # Permissions error. # enum ofp_role_request_failed_code OFPRRFC_STALE = 0 # Stale Message: old generation_id. OFPRRFC_UNSUP = 1 # Controller role change unsupported. OFPRRFC_BAD_ROLE = 2 # Invalid role. # enum ofp_meter_mod_failed_code OFPMMFC_UNKNOWN = 0 # Unspecified error. OFPMMFC_METER_EXISTS = 1 # Meter not added because a Meter ADD # attempted to replace an existing Meter. OFPMMFC_INVALID_METER = 2 # Meter not added because Meter specified # is invalid. OFPMMFC_UNKNOWN_METER = 3 # Meter not modified because a Meter # MODIFY attempted to modify a non-existent # Meter. OFPMMFC_BAD_COMMAND = 4 # Unsupported or unknown command. OFPMMFC_BAD_FLAGS = 5 # Flag configuration unsupported. OFPMMFC_BAD_RATE = 6 # Rate unsupported. OFPMMFC_BAD_BURST = 7 # Burst size unsupported. OFPMMFC_BAD_BAND = 8 # Band unsupported. OFPMMFC_BAD_BAND_VALUE = 9 # Band value unsupported. OFPMMFC_OUT_OF_METERS = 10 # No more meters availabile. OFPMMFC_OUT_OF_BANDS = 11 # The maximum number of properties # for a meter has been exceeded. # enum ofp_table_features_failed_code OFPTFFC_BAD_TABLE = 0 # Specified table does not exist. OFPTFFC_BAD_METADATA = 1 # Invalid metadata mask. OFPTFFC_BAD_TYPE = 2 # Unknown property type. OFPTFFC_BAD_LEN = 3 # Length problem in properties. OFPTFFC_BAD_ARGUMENT = 4 # Unsupported property value. OFPTFFC_EPERM = 5 # Permissions error. # struct ofp_error_experimenter_msg OFP_ERROR_EXPERIMENTER_MSG_PACK_STR = '!HHI' OFP_ERROR_EXPERIMENTER_MSG_SIZE = 16 assert (calcsize(OFP_ERROR_EXPERIMENTER_MSG_PACK_STR) + OFP_HEADER_SIZE) == OFP_ERROR_EXPERIMENTER_MSG_SIZE # struct ofp_experimenter_header OFP_EXPERIMENTER_HEADER_PACK_STR = '!II' OFP_EXPERIMENTER_HEADER_SIZE = 16 assert (calcsize(OFP_EXPERIMENTER_HEADER_PACK_STR) + OFP_HEADER_SIZE == OFP_EXPERIMENTER_HEADER_SIZE) # exp_type values for OFPET_EXPERIMENTER (experimenter=ONF_EXPERIMENTER_ID) ONFERR_ET_UNKNOWN = 2300 ONFERR_ET_EPERM = 2301 ONFERR_ET_BAD_ID = 2302 ONFERR_ET_BUNDLE_EXIST = 2303 ONFERR_ET_BUNDLE_CLOSED = 2304 ONFERR_ET_OUT_OF_BUNDLES = 2305 ONFERR_ET_BAD_TYPE = 2306 ONFERR_ET_BAD_FLAGS = 2307 ONFERR_ET_MSG_BAD_LEN = 2308 ONFERR_ET_MSG_BAD_XID = 2309 ONFERR_ET_MSG_UNSUP = 2310 ONFERR_ET_MSG_CONFLICT = 2311 ONFERR_ET_MSG_TOO_MANY = 2312 ONFERR_ET_FAILED = 2313 ONFERR_ET_TIMEOUT = 2314 ONFERR_ET_BUNDLE_IN_PROGRESS = 2315 ONFERR_ET_CANT_SYNC = 2320 ONFERR_ET_BAD_PRIORITY = 2360 ONFERR_ET_ASYNC_INVALUD = 2370 ONFERR_ET_ASYNC_UNSUPPORTED = 2371 ONFERR_ET_ASYNC_EPERM = 2372 ONFERR_DUP_INSTRUCTION = 2600 # the lack of _ET_ is per spec ONFERR_ET_MPART_REQUEST_TIMEOUT = 2640 ONFERR_ET_MPART_REPLY_TIMEOUT = 2641 # struct ofp_hello OFP_HELLO_HEADER_SIZE = 8 # struct ofp_hello_elem_header OFP_HELLO_ELEM_HEADER_PACK_STR = '!HH' OFP_HELLO_ELEM_HEADER_SIZE = 4 assert (calcsize(OFP_HELLO_ELEM_HEADER_PACK_STR) == OFP_HELLO_ELEM_HEADER_SIZE) # enum ofp_hello_elem_type OFPHET_VERSIONBITMAP = 1 # struct ofp_hello_elem_versionbitmap OFP_HELLO_ELEM_VERSIONBITMAP_HEADER_PACK_STR = '!HH' OFP_HELLO_ELEM_VERSIONBITMAP_HEADER_SIZE = 4 assert (calcsize(OFP_HELLO_ELEM_VERSIONBITMAP_HEADER_PACK_STR) == OFP_HELLO_ELEM_VERSIONBITMAP_HEADER_SIZE) # OXM def _oxm_tlv_header(class_, field, hasmask, length): return (class_ << 16) | (field << 9) | (hasmask << 8) | length def oxm_tlv_header(field, length): return _oxm_tlv_header(OFPXMC_OPENFLOW_BASIC, field, 0, length) def oxm_tlv_header_w(field, length): return _oxm_tlv_header(OFPXMC_OPENFLOW_BASIC, field, 1, length * 2) def oxm_tlv_header_extract_hasmask(header): return (header >> 8) & 1 def oxm_tlv_header_extract_length(header): if oxm_tlv_header_extract_hasmask(header): length = (header & 0xff) // 2 else: length = header & 0xff return length oxm_types = [ oxm_fields.OpenFlowBasic('in_port', 0, type_desc.Int4), oxm_fields.OpenFlowBasic('in_phy_port', 1, type_desc.Int4), oxm_fields.OpenFlowBasic('metadata', 2, type_desc.Int8), oxm_fields.OpenFlowBasic('eth_dst', 3, type_desc.MacAddr), oxm_fields.OpenFlowBasic('eth_src', 4, type_desc.MacAddr), oxm_fields.OpenFlowBasic('eth_type', 5, type_desc.Int2), oxm_fields.OpenFlowBasic('vlan_vid', 6, type_desc.Int2), oxm_fields.OpenFlowBasic('vlan_pcp', 7, type_desc.Int1), oxm_fields.OpenFlowBasic('ip_dscp', 8, type_desc.Int1), oxm_fields.OpenFlowBasic('ip_ecn', 9, type_desc.Int1), oxm_fields.OpenFlowBasic('ip_proto', 10, type_desc.Int1), oxm_fields.OpenFlowBasic('ipv4_src', 11, type_desc.IPv4Addr), oxm_fields.OpenFlowBasic('ipv4_dst', 12, type_desc.IPv4Addr), oxm_fields.OpenFlowBasic('tcp_src', 13, type_desc.Int2), oxm_fields.OpenFlowBasic('tcp_dst', 14, type_desc.Int2), oxm_fields.OpenFlowBasic('udp_src', 15, type_desc.Int2), oxm_fields.OpenFlowBasic('udp_dst', 16, type_desc.Int2), oxm_fields.OpenFlowBasic('sctp_src', 17, type_desc.Int2), oxm_fields.OpenFlowBasic('sctp_dst', 18, type_desc.Int2), oxm_fields.OpenFlowBasic('icmpv4_type', 19, type_desc.Int1), oxm_fields.OpenFlowBasic('icmpv4_code', 20, type_desc.Int1), oxm_fields.OpenFlowBasic('arp_op', 21, type_desc.Int2), oxm_fields.OpenFlowBasic('arp_spa', 22, type_desc.IPv4Addr), oxm_fields.OpenFlowBasic('arp_tpa', 23, type_desc.IPv4Addr), oxm_fields.OpenFlowBasic('arp_sha', 24, type_desc.MacAddr), oxm_fields.OpenFlowBasic('arp_tha', 25, type_desc.MacAddr), oxm_fields.OpenFlowBasic('ipv6_src', 26, type_desc.IPv6Addr), oxm_fields.OpenFlowBasic('ipv6_dst', 27, type_desc.IPv6Addr), oxm_fields.OpenFlowBasic('ipv6_flabel', 28, type_desc.Int4), oxm_fields.OpenFlowBasic('icmpv6_type', 29, type_desc.Int1), oxm_fields.OpenFlowBasic('icmpv6_code', 30, type_desc.Int1), oxm_fields.OpenFlowBasic('ipv6_nd_target', 31, type_desc.IPv6Addr), oxm_fields.OpenFlowBasic('ipv6_nd_sll', 32, type_desc.MacAddr), oxm_fields.OpenFlowBasic('ipv6_nd_tll', 33, type_desc.MacAddr), oxm_fields.OpenFlowBasic('mpls_label', 34, type_desc.Int4), oxm_fields.OpenFlowBasic('mpls_tc', 35, type_desc.Int1), oxm_fields.OpenFlowBasic('mpls_bos', 36, type_desc.Int1), oxm_fields.OpenFlowBasic('pbb_isid', 37, type_desc.Int3), oxm_fields.OpenFlowBasic('tunnel_id', 38, type_desc.Int8), oxm_fields.OpenFlowBasic('ipv6_exthdr', 39, type_desc.Int2), # EXT-256 Old version of ONF Extension oxm_fields.OldONFExperimenter('pbb_uca', 2560, type_desc.Int1), # EXT-109 TCP flags match field Extension oxm_fields.ONFExperimenter('tcp_flags', 42, type_desc.Int2), # EXT-233 Output match Extension # NOTE(yamamoto): The spec says uint64_t but I assume it's an error. oxm_fields.ONFExperimenter('actset_output', 43, type_desc.Int4), # Support for matching/setting xreg0-7 oxm_fields.PacketRegs('xreg0', 0, type_desc.Int8), oxm_fields.PacketRegs('xreg1', 1, type_desc.Int8), oxm_fields.PacketRegs('xreg2', 2, type_desc.Int8), oxm_fields.PacketRegs('xreg3', 3, type_desc.Int8), oxm_fields.PacketRegs('xreg4', 4, type_desc.Int8), oxm_fields.PacketRegs('xreg5', 5, type_desc.Int8), oxm_fields.PacketRegs('xreg6', 6, type_desc.Int8), oxm_fields.PacketRegs('xreg7', 7, type_desc.Int8), ] + nicira_ext.oxm_types oxm_fields.generate(__name__) # Note: struct ofp_prop_experimenter is specific to this implementation. # It does not have a corresponding structure in the specification. # This structure defines common structure for ofp_*_prop_experimenter. # struct ofp_prop_experimenter OFP_PROP_EXPERIMENTER_PACK_STR = '!HHII' OFP_PROP_EXPERIMENTER_SIZE = 12 assert (calcsize(OFP_PROP_EXPERIMENTER_PACK_STR) == OFP_PROP_EXPERIMENTER_SIZE) # generate utility methods ofproto_utils.generate(__name__) # define constants OFP_VERSION = 0x04 OFP_TCP_PORT = 6633 MAX_XID = 0xffffffff OFP_NO_BUFFER = 0xffffffff ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/ofproto/ofproto_v1_3_parser.py0000664000175000017500000072274300000000000022244 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2012, 2013 Isaku Yamahata # # 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 implements OpenFlow 1.3.x. This module also implements some of extensions shown in "OpenFlow Extensions for 1.3.X Pack 1". Namely, the following extensions are implemented. - EXT-230 Bundle Extension (without bundle properties) - EXT-236 Bad flow entry priority error Extension - EXT-237 Set async config error Extension - EXT-256 PBB UCA header field Extension - EXT-260 Duplicate instruction error Extension - EXT-264 Multipart timeout errors Extension The following extensions are partially implemented. - EXT-187 Flow entry notifications Extension (ONFMP_FLOW_MONITOR only) - EXT-232 Table synchronisation Extension (Error codes only) The following extensions are not implemented yet. - EXT-191 Role Status Extension - EXT-192-e Flow entry eviction Extension - EXT-192-v Vacancy events Extension """ import struct import base64 from os_ken.lib import addrconv from os_ken.lib import mac from os_ken.lib.pack_utils import msg_pack_into from os_ken.lib.packet import packet from os_ken import exception from os_ken import utils from os_ken.ofproto.ofproto_parser import StringifyMixin, MsgBase from os_ken.ofproto import ether from os_ken.ofproto import nicira_ext from os_ken.ofproto import nx_actions from os_ken.ofproto import ofproto_parser from os_ken.ofproto import ofproto_common from os_ken.ofproto import ofproto_v1_3 as ofproto import logging LOG = logging.getLogger('os_ken.ofproto.ofproto_v1_3_parser') _MSG_PARSERS = {} def _set_msg_type(msg_type): def _set_cls_msg_type(cls): cls.cls_msg_type = msg_type return cls return _set_cls_msg_type def _register_parser(cls): '''class decorator to register msg parser''' assert cls.cls_msg_type is not None assert cls.cls_msg_type not in _MSG_PARSERS _MSG_PARSERS[cls.cls_msg_type] = cls.parser return cls def _register_exp_type(experimenter, exp_type): assert exp_type not in OFPExperimenter._subtypes def _wrapper(cls): OFPExperimenter._subtypes[(experimenter, exp_type)] = cls return cls return _wrapper @ofproto_parser.register_msg_parser(ofproto.OFP_VERSION) def msg_parser(datapath, version, msg_type, msg_len, xid, buf): parser = _MSG_PARSERS.get(msg_type) return parser(datapath, version, msg_type, msg_len, xid, buf) @_register_parser @_set_msg_type(ofproto.OFPT_HELLO) class OFPHello(MsgBase): """ Hello message When connection is started, the hello message is exchanged between a switch and a controller. This message is handled by the OSKen framework, so the OSKen application do not need to process this typically. ========== ========================================================= Attribute Description ========== ========================================================= elements list of ``OFPHelloElemVersionBitmap`` instance ========== ========================================================= """ def __init__(self, datapath, elements=None): elements = elements if elements else [] super(OFPHello, self).__init__(datapath) self.elements = elements @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPHello, cls).parser(datapath, version, msg_type, msg_len, xid, buf) offset = ofproto.OFP_HELLO_HEADER_SIZE elems = [] while offset < msg.msg_len: type_, length = struct.unpack_from( ofproto.OFP_HELLO_ELEM_HEADER_PACK_STR, msg.buf, offset) # better to register Hello Element classes but currently # Only VerisonBitmap is supported so let's be simple. if type_ == ofproto.OFPHET_VERSIONBITMAP: elem = OFPHelloElemVersionBitmap.parser(msg.buf, offset) elems.append(elem) offset += length msg.elements = elems return msg class OFPHelloElemVersionBitmap(StringifyMixin): """ Version bitmap Hello Element ========== ========================================================= Attribute Description ========== ========================================================= versions list of versions of OpenFlow protocol a device supports ========== ========================================================= """ def __init__(self, versions, type_=None, length=None): super(OFPHelloElemVersionBitmap, self).__init__() self.type = ofproto.OFPHET_VERSIONBITMAP self.length = None self._bitmaps = None self.versions = versions @classmethod def parser(cls, buf, offset): type_, length = struct.unpack_from( ofproto.OFP_HELLO_ELEM_VERSIONBITMAP_HEADER_PACK_STR, buf, offset) assert type_ == ofproto.OFPHET_VERSIONBITMAP bitmaps_len = (length - ofproto.OFP_HELLO_ELEM_VERSIONBITMAP_HEADER_SIZE) offset += ofproto.OFP_HELLO_ELEM_VERSIONBITMAP_HEADER_SIZE bitmaps = [] while bitmaps_len >= 4: bitmap = struct.unpack_from('!I', buf, offset) bitmaps.append(bitmap[0]) offset += 4 bitmaps_len -= 4 versions = [i * 32 + shift for i, bitmap in enumerate(bitmaps) for shift in range(31) if bitmap & (1 << shift)] elem = cls(versions) elem.length = length elem._bitmaps = bitmaps return elem @_register_parser @_set_msg_type(ofproto.OFPT_ERROR) class OFPErrorMsg(MsgBase): """ Error message The switch notifies controller of problems by this message. ========== ========================================================= Attribute Description ========== ========================================================= type High level type of error code Details depending on the type data Variable length data depending on the type and code ========== ========================================================= ``type`` attribute corresponds to ``type_`` parameter of __init__. Types and codes are defined in ``os_ken.ofproto.ofproto``. ============================= =========== Type Code ============================= =========== OFPET_HELLO_FAILED OFPHFC_* OFPET_BAD_REQUEST OFPBRC_* OFPET_BAD_ACTION OFPBAC_* OFPET_BAD_INSTRUCTION OFPBIC_* OFPET_BAD_MATCH OFPBMC_* OFPET_FLOW_MOD_FAILED OFPFMFC_* OFPET_GROUP_MOD_FAILED OFPGMFC_* OFPET_PORT_MOD_FAILED OFPPMFC_* OFPET_TABLE_MOD_FAILED OFPTMFC_* OFPET_QUEUE_OP_FAILED OFPQOFC_* OFPET_SWITCH_CONFIG_FAILED OFPSCFC_* OFPET_ROLE_REQUEST_FAILED OFPRRFC_* OFPET_METER_MOD_FAILED OFPMMFC_* OFPET_TABLE_FEATURES_FAILED OFPTFFC_* OFPET_EXPERIMENTER N/A ============================= =========== If ``type == OFPET_EXPERIMENTER``, this message has also the following attributes. ============= ====================================================== Attribute Description ============= ====================================================== exp_type Experimenter defined type experimenter Experimenter ID ============= ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPErrorMsg, [HANDSHAKE_DISPATCHER, CONFIG_DISPATCHER, MAIN_DISPATCHER]) def error_msg_handler(self, ev): msg = ev.msg self.logger.debug('OFPErrorMsg received: type=0x%02x code=0x%02x ' 'message=%s', msg.type, msg.code, utils.hex_array(msg.data)) """ def __init__(self, datapath, type_=None, code=None, data=None, **kwargs): super(OFPErrorMsg, self).__init__(datapath) self.type = type_ self.code = code if isinstance(data, str): data = data.encode('ascii') self.data = data if self.type == ofproto.OFPET_EXPERIMENTER: self.exp_type = kwargs.get('exp_type', None) self.experimenter = kwargs.get('experimenter', None) @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): type_, = struct.unpack_from('!H', bytes(buf), ofproto.OFP_HEADER_SIZE) msg = super(OFPErrorMsg, cls).parser(datapath, version, msg_type, msg_len, xid, buf) if type_ == ofproto.OFPET_EXPERIMENTER: (msg.type, msg.exp_type, msg.experimenter, msg.data) = cls.parse_experimenter_body(buf) else: (msg.type, msg.code, msg.data) = cls.parse_body(buf) return msg @classmethod def parse_body(cls, buf): type_, code = struct.unpack_from( ofproto.OFP_ERROR_MSG_PACK_STR, buf, ofproto.OFP_HEADER_SIZE) data = buf[ofproto.OFP_ERROR_MSG_SIZE:] return type_, code, data @classmethod def parse_experimenter_body(cls, buf): type_, exp_type, experimenter = struct.unpack_from( ofproto.OFP_ERROR_EXPERIMENTER_MSG_PACK_STR, buf, ofproto.OFP_HEADER_SIZE) data = buf[ofproto.OFP_ERROR_EXPERIMENTER_MSG_SIZE:] return type_, exp_type, experimenter, data def _serialize_body(self): assert self.data is not None if self.type == ofproto.OFPET_EXPERIMENTER: msg_pack_into(ofproto.OFP_ERROR_EXPERIMENTER_MSG_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.type, self.exp_type, self.experimenter) self.buf += self.data else: msg_pack_into(ofproto.OFP_ERROR_MSG_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.type, self.code) self.buf += self.data # For the backward compatibility def OFPErrorExperimenterMsg(datapath, type_=None, exp_type=None, experimenter=None, data=None): msg = OFPErrorMsg(datapath, data=data) msg.type = ofproto.OFPET_EXPERIMENTER msg.exp_type = exp_type msg.experimenter = experimenter return msg @_register_parser @_set_msg_type(ofproto.OFPT_ECHO_REQUEST) class OFPEchoRequest(MsgBase): """ Echo request message This message is handled by the OSKen framework, so the OSKen application do not need to process this typically. ========== ========================================================= Attribute Description ========== ========================================================= data An arbitrary length data ========== ========================================================= Example:: def send_echo_request(self, datapath, data): ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPEchoRequest(datapath, data) datapath.send_msg(req) @set_ev_cls(ofp_event.EventOFPEchoRequest, [HANDSHAKE_DISPATCHER, CONFIG_DISPATCHER, MAIN_DISPATCHER]) def echo_request_handler(self, ev): self.logger.debug('OFPEchoRequest received: data=%s', utils.hex_array(ev.msg.data)) """ def __init__(self, datapath, data=None): super(OFPEchoRequest, self).__init__(datapath) self.data = data @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPEchoRequest, cls).parser(datapath, version, msg_type, msg_len, xid, buf) msg.data = msg.buf[ofproto.OFP_HEADER_SIZE:] return msg def _serialize_body(self): if self.data is not None: self.buf += self.data @_register_parser @_set_msg_type(ofproto.OFPT_ECHO_REPLY) class OFPEchoReply(MsgBase): """ Echo reply message This message is handled by the OSKen framework, so the OSKen application do not need to process this typically. ========== ========================================================= Attribute Description ========== ========================================================= data An arbitrary length data ========== ========================================================= Example:: def send_echo_reply(self, datapath, data): ofp_parser = datapath.ofproto_parser reply = ofp_parser.OFPEchoReply(datapath, data) datapath.send_msg(reply) @set_ev_cls(ofp_event.EventOFPEchoReply, [HANDSHAKE_DISPATCHER, CONFIG_DISPATCHER, MAIN_DISPATCHER]) def echo_reply_handler(self, ev): self.logger.debug('OFPEchoReply received: data=%s', utils.hex_array(ev.msg.data)) """ def __init__(self, datapath, data=None): super(OFPEchoReply, self).__init__(datapath) self.data = data @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPEchoReply, cls).parser(datapath, version, msg_type, msg_len, xid, buf) msg.data = msg.buf[ofproto.OFP_HEADER_SIZE:] return msg def _serialize_body(self): assert self.data is not None self.buf += self.data @_register_parser @_set_msg_type(ofproto.OFPT_EXPERIMENTER) class OFPExperimenter(MsgBase): """ Experimenter extension message ============= ========================================================= Attribute Description ============= ========================================================= experimenter Experimenter ID exp_type Experimenter defined data Experimenter defined arbitrary additional data ============= ========================================================= """ _subtypes = {} def __init__(self, datapath, experimenter=None, exp_type=None, data=None): super(OFPExperimenter, self).__init__(datapath) self.experimenter = experimenter self.exp_type = exp_type self.data = data @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPExperimenter, cls).parser(datapath, version, msg_type, msg_len, xid, buf) (msg.experimenter, msg.exp_type) = struct.unpack_from( ofproto.OFP_EXPERIMENTER_HEADER_PACK_STR, msg.buf, ofproto.OFP_HEADER_SIZE) msg.data = msg.buf[ofproto.OFP_EXPERIMENTER_HEADER_SIZE:] if (msg.experimenter, msg.exp_type) in cls._subtypes: new_msg = cls._subtypes[ (msg.experimenter, msg.exp_type)].parser_subtype(msg) new_msg.set_headers(msg.version, msg.msg_type, msg.msg_len, msg.xid) new_msg.set_buf(msg.buf) return new_msg return msg def _serialize_body(self): assert self.data is not None msg_pack_into(ofproto.OFP_EXPERIMENTER_HEADER_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.experimenter, self.exp_type) self.buf += self.data @_set_msg_type(ofproto.OFPT_FEATURES_REQUEST) class OFPFeaturesRequest(MsgBase): """ Features request message The controller sends a feature request to the switch upon session establishment. This message is handled by the OSKen framework, so the OSKen application do not need to process this typically. Example:: def send_features_request(self, datapath): ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPFeaturesRequest(datapath) datapath.send_msg(req) """ def __init__(self, datapath): super(OFPFeaturesRequest, self).__init__(datapath) @_register_parser @_set_msg_type(ofproto.OFPT_FEATURES_REPLY) class OFPSwitchFeatures(MsgBase): """ Features reply message The switch responds with a features reply message to a features request. This message is handled by the OSKen framework, so the OSKen application do not need to process this typically. Example:: @set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER) def switch_features_handler(self, ev): msg = ev.msg self.logger.debug('OFPSwitchFeatures received: ' 'datapath_id=0x%016x n_buffers=%d ' 'n_tables=%d auxiliary_id=%d ' 'capabilities=0x%08x', msg.datapath_id, msg.n_buffers, msg.n_tables, msg.auxiliary_id, msg.capabilities) """ def __init__(self, datapath, datapath_id=None, n_buffers=None, n_tables=None, auxiliary_id=None, capabilities=None): super(OFPSwitchFeatures, self).__init__(datapath) self.datapath_id = datapath_id self.n_buffers = n_buffers self.n_tables = n_tables self.auxiliary_id = auxiliary_id self.capabilities = capabilities @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPSwitchFeatures, cls).parser(datapath, version, msg_type, msg_len, xid, buf) (msg.datapath_id, msg.n_buffers, msg.n_tables, msg.auxiliary_id, msg.capabilities, msg._reserved) = struct.unpack_from( ofproto.OFP_SWITCH_FEATURES_PACK_STR, msg.buf, ofproto.OFP_HEADER_SIZE) return msg @_set_msg_type(ofproto.OFPT_GET_CONFIG_REQUEST) class OFPGetConfigRequest(MsgBase): """ Get config request message The controller sends a get config request to query configuration parameters in the switch. Example:: def send_get_config_request(self, datapath): ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPGetConfigRequest(datapath) datapath.send_msg(req) """ def __init__(self, datapath): super(OFPGetConfigRequest, self).__init__(datapath) @_register_parser @_set_msg_type(ofproto.OFPT_GET_CONFIG_REPLY) class OFPGetConfigReply(MsgBase): """ Get config reply message The switch responds to a configuration request with a get config reply message. ============= ========================================================= Attribute Description ============= ========================================================= flags Bitmap of the following flags. | OFPC_FRAG_NORMAL | OFPC_FRAG_DROP | OFPC_FRAG_REASM | OFPC_FRAG_MASK miss_send_len Max bytes of new flow that datapath should send to the controller ============= ========================================================= Example:: @set_ev_cls(ofp_event.EventOFPGetConfigReply, MAIN_DISPATCHER) def get_config_reply_handler(self, ev): msg = ev.msg dp = msg.datapath ofp = dp.ofproto flags = [] if msg.flags & ofp.OFPC_FRAG_NORMAL: flags.append('NORMAL') if msg.flags & ofp.OFPC_FRAG_DROP: flags.append('DROP') if msg.flags & ofp.OFPC_FRAG_REASM: flags.append('REASM') self.logger.debug('OFPGetConfigReply received: ' 'flags=%s miss_send_len=%d', ','.join(flags), msg.miss_send_len) """ def __init__(self, datapath, flags=None, miss_send_len=None): super(OFPGetConfigReply, self).__init__(datapath) self.flags = flags self.miss_send_len = miss_send_len @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPGetConfigReply, cls).parser(datapath, version, msg_type, msg_len, xid, buf) msg.flags, msg.miss_send_len = struct.unpack_from( ofproto.OFP_SWITCH_CONFIG_PACK_STR, msg.buf, ofproto.OFP_HEADER_SIZE) return msg @_set_msg_type(ofproto.OFPT_SET_CONFIG) class OFPSetConfig(MsgBase): """ Set config request message The controller sends a set config request message to set configuraion parameters. ============= ========================================================= Attribute Description ============= ========================================================= flags Bitmap of the following flags. | OFPC_FRAG_NORMAL | OFPC_FRAG_DROP | OFPC_FRAG_REASM miss_send_len Max bytes of new flow that datapath should send to the controller ============= ========================================================= Example:: def send_set_config(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPSetConfig(datapath, ofp.OFPC_FRAG_NORMAL, 256) datapath.send_msg(req) """ def __init__(self, datapath, flags=0, miss_send_len=0): super(OFPSetConfig, self).__init__(datapath) self.flags = flags self.miss_send_len = miss_send_len def _serialize_body(self): assert self.flags is not None assert self.miss_send_len is not None msg_pack_into(ofproto.OFP_SWITCH_CONFIG_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.flags, self.miss_send_len) UINT64_MAX = (1 << 64) - 1 UINT32_MAX = (1 << 32) - 1 UINT16_MAX = (1 << 16) - 1 class Flow(object): def __init__(self): self.in_port = 0 self.in_phy_port = 0 self.metadata = 0 self.dl_dst = mac.DONTCARE self.dl_src = mac.DONTCARE self.dl_type = 0 self.vlan_vid = 0 self.vlan_pcp = 0 self.ip_dscp = 0 self.ip_ecn = 0 self.ip_proto = 0 self.ipv4_src = 0 self.ipv4_dst = 0 self.tcp_src = 0 self.tcp_dst = 0 self.udp_src = 0 self.udp_dst = 0 self.sctp_src = 0 self.sctp_dst = 0 self.icmpv4_type = 0 self.icmpv4_code = 0 self.arp_op = 0 self.arp_spa = 0 self.arp_tpa = 0 self.arp_sha = 0 self.arp_tha = 0 self.ipv6_src = [] self.ipv6_dst = [] self.ipv6_flabel = 0 self.icmpv6_type = 0 self.icmpv6_code = 0 self.ipv6_nd_target = [] self.ipv6_nd_sll = 0 self.ipv6_nd_tll = 0 self.mpls_label = 0 self.mpls_tc = 0 self.mpls_bos = 0 self.pbb_isid = 0 self.tunnel_id = 0 self.ipv6_exthdr = 0 class FlowWildcards(object): def __init__(self): self.metadata_mask = 0 self.dl_dst_mask = 0 self.dl_src_mask = 0 self.vlan_vid_mask = 0 self.ipv4_src_mask = 0 self.ipv4_dst_mask = 0 self.arp_spa_mask = 0 self.arp_tpa_mask = 0 self.arp_sha_mask = 0 self.arp_tha_mask = 0 self.ipv6_src_mask = [] self.ipv6_dst_mask = [] self.ipv6_flabel_mask = 0 self.pbb_isid_mask = 0 self.tunnel_id_mask = 0 self.ipv6_exthdr_mask = 0 self.wildcards = (1 << 64) - 1 def ft_set(self, shift): self.wildcards &= ~(1 << shift) def ft_test(self, shift): return not self.wildcards & (1 << shift) class OFPMatch(StringifyMixin): """ Flow Match Structure This class is implementation of the flow match structure having compose/query API. There are new API and old API for compatibility. the old API is supposed to be removed later. You can define the flow match by the keyword arguments. The following arguments are available. ================ =============== ================================== Argument Value Description ================ =============== ================================== in_port Integer 32bit Switch input port in_phy_port Integer 32bit Switch physical input port metadata Integer 64bit Metadata passed between tables eth_dst MAC address Ethernet destination address eth_src MAC address Ethernet source address eth_type Integer 16bit Ethernet frame type vlan_vid Integer 16bit VLAN id vlan_pcp Integer 8bit VLAN priority ip_dscp Integer 8bit IP DSCP (6 bits in ToS field) ip_ecn Integer 8bit IP ECN (2 bits in ToS field) ip_proto Integer 8bit IP protocol ipv4_src IPv4 address IPv4 source address ipv4_dst IPv4 address IPv4 destination address tcp_src Integer 16bit TCP source port tcp_dst Integer 16bit TCP destination port udp_src Integer 16bit UDP source port udp_dst Integer 16bit UDP destination port sctp_src Integer 16bit SCTP source port sctp_dst Integer 16bit SCTP destination port icmpv4_type Integer 8bit ICMP type icmpv4_code Integer 8bit ICMP code arp_op Integer 16bit ARP opcode arp_spa IPv4 address ARP source IPv4 address arp_tpa IPv4 address ARP target IPv4 address arp_sha MAC address ARP source hardware address arp_tha MAC address ARP target hardware address ipv6_src IPv6 address IPv6 source address ipv6_dst IPv6 address IPv6 destination address ipv6_flabel Integer 32bit IPv6 Flow Label icmpv6_type Integer 8bit ICMPv6 type icmpv6_code Integer 8bit ICMPv6 code ipv6_nd_target IPv6 address Target address for ND ipv6_nd_sll MAC address Source link-layer for ND ipv6_nd_tll MAC address Target link-layer for ND mpls_label Integer 32bit MPLS label mpls_tc Integer 8bit MPLS TC mpls_bos Integer 8bit MPLS BoS bit pbb_isid Integer 24bit PBB I-SID tunnel_id Integer 64bit Logical Port Metadata ipv6_exthdr Integer 16bit IPv6 Extension Header pseudo-field pbb_uca Integer 8bit PBB UCA header field (EXT-256 Old version of ONF Extension) tcp_flags Integer 16bit TCP flags (EXT-109 ONF Extension) actset_output Integer 32bit Output port from action set metadata (EXT-233 ONF Extension) ================ =============== ================================== Example:: >>> # compose >>> match = parser.OFPMatch( ... in_port=1, ... eth_type=0x86dd, ... ipv6_src=('2001:db8:bd05:1d2:288a:1fc0:1:10ee', ... 'ffff:ffff:ffff:ffff::'), ... ipv6_dst='2001:db8:bd05:1d2:288a:1fc0:1:10ee') >>> # query >>> if 'ipv6_src' in match: ... print match['ipv6_src'] ... ('2001:db8:bd05:1d2:288a:1fc0:1:10ee', 'ffff:ffff:ffff:ffff::') .. Note:: For the list of the supported Nicira experimenter matches, please refer to :ref:`os_ken.ofproto.nx_match `. .. Note:: For VLAN id match field, special values are defined in OpenFlow Spec. 1) Packets with and without a VLAN tag - Example:: match = parser.OFPMatch() - Packet Matching ====================== ===== non-VLAN-tagged MATCH VLAN-tagged(vlan_id=3) MATCH VLAN-tagged(vlan_id=5) MATCH ====================== ===== 2) Only packets without a VLAN tag - Example:: match = parser.OFPMatch(vlan_vid=0x0000) - Packet Matching ====================== ===== non-VLAN-tagged MATCH VLAN-tagged(vlan_id=3) x VLAN-tagged(vlan_id=5) x ====================== ===== 3) Only packets with a VLAN tag regardless of its value - Example:: match = parser.OFPMatch(vlan_vid=(0x1000, 0x1000)) - Packet Matching ====================== ===== non-VLAN-tagged x VLAN-tagged(vlan_id=3) MATCH VLAN-tagged(vlan_id=5) MATCH ====================== ===== 4) Only packets with VLAN tag and VID equal - Example:: match = parser.OFPMatch(vlan_vid=(0x1000 | 3)) - Packet Matching ====================== ===== non-VLAN-tagged x VLAN-tagged(vlan_id=3) MATCH VLAN-tagged(vlan_id=5) x ====================== ===== """ def __init__(self, type_=None, length=None, _ordered_fields=None, **kwargs): """ You can define the flow match by the keyword arguments. Please refer to ofproto.oxm_types for the key which you can define. """ super(OFPMatch, self).__init__() self._wc = FlowWildcards() self._flow = Flow() self.fields = [] self.type = ofproto.OFPMT_OXM self.length = length if _ordered_fields is not None: assert not kwargs self._fields2 = _ordered_fields else: # eg. # OFPMatch(eth_src=('ff:ff:ff:00:00:00'), eth_type=0x800, # ipv4_src='10.0.0.1') kwargs = dict(ofproto.oxm_normalize_user(k, v) for (k, v) in kwargs.items()) fields = [ofproto.oxm_from_user(k, v) for (k, v) in kwargs.items()] # assumption: sorting by OXM type values makes fields # meet ordering requirements (eg. eth_type before ipv4_src) fields.sort( key=lambda x: x[0][0] if isinstance(x[0], tuple) else x[0]) self._fields2 = [ofproto.oxm_to_user(n, v, m) for (n, v, m) in fields] def __getitem__(self, key): return dict(self._fields2)[key] def __contains__(self, key): return key in dict(self._fields2) def iteritems(self): return iter(dict(self._fields2).items()) def items(self): return self._fields2 def get(self, key, default=None): return dict(self._fields2).get(key, default) def stringify_attrs(self): yield "oxm_fields", dict(self._fields2) def to_jsondict(self): """ Returns a dict expressing the flow match. """ # XXX old api compat if self._composed_with_old_api(): # copy object first because serialize_old is destructive o2 = OFPMatch() o2.fields = self.fields[:] # serialize and parse to fill OFPMatch._fields2 buf = bytearray() o2.serialize(buf, 0) o = OFPMatch.parser(bytes(buf), 0) else: o = self body = {"oxm_fields": [ofproto.oxm_to_jsondict(k, uv) for k, uv in o._fields2], "length": o.length, "type": o.type} return {self.__class__.__name__: body} @classmethod def from_jsondict(cls, dict_): """ Returns an object which is generated from a dict. Exception raises: KeyError -- Unknown match field is defined in dict """ fields = [ofproto.oxm_from_jsondict(f) for f in dict_['oxm_fields']] o = OFPMatch(_ordered_fields=fields) # XXX old api compat # serialize and parse to fill OFPMatch.fields buf = bytearray() o.serialize(buf, 0) return OFPMatch.parser(bytes(buf), 0) def __str__(self): # XXX old api compat if self._composed_with_old_api(): # copy object first because serialize_old is destructive o2 = OFPMatch() o2.fields = self.fields[:] # serialize and parse to fill OFPMatch._fields2 buf = bytearray() o2.serialize(buf, 0) o = OFPMatch.parser(bytes(buf), 0) else: o = self return super(OFPMatch, o).__str__() __repr__ = __str__ def append_field(self, header, value, mask=None): """ Append a match field. ========= ======================================================= Argument Description ========= ======================================================= header match field header ID which is defined automatically in ``ofproto`` value match field value mask mask value to the match field ========= ======================================================= The available ``header`` is as follows. ====================== =================================== Header ID Description ====================== =================================== OXM_OF_IN_PORT Switch input port OXM_OF_IN_PHY_PORT Switch physical input port OXM_OF_METADATA Metadata passed between tables OXM_OF_ETH_DST Ethernet destination address OXM_OF_ETH_SRC Ethernet source address OXM_OF_ETH_TYPE Ethernet frame type OXM_OF_VLAN_VID VLAN id OXM_OF_VLAN_PCP VLAN priority OXM_OF_IP_DSCP IP DSCP (6 bits in ToS field) OXM_OF_IP_ECN IP ECN (2 bits in ToS field) OXM_OF_IP_PROTO IP protocol OXM_OF_IPV4_SRC IPv4 source address OXM_OF_IPV4_DST IPv4 destination address OXM_OF_TCP_SRC TCP source port OXM_OF_TCP_DST TCP destination port OXM_OF_UDP_SRC UDP source port OXM_OF_UDP_DST UDP destination port OXM_OF_SCTP_SRC SCTP source port OXM_OF_SCTP_DST SCTP destination port OXM_OF_ICMPV4_TYPE ICMP type OXM_OF_ICMPV4_CODE ICMP code OXM_OF_ARP_OP ARP opcode OXM_OF_ARP_SPA ARP source IPv4 address OXM_OF_ARP_TPA ARP target IPv4 address OXM_OF_ARP_SHA ARP source hardware address OXM_OF_ARP_THA ARP target hardware address OXM_OF_IPV6_SRC IPv6 source address OXM_OF_IPV6_DST IPv6 destination address OXM_OF_IPV6_FLABEL IPv6 Flow Label OXM_OF_ICMPV6_TYPE ICMPv6 type OXM_OF_ICMPV6_CODE ICMPv6 code OXM_OF_IPV6_ND_TARGET Target address for ND OXM_OF_IPV6_ND_SLL Source link-layer for ND OXM_OF_IPV6_ND_TLL Target link-layer for ND OXM_OF_MPLS_LABEL MPLS label OXM_OF_MPLS_TC MPLS TC OXM_OF_MPLS_BOS MPLS BoS bit OXM_OF_PBB_ISID PBB I-SID OXM_OF_TUNNEL_ID Logical Port Metadata OXM_OF_IPV6_EXTHDR IPv6 Extension Header pseudo-field ====================== =================================== """ self.fields.append(OFPMatchField.make(header, value, mask)) def _composed_with_old_api(self): return (self.fields and not self._fields2) or \ self._wc.__dict__ != FlowWildcards().__dict__ def serialize(self, buf, offset): """ Outputs the expression of the wire protocol of the flow match into the buf. Returns the output length. """ # XXX compat if self._composed_with_old_api(): return self.serialize_old(buf, offset) fields = [ofproto.oxm_from_user(k, uv) for (k, uv) in self._fields2] hdr_pack_str = '!HH' field_offset = offset + struct.calcsize(hdr_pack_str) for (n, value, mask) in fields: field_offset += ofproto.oxm_serialize(n, value, mask, buf, field_offset) length = field_offset - offset msg_pack_into(hdr_pack_str, buf, offset, ofproto.OFPMT_OXM, length) self.length = length pad_len = utils.round_up(length, 8) - length msg_pack_into("%dx" % pad_len, buf, field_offset) return length + pad_len def serialize_old(self, buf, offset): if hasattr(self, '_serialized'): raise Exception('serializing an OFPMatch composed with ' 'old API multiple times is not supported') self._serialized = True if self._wc.ft_test(ofproto.OFPXMT_OFB_IN_PORT): self.append_field(ofproto.OXM_OF_IN_PORT, self._flow.in_port) if self._wc.ft_test(ofproto.OFPXMT_OFB_IN_PHY_PORT): self.append_field(ofproto.OXM_OF_IN_PHY_PORT, self._flow.in_phy_port) if self._wc.ft_test(ofproto.OFPXMT_OFB_METADATA): if self._wc.metadata_mask == UINT64_MAX: header = ofproto.OXM_OF_METADATA else: header = ofproto.OXM_OF_METADATA_W self.append_field(header, self._flow.metadata, self._wc.metadata_mask) if self._wc.ft_test(ofproto.OFPXMT_OFB_ETH_DST): if self._wc.dl_dst_mask: header = ofproto.OXM_OF_ETH_DST_W else: header = ofproto.OXM_OF_ETH_DST self.append_field(header, self._flow.dl_dst, self._wc.dl_dst_mask) if self._wc.ft_test(ofproto.OFPXMT_OFB_ETH_SRC): if self._wc.dl_src_mask: header = ofproto.OXM_OF_ETH_SRC_W else: header = ofproto.OXM_OF_ETH_SRC self.append_field(header, self._flow.dl_src, self._wc.dl_src_mask) if self._wc.ft_test(ofproto.OFPXMT_OFB_ETH_TYPE): self.append_field(ofproto.OXM_OF_ETH_TYPE, self._flow.dl_type) if self._wc.ft_test(ofproto.OFPXMT_OFB_VLAN_VID): if self._wc.vlan_vid_mask == UINT16_MAX: header = ofproto.OXM_OF_VLAN_VID else: header = ofproto.OXM_OF_VLAN_VID_W self.append_field(header, self._flow.vlan_vid, self._wc.vlan_vid_mask) if self._wc.ft_test(ofproto.OFPXMT_OFB_VLAN_PCP): self.append_field(ofproto.OXM_OF_VLAN_PCP, self._flow.vlan_pcp) if self._wc.ft_test(ofproto.OFPXMT_OFB_IP_DSCP): self.append_field(ofproto.OXM_OF_IP_DSCP, self._flow.ip_dscp) if self._wc.ft_test(ofproto.OFPXMT_OFB_IP_ECN): self.append_field(ofproto.OXM_OF_IP_ECN, self._flow.ip_ecn) if self._wc.ft_test(ofproto.OFPXMT_OFB_IP_PROTO): self.append_field(ofproto.OXM_OF_IP_PROTO, self._flow.ip_proto) if self._wc.ft_test(ofproto.OFPXMT_OFB_IPV4_SRC): if self._wc.ipv4_src_mask == UINT32_MAX: header = ofproto.OXM_OF_IPV4_SRC else: header = ofproto.OXM_OF_IPV4_SRC_W self.append_field(header, self._flow.ipv4_src, self._wc.ipv4_src_mask) if self._wc.ft_test(ofproto.OFPXMT_OFB_IPV4_DST): if self._wc.ipv4_dst_mask == UINT32_MAX: header = ofproto.OXM_OF_IPV4_DST else: header = ofproto.OXM_OF_IPV4_DST_W self.append_field(header, self._flow.ipv4_dst, self._wc.ipv4_dst_mask) if self._wc.ft_test(ofproto.OFPXMT_OFB_TCP_SRC): self.append_field(ofproto.OXM_OF_TCP_SRC, self._flow.tcp_src) if self._wc.ft_test(ofproto.OFPXMT_OFB_TCP_DST): self.append_field(ofproto.OXM_OF_TCP_DST, self._flow.tcp_dst) if self._wc.ft_test(ofproto.OFPXMT_OFB_UDP_SRC): self.append_field(ofproto.OXM_OF_UDP_SRC, self._flow.udp_src) if self._wc.ft_test(ofproto.OFPXMT_OFB_UDP_DST): self.append_field(ofproto.OXM_OF_UDP_DST, self._flow.udp_dst) if self._wc.ft_test(ofproto.OFPXMT_OFB_SCTP_SRC): self.append_field(ofproto.OXM_OF_SCTP_SRC, self._flow.sctp_src) if self._wc.ft_test(ofproto.OFPXMT_OFB_SCTP_DST): self.append_field(ofproto.OXM_OF_SCTP_DST, self._flow.sctp_dst) if self._wc.ft_test(ofproto.OFPXMT_OFB_ICMPV4_TYPE): self.append_field(ofproto.OXM_OF_ICMPV4_TYPE, self._flow.icmpv4_type) if self._wc.ft_test(ofproto.OFPXMT_OFB_ICMPV4_CODE): self.append_field(ofproto.OXM_OF_ICMPV4_CODE, self._flow.icmpv4_code) if self._wc.ft_test(ofproto.OFPXMT_OFB_ARP_OP): self.append_field(ofproto.OXM_OF_ARP_OP, self._flow.arp_op) if self._wc.ft_test(ofproto.OFPXMT_OFB_ARP_SPA): if self._wc.arp_spa_mask == UINT32_MAX: header = ofproto.OXM_OF_ARP_SPA else: header = ofproto.OXM_OF_ARP_SPA_W self.append_field(header, self._flow.arp_spa, self._wc.arp_spa_mask) if self._wc.ft_test(ofproto.OFPXMT_OFB_ARP_TPA): if self._wc.arp_tpa_mask == UINT32_MAX: header = ofproto.OXM_OF_ARP_TPA else: header = ofproto.OXM_OF_ARP_TPA_W self.append_field(header, self._flow.arp_tpa, self._wc.arp_tpa_mask) if self._wc.ft_test(ofproto.OFPXMT_OFB_ARP_SHA): if self._wc.arp_sha_mask: header = ofproto.OXM_OF_ARP_SHA_W else: header = ofproto.OXM_OF_ARP_SHA self.append_field(header, self._flow.arp_sha, self._wc.arp_sha_mask) if self._wc.ft_test(ofproto.OFPXMT_OFB_ARP_THA): if self._wc.arp_tha_mask: header = ofproto.OXM_OF_ARP_THA_W else: header = ofproto.OXM_OF_ARP_THA self.append_field(header, self._flow.arp_tha, self._wc.arp_tha_mask) if self._wc.ft_test(ofproto.OFPXMT_OFB_IPV6_SRC): if len(self._wc.ipv6_src_mask): header = ofproto.OXM_OF_IPV6_SRC_W else: header = ofproto.OXM_OF_IPV6_SRC self.append_field(header, self._flow.ipv6_src, self._wc.ipv6_src_mask) if self._wc.ft_test(ofproto.OFPXMT_OFB_IPV6_DST): if len(self._wc.ipv6_dst_mask): header = ofproto.OXM_OF_IPV6_DST_W else: header = ofproto.OXM_OF_IPV6_DST self.append_field(header, self._flow.ipv6_dst, self._wc.ipv6_dst_mask) if self._wc.ft_test(ofproto.OFPXMT_OFB_IPV6_FLABEL): if self._wc.ipv6_flabel_mask == UINT32_MAX: header = ofproto.OXM_OF_IPV6_FLABEL else: header = ofproto.OXM_OF_IPV6_FLABEL_W self.append_field(header, self._flow.ipv6_flabel, self._wc.ipv6_flabel_mask) if self._wc.ft_test(ofproto.OFPXMT_OFB_ICMPV6_TYPE): self.append_field(ofproto.OXM_OF_ICMPV6_TYPE, self._flow.icmpv6_type) if self._wc.ft_test(ofproto.OFPXMT_OFB_ICMPV6_CODE): self.append_field(ofproto.OXM_OF_ICMPV6_CODE, self._flow.icmpv6_code) if self._wc.ft_test(ofproto.OFPXMT_OFB_IPV6_ND_TARGET): self.append_field(ofproto.OXM_OF_IPV6_ND_TARGET, self._flow.ipv6_nd_target) if self._wc.ft_test(ofproto.OFPXMT_OFB_IPV6_ND_SLL): self.append_field(ofproto.OXM_OF_IPV6_ND_SLL, self._flow.ipv6_nd_sll) if self._wc.ft_test(ofproto.OFPXMT_OFB_IPV6_ND_TLL): self.append_field(ofproto.OXM_OF_IPV6_ND_TLL, self._flow.ipv6_nd_tll) if self._wc.ft_test(ofproto.OFPXMT_OFB_MPLS_LABEL): self.append_field(ofproto.OXM_OF_MPLS_LABEL, self._flow.mpls_label) if self._wc.ft_test(ofproto.OFPXMT_OFB_MPLS_TC): self.append_field(ofproto.OXM_OF_MPLS_TC, self._flow.mpls_tc) if self._wc.ft_test(ofproto.OFPXMT_OFB_MPLS_BOS): self.append_field(ofproto.OXM_OF_MPLS_BOS, self._flow.mpls_bos) if self._wc.ft_test(ofproto.OFPXMT_OFB_PBB_ISID): if self._wc.pbb_isid_mask: header = ofproto.OXM_OF_PBB_ISID_W else: header = ofproto.OXM_OF_PBB_ISID self.append_field(header, self._flow.pbb_isid, self._wc.pbb_isid_mask) if self._wc.ft_test(ofproto.OFPXMT_OFB_TUNNEL_ID): if self._wc.tunnel_id_mask: header = ofproto.OXM_OF_TUNNEL_ID_W else: header = ofproto.OXM_OF_TUNNEL_ID self.append_field(header, self._flow.tunnel_id, self._wc.tunnel_id_mask) if self._wc.ft_test(ofproto.OFPXMT_OFB_IPV6_EXTHDR): if self._wc.ipv6_exthdr_mask: header = ofproto.OXM_OF_IPV6_EXTHDR_W else: header = ofproto.OXM_OF_IPV6_EXTHDR self.append_field(header, self._flow.ipv6_exthdr, self._wc.ipv6_exthdr_mask) field_offset = offset + 4 for f in self.fields: f.serialize(buf, field_offset) field_offset += f.length length = field_offset - offset msg_pack_into('!HH', buf, offset, ofproto.OFPMT_OXM, length) pad_len = utils.round_up(length, 8) - length msg_pack_into("%dx" % pad_len, buf, field_offset) return length + pad_len @classmethod def parser(cls, buf, offset): """ Returns an object which is generated from a buffer including the expression of the wire protocol of the flow match. """ match = OFPMatch() type_, length = struct.unpack_from('!HH', buf, offset) match.type = type_ match.length = length # ofp_match adjustment offset += 4 length -= 4 exc = None residue = None # XXXcompat try: cls.parser_old(match, buf, offset, length) except struct.error as e: exc = e fields = [] try: while length > 0: n, value, mask, field_len = ofproto.oxm_parse(buf, offset) k, uv = ofproto.oxm_to_user(n, value, mask) fields.append((k, uv)) offset += field_len length -= field_len except struct.error as e: exc = e residue = buf[offset:] match._fields2 = fields if exc is not None: raise exception.OFPTruncatedMessage(match, residue, exc) return match @staticmethod def parser_old(match, buf, offset, length): while length > 0: field = OFPMatchField.parser(buf, offset) offset += field.length length -= field.length match.fields.append(field) def set_in_port(self, port): self._wc.ft_set(ofproto.OFPXMT_OFB_IN_PORT) self._flow.in_port = port def set_in_phy_port(self, phy_port): self._wc.ft_set(ofproto.OFPXMT_OFB_IN_PHY_PORT) self._flow.in_phy_port = phy_port def set_metadata(self, metadata): self.set_metadata_masked(metadata, UINT64_MAX) def set_metadata_masked(self, metadata, mask): self._wc.ft_set(ofproto.OFPXMT_OFB_METADATA) self._wc.metadata_mask = mask self._flow.metadata = metadata & mask def set_dl_dst(self, dl_dst): self._wc.ft_set(ofproto.OFPXMT_OFB_ETH_DST) self._flow.dl_dst = dl_dst def set_dl_dst_masked(self, dl_dst, mask): self._wc.ft_set(ofproto.OFPXMT_OFB_ETH_DST) self._wc.dl_dst_mask = mask # bit-wise and of the corresponding elements of dl_dst and mask self._flow.dl_dst = mac.haddr_bitand(dl_dst, mask) def set_dl_src(self, dl_src): self._wc.ft_set(ofproto.OFPXMT_OFB_ETH_SRC) self._flow.dl_src = dl_src def set_dl_src_masked(self, dl_src, mask): self._wc.ft_set(ofproto.OFPXMT_OFB_ETH_SRC) self._wc.dl_src_mask = mask self._flow.dl_src = mac.haddr_bitand(dl_src, mask) def set_dl_type(self, dl_type): self._wc.ft_set(ofproto.OFPXMT_OFB_ETH_TYPE) self._flow.dl_type = dl_type def set_vlan_vid_none(self): self._wc.ft_set(ofproto.OFPXMT_OFB_VLAN_VID) self._wc.vlan_vid_mask = UINT16_MAX self._flow.vlan_vid = ofproto.OFPVID_NONE def set_vlan_vid(self, vid): self.set_vlan_vid_masked(vid, UINT16_MAX) def set_vlan_vid_masked(self, vid, mask): vid |= ofproto.OFPVID_PRESENT self._wc.ft_set(ofproto.OFPXMT_OFB_VLAN_VID) self._wc.vlan_vid_mask = mask self._flow.vlan_vid = vid def set_vlan_pcp(self, pcp): self._wc.ft_set(ofproto.OFPXMT_OFB_VLAN_PCP) self._flow.vlan_pcp = pcp def set_ip_dscp(self, ip_dscp): self._wc.ft_set(ofproto.OFPXMT_OFB_IP_DSCP) self._flow.ip_dscp = ip_dscp def set_ip_ecn(self, ip_ecn): self._wc.ft_set(ofproto.OFPXMT_OFB_IP_ECN) self._flow.ip_ecn = ip_ecn def set_ip_proto(self, ip_proto): self._wc.ft_set(ofproto.OFPXMT_OFB_IP_PROTO) self._flow.ip_proto = ip_proto def set_ipv4_src(self, ipv4_src): self.set_ipv4_src_masked(ipv4_src, UINT32_MAX) def set_ipv4_src_masked(self, ipv4_src, mask): self._wc.ft_set(ofproto.OFPXMT_OFB_IPV4_SRC) self._flow.ipv4_src = ipv4_src self._wc.ipv4_src_mask = mask def set_ipv4_dst(self, ipv4_dst): self.set_ipv4_dst_masked(ipv4_dst, UINT32_MAX) def set_ipv4_dst_masked(self, ipv4_dst, mask): self._wc.ft_set(ofproto.OFPXMT_OFB_IPV4_DST) self._flow.ipv4_dst = ipv4_dst self._wc.ipv4_dst_mask = mask def set_tcp_src(self, tcp_src): self._wc.ft_set(ofproto.OFPXMT_OFB_TCP_SRC) self._flow.tcp_src = tcp_src def set_tcp_dst(self, tcp_dst): self._wc.ft_set(ofproto.OFPXMT_OFB_TCP_DST) self._flow.tcp_dst = tcp_dst def set_udp_src(self, udp_src): self._wc.ft_set(ofproto.OFPXMT_OFB_UDP_SRC) self._flow.udp_src = udp_src def set_udp_dst(self, udp_dst): self._wc.ft_set(ofproto.OFPXMT_OFB_UDP_DST) self._flow.udp_dst = udp_dst def set_sctp_src(self, sctp_src): self._wc.ft_set(ofproto.OFPXMT_OFB_SCTP_SRC) self._flow.sctp_src = sctp_src def set_sctp_dst(self, sctp_dst): self._wc.ft_set(ofproto.OFPXMT_OFB_SCTP_DST) self._flow.sctp_dst = sctp_dst def set_icmpv4_type(self, icmpv4_type): self._wc.ft_set(ofproto.OFPXMT_OFB_ICMPV4_TYPE) self._flow.icmpv4_type = icmpv4_type def set_icmpv4_code(self, icmpv4_code): self._wc.ft_set(ofproto.OFPXMT_OFB_ICMPV4_CODE) self._flow.icmpv4_code = icmpv4_code def set_arp_opcode(self, arp_op): self._wc.ft_set(ofproto.OFPXMT_OFB_ARP_OP) self._flow.arp_op = arp_op def set_arp_spa(self, arp_spa): self.set_arp_spa_masked(arp_spa, UINT32_MAX) def set_arp_spa_masked(self, arp_spa, mask): self._wc.ft_set(ofproto.OFPXMT_OFB_ARP_SPA) self._wc.arp_spa_mask = mask self._flow.arp_spa = arp_spa def set_arp_tpa(self, arp_tpa): self.set_arp_tpa_masked(arp_tpa, UINT32_MAX) def set_arp_tpa_masked(self, arp_tpa, mask): self._wc.ft_set(ofproto.OFPXMT_OFB_ARP_TPA) self._wc.arp_tpa_mask = mask self._flow.arp_tpa = arp_tpa def set_arp_sha(self, arp_sha): self._wc.ft_set(ofproto.OFPXMT_OFB_ARP_SHA) self._flow.arp_sha = arp_sha def set_arp_sha_masked(self, arp_sha, mask): self._wc.ft_set(ofproto.OFPXMT_OFB_ARP_SHA) self._wc.arp_sha_mask = mask self._flow.arp_sha = mac.haddr_bitand(arp_sha, mask) def set_arp_tha(self, arp_tha): self._wc.ft_set(ofproto.OFPXMT_OFB_ARP_THA) self._flow.arp_tha = arp_tha def set_arp_tha_masked(self, arp_tha, mask): self._wc.ft_set(ofproto.OFPXMT_OFB_ARP_THA) self._wc.arp_tha_mask = mask self._flow.arp_tha = mac.haddr_bitand(arp_tha, mask) def set_ipv6_src(self, src): self._wc.ft_set(ofproto.OFPXMT_OFB_IPV6_SRC) self._flow.ipv6_src = src def set_ipv6_src_masked(self, src, mask): self._wc.ft_set(ofproto.OFPXMT_OFB_IPV6_SRC) self._wc.ipv6_src_mask = mask self._flow.ipv6_src = [x & y for (x, y) in zip(src, mask)] def set_ipv6_dst(self, dst): self._wc.ft_set(ofproto.OFPXMT_OFB_IPV6_DST) self._flow.ipv6_dst = dst def set_ipv6_dst_masked(self, dst, mask): self._wc.ft_set(ofproto.OFPXMT_OFB_IPV6_DST) self._wc.ipv6_dst_mask = mask self._flow.ipv6_dst = [x & y for (x, y) in zip(dst, mask)] def set_ipv6_flabel(self, flabel): self.set_ipv6_flabel_masked(flabel, UINT32_MAX) def set_ipv6_flabel_masked(self, flabel, mask): self._wc.ft_set(ofproto.OFPXMT_OFB_IPV6_FLABEL) self._wc.ipv6_flabel_mask = mask self._flow.ipv6_flabel = flabel def set_icmpv6_type(self, icmpv6_type): self._wc.ft_set(ofproto.OFPXMT_OFB_ICMPV6_TYPE) self._flow.icmpv6_type = icmpv6_type def set_icmpv6_code(self, icmpv6_code): self._wc.ft_set(ofproto.OFPXMT_OFB_ICMPV6_CODE) self._flow.icmpv6_code = icmpv6_code def set_ipv6_nd_target(self, target): self._wc.ft_set(ofproto.OFPXMT_OFB_IPV6_ND_TARGET) self._flow.ipv6_nd_target = target def set_ipv6_nd_sll(self, ipv6_nd_sll): self._wc.ft_set(ofproto.OFPXMT_OFB_IPV6_ND_SLL) self._flow.ipv6_nd_sll = ipv6_nd_sll def set_ipv6_nd_tll(self, ipv6_nd_tll): self._wc.ft_set(ofproto.OFPXMT_OFB_IPV6_ND_TLL) self._flow.ipv6_nd_tll = ipv6_nd_tll def set_mpls_label(self, mpls_label): self._wc.ft_set(ofproto.OFPXMT_OFB_MPLS_LABEL) self._flow.mpls_label = mpls_label def set_mpls_tc(self, mpls_tc): self._wc.ft_set(ofproto.OFPXMT_OFB_MPLS_TC) self._flow.mpls_tc = mpls_tc def set_mpls_bos(self, bos): self._wc.ft_set(ofproto.OFPXMT_OFB_MPLS_BOS) self._flow.mpls_bos = bos def set_pbb_isid(self, isid): self._wc.ft_set(ofproto.OFPXMT_OFB_PBB_ISID) self._flow.pbb_isid = isid def set_pbb_isid_masked(self, isid, mask): self._wc.ft_set(ofproto.OFPXMT_OFB_PBB_ISID) self._wc.pbb_isid_mask = mask self._flow.pbb_isid = isid def set_tunnel_id(self, tunnel_id): self._wc.ft_set(ofproto.OFPXMT_OFB_TUNNEL_ID) self._flow.tunnel_id = tunnel_id def set_tunnel_id_masked(self, tunnel_id, mask): self._wc.ft_set(ofproto.OFPXMT_OFB_TUNNEL_ID) self._wc.tunnel_id_mask = mask self._flow.tunnel_id = tunnel_id def set_ipv6_exthdr(self, hdr): self._wc.ft_set(ofproto.OFPXMT_OFB_IPV6_EXTHDR) self._flow.ipv6_exthdr = hdr def set_ipv6_exthdr_masked(self, hdr, mask): self._wc.ft_set(ofproto.OFPXMT_OFB_IPV6_EXTHDR) self._wc.ipv6_exthdr_mask = mask self._flow.ipv6_exthdr = hdr class OFPPropUnknown(StringifyMixin): def __init__(self, type_=None, length=None, buf=None): self.buf = buf @classmethod def parser(cls, buf): return cls(buf=buf) class OFPPropBase(StringifyMixin): _PACK_STR = '!HH' # _TYPES = {} must be an attribute of subclass def __init__(self, type_, length=None): self.type = type_ self.length = length @classmethod def register_type(cls, type_): def _register_type(subcls): cls._TYPES[type_] = subcls return subcls return _register_type @classmethod def parse(cls, buf): (type_, length) = struct.unpack_from(cls._PACK_STR, buf, 0) if not length: raise ValueError rest = buf[utils.round_up(length, 8):] try: subcls = cls._TYPES[type_] except KeyError: subcls = OFPPropUnknown prop = subcls.parser(buf) prop.type = type_ prop.length = length return prop, rest @classmethod def get_rest(cls, buf): (type_, length) = struct.unpack_from(cls._PACK_STR, buf, 0) offset = struct.calcsize(cls._PACK_STR) return buf[offset:length] def serialize(self): # Body # serialize_body should be implemented by subclass body = bytearray() body += self.serialize_body() # fixup self.length = len(body) + struct.calcsize(self._PACK_STR) # Header buf = bytearray() msg_pack_into(self._PACK_STR, buf, 0, self.type, self.length) buf += body # Pad pad_len = utils.round_up(self.length, 8) - self.length msg_pack_into("%dx" % pad_len, buf, len(buf)) return buf class OFPPropCommonExperimenter4ByteData(StringifyMixin): _PACK_STR = '!HHII' _EXPERIMENTER_DATA_PACK_STR = '!I' _EXPERIMENTER_DATA_SIZE = 4 def __init__(self, type_=None, length=None, experimenter=None, exp_type=None, data=bytearray()): self.type = type_ self.length = length self.experimenter = experimenter self.exp_type = exp_type self.data = data @classmethod def parser(cls, buf): (type_, length, experimenter, exp_type) = struct.unpack_from( ofproto.OFP_PROP_EXPERIMENTER_PACK_STR, buf, 0) rest = buf[ofproto.OFP_PROP_EXPERIMENTER_SIZE:length] data = [] while rest: (d,) = struct.unpack_from( cls._EXPERIMENTER_DATA_PACK_STR, rest, 0) data.append(d) rest = rest[cls._EXPERIMENTER_DATA_SIZE:] return cls(type_, length, experimenter, exp_type, data) def serialize(self): offset = 0 bin_data = bytearray() for d in self.data: msg_pack_into(self._EXPERIMENTER_DATA_PACK_STR, bin_data, offset, d) offset += self._EXPERIMENTER_DATA_SIZE # fixup self.length = struct.calcsize(self._PACK_STR) self.length += len(bin_data) buf = bytearray() msg_pack_into(self._PACK_STR, buf, 0, self.type, self.length, self.experimenter, self.exp_type) buf += bin_data # Pad pad_len = utils.round_up(self.length, 8) - self.length msg_pack_into("%dx" % pad_len, buf, len(buf)) return buf class OFPMatchField(StringifyMixin): _FIELDS_HEADERS = {} @staticmethod def register_field_header(headers): def _register_field_header(cls): for header in headers: OFPMatchField._FIELDS_HEADERS[header] = cls return cls return _register_field_header def __init__(self, header): self.header = header self.n_bytes = ofproto.oxm_tlv_header_extract_length(header) self.length = 0 @classmethod def cls_to_header(cls, cls_, hasmask): # XXX efficiency inv = dict((v, k) for k, v in cls._FIELDS_HEADERS.items() if (((k >> 8) & 1) != 0) == hasmask) return inv[cls_] @staticmethod def make(header, value, mask=None): cls_ = OFPMatchField._FIELDS_HEADERS.get(header) return cls_(header, value, mask) @classmethod def parser(cls, buf, offset): (header,) = struct.unpack_from('!I', buf, offset) cls_ = OFPMatchField._FIELDS_HEADERS.get(header) if cls_: field = cls_.field_parser(header, buf, offset) else: field = OFPMatchField(header) field.length = (header & 0xff) + 4 return field @classmethod def field_parser(cls, header, buf, offset): mask = None if ofproto.oxm_tlv_header_extract_hasmask(header): pack_str = '!' + cls.pack_str[1:] * 2 (value, mask) = struct.unpack_from(pack_str, buf, offset + 4) else: (value,) = struct.unpack_from(cls.pack_str, buf, offset + 4) return cls(header, value, mask) # pytype: disable=wrong-arg-count def serialize(self, buf, offset): if ofproto.oxm_tlv_header_extract_hasmask(self.header): self.put_w(buf, offset, self.value, self.mask) else: self.put(buf, offset, self.value) def _put_header(self, buf, offset): msg_pack_into('!I', buf, offset, self.header) self.length = 4 def _put(self, buf, offset, value): msg_pack_into(self.pack_str, buf, offset, value) self.length += self.n_bytes def put_w(self, buf, offset, value, mask): self._put_header(buf, offset) self._put(buf, offset + self.length, value) self._put(buf, offset + self.length, mask) def put(self, buf, offset, value): self._put_header(buf, offset) self._put(buf, offset + self.length, value) def _putv6(self, buf, offset, value): msg_pack_into(self.pack_str, buf, offset, *value) self.length += self.n_bytes def putv6(self, buf, offset, value, mask=None): self._put_header(buf, offset) self._putv6(buf, offset + self.length, value) if mask and len(mask): self._putv6(buf, offset + self.length, mask) def oxm_len(self): return self.header & 0xff def to_jsondict(self): # remove some redundant attributes d = super(OFPMatchField, self).to_jsondict() v = d[self.__class__.__name__] del v['header'] del v['length'] del v['n_bytes'] return d @classmethod def from_jsondict(cls, dict_): # just pass the dict around. # it will be converted by OFPMatch.__init__(). return {cls.__name__: dict_} def stringify_attrs(self): f = super(OFPMatchField, self).stringify_attrs if not ofproto.oxm_tlv_header_extract_hasmask(self.header): # something like the following, but yield two values (k,v) # return itertools.ifilter(lambda k, v: k != 'mask', iter()) def g(): for k, v in f(): if k != 'mask': yield (k, v) return g() else: return f() @OFPMatchField.register_field_header([ofproto.OXM_OF_IN_PORT]) class MTInPort(OFPMatchField): pack_str = '!I' def __init__(self, header, value, mask=None): super(MTInPort, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto.OXM_OF_METADATA, ofproto.OXM_OF_METADATA_W]) class MTMetadata(OFPMatchField): pack_str = '!Q' def __init__(self, header, value, mask=None): super(MTMetadata, self).__init__(header) self.value = value self.mask = mask @OFPMatchField.register_field_header([ofproto.OXM_OF_IN_PHY_PORT]) class MTInPhyPort(OFPMatchField): pack_str = '!I' def __init__(self, header, value, mask=None): super(MTInPhyPort, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto.OXM_OF_ETH_DST, ofproto.OXM_OF_ETH_DST_W]) class MTEthDst(OFPMatchField): pack_str = '!6s' def __init__(self, header, value, mask=None): super(MTEthDst, self).__init__(header) self.value = value self.mask = mask @OFPMatchField.register_field_header([ofproto.OXM_OF_ETH_SRC, ofproto.OXM_OF_ETH_SRC_W]) class MTEthSrc(OFPMatchField): pack_str = '!6s' def __init__(self, header, value, mask=None): super(MTEthSrc, self).__init__(header) self.value = value self.mask = mask @OFPMatchField.register_field_header([ofproto.OXM_OF_ETH_TYPE]) class MTEthType(OFPMatchField): pack_str = '!H' def __init__(self, header, value, mask=None): super(MTEthType, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto.OXM_OF_VLAN_VID, ofproto.OXM_OF_VLAN_VID_W]) class MTVlanVid(OFPMatchField): pack_str = '!H' def __init__(self, header, value, mask=None): super(MTVlanVid, self).__init__(header) self.value = value self.mask = mask @classmethod def field_parser(cls, header, buf, offset): m = super(MTVlanVid, cls).field_parser(header, buf, offset) m.value &= ~ofproto.OFPVID_PRESENT return m @OFPMatchField.register_field_header([ofproto.OXM_OF_VLAN_PCP]) class MTVlanPcp(OFPMatchField): pack_str = '!B' def __init__(self, header, value, mask=None): super(MTVlanPcp, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto.OXM_OF_IP_DSCP]) class MTIPDscp(OFPMatchField): pack_str = '!B' def __init__(self, header, value, mask=None): super(MTIPDscp, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto.OXM_OF_IP_ECN]) class MTIPECN(OFPMatchField): pack_str = '!B' def __init__(self, header, value, mask=None): super(MTIPECN, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto.OXM_OF_IP_PROTO]) class MTIPProto(OFPMatchField): pack_str = '!B' def __init__(self, header, value, mask=None): super(MTIPProto, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto.OXM_OF_IPV4_SRC, ofproto.OXM_OF_IPV4_SRC_W]) class MTIPV4Src(OFPMatchField): pack_str = '!I' def __init__(self, header, value, mask=None): super(MTIPV4Src, self).__init__(header) self.value = value self.mask = mask @OFPMatchField.register_field_header([ofproto.OXM_OF_IPV4_DST, ofproto.OXM_OF_IPV4_DST_W]) class MTIPV4Dst(OFPMatchField): pack_str = '!I' def __init__(self, header, value, mask=None): super(MTIPV4Dst, self).__init__(header) self.value = value self.mask = mask @OFPMatchField.register_field_header([ofproto.OXM_OF_TCP_SRC]) class MTTCPSrc(OFPMatchField): pack_str = '!H' def __init__(self, header, value, mask=None): super(MTTCPSrc, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto.OXM_OF_TCP_DST]) class MTTCPDst(OFPMatchField): pack_str = '!H' def __init__(self, header, value, mask=None): super(MTTCPDst, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto.OXM_OF_UDP_SRC]) class MTUDPSrc(OFPMatchField): pack_str = '!H' def __init__(self, header, value, mask=None): super(MTUDPSrc, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto.OXM_OF_UDP_DST]) class MTUDPDst(OFPMatchField): pack_str = '!H' def __init__(self, header, value, mask=None): super(MTUDPDst, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto.OXM_OF_SCTP_SRC]) class MTSCTPSrc(OFPMatchField): pack_str = '!H' def __init__(self, header, value, mask=None): super(MTSCTPSrc, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto.OXM_OF_SCTP_DST]) class MTSCTPDst(OFPMatchField): pack_str = '!H' def __init__(self, header, value, mask=None): super(MTSCTPDst, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto.OXM_OF_ICMPV4_TYPE]) class MTICMPV4Type(OFPMatchField): pack_str = '!B' def __init__(self, header, value, mask=None): super(MTICMPV4Type, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto.OXM_OF_ICMPV4_CODE]) class MTICMPV4Code(OFPMatchField): pack_str = '!B' def __init__(self, header, value, mask=None): super(MTICMPV4Code, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto.OXM_OF_ARP_OP]) class MTArpOp(OFPMatchField): pack_str = '!H' def __init__(self, header, value, mask=None): super(MTArpOp, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto.OXM_OF_ARP_SPA, ofproto.OXM_OF_ARP_SPA_W]) class MTArpSpa(OFPMatchField): pack_str = '!I' def __init__(self, header, value, mask=None): super(MTArpSpa, self).__init__(header) self.value = value self.mask = mask @OFPMatchField.register_field_header([ofproto.OXM_OF_ARP_TPA, ofproto.OXM_OF_ARP_TPA_W]) class MTArpTpa(OFPMatchField): pack_str = '!I' def __init__(self, header, value, mask=None): super(MTArpTpa, self).__init__(header) self.value = value self.mask = mask @OFPMatchField.register_field_header([ofproto.OXM_OF_ARP_SHA, ofproto.OXM_OF_ARP_SHA_W]) class MTArpSha(OFPMatchField): pack_str = '!6s' def __init__(self, header, value, mask=None): super(MTArpSha, self).__init__(header) self.value = value self.mask = mask @OFPMatchField.register_field_header([ofproto.OXM_OF_ARP_THA, ofproto.OXM_OF_ARP_THA_W]) class MTArpTha(OFPMatchField): pack_str = '!6s' def __init__(self, header, value, mask=None): super(MTArpTha, self).__init__(header) self.value = value self.mask = mask class MTIPv6(StringifyMixin): @classmethod def field_parser(cls, header, buf, offset): if ofproto.oxm_tlv_header_extract_hasmask(header): pack_str = '!' + cls.pack_str[1:] * 2 value = struct.unpack_from(pack_str, buf, offset + 4) return cls(header, list(value[:8]), list(value[8:])) else: value = struct.unpack_from(cls.pack_str, buf, offset + 4) return cls(header, list(value)) def serialize(self, buf, offset): self.putv6(buf, offset, self.value, self.mask) @OFPMatchField.register_field_header([ofproto.OXM_OF_IPV6_SRC, ofproto.OXM_OF_IPV6_SRC_W]) class MTIPv6Src(MTIPv6, OFPMatchField): pack_str = '!8H' def __init__(self, header, value, mask=None): super(MTIPv6Src, self).__init__(header) self.value = value self.mask = mask @OFPMatchField.register_field_header([ofproto.OXM_OF_IPV6_DST, ofproto.OXM_OF_IPV6_DST_W]) class MTIPv6Dst(MTIPv6, OFPMatchField): pack_str = '!8H' def __init__(self, header, value, mask=None): super(MTIPv6Dst, self).__init__(header) self.value = value self.mask = mask @OFPMatchField.register_field_header([ofproto.OXM_OF_IPV6_FLABEL, ofproto.OXM_OF_IPV6_FLABEL_W]) class MTIPv6Flabel(OFPMatchField): pack_str = '!I' def __init__(self, header, value, mask=None): super(MTIPv6Flabel, self).__init__(header) self.value = value self.mask = mask @OFPMatchField.register_field_header([ofproto.OXM_OF_MPLS_LABEL]) class MTMplsLabel(OFPMatchField): pack_str = '!I' def __init__(self, header, value, mask=None): super(MTMplsLabel, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto.OXM_OF_ICMPV6_TYPE]) class MTICMPV6Type(OFPMatchField): pack_str = '!B' def __init__(self, header, value, mask=None): super(MTICMPV6Type, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto.OXM_OF_ICMPV6_CODE]) class MTICMPV6Code(OFPMatchField): pack_str = '!B' def __init__(self, header, value, mask=None): super(MTICMPV6Code, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto.OXM_OF_IPV6_ND_TARGET]) class MTIPv6NdTarget(MTIPv6, OFPMatchField): pack_str = '!8H' def __init__(self, header, value, mask=None): super(MTIPv6NdTarget, self).__init__(header) self.value = value def serialize(self, buf, offset): self.putv6(buf, offset, self.value) @OFPMatchField.register_field_header([ofproto.OXM_OF_IPV6_ND_SLL]) class MTIPv6NdSll(OFPMatchField): pack_str = '!6s' def __init__(self, header, value, mask=None): super(MTIPv6NdSll, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto.OXM_OF_IPV6_ND_TLL]) class MTIPv6NdTll(OFPMatchField): pack_str = '!6s' def __init__(self, header, value, mask=None): super(MTIPv6NdTll, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto.OXM_OF_MPLS_TC]) class MTMplsTc(OFPMatchField): pack_str = '!B' def __init__(self, header, value, mask=None): super(MTMplsTc, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto.OXM_OF_MPLS_BOS]) class MTMplsBos(OFPMatchField): pack_str = '!B' def __init__(self, header, value, mask=None): super(MTMplsBos, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto.OXM_OF_PBB_ISID, ofproto.OXM_OF_PBB_ISID_W]) class MTPbbIsid(OFPMatchField): pack_str = '!3B' def __init__(self, header, value, mask=None): super(MTPbbIsid, self).__init__(header) self.value = value self.mask = mask @classmethod def field_parser(cls, header, buf, offset): mask = None if ofproto.oxm_tlv_header_extract_hasmask(header): pack_str = '!' + cls.pack_str[1:] * 2 (v1, v2, v3, m1, m2, m3) = struct.unpack_from(pack_str, buf, offset + 4) value = v1 << 16 | v2 << 8 | v3 mask = m1 << 16 | m2 << 8 | m3 else: (v1, v2, v3,) = struct.unpack_from(cls.pack_str, buf, offset + 4) value = v1 << 16 | v2 << 8 | v3 return cls(header, value, mask) def _put(self, buf, offset, value): msg_pack_into(self.pack_str, buf, offset, (value >> 16) & 0xff, (value >> 8) & 0xff, (value >> 0) & 0xff) self.length += self.n_bytes @OFPMatchField.register_field_header([ofproto.OXM_OF_TUNNEL_ID, ofproto.OXM_OF_TUNNEL_ID_W]) class MTTunnelId(OFPMatchField): pack_str = '!Q' def __init__(self, header, value, mask=None): super(MTTunnelId, self).__init__(header) self.value = value self.mask = mask @OFPMatchField.register_field_header([ofproto.OXM_OF_IPV6_EXTHDR, ofproto.OXM_OF_IPV6_EXTHDR_W]) class MTIPv6ExtHdr(OFPMatchField): pack_str = '!H' def __init__(self, header, value, mask=None): super(MTIPv6ExtHdr, self).__init__(header) self.value = value self.mask = mask @_register_parser @_set_msg_type(ofproto.OFPT_PACKET_IN) class OFPPacketIn(MsgBase): """ Packet-In message The switch sends the packet that received to the controller by this message. ============= ========================================================= Attribute Description ============= ========================================================= buffer_id ID assigned by datapath total_len Full length of frame reason Reason packet is being sent. | OFPR_NO_MATCH | OFPR_ACTION | OFPR_INVALID_TTL table_id ID of the table that was looked up cookie Cookie of the flow entry that was looked up match Instance of ``OFPMatch`` data Ethernet frame ============= ========================================================= Example:: @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER) def packet_in_handler(self, ev): msg = ev.msg dp = msg.datapath ofp = dp.ofproto if msg.reason == ofp.OFPR_NO_MATCH: reason = 'NO MATCH' elif msg.reason == ofp.OFPR_ACTION: reason = 'ACTION' elif msg.reason == ofp.OFPR_INVALID_TTL: reason = 'INVALID TTL' else: reason = 'unknown' self.logger.debug('OFPPacketIn received: ' 'buffer_id=%x total_len=%d reason=%s ' 'table_id=%d cookie=%d match=%s data=%s', msg.buffer_id, msg.total_len, reason, msg.table_id, msg.cookie, msg.match, utils.hex_array(msg.data)) """ def __init__(self, datapath, buffer_id=None, total_len=None, reason=None, table_id=None, cookie=None, match=None, data=None): super(OFPPacketIn, self).__init__(datapath) self.buffer_id = buffer_id self.total_len = total_len self.reason = reason self.table_id = table_id self.cookie = cookie self.match = match self.data = data @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPPacketIn, cls).parser(datapath, version, msg_type, msg_len, xid, buf) (msg.buffer_id, msg.total_len, msg.reason, msg.table_id, msg.cookie) = struct.unpack_from( ofproto.OFP_PACKET_IN_PACK_STR, msg.buf, ofproto.OFP_HEADER_SIZE) msg.match = OFPMatch.parser(msg.buf, ofproto.OFP_PACKET_IN_SIZE - ofproto.OFP_MATCH_SIZE) match_len = utils.round_up(msg.match.length, 8) msg.data = msg.buf[(ofproto.OFP_PACKET_IN_SIZE - ofproto.OFP_MATCH_SIZE + match_len + 2):] if msg.total_len < len(msg.data): # discard padding for 8-byte alignment of OFP packet msg.data = msg.data[:msg.total_len] return msg @_register_parser @_set_msg_type(ofproto.OFPT_FLOW_REMOVED) class OFPFlowRemoved(MsgBase): """ Flow removed message When flow entries time out or are deleted, the switch notifies controller with this message. ================ ====================================================== Attribute Description ================ ====================================================== cookie Opaque controller-issued identifier priority Priority level of flow entry reason One of the following values. | OFPRR_IDLE_TIMEOUT | OFPRR_HARD_TIMEOUT | OFPRR_DELETE | OFPRR_GROUP_DELETE table_id ID of the table duration_sec Time flow was alive in seconds duration_nsec Time flow was alive in nanoseconds beyond duration_sec idle_timeout Idle timeout from original flow mod hard_timeout Hard timeout from original flow mod packet_count Number of packets that was associated with the flow byte_count Number of bytes that was associated with the flow match Instance of ``OFPMatch`` ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPFlowRemoved, MAIN_DISPATCHER) def flow_removed_handler(self, ev): msg = ev.msg dp = msg.datapath ofp = dp.ofproto if msg.reason == ofp.OFPRR_IDLE_TIMEOUT: reason = 'IDLE TIMEOUT' elif msg.reason == ofp.OFPRR_HARD_TIMEOUT: reason = 'HARD TIMEOUT' elif msg.reason == ofp.OFPRR_DELETE: reason = 'DELETE' elif msg.reason == ofp.OFPRR_GROUP_DELETE: reason = 'GROUP DELETE' else: reason = 'unknown' self.logger.debug('OFPFlowRemoved received: ' 'cookie=%d priority=%d reason=%s table_id=%d ' 'duration_sec=%d duration_nsec=%d ' 'idle_timeout=%d hard_timeout=%d ' 'packet_count=%d byte_count=%d match.fields=%s', msg.cookie, msg.priority, reason, msg.table_id, msg.duration_sec, msg.duration_nsec, msg.idle_timeout, msg.hard_timeout, msg.packet_count, msg.byte_count, msg.match) """ def __init__(self, datapath, cookie=None, priority=None, reason=None, table_id=None, duration_sec=None, duration_nsec=None, idle_timeout=None, hard_timeout=None, packet_count=None, byte_count=None, match=None): super(OFPFlowRemoved, self).__init__(datapath) self.cookie = cookie self.priority = priority self.reason = reason self.table_id = table_id self.duration_sec = duration_sec self.duration_nsec = duration_nsec self.idle_timeout = idle_timeout self.hard_timeout = hard_timeout self.packet_count = packet_count self.byte_count = byte_count self.match = match @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPFlowRemoved, cls).parser(datapath, version, msg_type, msg_len, xid, buf) (msg.cookie, msg.priority, msg.reason, msg.table_id, msg.duration_sec, msg.duration_nsec, msg.idle_timeout, msg.hard_timeout, msg.packet_count, msg.byte_count) = struct.unpack_from( ofproto.OFP_FLOW_REMOVED_PACK_STR0, msg.buf, ofproto.OFP_HEADER_SIZE) offset = (ofproto.OFP_FLOW_REMOVED_SIZE - ofproto.OFP_MATCH_SIZE) msg.match = OFPMatch.parser(msg.buf, offset) return msg class OFPPort(ofproto_parser.namedtuple('OFPPort', ( 'port_no', 'hw_addr', 'name', 'config', 'state', 'curr', 'advertised', 'supported', 'peer', 'curr_speed', 'max_speed'))): """ Description of a port ========== ========================================================= Attribute Description ========== ========================================================= port_no Port number and it uniquely identifies a port within a switch. hw_addr MAC address for the port. name Null-terminated string containing a human-readable name for the interface. config Bitmap of port configuration flags. | OFPPC_PORT_DOWN | OFPPC_NO_RECV | OFPPC_NO_FWD | OFPPC_NO_PACKET_IN state Bitmap of port state flags. | OFPPS_LINK_DOWN | OFPPS_BLOCKED | OFPPS_LIVE curr Current features. advertised Features being advertised by the port. supported Features supported by the port. peer Features advertised by peer. curr_speed Current port bitrate in kbps. max_speed Max port bitrate in kbps. ========== ========================================================= """ _TYPE = { 'ascii': [ 'hw_addr', ], 'utf-8': [ # OF spec is unclear about the encoding of name. # we assumes UTF-8, which is used by OVS. 'name', ] } @classmethod def parser(cls, buf, offset): port = struct.unpack_from(ofproto.OFP_PORT_PACK_STR, buf, offset) port = list(port) i = cls._fields.index('hw_addr') port[i] = addrconv.mac.bin_to_text(port[i]) i = cls._fields.index('name') port[i] = port[i].rstrip(b'\0') ofpport = cls(*port) ofpport.length = ofproto.OFP_PORT_SIZE return ofpport @_register_parser @_set_msg_type(ofproto.OFPT_PORT_STATUS) class OFPPortStatus(MsgBase): """ Port status message The switch notifies controller of change of ports. ================ ====================================================== Attribute Description ================ ====================================================== reason One of the following values. | OFPPR_ADD | OFPPR_DELETE | OFPPR_MODIFY desc instance of ``OFPPort`` ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPPortStatus, MAIN_DISPATCHER) def port_status_handler(self, ev): msg = ev.msg dp = msg.datapath ofp = dp.ofproto if msg.reason == ofp.OFPPR_ADD: reason = 'ADD' elif msg.reason == ofp.OFPPR_DELETE: reason = 'DELETE' elif msg.reason == ofp.OFPPR_MODIFY: reason = 'MODIFY' else: reason = 'unknown' self.logger.debug('OFPPortStatus received: reason=%s desc=%s', reason, msg.desc) """ def __init__(self, datapath, reason=None, desc=None): super(OFPPortStatus, self).__init__(datapath) self.reason = reason self.desc = desc @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPPortStatus, cls).parser(datapath, version, msg_type, msg_len, xid, buf) msg.reason = struct.unpack_from( ofproto.OFP_PORT_STATUS_PACK_STR, msg.buf, ofproto.OFP_HEADER_SIZE)[0] msg.desc = OFPPort.parser(msg.buf, ofproto.OFP_PORT_STATUS_DESC_OFFSET) return msg @_set_msg_type(ofproto.OFPT_PACKET_OUT) class OFPPacketOut(MsgBase): """ Packet-Out message The controller uses this message to send a packet out throught the switch. ================ ====================================================== Attribute Description ================ ====================================================== buffer_id ID assigned by datapath (OFP_NO_BUFFER if none) in_port Packet's input port or ``OFPP_CONTROLLER`` actions list of OpenFlow action class data Packet data of a binary type value or an instances of packet.Packet. ================ ====================================================== Example:: def send_packet_out(self, datapath, buffer_id, in_port): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser actions = [ofp_parser.OFPActionOutput(ofp.OFPP_FLOOD, 0)] req = ofp_parser.OFPPacketOut(datapath, buffer_id, in_port, actions) datapath.send_msg(req) """ def __init__(self, datapath, buffer_id=None, in_port=None, actions=None, data=None, actions_len=None): assert in_port is not None super(OFPPacketOut, self).__init__(datapath) self.buffer_id = buffer_id self.in_port = in_port self.actions_len = 0 self.actions = actions self.data = data def _serialize_body(self): self.actions_len = 0 offset = ofproto.OFP_PACKET_OUT_SIZE for a in self.actions: a.serialize(self.buf, offset) offset += a.len self.actions_len += a.len if self.data is not None: assert self.buffer_id == 0xffffffff if isinstance(self.data, packet.Packet): self.data.serialize() self.buf += self.data.data else: self.buf += self.data msg_pack_into(ofproto.OFP_PACKET_OUT_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.buffer_id, self.in_port, self.actions_len) @classmethod def from_jsondict(cls, dict_, decode_string=base64.b64decode, **additional_args): if isinstance(dict_['data'], dict): data = dict_.pop('data') ins = super(OFPPacketOut, cls).from_jsondict(dict_, decode_string, **additional_args) ins.data = packet.Packet.from_jsondict(data['Packet']) dict_['data'] = data else: ins = super(OFPPacketOut, cls).from_jsondict(dict_, decode_string, **additional_args) return ins @_register_parser @_set_msg_type(ofproto.OFPT_FLOW_MOD) class OFPFlowMod(MsgBase): """ Modify Flow entry message The controller sends this message to modify the flow table. ================ ====================================================== Attribute Description ================ ====================================================== cookie Opaque controller-issued identifier cookie_mask Mask used to restrict the cookie bits that must match when the command is ``OPFFC_MODIFY*`` or ``OFPFC_DELETE*`` table_id ID of the table to put the flow in command One of the following values. | OFPFC_ADD | OFPFC_MODIFY | OFPFC_MODIFY_STRICT | OFPFC_DELETE | OFPFC_DELETE_STRICT idle_timeout Idle time before discarding (seconds) hard_timeout Max time before discarding (seconds) priority Priority level of flow entry buffer_id Buffered packet to apply to (or OFP_NO_BUFFER) out_port For ``OFPFC_DELETE*`` commands, require matching entries to include this as an output port out_group For ``OFPFC_DELETE*`` commands, require matching entries to include this as an output group flags Bitmap of the following flags. | OFPFF_SEND_FLOW_REM | OFPFF_CHECK_OVERLAP | OFPFF_RESET_COUNTS | OFPFF_NO_PKT_COUNTS | OFPFF_NO_BYT_COUNTS match Instance of ``OFPMatch`` instructions list of ``OFPInstruction*`` instance ================ ====================================================== Example:: def send_flow_mod(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser cookie = cookie_mask = 0 table_id = 0 idle_timeout = hard_timeout = 0 priority = 32768 buffer_id = ofp.OFP_NO_BUFFER match = ofp_parser.OFPMatch(in_port=1, eth_dst='ff:ff:ff:ff:ff:ff') actions = [ofp_parser.OFPActionOutput(ofp.OFPP_NORMAL, 0)] inst = [ofp_parser.OFPInstructionActions(ofp.OFPIT_APPLY_ACTIONS, actions)] req = ofp_parser.OFPFlowMod(datapath, cookie, cookie_mask, table_id, ofp.OFPFC_ADD, idle_timeout, hard_timeout, priority, buffer_id, ofp.OFPP_ANY, ofp.OFPG_ANY, ofp.OFPFF_SEND_FLOW_REM, match, inst) datapath.send_msg(req) """ def __init__(self, datapath, cookie=0, cookie_mask=0, table_id=0, command=ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=0, priority=ofproto.OFP_DEFAULT_PRIORITY, buffer_id=ofproto.OFP_NO_BUFFER, out_port=0, out_group=0, flags=0, match=None, instructions=None): instructions = instructions if instructions else [] super(OFPFlowMod, self).__init__(datapath) self.cookie = cookie self.cookie_mask = cookie_mask self.table_id = table_id self.command = command self.idle_timeout = idle_timeout self.hard_timeout = hard_timeout self.priority = priority self.buffer_id = buffer_id self.out_port = out_port self.out_group = out_group self.flags = flags if match is None: match = OFPMatch() assert isinstance(match, OFPMatch) self.match = match for i in instructions: assert isinstance(i, OFPInstruction) self.instructions = instructions def _serialize_body(self): msg_pack_into(ofproto.OFP_FLOW_MOD_PACK_STR0, self.buf, ofproto.OFP_HEADER_SIZE, self.cookie, self.cookie_mask, self.table_id, self.command, self.idle_timeout, self.hard_timeout, self.priority, self.buffer_id, self.out_port, self.out_group, self.flags) offset = (ofproto.OFP_FLOW_MOD_SIZE - ofproto.OFP_MATCH_SIZE) match_len = self.match.serialize(self.buf, offset) offset += match_len for inst in self.instructions: inst.serialize(self.buf, offset) offset += inst.len @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPFlowMod, cls).parser( datapath, version, msg_type, msg_len, xid, buf) (msg.cookie, msg.cookie_mask, msg.table_id, msg.command, msg.idle_timeout, msg.hard_timeout, msg.priority, msg.buffer_id, msg.out_port, msg.out_group, msg.flags) = struct.unpack_from( ofproto.OFP_FLOW_MOD_PACK_STR0, msg.buf, ofproto.OFP_HEADER_SIZE) offset = ofproto.OFP_FLOW_MOD_SIZE - ofproto.OFP_HEADER_SIZE try: msg.match = OFPMatch.parser(buf, offset) except exception.OFPTruncatedMessage as e: msg.match = e.ofpmsg e.ofpmsg = msg raise e offset += utils.round_up(msg.match.length, 8) instructions = [] try: while offset < msg_len: i = OFPInstruction.parser(buf, offset) if i is not None: instructions.append(i) offset += i.len except exception.OFPTruncatedMessage as e: instructions.append(e.ofpmsg) msg.instructions = instructions e.ofpmsg = msg raise e except struct.error as e: msg.instructions = instructions raise exception.OFPTruncatedMessage(ofpmsg=msg, residue=buf[offset:], original_exception=e) msg.instructions = instructions return msg class OFPInstruction(StringifyMixin): _INSTRUCTION_TYPES = {} @staticmethod def register_instruction_type(types): def _register_instruction_type(cls): for type_ in types: OFPInstruction._INSTRUCTION_TYPES[type_] = cls return cls return _register_instruction_type @classmethod def parser(cls, buf, offset): (type_, len_) = struct.unpack_from('!HH', buf, offset) cls_ = cls._INSTRUCTION_TYPES.get(type_) if cls_ is not None: return cls_.parser(buf, offset) return None @OFPInstruction.register_instruction_type([ofproto.OFPIT_GOTO_TABLE]) class OFPInstructionGotoTable(OFPInstruction): """ Goto table instruction This instruction indicates the next table in the processing pipeline. ================ ====================================================== Attribute Description ================ ====================================================== table_id Next table ================ ====================================================== """ def __init__(self, table_id, type_=None, len_=None): super(OFPInstructionGotoTable, self).__init__() self.type = ofproto.OFPIT_GOTO_TABLE self.len = ofproto.OFP_INSTRUCTION_GOTO_TABLE_SIZE self.table_id = table_id @classmethod def parser(cls, buf, offset): (type_, len_, table_id) = struct.unpack_from( ofproto.OFP_INSTRUCTION_GOTO_TABLE_PACK_STR, buf, offset) return cls(table_id) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_INSTRUCTION_GOTO_TABLE_PACK_STR, buf, offset, self.type, self.len, self.table_id) @OFPInstruction.register_instruction_type([ofproto.OFPIT_WRITE_METADATA]) class OFPInstructionWriteMetadata(OFPInstruction): """ Write metadata instruction This instruction writes the masked metadata value into the metadata field. ================ ====================================================== Attribute Description ================ ====================================================== metadata Metadata value to write metadata_mask Metadata write bitmask ================ ====================================================== """ def __init__(self, metadata, metadata_mask, type_=None, len_=None): super(OFPInstructionWriteMetadata, self).__init__() self.type = ofproto.OFPIT_WRITE_METADATA self.len = ofproto.OFP_INSTRUCTION_WRITE_METADATA_SIZE self.metadata = metadata self.metadata_mask = metadata_mask @classmethod def parser(cls, buf, offset): (type_, len_, metadata, metadata_mask) = struct.unpack_from( ofproto.OFP_INSTRUCTION_WRITE_METADATA_PACK_STR, buf, offset) return cls(metadata, metadata_mask) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_INSTRUCTION_WRITE_METADATA_PACK_STR, buf, offset, self.type, self.len, self.metadata, self.metadata_mask) @OFPInstruction.register_instruction_type([ofproto.OFPIT_WRITE_ACTIONS, ofproto.OFPIT_APPLY_ACTIONS, ofproto.OFPIT_CLEAR_ACTIONS]) class OFPInstructionActions(OFPInstruction): """ Actions instruction This instruction writes/applies/clears the actions. ================ ====================================================== Attribute Description ================ ====================================================== type One of following values. | OFPIT_WRITE_ACTIONS | OFPIT_APPLY_ACTIONS | OFPIT_CLEAR_ACTIONS actions list of OpenFlow action class ================ ====================================================== ``type`` attribute corresponds to ``type_`` parameter of __init__. """ def __init__(self, type_, actions=None, len_=None): super(OFPInstructionActions, self).__init__() self.type = type_ for a in actions: assert isinstance(a, OFPAction) self.actions = actions @classmethod def parser(cls, buf, offset): (type_, len_) = struct.unpack_from( ofproto.OFP_INSTRUCTION_ACTIONS_PACK_STR, buf, offset) offset += ofproto.OFP_INSTRUCTION_ACTIONS_SIZE actions = [] actions_len = len_ - ofproto.OFP_INSTRUCTION_ACTIONS_SIZE exc = None try: while actions_len > 0: a = OFPAction.parser(buf, offset) actions.append(a) actions_len -= a.len offset += a.len except struct.error as e: exc = e inst = cls(type_, actions) inst.len = len_ if exc is not None: raise exception.OFPTruncatedMessage(ofpmsg=inst, residue=buf[offset:], original_exception=exc) return inst def serialize(self, buf, offset): action_offset = offset + ofproto.OFP_INSTRUCTION_ACTIONS_SIZE if self.actions: for a in self.actions: a.serialize(buf, action_offset) action_offset += a.len self.len = action_offset - offset pad_len = utils.round_up(self.len, 8) - self.len msg_pack_into("%dx" % pad_len, buf, action_offset) self.len += pad_len msg_pack_into(ofproto.OFP_INSTRUCTION_ACTIONS_PACK_STR, buf, offset, self.type, self.len) @OFPInstruction.register_instruction_type([ofproto.OFPIT_METER]) class OFPInstructionMeter(OFPInstruction): """ Meter instruction This instruction applies the meter. ================ ====================================================== Attribute Description ================ ====================================================== meter_id Meter instance ================ ====================================================== """ def __init__(self, meter_id=1, type_=None, len_=None): super(OFPInstructionMeter, self).__init__() self.type = ofproto.OFPIT_METER self.len = ofproto.OFP_INSTRUCTION_METER_SIZE self.meter_id = meter_id @classmethod def parser(cls, buf, offset): (type_, len_, meter_id) = struct.unpack_from( ofproto.OFP_INSTRUCTION_METER_PACK_STR, buf, offset) return cls(meter_id) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_INSTRUCTION_METER_PACK_STR, buf, offset, self.type, self.len, self.meter_id) class OFPActionHeader(StringifyMixin): def __init__(self, type_, len_): self.type = type_ self.len = len_ def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_HEADER_PACK_STR, buf, offset, self.type, self.len) class OFPAction(OFPActionHeader): _ACTION_TYPES = {} @staticmethod def register_action_type(type_, len_): def _register_action_type(cls): cls.cls_action_type = type_ cls.cls_action_len = len_ OFPAction._ACTION_TYPES[cls.cls_action_type] = cls return cls return _register_action_type def __init__(self): cls = self.__class__ super(OFPAction, self).__init__(cls.cls_action_type, cls.cls_action_len) @classmethod def parser(cls, buf, offset): type_, len_ = struct.unpack_from( ofproto.OFP_ACTION_HEADER_PACK_STR, buf, offset) cls_ = cls._ACTION_TYPES.get(type_) assert cls_ is not None return cls_.parser(buf, offset) @OFPAction.register_action_type(ofproto.OFPAT_OUTPUT, ofproto.OFP_ACTION_OUTPUT_SIZE) class OFPActionOutput(OFPAction): """ Output action This action indicates output a packet to the switch port. ================ ====================================================== Attribute Description ================ ====================================================== port Output port max_len Max length to send to controller ================ ====================================================== """ def __init__(self, port, max_len=ofproto.OFPCML_MAX, type_=None, len_=None): super(OFPActionOutput, self).__init__() self.port = port self.max_len = max_len @classmethod def parser(cls, buf, offset): type_, len_, port, max_len = struct.unpack_from( ofproto.OFP_ACTION_OUTPUT_PACK_STR, buf, offset) return cls(port, max_len) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_OUTPUT_PACK_STR, buf, offset, self.type, self.len, self.port, self.max_len) @OFPAction.register_action_type(ofproto.OFPAT_GROUP, ofproto.OFP_ACTION_GROUP_SIZE) class OFPActionGroup(OFPAction): """ Group action This action indicates the group used to process the packet. ================ ====================================================== Attribute Description ================ ====================================================== group_id Group identifier ================ ====================================================== """ def __init__(self, group_id=0, type_=None, len_=None): super(OFPActionGroup, self).__init__() self.group_id = group_id @classmethod def parser(cls, buf, offset): (type_, len_, group_id) = struct.unpack_from( ofproto.OFP_ACTION_GROUP_PACK_STR, buf, offset) return cls(group_id) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_GROUP_PACK_STR, buf, offset, self.type, self.len, self.group_id) @OFPAction.register_action_type(ofproto.OFPAT_SET_QUEUE, ofproto.OFP_ACTION_SET_QUEUE_SIZE) class OFPActionSetQueue(OFPAction): """ Set queue action This action sets the queue id that will be used to map a flow to an already-configured queue on a port. ================ ====================================================== Attribute Description ================ ====================================================== queue_id Queue ID for the packets ================ ====================================================== """ def __init__(self, queue_id, type_=None, len_=None): super(OFPActionSetQueue, self).__init__() self.queue_id = queue_id @classmethod def parser(cls, buf, offset): (type_, len_, queue_id) = struct.unpack_from( ofproto.OFP_ACTION_SET_QUEUE_PACK_STR, buf, offset) return cls(queue_id) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_SET_QUEUE_PACK_STR, buf, offset, self.type, self.len, self.queue_id) @OFPAction.register_action_type(ofproto.OFPAT_SET_MPLS_TTL, ofproto.OFP_ACTION_MPLS_TTL_SIZE) class OFPActionSetMplsTtl(OFPAction): """ Set MPLS TTL action This action sets the MPLS TTL. ================ ====================================================== Attribute Description ================ ====================================================== mpls_ttl MPLS TTL ================ ====================================================== """ def __init__(self, mpls_ttl, type_=None, len_=None): super(OFPActionSetMplsTtl, self).__init__() self.mpls_ttl = mpls_ttl @classmethod def parser(cls, buf, offset): (type_, len_, mpls_ttl) = struct.unpack_from( ofproto.OFP_ACTION_MPLS_TTL_PACK_STR, buf, offset) return cls(mpls_ttl) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_MPLS_TTL_PACK_STR, buf, offset, self.type, self.len, self.mpls_ttl) @OFPAction.register_action_type(ofproto.OFPAT_DEC_MPLS_TTL, ofproto.OFP_ACTION_HEADER_SIZE) class OFPActionDecMplsTtl(OFPAction): """ Decrement MPLS TTL action This action decrements the MPLS TTL. """ def __init__(self, type_=None, len_=None): super(OFPActionDecMplsTtl, self).__init__() @classmethod def parser(cls, buf, offset): (type_, len_) = struct.unpack_from( ofproto.OFP_ACTION_HEADER_PACK_STR, buf, offset) return cls() @OFPAction.register_action_type(ofproto.OFPAT_SET_NW_TTL, ofproto.OFP_ACTION_NW_TTL_SIZE) class OFPActionSetNwTtl(OFPAction): """ Set IP TTL action This action sets the IP TTL. ================ ====================================================== Attribute Description ================ ====================================================== nw_ttl IP TTL ================ ====================================================== """ def __init__(self, nw_ttl, type_=None, len_=None): super(OFPActionSetNwTtl, self).__init__() self.nw_ttl = nw_ttl @classmethod def parser(cls, buf, offset): (type_, len_, nw_ttl) = struct.unpack_from( ofproto.OFP_ACTION_NW_TTL_PACK_STR, buf, offset) return cls(nw_ttl) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_NW_TTL_PACK_STR, buf, offset, self.type, self.len, self.nw_ttl) @OFPAction.register_action_type(ofproto.OFPAT_DEC_NW_TTL, ofproto.OFP_ACTION_HEADER_SIZE) class OFPActionDecNwTtl(OFPAction): """ Decrement IP TTL action This action decrements the IP TTL. """ def __init__(self, type_=None, len_=None): super(OFPActionDecNwTtl, self).__init__() @classmethod def parser(cls, buf, offset): (type_, len_) = struct.unpack_from( ofproto.OFP_ACTION_HEADER_PACK_STR, buf, offset) return cls() @OFPAction.register_action_type(ofproto.OFPAT_COPY_TTL_OUT, ofproto.OFP_ACTION_HEADER_SIZE) class OFPActionCopyTtlOut(OFPAction): """ Copy TTL Out action This action copies the TTL from the next-to-outermost header with TTL to the outermost header with TTL. """ def __init__(self, type_=None, len_=None): super(OFPActionCopyTtlOut, self).__init__() @classmethod def parser(cls, buf, offset): (type_, len_) = struct.unpack_from( ofproto.OFP_ACTION_HEADER_PACK_STR, buf, offset) return cls() @OFPAction.register_action_type(ofproto.OFPAT_COPY_TTL_IN, ofproto.OFP_ACTION_HEADER_SIZE) class OFPActionCopyTtlIn(OFPAction): """ Copy TTL In action This action copies the TTL from the outermost header with TTL to the next-to-outermost header with TTL. """ def __init__(self, type_=None, len_=None): super(OFPActionCopyTtlIn, self).__init__() @classmethod def parser(cls, buf, offset): (type_, len_) = struct.unpack_from( ofproto.OFP_ACTION_HEADER_PACK_STR, buf, offset) return cls() @OFPAction.register_action_type(ofproto.OFPAT_PUSH_VLAN, ofproto.OFP_ACTION_PUSH_SIZE) class OFPActionPushVlan(OFPAction): """ Push VLAN action This action pushes a new VLAN tag to the packet. ================ ====================================================== Attribute Description ================ ====================================================== ethertype Ether type. The default is 802.1Q. (0x8100) ================ ====================================================== """ def __init__(self, ethertype=ether.ETH_TYPE_8021Q, type_=None, len_=None): super(OFPActionPushVlan, self).__init__() self.ethertype = ethertype @classmethod def parser(cls, buf, offset): (type_, len_, ethertype) = struct.unpack_from( ofproto.OFP_ACTION_PUSH_PACK_STR, buf, offset) return cls(ethertype) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_PUSH_PACK_STR, buf, offset, self.type, self.len, self.ethertype) @OFPAction.register_action_type(ofproto.OFPAT_PUSH_MPLS, ofproto.OFP_ACTION_PUSH_SIZE) class OFPActionPushMpls(OFPAction): """ Push MPLS action This action pushes a new MPLS header to the packet. ================ ====================================================== Attribute Description ================ ====================================================== ethertype Ether type ================ ====================================================== """ def __init__(self, ethertype=ether.ETH_TYPE_MPLS, type_=None, len_=None): super(OFPActionPushMpls, self).__init__() self.ethertype = ethertype @classmethod def parser(cls, buf, offset): (type_, len_, ethertype) = struct.unpack_from( ofproto.OFP_ACTION_PUSH_PACK_STR, buf, offset) return cls(ethertype) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_PUSH_PACK_STR, buf, offset, self.type, self.len, self.ethertype) @OFPAction.register_action_type(ofproto.OFPAT_POP_VLAN, ofproto.OFP_ACTION_HEADER_SIZE) class OFPActionPopVlan(OFPAction): """ Pop VLAN action This action pops the outermost VLAN tag from the packet. """ def __init__(self, type_=None, len_=None): super(OFPActionPopVlan, self).__init__() @classmethod def parser(cls, buf, offset): (type_, len_) = struct.unpack_from( ofproto.OFP_ACTION_HEADER_PACK_STR, buf, offset) return cls() @OFPAction.register_action_type(ofproto.OFPAT_POP_MPLS, ofproto.OFP_ACTION_POP_MPLS_SIZE) class OFPActionPopMpls(OFPAction): """ Pop MPLS action This action pops the MPLS header from the packet. """ def __init__(self, ethertype=ether.ETH_TYPE_IP, type_=None, len_=None): super(OFPActionPopMpls, self).__init__() self.ethertype = ethertype @classmethod def parser(cls, buf, offset): (type_, len_, ethertype) = struct.unpack_from( ofproto.OFP_ACTION_POP_MPLS_PACK_STR, buf, offset) return cls(ethertype) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_POP_MPLS_PACK_STR, buf, offset, self.type, self.len, self.ethertype) @OFPAction.register_action_type(ofproto.OFPAT_SET_FIELD, ofproto.OFP_ACTION_SET_FIELD_SIZE) class OFPActionSetField(OFPAction): """ Set field action This action modifies a header field in the packet. The set of keywords available for this is same as OFPMatch. Example:: set_field = OFPActionSetField(eth_src="00:00:00:00:00:00") """ def __init__(self, field=None, **kwargs): # old api # OFPActionSetField(field) # new api # OFPActionSetField(eth_src="00:00:00:00:00") super(OFPActionSetField, self).__init__() if isinstance(field, OFPMatchField): # old api compat assert len(kwargs) == 0 self.field = field else: # new api assert len(kwargs) == 1 key = list(kwargs.keys())[0] value = kwargs[key] assert isinstance(key, (str, str)) assert not isinstance(value, tuple) # no mask self.key = key self.value = value @classmethod def parser(cls, buf, offset): (type_, len_) = struct.unpack_from( ofproto.OFP_ACTION_SET_FIELD_PACK_STR, buf, offset) (n, value, mask, _len) = ofproto.oxm_parse(buf, offset + 4) k, uv = ofproto.oxm_to_user(n, value, mask) action = cls(**{k: uv}) action.len = len_ # old api compat action.field = OFPMatchField.parser(buf, offset + 4) return action def serialize(self, buf, offset): # old api compat if self._composed_with_old_api(): return self.serialize_old(buf, offset) n, value, mask = ofproto.oxm_from_user(self.key, self.value) len_ = ofproto.oxm_serialize(n, value, mask, buf, offset + 4) self.len = utils.round_up(4 + len_, 8) msg_pack_into('!HH', buf, offset, self.type, self.len) pad_len = self.len - (4 + len_) msg_pack_into("%dx" % pad_len, buf, offset + 4 + len_) # XXX old api compat def serialize_old(self, buf, offset): len_ = ofproto.OFP_ACTION_SET_FIELD_SIZE + self.field.oxm_len() self.len = utils.round_up(len_, 8) pad_len = self.len - len_ msg_pack_into('!HH', buf, offset, self.type, self.len) self.field.serialize(buf, offset + 4) offset += len_ msg_pack_into("%dx" % pad_len, buf, offset) # XXX old api compat def _composed_with_old_api(self): return not hasattr(self, 'value') def to_jsondict(self): return { self.__class__.__name__: { 'field': ofproto.oxm_to_jsondict(self.key, self.value), "len": self.len, "type": self.type } } @classmethod def from_jsondict(cls, dict_): k, v = ofproto.oxm_from_jsondict(dict_['field']) o = OFPActionSetField(**{k: v}) # XXX old api compat # serialize and parse to fill old attributes buf = bytearray() o.serialize(buf, 0) return OFPActionSetField.parser(bytes(buf), 0) # XXX old api compat def __str__(self): # XXX old api compat if self._composed_with_old_api(): # copy object first because serialize_old is destructive o2 = OFPActionSetField(self.field) # serialize and parse to fill new fields buf = bytearray() o2.serialize(buf, 0) o = OFPActionSetField.parser(bytes(buf), 0) else: o = self return super(OFPActionSetField, o).__str__() __repr__ = __str__ def stringify_attrs(self): yield (self.key, self.value) @OFPAction.register_action_type(ofproto.OFPAT_PUSH_PBB, ofproto.OFP_ACTION_PUSH_SIZE) class OFPActionPushPbb(OFPAction): """ Push PBB action This action pushes a new PBB header to the packet. ================ ====================================================== Attribute Description ================ ====================================================== ethertype Ether type ================ ====================================================== """ def __init__(self, ethertype, type_=None, len_=None): super(OFPActionPushPbb, self).__init__() self.ethertype = ethertype @classmethod def parser(cls, buf, offset): (type_, len_, ethertype) = struct.unpack_from( ofproto.OFP_ACTION_PUSH_PACK_STR, buf, offset) return cls(ethertype) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_PUSH_PACK_STR, buf, offset, self.type, self.len, self.ethertype) @OFPAction.register_action_type(ofproto.OFPAT_POP_PBB, ofproto.OFP_ACTION_HEADER_SIZE) class OFPActionPopPbb(OFPAction): """ Pop PBB action This action pops the outermost PBB service instance header from the packet. """ def __init__(self, type_=None, len_=None): super(OFPActionPopPbb, self).__init__() @classmethod def parser(cls, buf, offset): (type_, len_) = struct.unpack_from( ofproto.OFP_ACTION_HEADER_PACK_STR, buf, offset) return cls() @OFPAction.register_action_type( ofproto.OFPAT_EXPERIMENTER, ofproto.OFP_ACTION_EXPERIMENTER_HEADER_SIZE) class OFPActionExperimenter(OFPAction): """ Experimenter action This action is an extensible action for the experimenter. ================ ====================================================== Attribute Description ================ ====================================================== experimenter Experimenter ID ================ ====================================================== .. Note:: For the list of the supported Nicira experimenter actions, please refer to :ref:`os_ken.ofproto.nx_actions `. """ def __init__(self, experimenter): super(OFPActionExperimenter, self).__init__() self.type = ofproto.OFPAT_EXPERIMENTER self.experimenter = experimenter self.len = None @classmethod def parser(cls, buf, offset): (type_, len_, experimenter) = struct.unpack_from( ofproto.OFP_ACTION_EXPERIMENTER_HEADER_PACK_STR, buf, offset) data = buf[(offset + ofproto.OFP_ACTION_EXPERIMENTER_HEADER_SIZE ): offset + len_] if experimenter == ofproto_common.NX_EXPERIMENTER_ID: obj = NXAction.parse(data) # pytype: disable=name-error # noqa else: obj = OFPActionExperimenterUnknown(experimenter, data) obj.len = len_ return obj def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_EXPERIMENTER_HEADER_PACK_STR, buf, offset, self.type, self.len, self.experimenter) class OFPActionExperimenterUnknown(OFPActionExperimenter): def __init__(self, experimenter, data=None, type_=None, len_=None): super(OFPActionExperimenterUnknown, self).__init__(experimenter=experimenter) self.data = data def serialize(self, buf, offset): # fixup data = self.data if data is None: data = bytearray() self.len = (utils.round_up(len(data), 8) + ofproto.OFP_ACTION_EXPERIMENTER_HEADER_SIZE) super(OFPActionExperimenterUnknown, self).serialize(buf, offset) msg_pack_into('!%ds' % len(self.data), buf, offset + ofproto.OFP_ACTION_EXPERIMENTER_HEADER_SIZE, self.data) class OFPBucket(StringifyMixin): def __init__(self, weight=0, watch_port=ofproto.OFPP_ANY, watch_group=ofproto.OFPG_ANY, actions=None, len_=None): super(OFPBucket, self).__init__() self.weight = weight self.watch_port = watch_port self.watch_group = watch_group self.actions = actions @classmethod def parser(cls, buf, offset): (len_, weight, watch_port, watch_group) = struct.unpack_from( ofproto.OFP_BUCKET_PACK_STR, buf, offset) msg = cls(weight, watch_port, watch_group, []) msg.len = len_ length = ofproto.OFP_BUCKET_SIZE offset += ofproto.OFP_BUCKET_SIZE while length < msg.len: action = OFPAction.parser(buf, offset) msg.actions.append(action) offset += action.len length += action.len return msg def serialize(self, buf, offset): action_offset = offset + ofproto.OFP_BUCKET_SIZE action_len = 0 for a in self.actions: a.serialize(buf, action_offset) action_offset += a.len action_len += a.len self.len = utils.round_up(ofproto.OFP_BUCKET_SIZE + action_len, 8) msg_pack_into(ofproto.OFP_BUCKET_PACK_STR, buf, offset, self.len, self.weight, self.watch_port, self.watch_group) @_set_msg_type(ofproto.OFPT_GROUP_MOD) class OFPGroupMod(MsgBase): """ Modify group entry message The controller sends this message to modify the group table. ================ ====================================================== Attribute Description ================ ====================================================== command One of the following values. | OFPGC_ADD | OFPGC_MODIFY | OFPGC_DELETE type One of the following values. | OFPGT_ALL | OFPGT_SELECT | OFPGT_INDIRECT | OFPGT_FF group_id Group identifier buckets list of ``OFPBucket`` ================ ====================================================== ``type`` attribute corresponds to ``type_`` parameter of __init__. Example:: def send_group_mod(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser port = 1 max_len = 2000 actions = [ofp_parser.OFPActionOutput(port, max_len)] weight = 100 watch_port = 0 watch_group = 0 buckets = [ofp_parser.OFPBucket(weight, watch_port, watch_group, actions)] group_id = 1 req = ofp_parser.OFPGroupMod(datapath, ofp.OFPGC_ADD, ofp.OFPGT_SELECT, group_id, buckets) datapath.send_msg(req) """ def __init__(self, datapath, command=ofproto.OFPGC_ADD, type_=ofproto.OFPGT_ALL, group_id=0, buckets=None): buckets = buckets if buckets else [] super(OFPGroupMod, self).__init__(datapath) self.command = command self.type = type_ self.group_id = group_id self.buckets = buckets def _serialize_body(self): msg_pack_into(ofproto.OFP_GROUP_MOD_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.command, self.type, self.group_id) offset = ofproto.OFP_GROUP_MOD_SIZE for b in self.buckets: b.serialize(self.buf, offset) offset += b.len @_set_msg_type(ofproto.OFPT_PORT_MOD) class OFPPortMod(MsgBase): """ Port modification message The controller sneds this message to modify the behavior of the port. ================ ====================================================== Attribute Description ================ ====================================================== port_no Port number to modify hw_addr The hardware address that must be the same as hw_addr of ``OFPPort`` of ``OFPSwitchFeatures`` config Bitmap of configuration flags. | OFPPC_PORT_DOWN | OFPPC_NO_RECV | OFPPC_NO_FWD | OFPPC_NO_PACKET_IN mask Bitmap of configuration flags above to be changed advertise Bitmap of the following flags. | OFPPF_10MB_HD | OFPPF_10MB_FD | OFPPF_100MB_HD | OFPPF_100MB_FD | OFPPF_1GB_HD | OFPPF_1GB_FD | OFPPF_10GB_FD | OFPPF_40GB_FD | OFPPF_100GB_FD | OFPPF_1TB_FD | OFPPF_OTHER | OFPPF_COPPER | OFPPF_FIBER | OFPPF_AUTONEG | OFPPF_PAUSE | OFPPF_PAUSE_ASYM ================ ====================================================== Example:: def send_port_mod(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser port_no = 3 hw_addr = 'fa:c8:e8:76:1d:7e' config = 0 mask = (ofp.OFPPC_PORT_DOWN | ofp.OFPPC_NO_RECV | ofp.OFPPC_NO_FWD | ofp.OFPPC_NO_PACKET_IN) advertise = (ofp.OFPPF_10MB_HD | ofp.OFPPF_100MB_FD | ofp.OFPPF_1GB_FD | ofp.OFPPF_COPPER | ofp.OFPPF_AUTONEG | ofp.OFPPF_PAUSE | ofp.OFPPF_PAUSE_ASYM) req = ofp_parser.OFPPortMod(datapath, port_no, hw_addr, config, mask, advertise) datapath.send_msg(req) """ _TYPE = { 'ascii': [ 'hw_addr', ] } def __init__(self, datapath, port_no=0, hw_addr='00:00:00:00:00:00', config=0, mask=0, advertise=0): super(OFPPortMod, self).__init__(datapath) self.port_no = port_no self.hw_addr = hw_addr self.config = config self.mask = mask self.advertise = advertise def _serialize_body(self): msg_pack_into(ofproto.OFP_PORT_MOD_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.port_no, addrconv.mac.text_to_bin(self.hw_addr), self.config, self.mask, self.advertise) @_set_msg_type(ofproto.OFPT_METER_MOD) class OFPMeterMod(MsgBase): """ Meter modification message The controller sends this message to modify the meter. ================ ====================================================== Attribute Description ================ ====================================================== command One of the following values. | OFPMC_ADD | OFPMC_MODIFY | OFPMC_DELETE flags Bitmap of the following flags. | OFPMF_KBPS | OFPMF_PKTPS | OFPMF_BURST | OFPMF_STATS meter_id Meter instance bands list of the following class instance. | OFPMeterBandDrop | OFPMeterBandDscpRemark | OFPMeterBandExperimenter ================ ====================================================== """ def __init__(self, datapath, command=ofproto.OFPMC_ADD, flags=ofproto.OFPMF_KBPS, meter_id=1, bands=None): bands = bands if bands else [] super(OFPMeterMod, self).__init__(datapath) self.command = command self.flags = flags self.meter_id = meter_id self.bands = bands def _serialize_body(self): msg_pack_into(ofproto.OFP_METER_MOD_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.command, self.flags, self.meter_id) offset = ofproto.OFP_METER_MOD_SIZE for b in self.bands: b.serialize(self.buf, offset) offset += b.len @_set_msg_type(ofproto.OFPT_TABLE_MOD) class OFPTableMod(MsgBase): """ Flow table configuration message The controller sends this message to configure table state. ================ ====================================================== Attribute Description ================ ====================================================== table_id ID of the table (OFPTT_ALL indicates all tables) config Bitmap of the following flags. OFPTC_DEPRECATED_MASK (3) ================ ====================================================== Example:: def send_table_mod(self, datapath): ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPTableMod(datapath, 1, 3) datapath.send_msg(req) """ def __init__(self, datapath, table_id, config): super(OFPTableMod, self).__init__(datapath) self.table_id = table_id self.config = config def _serialize_body(self): msg_pack_into(ofproto.OFP_TABLE_MOD_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.table_id, self.config) def _set_stats_type(stats_type, stats_body_cls): def _set_cls_stats_type(cls): cls.cls_stats_type = stats_type cls.cls_stats_body_cls = stats_body_cls return cls return _set_cls_stats_type @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPMultipartRequest(MsgBase): def __init__(self, datapath, flags): super(OFPMultipartRequest, self).__init__(datapath) self.type = self.__class__.cls_stats_type self.flags = flags def _serialize_stats_body(self): pass def _serialize_body(self): msg_pack_into(ofproto.OFP_MULTIPART_REQUEST_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.type, self.flags) self._serialize_stats_body() @_register_parser @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPMultipartReply(MsgBase): _STATS_MSG_TYPES = {} @staticmethod def register_stats_type(body_single_struct=False): def _register_stats_type(cls): assert cls.cls_stats_type is not None assert cls.cls_stats_type not in OFPMultipartReply._STATS_MSG_TYPES assert cls.cls_stats_body_cls is not None cls.cls_body_single_struct = body_single_struct OFPMultipartReply._STATS_MSG_TYPES[cls.cls_stats_type] = cls return cls return _register_stats_type def __init__(self, datapath, body=None, flags=None): super(OFPMultipartReply, self).__init__(datapath) self.body = body self.flags = flags @classmethod def parser_stats_body(cls, buf, msg_len, offset): body_cls = cls.cls_stats_body_cls body = [] while offset < msg_len: entry = body_cls.parser(buf, offset) body.append(entry) offset += entry.length if cls.cls_body_single_struct: return body[0] return body @classmethod def parser_stats(cls, datapath, version, msg_type, msg_len, xid, buf): msg = MsgBase.parser.__func__( cls, datapath, version, msg_type, msg_len, xid, buf) msg.body = msg.parser_stats_body(msg.buf, msg.msg_len, ofproto.OFP_MULTIPART_REPLY_SIZE) return msg @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): type_, flags = struct.unpack_from( ofproto.OFP_MULTIPART_REPLY_PACK_STR, bytes(buf), ofproto.OFP_HEADER_SIZE) stats_type_cls = cls._STATS_MSG_TYPES.get(type_) msg = super(OFPMultipartReply, stats_type_cls).parser( # pytype: disable=attribute-error datapath, version, msg_type, msg_len, xid, buf) msg.type = type_ msg.flags = flags if stats_type_cls is not None: offset = ofproto.OFP_MULTIPART_REPLY_SIZE body = [] while offset < msg_len: b = stats_type_cls.cls_stats_body_cls.parser(msg.buf, offset) body.append(b) offset += b.length if hasattr(b, 'length') else b.len if stats_type_cls.cls_body_single_struct: msg.body = body[0] else: msg.body = body return msg class OFPDescStats(ofproto_parser.namedtuple('OFPDescStats', ( 'mfr_desc', 'hw_desc', 'sw_desc', 'serial_num', 'dp_desc'))): _TYPE = { 'ascii': [ 'mfr_desc', 'hw_desc', 'sw_desc', 'serial_num', 'dp_desc', ] } @classmethod def parser(cls, buf, offset): desc = struct.unpack_from(ofproto.OFP_DESC_PACK_STR, buf, offset) desc = list(desc) desc = [x.rstrip(b'\0') for x in desc] stats = cls(*desc) stats.length = ofproto.OFP_DESC_SIZE return stats @_set_stats_type(ofproto.OFPMP_DESC, OFPDescStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPDescStatsRequest(OFPMultipartRequest): """ Description statistics request message The controller uses this message to query description of the switch. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or ``OFPMPF_REQ_MORE`` ================ ====================================================== Example:: def send_desc_stats_request(self, datapath): ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPDescStatsRequest(datapath, 0) datapath.send_msg(req) """ def __init__(self, datapath, flags=0, type_=None): super(OFPDescStatsRequest, self).__init__(datapath, flags) @OFPMultipartReply.register_stats_type(body_single_struct=True) @_set_stats_type(ofproto.OFPMP_DESC, OFPDescStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPDescStatsReply(OFPMultipartReply): """ Description statistics reply message The switch responds with this message to a description statistics request. ================ ====================================================== Attribute Description ================ ====================================================== body Instance of ``OFPDescStats`` ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPDescStatsReply, MAIN_DISPATCHER) def desc_stats_reply_handler(self, ev): body = ev.msg.body self.logger.debug('DescStats: mfr_desc=%s hw_desc=%s sw_desc=%s ' 'serial_num=%s dp_desc=%s', body.mfr_desc, body.hw_desc, body.sw_desc, body.serial_num, body.dp_desc) """ def __init__(self, datapath, type_=None, **kwargs): super(OFPDescStatsReply, self).__init__(datapath, **kwargs) class OFPFlowStats(StringifyMixin): def __init__(self, table_id=None, duration_sec=None, duration_nsec=None, priority=None, idle_timeout=None, hard_timeout=None, flags=None, cookie=None, packet_count=None, byte_count=None, match=None, instructions=None, length=None): super(OFPFlowStats, self).__init__() self.table_id = table_id self.duration_sec = duration_sec self.duration_nsec = duration_nsec self.priority = priority self.idle_timeout = idle_timeout self.hard_timeout = hard_timeout self.flags = flags self.cookie = cookie self.packet_count = packet_count self.byte_count = byte_count self.match = match self.instructions = instructions self.length = length @classmethod def parser(cls, buf, offset): flow_stats = cls() (flow_stats.length, flow_stats.table_id, flow_stats.duration_sec, flow_stats.duration_nsec, flow_stats.priority, flow_stats.idle_timeout, flow_stats.hard_timeout, flow_stats.flags, flow_stats.cookie, flow_stats.packet_count, flow_stats.byte_count) = struct.unpack_from( ofproto.OFP_FLOW_STATS_0_PACK_STR, buf, offset) offset += ofproto.OFP_FLOW_STATS_0_SIZE flow_stats.match = OFPMatch.parser(buf, offset) match_length = utils.round_up(flow_stats.match.length, 8) inst_length = (flow_stats.length - (ofproto.OFP_FLOW_STATS_SIZE - ofproto.OFP_MATCH_SIZE + match_length)) offset += match_length instructions = [] while inst_length > 0: inst = OFPInstruction.parser(buf, offset) instructions.append(inst) offset += inst.len inst_length -= inst.len flow_stats.instructions = instructions return flow_stats class OFPFlowStatsRequestBase(OFPMultipartRequest): def __init__(self, datapath, flags, table_id, out_port, out_group, cookie, cookie_mask, match): super(OFPFlowStatsRequestBase, self).__init__(datapath, flags) self.table_id = table_id self.out_port = out_port self.out_group = out_group self.cookie = cookie self.cookie_mask = cookie_mask self.match = match def _serialize_stats_body(self): offset = ofproto.OFP_MULTIPART_REQUEST_SIZE msg_pack_into(ofproto.OFP_FLOW_STATS_REQUEST_0_PACK_STR, self.buf, offset, self.table_id, self.out_port, self.out_group, self.cookie, self.cookie_mask) offset += ofproto.OFP_FLOW_STATS_REQUEST_0_SIZE self.match.serialize(self.buf, offset) @_set_stats_type(ofproto.OFPMP_FLOW, OFPFlowStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPFlowStatsRequest(OFPFlowStatsRequestBase): """ Individual flow statistics request message The controller uses this message to query individual flow statistics. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or ``OFPMPF_REQ_MORE`` table_id ID of table to read out_port Require matching entries to include this as an output port out_group Require matching entries to include this as an output group cookie Require matching entries to contain this cookie value cookie_mask Mask used to restrict the cookie bits that must match match Instance of ``OFPMatch`` ================ ====================================================== Example:: def send_flow_stats_request(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser cookie = cookie_mask = 0 match = ofp_parser.OFPMatch(in_port=1) req = ofp_parser.OFPFlowStatsRequest(datapath, 0, ofp.OFPTT_ALL, ofp.OFPP_ANY, ofp.OFPG_ANY, cookie, cookie_mask, match) datapath.send_msg(req) """ def __init__(self, datapath, flags=0, table_id=ofproto.OFPTT_ALL, out_port=ofproto.OFPP_ANY, out_group=ofproto.OFPG_ANY, cookie=0, cookie_mask=0, match=None, type_=None): if match is None: match = OFPMatch() super(OFPFlowStatsRequest, self).__init__(datapath, flags, table_id, out_port, out_group, cookie, cookie_mask, match) @OFPMultipartReply.register_stats_type() @_set_stats_type(ofproto.OFPMP_FLOW, OFPFlowStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPFlowStatsReply(OFPMultipartReply): """ Individual flow statistics reply message The switch responds with this message to an individual flow statistics request. ================ ====================================================== Attribute Description ================ ====================================================== body List of ``OFPFlowStats`` instance ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPFlowStatsReply, MAIN_DISPATCHER) def flow_stats_reply_handler(self, ev): flows = [] for stat in ev.msg.body: flows.append('table_id=%s ' 'duration_sec=%d duration_nsec=%d ' 'priority=%d ' 'idle_timeout=%d hard_timeout=%d flags=0x%04x ' 'cookie=%d packet_count=%d byte_count=%d ' 'match=%s instructions=%s' % (stat.table_id, stat.duration_sec, stat.duration_nsec, stat.priority, stat.idle_timeout, stat.hard_timeout, stat.flags, stat.cookie, stat.packet_count, stat.byte_count, stat.match, stat.instructions)) self.logger.debug('FlowStats: %s', flows) """ def __init__(self, datapath, type_=None, **kwargs): super(OFPFlowStatsReply, self).__init__(datapath, **kwargs) class OFPAggregateStats(ofproto_parser.namedtuple('OFPAggregateStats', ( 'packet_count', 'byte_count', 'flow_count'))): @classmethod def parser(cls, buf, offset): agg = struct.unpack_from( ofproto.OFP_AGGREGATE_STATS_REPLY_PACK_STR, buf, offset) stats = cls(*agg) stats.length = ofproto.OFP_AGGREGATE_STATS_REPLY_SIZE return stats @_set_stats_type(ofproto.OFPMP_AGGREGATE, OFPAggregateStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPAggregateStatsRequest(OFPFlowStatsRequestBase): """ Aggregate flow statistics request message The controller uses this message to query aggregate flow statictics. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or ``OFPMPF_REQ_MORE`` table_id ID of table to read out_port Require matching entries to include this as an output port out_group Require matching entries to include this as an output group cookie Require matching entries to contain this cookie value cookie_mask Mask used to restrict the cookie bits that must match match Instance of ``OFPMatch`` ================ ====================================================== Example:: def send_aggregate_stats_request(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser cookie = cookie_mask = 0 match = ofp_parser.OFPMatch(in_port=1) req = ofp_parser.OFPAggregateStatsRequest(datapath, 0, ofp.OFPTT_ALL, ofp.OFPP_ANY, ofp.OFPG_ANY, cookie, cookie_mask, match) datapath.send_msg(req) """ def __init__(self, datapath, flags, table_id, out_port, out_group, cookie, cookie_mask, match, type_=None): super(OFPAggregateStatsRequest, self).__init__(datapath, flags, table_id, out_port, out_group, cookie, cookie_mask, match) @OFPMultipartReply.register_stats_type(body_single_struct=True) @_set_stats_type(ofproto.OFPMP_AGGREGATE, OFPAggregateStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPAggregateStatsReply(OFPMultipartReply): """ Aggregate flow statistics reply message The switch responds with this message to an aggregate flow statistics request. ================ ====================================================== Attribute Description ================ ====================================================== body Instance of ``OFPAggregateStats`` ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPAggregateStatsReply, MAIN_DISPATCHER) def aggregate_stats_reply_handler(self, ev): body = ev.msg.body self.logger.debug('AggregateStats: packet_count=%d byte_count=%d ' 'flow_count=%d', body.packet_count, body.byte_count, body.flow_count) """ def __init__(self, datapath, type_=None, **kwargs): super(OFPAggregateStatsReply, self).__init__(datapath, **kwargs) class OFPTableStats(ofproto_parser.namedtuple('OFPTableStats', ( 'table_id', 'active_count', 'lookup_count', 'matched_count'))): @classmethod def parser(cls, buf, offset): tbl = struct.unpack_from(ofproto.OFP_TABLE_STATS_PACK_STR, buf, offset) stats = cls(*tbl) stats.length = ofproto.OFP_TABLE_STATS_SIZE return stats @_set_stats_type(ofproto.OFPMP_TABLE, OFPTableStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPTableStatsRequest(OFPMultipartRequest): """ Table statistics request message The controller uses this message to query flow table statictics. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or ``OFPMPF_REQ_MORE`` ================ ====================================================== Example:: def send_table_stats_request(self, datapath): ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPTableStatsRequest(datapath, 0) datapath.send_msg(req) """ def __init__(self, datapath, flags=0, type_=None): super(OFPTableStatsRequest, self).__init__(datapath, flags) @OFPMultipartReply.register_stats_type() @_set_stats_type(ofproto.OFPMP_TABLE, OFPTableStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPTableStatsReply(OFPMultipartReply): """ Table statistics reply message The switch responds with this message to a table statistics request. ================ ====================================================== Attribute Description ================ ====================================================== body List of ``OFPTableStats`` instance ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPTableStatsReply, MAIN_DISPATCHER) def table_stats_reply_handler(self, ev): tables = [] for stat in ev.msg.body: tables.append('table_id=%d active_count=%d lookup_count=%d ' ' matched_count=%d' % (stat.table_id, stat.active_count, stat.lookup_count, stat.matched_count)) self.logger.debug('TableStats: %s', tables) """ def __init__(self, datapath, type_=None, **kwargs): super(OFPTableStatsReply, self).__init__(datapath, **kwargs) class OFPPortStats(ofproto_parser.namedtuple('OFPPortStats', ( 'port_no', 'rx_packets', 'tx_packets', 'rx_bytes', 'tx_bytes', 'rx_dropped', 'tx_dropped', 'rx_errors', 'tx_errors', 'rx_frame_err', 'rx_over_err', 'rx_crc_err', 'collisions', 'duration_sec', 'duration_nsec'))): @classmethod def parser(cls, buf, offset): port = struct.unpack_from(ofproto.OFP_PORT_STATS_PACK_STR, buf, offset) stats = cls(*port) stats.length = ofproto.OFP_PORT_STATS_SIZE return stats @_set_stats_type(ofproto.OFPMP_PORT_STATS, OFPPortStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPPortStatsRequest(OFPMultipartRequest): """ Port statistics request message The controller uses this message to query information about ports statistics. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or ``OFPMPF_REQ_MORE`` port_no Port number to read (OFPP_ANY to all ports) ================ ====================================================== Example:: def send_port_stats_request(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPPortStatsRequest(datapath, 0, ofp.OFPP_ANY) datapath.send_msg(req) """ def __init__(self, datapath, flags=0, port_no=ofproto.OFPP_ANY, type_=None): super(OFPPortStatsRequest, self).__init__(datapath, flags) self.port_no = port_no def _serialize_stats_body(self): msg_pack_into(ofproto.OFP_PORT_STATS_REQUEST_PACK_STR, self.buf, ofproto.OFP_MULTIPART_REQUEST_SIZE, self.port_no) @OFPMultipartReply.register_stats_type() @_set_stats_type(ofproto.OFPMP_PORT_STATS, OFPPortStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPPortStatsReply(OFPMultipartReply): """ Port statistics reply message The switch responds with this message to a port statistics request. ================ ====================================================== Attribute Description ================ ====================================================== body List of ``OFPPortStats`` instance ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPPortStatsReply, MAIN_DISPATCHER) def port_stats_reply_handler(self, ev): ports = [] for stat in ev.msg.body: ports.append('port_no=%d ' 'rx_packets=%d tx_packets=%d ' 'rx_bytes=%d tx_bytes=%d ' 'rx_dropped=%d tx_dropped=%d ' 'rx_errors=%d tx_errors=%d ' 'rx_frame_err=%d rx_over_err=%d rx_crc_err=%d ' 'collisions=%d duration_sec=%d duration_nsec=%d' % (stat.port_no, stat.rx_packets, stat.tx_packets, stat.rx_bytes, stat.tx_bytes, stat.rx_dropped, stat.tx_dropped, stat.rx_errors, stat.tx_errors, stat.rx_frame_err, stat.rx_over_err, stat.rx_crc_err, stat.collisions, stat.duration_sec, stat.duration_nsec)) self.logger.debug('PortStats: %s', ports) """ def __init__(self, datapath, type_=None, **kwargs): super(OFPPortStatsReply, self).__init__(datapath, **kwargs) class OFPQueueStats(ofproto_parser.namedtuple('OFPQueueStats', ( 'port_no', 'queue_id', 'tx_bytes', 'tx_packets', 'tx_errors', 'duration_sec', 'duration_nsec'))): @classmethod def parser(cls, buf, offset): queue = struct.unpack_from(ofproto.OFP_QUEUE_STATS_PACK_STR, buf, offset) stats = cls(*queue) stats.length = ofproto.OFP_QUEUE_STATS_SIZE return stats @_set_stats_type(ofproto.OFPMP_QUEUE, OFPQueueStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPQueueStatsRequest(OFPMultipartRequest): """ Queue statistics request message The controller uses this message to query queue statictics. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or ``OFPMPF_REQ_MORE`` port_no Port number to read queue_id ID of queue to read ================ ====================================================== Example:: def send_queue_stats_request(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPQueueStatsRequest(datapath, 0, ofp.OFPP_ANY, ofp.OFPQ_ALL) datapath.send_msg(req) """ def __init__(self, datapath, flags=0, port_no=ofproto.OFPP_ANY, queue_id=ofproto.OFPQ_ALL, type_=None): super(OFPQueueStatsRequest, self).__init__(datapath, flags) self.port_no = port_no self.queue_id = queue_id def _serialize_stats_body(self): msg_pack_into(ofproto.OFP_QUEUE_STATS_REQUEST_PACK_STR, self.buf, ofproto.OFP_MULTIPART_REQUEST_SIZE, self.port_no, self.queue_id) @OFPMultipartReply.register_stats_type() @_set_stats_type(ofproto.OFPMP_QUEUE, OFPQueueStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPQueueStatsReply(OFPMultipartReply): """ Queue statistics reply message The switch responds with this message to an aggregate flow statistics request. ================ ====================================================== Attribute Description ================ ====================================================== body List of ``OFPQueueStats`` instance ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPQueueStatsReply, MAIN_DISPATCHER) def queue_stats_reply_handler(self, ev): queues = [] for stat in ev.msg.body: queues.append('port_no=%d queue_id=%d ' 'tx_bytes=%d tx_packets=%d tx_errors=%d ' 'duration_sec=%d duration_nsec=%d' % (stat.port_no, stat.queue_id, stat.tx_bytes, stat.tx_packets, stat.tx_errors, stat.duration_sec, stat.duration_nsec)) self.logger.debug('QueueStats: %s', queues) """ def __init__(self, datapath, type_=None, **kwargs): super(OFPQueueStatsReply, self).__init__(datapath, **kwargs) class OFPBucketCounter(StringifyMixin): def __init__(self, packet_count, byte_count): super(OFPBucketCounter, self).__init__() self.packet_count = packet_count self.byte_count = byte_count @classmethod def parser(cls, buf, offset): packet_count, byte_count = struct.unpack_from( ofproto.OFP_BUCKET_COUNTER_PACK_STR, buf, offset) return cls(packet_count, byte_count) class OFPGroupStats(StringifyMixin): def __init__(self, length=None, group_id=None, ref_count=None, packet_count=None, byte_count=None, duration_sec=None, duration_nsec=None, bucket_stats=None): super(OFPGroupStats, self).__init__() self.length = length self.group_id = group_id self.ref_count = ref_count self.packet_count = packet_count self.byte_count = byte_count self.duration_sec = duration_sec self.duration_nsec = duration_nsec self.bucket_stats = bucket_stats @classmethod def parser(cls, buf, offset): group = struct.unpack_from(ofproto.OFP_GROUP_STATS_PACK_STR, buf, offset) group_stats = cls(*group) group_stats.bucket_stats = [] if group_stats.length is not None: total_len = group_stats.length + offset offset += ofproto.OFP_GROUP_STATS_SIZE while total_len > offset: b = OFPBucketCounter.parser(buf, offset) group_stats.bucket_stats.append(b) offset += ofproto.OFP_BUCKET_COUNTER_SIZE return group_stats @_set_stats_type(ofproto.OFPMP_GROUP, OFPGroupStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPGroupStatsRequest(OFPMultipartRequest): """ Group statistics request message The controller uses this message to query statistics of one or more groups. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or ``OFPMPF_REQ_MORE`` group_id ID of group to read (OFPG_ALL to all groups) ================ ====================================================== Example:: def send_group_stats_request(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPGroupStatsRequest(datapath, 0, ofp.OFPG_ALL) datapath.send_msg(req) """ def __init__(self, datapath, flags=0, group_id=ofproto.OFPG_ALL, type_=None): super(OFPGroupStatsRequest, self).__init__(datapath, flags) self.group_id = group_id def _serialize_stats_body(self): msg_pack_into(ofproto.OFP_GROUP_STATS_REQUEST_PACK_STR, self.buf, ofproto.OFP_MULTIPART_REQUEST_SIZE, self.group_id) @OFPMultipartReply.register_stats_type() @_set_stats_type(ofproto.OFPMP_GROUP, OFPGroupStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPGroupStatsReply(OFPMultipartReply): """ Group statistics reply message The switch responds with this message to a group statistics request. ================ ====================================================== Attribute Description ================ ====================================================== body List of ``OFPGroupStats`` instance ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPGroupStatsReply, MAIN_DISPATCHER) def group_stats_reply_handler(self, ev): groups = [] for stat in ev.msg.body: groups.append('length=%d group_id=%d ' 'ref_count=%d packet_count=%d byte_count=%d ' 'duration_sec=%d duration_nsec=%d' % (stat.length, stat.group_id, stat.ref_count, stat.packet_count, stat.byte_count, stat.duration_sec, stat.duration_nsec)) self.logger.debug('GroupStats: %s', groups) """ def __init__(self, datapath, type_=None, **kwargs): super(OFPGroupStatsReply, self).__init__(datapath, **kwargs) class OFPGroupDescStats(StringifyMixin): def __init__(self, type_=None, group_id=None, buckets=None, length=None): super(OFPGroupDescStats, self).__init__() self.type = type_ self.group_id = group_id self.buckets = buckets @classmethod def parser(cls, buf, offset): stats = cls() (stats.length, stats.type, stats.group_id) = struct.unpack_from( ofproto.OFP_GROUP_DESC_STATS_PACK_STR, buf, offset) offset += ofproto.OFP_GROUP_DESC_STATS_SIZE stats.buckets = [] length = ofproto.OFP_GROUP_DESC_STATS_SIZE while length < stats.length: bucket = OFPBucket.parser(buf, offset) stats.buckets.append(bucket) offset += bucket.len length += bucket.len return stats @_set_stats_type(ofproto.OFPMP_GROUP_DESC, OFPGroupDescStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPGroupDescStatsRequest(OFPMultipartRequest): """ Group description request message The controller uses this message to list the set of groups on a switch. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or ``OFPMPF_REQ_MORE`` ================ ====================================================== Example:: def send_group_desc_stats_request(self, datapath): ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPGroupDescStatsRequest(datapath, 0) datapath.send_msg(req) """ def __init__(self, datapath, flags=0, type_=None): super(OFPGroupDescStatsRequest, self).__init__(datapath, flags) @OFPMultipartReply.register_stats_type() @_set_stats_type(ofproto.OFPMP_GROUP_DESC, OFPGroupDescStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPGroupDescStatsReply(OFPMultipartReply): """ Group description reply message The switch responds with this message to a group description request. ================ ====================================================== Attribute Description ================ ====================================================== body List of ``OFPGroupDescStats`` instance ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPGroupDescStatsReply, MAIN_DISPATCHER) def group_desc_stats_reply_handler(self, ev): descs = [] for stat in ev.msg.body: descs.append('length=%d type=%d group_id=%d ' 'buckets=%s' % (stat.length, stat.type, stat.group_id, stat.bucket)) self.logger.debug('GroupDescStats: %s', descs) """ def __init__(self, datapath, type_=None, **kwargs): super(OFPGroupDescStatsReply, self).__init__(datapath, **kwargs) class OFPGroupFeaturesStats(ofproto_parser.namedtuple('OFPGroupFeaturesStats', ('types', 'capabilities', 'max_groups', 'actions'))): @classmethod def parser(cls, buf, offset): group_features = struct.unpack_from( ofproto.OFP_GROUP_FEATURES_PACK_STR, buf, offset) types = group_features[0] capabilities = group_features[1] max_groups = list(group_features[2:6]) actions = list(group_features[6:10]) stats = cls(types, capabilities, max_groups, actions) stats.length = ofproto.OFP_GROUP_FEATURES_SIZE return stats @_set_stats_type(ofproto.OFPMP_GROUP_FEATURES, OFPGroupFeaturesStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPGroupFeaturesStatsRequest(OFPMultipartRequest): """ Group features request message The controller uses this message to list the capabilities of groups on a switch. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or ``OFPMPF_REQ_MORE`` ================ ====================================================== Example:: def send_group_features_stats_request(self, datapath): ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPGroupFeaturesStatsRequest(datapath, 0) datapath.send_msg(req) """ def __init__(self, datapath, flags=0, type_=None): super(OFPGroupFeaturesStatsRequest, self).__init__(datapath, flags) @OFPMultipartReply.register_stats_type(body_single_struct=True) @_set_stats_type(ofproto.OFPMP_GROUP_FEATURES, OFPGroupFeaturesStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPGroupFeaturesStatsReply(OFPMultipartReply): """ Group features reply message The switch responds with this message to a group features request. ================ ====================================================== Attribute Description ================ ====================================================== body Instance of ``OFPGroupFeaturesStats`` ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPGroupFeaturesStatsReply, MAIN_DISPATCHER) def group_features_stats_reply_handler(self, ev): body = ev.msg.body self.logger.debug('GroupFeaturesStats: types=%d ' 'capabilities=0x%08x max_groups=%s ' 'actions=%s', body.types, body.capabilities, body.max_groups, body.actions) """ def __init__(self, datapath, type_=None, **kwargs): super(OFPGroupFeaturesStatsReply, self).__init__(datapath, **kwargs) class OFPMeterBandStats(StringifyMixin): def __init__(self, packet_band_count, byte_band_count): super(OFPMeterBandStats, self).__init__() self.packet_band_count = packet_band_count self.byte_band_count = byte_band_count @classmethod def parser(cls, buf, offset): band_stats = struct.unpack_from( ofproto.OFP_METER_BAND_STATS_PACK_STR, buf, offset) return cls(*band_stats) class OFPMeterStats(StringifyMixin): def __init__(self, meter_id=None, flow_count=None, packet_in_count=None, byte_in_count=None, duration_sec=None, duration_nsec=None, band_stats=None, len_=None): super(OFPMeterStats, self).__init__() self.meter_id = meter_id self.len = 0 self.flow_count = flow_count self.packet_in_count = packet_in_count self.byte_in_count = byte_in_count self.duration_sec = duration_sec self.duration_nsec = duration_nsec self.band_stats = band_stats @classmethod def parser(cls, buf, offset): meter_stats = cls() (meter_stats.meter_id, meter_stats.len, meter_stats.flow_count, meter_stats.packet_in_count, meter_stats.byte_in_count, meter_stats.duration_sec, meter_stats.duration_nsec) = struct.unpack_from( ofproto.OFP_METER_STATS_PACK_STR, buf, offset) offset += ofproto.OFP_METER_STATS_SIZE meter_stats.band_stats = [] length = ofproto.OFP_METER_STATS_SIZE while length < meter_stats.len: band_stats = OFPMeterBandStats.parser(buf, offset) meter_stats.band_stats.append(band_stats) offset += ofproto.OFP_METER_BAND_STATS_SIZE length += ofproto.OFP_METER_BAND_STATS_SIZE return meter_stats @_set_stats_type(ofproto.OFPMP_METER, OFPMeterStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPMeterStatsRequest(OFPMultipartRequest): """ Meter statistics request message The controller uses this message to query statistics for one or more meters. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or ``OFPMPF_REQ_MORE`` meter_id ID of meter to read (OFPM_ALL to all meters) ================ ====================================================== Example:: def send_meter_stats_request(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPMeterStatsRequest(datapath, 0, ofp.OFPM_ALL) datapath.send_msg(req) """ def __init__(self, datapath, flags=0, meter_id=ofproto.OFPM_ALL, type_=None): super(OFPMeterStatsRequest, self).__init__(datapath, flags) self.meter_id = meter_id def _serialize_stats_body(self): msg_pack_into(ofproto.OFP_METER_MULTIPART_REQUEST_PACK_STR, self.buf, ofproto.OFP_MULTIPART_REQUEST_SIZE, self.meter_id) @OFPMultipartReply.register_stats_type() @_set_stats_type(ofproto.OFPMP_METER, OFPMeterStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPMeterStatsReply(OFPMultipartReply): """ Meter statistics reply message The switch responds with this message to a meter statistics request. ================ ====================================================== Attribute Description ================ ====================================================== body List of ``OFPMeterStats`` instance ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPMeterStatsReply, MAIN_DISPATCHER) def meter_stats_reply_handler(self, ev): meters = [] for stat in ev.msg.body: meters.append('meter_id=0x%08x len=%d flow_count=%d ' 'packet_in_count=%d byte_in_count=%d ' 'duration_sec=%d duration_nsec=%d ' 'band_stats=%s' % (stat.meter_id, stat.len, stat.flow_count, stat.packet_in_count, stat.byte_in_count, stat.duration_sec, stat.duration_nsec, stat.band_stats)) self.logger.debug('MeterStats: %s', meters) """ def __init__(self, datapath, type_=None, **kwargs): super(OFPMeterStatsReply, self).__init__(datapath, **kwargs) class OFPMeterBand(StringifyMixin): def __init__(self, type_, len_): super(OFPMeterBand, self).__init__() self.type = type_ self.len = len_ class OFPMeterBandHeader(OFPMeterBand): _METER_BAND = {} @staticmethod def register_meter_band_type(type_, len_): def _register_meter_band_type(cls): OFPMeterBandHeader._METER_BAND[type_] = cls cls.cls_meter_band_type = type_ cls.cls_meter_band_len = len_ return cls return _register_meter_band_type def __init__(self): cls = self.__class__ super(OFPMeterBandHeader, self).__init__(cls.cls_meter_band_type, cls.cls_meter_band_len) @classmethod def parser(cls, buf, offset): type_, len_, _rate, _burst_size = struct.unpack_from( ofproto.OFP_METER_BAND_HEADER_PACK_STR, buf, offset) cls_ = cls._METER_BAND[type_] assert cls_.cls_meter_band_len == len_ return cls_.parser(buf, offset) @OFPMeterBandHeader.register_meter_band_type( ofproto.OFPMBT_DROP, ofproto.OFP_METER_BAND_DROP_SIZE) class OFPMeterBandDrop(OFPMeterBandHeader): def __init__(self, rate=0, burst_size=0, type_=None, len_=None): super(OFPMeterBandDrop, self).__init__() self.rate = rate self.burst_size = burst_size def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_METER_BAND_DROP_PACK_STR, buf, offset, self.type, self.len, self.rate, self.burst_size) @classmethod def parser(cls, buf, offset): type_, len_, rate, burst_size = struct.unpack_from( ofproto.OFP_METER_BAND_DROP_PACK_STR, buf, offset) assert cls.cls_meter_band_type == type_ assert cls.cls_meter_band_len == len_ return cls(rate, burst_size) @OFPMeterBandHeader.register_meter_band_type( ofproto.OFPMBT_DSCP_REMARK, ofproto.OFP_METER_BAND_DSCP_REMARK_SIZE) class OFPMeterBandDscpRemark(OFPMeterBandHeader): def __init__(self, rate=0, burst_size=0, prec_level=0, type_=None, len_=None): super(OFPMeterBandDscpRemark, self).__init__() self.rate = rate self.burst_size = burst_size self.prec_level = prec_level def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_METER_BAND_DSCP_REMARK_PACK_STR, buf, offset, self.type, self.len, self.rate, self.burst_size, self.prec_level) @classmethod def parser(cls, buf, offset): type_, len_, rate, burst_size, prec_level = struct.unpack_from( ofproto.OFP_METER_BAND_DSCP_REMARK_PACK_STR, buf, offset) assert cls.cls_meter_band_type == type_ assert cls.cls_meter_band_len == len_ return cls(rate, burst_size, prec_level) @OFPMeterBandHeader.register_meter_band_type( ofproto.OFPMBT_EXPERIMENTER, ofproto.OFP_METER_BAND_EXPERIMENTER_SIZE) class OFPMeterBandExperimenter(OFPMeterBandHeader): def __init__(self, rate=0, burst_size=0, experimenter=None, type_=None, len_=None): super(OFPMeterBandExperimenter, self).__init__() self.rate = rate self.burst_size = burst_size self.experimenter = experimenter def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_METER_BAND_EXPERIMENTER_PACK_STR, buf, offset, self.type, self.len, self.rate, self.burst_size, self.experimenter) @classmethod def parser(cls, buf, offset): type_, len_, rate, burst_size, experimenter = struct.unpack_from( ofproto.OFP_METER_BAND_EXPERIMENTER_PACK_STR, buf, offset) assert cls.cls_meter_band_type == type_ assert cls.cls_meter_band_len == len_ return cls(rate, burst_size, experimenter) class OFPMeterConfigStats(StringifyMixin): def __init__(self, flags=None, meter_id=None, bands=None, length=None): super(OFPMeterConfigStats, self).__init__() self.length = None self.flags = flags self.meter_id = meter_id self.bands = bands @classmethod def parser(cls, buf, offset): meter_config = cls() (meter_config.length, meter_config.flags, meter_config.meter_id) = struct.unpack_from( ofproto.OFP_METER_CONFIG_PACK_STR, buf, offset) offset += ofproto.OFP_METER_CONFIG_SIZE meter_config.bands = [] length = ofproto.OFP_METER_CONFIG_SIZE while length < meter_config.length: band = OFPMeterBandHeader.parser(buf, offset) meter_config.bands.append(band) offset += band.len length += band.len return meter_config @_set_stats_type(ofproto.OFPMP_METER_CONFIG, OFPMeterConfigStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPMeterConfigStatsRequest(OFPMultipartRequest): """ Meter configuration statistics request message The controller uses this message to query configuration for one or more meters. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or ``OFPMPF_REQ_MORE`` meter_id ID of meter to read (OFPM_ALL to all meters) ================ ====================================================== Example:: def send_meter_config_stats_request(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPMeterConfigStatsRequest(datapath, 0, ofp.OFPM_ALL) datapath.send_msg(req) """ def __init__(self, datapath, flags=0, meter_id=ofproto.OFPM_ALL, type_=None): super(OFPMeterConfigStatsRequest, self).__init__(datapath, flags) self.meter_id = meter_id def _serialize_stats_body(self): msg_pack_into(ofproto.OFP_METER_MULTIPART_REQUEST_PACK_STR, self.buf, ofproto.OFP_MULTIPART_REQUEST_SIZE, self.meter_id) @OFPMultipartReply.register_stats_type() @_set_stats_type(ofproto.OFPMP_METER_CONFIG, OFPMeterConfigStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPMeterConfigStatsReply(OFPMultipartReply): """ Meter configuration statistics reply message The switch responds with this message to a meter configuration statistics request. ================ ====================================================== Attribute Description ================ ====================================================== body List of ``OFPMeterConfigStats`` instance ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPMeterConfigStatsReply, MAIN_DISPATCHER) def meter_config_stats_reply_handler(self, ev): configs = [] for stat in ev.msg.body: configs.append('length=%d flags=0x%04x meter_id=0x%08x ' 'bands=%s' % (stat.length, stat.flags, stat.meter_id, stat.bands)) self.logger.debug('MeterConfigStats: %s', configs) """ def __init__(self, datapath, type_=None, **kwargs): super(OFPMeterConfigStatsReply, self).__init__(datapath, **kwargs) class OFPMeterFeaturesStats(ofproto_parser.namedtuple('OFPMeterFeaturesStats', ('max_meter', 'band_types', 'capabilities', 'max_bands', 'max_color'))): @classmethod def parser(cls, buf, offset): meter_features = struct.unpack_from( ofproto.OFP_METER_FEATURES_PACK_STR, buf, offset) stats = cls(*meter_features) stats.length = ofproto.OFP_METER_FEATURES_SIZE return stats @_set_stats_type(ofproto.OFPMP_METER_FEATURES, OFPMeterFeaturesStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPMeterFeaturesStatsRequest(OFPMultipartRequest): """ Meter features statistics request message The controller uses this message to query the set of features of the metering subsystem. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or ``OFPMPF_REQ_MORE`` ================ ====================================================== Example:: def send_meter_features_stats_request(self, datapath): ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPMeterFeaturesStatsRequest(datapath, 0) datapath.send_msg(req) """ def __init__(self, datapath, flags=0, type_=None): super(OFPMeterFeaturesStatsRequest, self).__init__(datapath, flags) @OFPMultipartReply.register_stats_type() @_set_stats_type(ofproto.OFPMP_METER_FEATURES, OFPMeterFeaturesStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPMeterFeaturesStatsReply(OFPMultipartReply): """ Meter features statistics reply message The switch responds with this message to a meter features statistics request. ================ ====================================================== Attribute Description ================ ====================================================== body List of ``OFPMeterFeaturesStats`` instance ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPMeterFeaturesStatsReply, MAIN_DISPATCHER) def meter_features_stats_reply_handler(self, ev): features = [] for stat in ev.msg.body: features.append('max_meter=%d band_types=0x%08x ' 'capabilities=0x%08x max_bands=%d ' 'max_color=%d' % (stat.max_meter, stat.band_types, stat.capabilities, stat.max_bands, stat.max_color)) self.logger.debug('MeterFeaturesStats: %s', features) """ def __init__(self, datapath, type_=None, **kwargs): super(OFPMeterFeaturesStatsReply, self).__init__(datapath, **kwargs) class OFPTableFeaturesStats(StringifyMixin): _TYPE = { 'utf-8': [ # OF spec is unclear about the encoding of name. # we assumes UTF-8. 'name', ] } def __init__(self, table_id=None, name=None, metadata_match=None, metadata_write=None, config=None, max_entries=None, properties=None, length=None): super(OFPTableFeaturesStats, self).__init__() self.length = None self.table_id = table_id self.name = name self.metadata_match = metadata_match self.metadata_write = metadata_write self.config = config self.max_entries = max_entries self.properties = properties @classmethod def parser(cls, buf, offset): table_features = cls() (table_features.length, table_features.table_id, name, table_features.metadata_match, table_features.metadata_write, table_features.config, table_features.max_entries ) = struct.unpack_from(ofproto.OFP_TABLE_FEATURES_PACK_STR, buf, offset) table_features.name = name.rstrip(b'\0') props = [] rest = buf[offset + ofproto.OFP_TABLE_FEATURES_SIZE: offset + table_features.length] while rest: p, rest = OFPTableFeatureProp.parse(rest) props.append(p) table_features.properties = props return table_features def serialize(self): # fixup bin_props = bytearray() for p in self.properties: bin_props += p.serialize() self.length = ofproto.OFP_TABLE_FEATURES_SIZE + len(bin_props) buf = bytearray() msg_pack_into(ofproto.OFP_TABLE_FEATURES_PACK_STR, buf, 0, self.length, self.table_id, self.name, self.metadata_match, self.metadata_write, self.config, self.max_entries) return buf + bin_props class OFPTableFeatureProp(OFPPropBase): _TYPES = {} class OFPTableFeaturePropUnknown(OFPTableFeatureProp): def __init__(self, type_, length=None, data=None): super(OFPTableFeaturePropUnknown, self).__init__(type_, length) self.data = data @classmethod def _parse_prop(cls, buf): return {'data': buf} def _serialize_prop(self): return self.data # Implementation note: While OpenFlow 1.3.2 shares the same ofp_instruction # for flow_mod and table_features, we have separate classes. We named this # class to match with OpenFlow 1.4's name. (ofp_instruction_id) class OFPInstructionId(StringifyMixin): _PACK_STR = '!HH' # type, len def __init__(self, type_, len_=None): self.type = type_ self.len = len_ # XXX experimenter @classmethod def parse(cls, buf): (type_, len_,) = struct.unpack_from(cls._PACK_STR, bytes(buf), 0) rest = buf[len_:] return cls(type_=type_, len_=len_), rest def serialize(self): # fixup self.len = struct.calcsize(self._PACK_STR) buf = bytearray() msg_pack_into(self._PACK_STR, buf, 0, self.type, self.len) return buf @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_INSTRUCTIONS) @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_INSTRUCTIONS_MISS) class OFPTableFeaturePropInstructions(OFPTableFeatureProp): def __init__(self, type_=None, length=None, instruction_ids=None): instruction_ids = instruction_ids if instruction_ids else [] super(OFPTableFeaturePropInstructions, self).__init__(type_, length) self.instruction_ids = instruction_ids @classmethod def parser(cls, buf): rest = cls.get_rest(buf) ids = [] while rest: i, rest = OFPInstructionId.parse(rest) ids.append(i) return cls(instruction_ids=ids) def serialize_body(self): bin_ids = bytearray() for i in self.instruction_ids: bin_ids += i.serialize() return bin_ids @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_NEXT_TABLES) @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_NEXT_TABLES_MISS) class OFPTableFeaturePropNextTables(OFPTableFeatureProp): _TABLE_ID_PACK_STR = '!B' def __init__(self, type_=None, length=None, table_ids=None): table_ids = table_ids if table_ids else [] super(OFPTableFeaturePropNextTables, self).__init__(type_, length) self.table_ids = table_ids @classmethod def parser(cls, buf): rest = cls.get_rest(buf) ids = [] while rest: (i,) = struct.unpack_from(cls._TABLE_ID_PACK_STR, bytes(rest), 0) rest = rest[struct.calcsize(cls._TABLE_ID_PACK_STR):] ids.append(i) return cls(table_ids=ids) def serialize_body(self): bin_ids = bytearray() for i in self.table_ids: bin_id = bytearray() msg_pack_into(self._TABLE_ID_PACK_STR, bin_id, 0, i) bin_ids += bin_id return bin_ids # Implementation note: While OpenFlow 1.3.2 shares the same ofp_action_header # for flow_mod and table_features, we have separate classes. We named this # class to match with OpenFlow 1.4's name. (ofp_action_id) class OFPActionId(StringifyMixin): # XXX # ofp_action_header should have trailing pad bytes. # however, i guess it's a specification bug as: # - the spec explicitly says non-experimenter actions are 4 bytes # - linc/of_protocol doesn't use them # - OpenFlow 1.4 changed to use a separate structure _PACK_STR = '!HH' # type, len def __init__(self, type_, len_=None): self.type = type_ self.len = len_ # XXX experimenter @classmethod def parse(cls, buf): (type_, len_,) = struct.unpack_from(cls._PACK_STR, bytes(buf), 0) rest = buf[len_:] return cls(type_=type_, len_=len_), rest def serialize(self): # fixup self.len = struct.calcsize(self._PACK_STR) buf = bytearray() msg_pack_into(self._PACK_STR, buf, 0, self.type, self.len) return buf @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_WRITE_ACTIONS) @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_WRITE_ACTIONS_MISS) @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_APPLY_ACTIONS) @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_APPLY_ACTIONS_MISS) class OFPTableFeaturePropActions(OFPTableFeatureProp): def __init__(self, type_=None, length=None, action_ids=None): action_ids = action_ids if action_ids else [] super(OFPTableFeaturePropActions, self).__init__(type_, length) self.action_ids = action_ids @classmethod def parser(cls, buf): rest = cls.get_rest(buf) ids = [] while rest: i, rest = OFPActionId.parse(rest) ids.append(i) return cls(action_ids=ids) def serialize_body(self): bin_ids = bytearray() for i in self.action_ids: bin_ids += i.serialize() return bin_ids # Implementation note: OFPOxmId is specific to this implementation. # It does not have a corresponding structure in the specification. # (the specification uses plain uint32_t for non-experimenter OXMs # and uint64_t for experimenter OXMs.) # # i have taken a look at some of software switch implementations # but they all look broken or incomplete. according to the spec, # oxm_hasmask should be 1 if a switch supports masking for the type. # the right value for oxm_length is not clear from the spec. # update: OpenFlow 1.3.3 "clarified" that oxm_length here is the payload # length. it's still unclear if it should be doubled for hasmask or not, # though. # ofsoftswitch13 # oxm_hasmask always 0 # oxm_length same as ofp_match etc (as without mask) # linc/of_protocol # oxm_hasmask always 0 # oxm_length always 0 # ovs: # seems in flux as of writing this [20141003] class OFPOxmId(StringifyMixin): _PACK_STR = '!I' # oxm header _EXPERIMENTER_ID_PACK_STR = '!I' _TYPE = { 'ascii': [ 'type', ], } def __init__(self, type_, hasmask=False, length=None): self.type = type_ self.hasmask = hasmask self.length = length @classmethod def parse(cls, buf): (oxm,) = struct.unpack_from(cls._PACK_STR, bytes(buf), 0) # oxm (32 bit) == class (16) | field (7) | hasmask (1) | length (8) # in case of experimenter OXMs, another 32 bit value # (experimenter id) follows. (type_, _v) = ofproto.oxm_to_user(oxm >> (1 + 8), None, None) rest = buf[struct.calcsize(cls._PACK_STR):] hasmask = ofproto.oxm_tlv_header_extract_hasmask(oxm) length = oxm & 0xff # XXX see the comment on OFPOxmId class_ = oxm >> (7 + 1 + 8) if class_ == ofproto.OFPXMC_EXPERIMENTER: (exp_id,) = struct.unpack_from(cls._EXPERIMENTER_ID_PACK_STR, bytes(rest), 0) rest = rest[struct.calcsize(cls._EXPERIMENTER_ID_PACK_STR):] subcls = OFPExperimenterOxmId return subcls(type_=type_, exp_id=exp_id, hasmask=hasmask, length=length), rest else: return cls(type_=type_, hasmask=hasmask, length=length), rest def serialize(self): # fixup self.length = 0 # XXX see the comment on OFPOxmId (n, _v, _m) = ofproto.oxm_from_user(self.type, None) oxm = (n << (1 + 8)) | (self.hasmask << 8) | self.length buf = bytearray() msg_pack_into(self._PACK_STR, buf, 0, oxm) assert n >> 7 != ofproto.OFPXMC_EXPERIMENTER return buf class OFPExperimenterOxmId(OFPOxmId): def __init__(self, type_, exp_id, hasmask=False, length=None): super(OFPExperimenterOxmId, self).__init__(type_=type_, hasmask=hasmask, length=length) self.exp_id = exp_id def serialize(self): buf = super(OFPExperimenterOxmId, self).serialize() msg_pack_into(self._EXPERIMENTER_ID_PACK_STR, buf, struct.calcsize(self._PACK_STR), self.exp_id) @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_MATCH) @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_WILDCARDS) @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_WRITE_SETFIELD) @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_WRITE_SETFIELD_MISS) @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_APPLY_SETFIELD) @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_APPLY_SETFIELD_MISS) class OFPTableFeaturePropOxm(OFPTableFeatureProp): def __init__(self, type_=None, length=None, oxm_ids=None): oxm_ids = oxm_ids if oxm_ids else [] super(OFPTableFeaturePropOxm, self).__init__(type_, length) self.oxm_ids = oxm_ids @classmethod def parser(cls, buf): rest = cls.get_rest(buf) ids = [] while rest: i, rest = OFPOxmId.parse(rest) ids.append(i) return cls(oxm_ids=ids) def serialize_body(self): bin_ids = bytearray() for i in self.oxm_ids: bin_ids += i.serialize() return bin_ids @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_EXPERIMENTER) @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_EXPERIMENTER_MISS) class OFPTableFeaturePropExperimenter(OFPPropCommonExperimenter4ByteData): pass @_set_stats_type(ofproto.OFPMP_TABLE_FEATURES, OFPTableFeaturesStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPTableFeaturesStatsRequest(OFPMultipartRequest): """ Table features statistics request message The controller uses this message to query table features. ================ ====================================================== Attribute Description ================ ====================================================== body List of ``OFPTableFeaturesStats`` instances. The default is []. ================ ====================================================== """ def __init__(self, datapath, flags=0, body=None, type_=None): body = body if body else [] super(OFPTableFeaturesStatsRequest, self).__init__(datapath, flags) self.body = body def _serialize_stats_body(self): bin_body = bytearray() for p in self.body: bin_body += p.serialize() self.buf += bin_body @OFPMultipartReply.register_stats_type() @_set_stats_type(ofproto.OFPMP_TABLE_FEATURES, OFPTableFeaturesStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPTableFeaturesStatsReply(OFPMultipartReply): """ Table features statistics reply message The switch responds with this message to a table features statistics request. ================ ====================================================== Attribute Description ================ ====================================================== body List of ``OFPTableFeaturesStats`` instance ================ ====================================================== """ def __init__(self, datapath, type_=None, **kwargs): super(OFPTableFeaturesStatsReply, self).__init__(datapath, **kwargs) @_set_stats_type(ofproto.OFPMP_PORT_DESC, OFPPort) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPPortDescStatsRequest(OFPMultipartRequest): """ Port description request message The controller uses this message to query description of all the ports. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or ``OFPMPF_REQ_MORE`` ================ ====================================================== Example:: def send_port_desc_stats_request(self, datapath): ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPPortDescStatsRequest(datapath, 0) datapath.send_msg(req) """ def __init__(self, datapath, flags=0, type_=None): super(OFPPortDescStatsRequest, self).__init__(datapath, flags) @OFPMultipartReply.register_stats_type() @_set_stats_type(ofproto.OFPMP_PORT_DESC, OFPPort) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPPortDescStatsReply(OFPMultipartReply): """ Port description reply message The switch responds with this message to a port description request. ================ ====================================================== Attribute Description ================ ====================================================== body List of ``OFPPort`` instance ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPPortDescStatsReply, MAIN_DISPATCHER) def port_desc_stats_reply_handler(self, ev): ports = [] for p in ev.msg.body: ports.append('port_no=%d hw_addr=%s name=%s config=0x%08x ' 'state=0x%08x curr=0x%08x advertised=0x%08x ' 'supported=0x%08x peer=0x%08x curr_speed=%d ' 'max_speed=%d' % (p.port_no, p.hw_addr, p.name, p.config, p.state, p.curr, p.advertised, p.supported, p.peer, p.curr_speed, p.max_speed)) self.logger.debug('OFPPortDescStatsReply received: %s', ports) """ def __init__(self, datapath, type_=None, **kwargs): super(OFPPortDescStatsReply, self).__init__(datapath, **kwargs) class OFPExperimenterMultipart(ofproto_parser.namedtuple( 'OFPExperimenterMultipart', ('experimenter', 'exp_type', 'data'))): """ The body of OFPExperimenterStatsReply multipart messages. ================ ====================================================== Attribute Description ================ ====================================================== experimenter Experimenter ID exp_type Experimenter defined data Experimenter defined additional data ================ ====================================================== """ @classmethod def parser(cls, buf, offset): args = struct.unpack_from( ofproto.OFP_EXPERIMENTER_MULTIPART_HEADER_PACK_STR, buf, offset) args = list(args) args.append(buf[offset + ofproto.OFP_EXPERIMENTER_MULTIPART_HEADER_SIZE:]) stats = cls(*args) stats.length = ofproto.OFP_METER_FEATURES_SIZE return stats def serialize(self): buf = bytearray() msg_pack_into(ofproto.OFP_EXPERIMENTER_MULTIPART_HEADER_PACK_STR, buf, 0, self.experimenter, self.exp_type) return buf + self.data class OFPExperimenterStatsRequestBase(OFPMultipartRequest): def __init__(self, datapath, flags, experimenter, exp_type, type_=None): super(OFPExperimenterStatsRequestBase, self).__init__(datapath, flags) self.experimenter = experimenter self.exp_type = exp_type @_set_stats_type(ofproto.OFPMP_EXPERIMENTER, OFPExperimenterMultipart) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPExperimenterStatsRequest(OFPExperimenterStatsRequestBase): """ Experimenter multipart request message ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or ``OFPMPF_REQ_MORE`` experimenter Experimenter ID exp_type Experimenter defined data Experimenter defined additional data ================ ====================================================== """ def __init__(self, datapath, flags, experimenter, exp_type, data, type_=None): super(OFPExperimenterStatsRequest, self).__init__(datapath, flags, experimenter, exp_type, type_) self.data = data def _serialize_stats_body(self): body = OFPExperimenterMultipart(experimenter=self.experimenter, exp_type=self.exp_type, data=self.data) self.buf += body.serialize() # NOTE: we use OFPMatch while on-wire does not ofp_match. # (OF1.4 version uses ofp_match.) class ONFFlowMonitorRequest(StringifyMixin): def __init__(self, id_, flags, match=OFPMatch(), out_port=ofproto.OFPP_ANY, table_id=ofproto.OFPTT_ALL, match_len=None): self.id = id_ self.flags = flags self.match_len = match_len self.out_port = out_port self.table_id = table_id self.match = match def serialize(self): # fixup match = self.match bin_match = bytearray() ofp_match_len = match.serialize(bin_match, 0) assert len(bin_match) == ofp_match_len match_len = match.length match_hdr_len = ofproto.OFP_MATCH_SIZE - 4 # exclude pad[4] # strip ofp_match header and trailing padding bin_match = bytearray(bin_match)[match_hdr_len:match_len] self.match_len = len(bin_match) buf = bytearray() msg_pack_into(ofproto.ONF_FLOW_MONITOR_REQUEST_PACK_STR, buf, 0, self.id, self.flags, self.match_len, self.out_port, self.table_id) buf += bin_match pad_len = utils.round_up(self.match_len, 8) - self.match_len buf += pad_len * b'\0' return buf @_set_stats_type(ofproto.OFPMP_EXPERIMENTER, OFPExperimenterMultipart) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class ONFFlowMonitorStatsRequest(OFPExperimenterStatsRequestBase): """ ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or ``OFPMPF_REQ_MORE`` body List of ONFFlowMonitorRequest instances ================ ====================================================== """ def __init__(self, datapath, flags, body=None, type_=None, experimenter=None, exp_type=None): body = body if body else [] super(ONFFlowMonitorStatsRequest, self).__init__(datapath, flags, experimenter=ofproto_common.ONF_EXPERIMENTER_ID, exp_type=ofproto.ONFMP_FLOW_MONITOR) self.body = body def _serialize_stats_body(self): data = bytearray() for i in self.body: data += i.serialize() body = OFPExperimenterMultipart(experimenter=self.experimenter, exp_type=self.exp_type, data=data) self.buf += body.serialize() @OFPMultipartReply.register_stats_type(body_single_struct=True) @_set_stats_type(ofproto.OFPMP_EXPERIMENTER, OFPExperimenterMultipart) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPExperimenterStatsReply(OFPMultipartReply): """ Experimenter multipart reply message ================ ====================================================== Attribute Description ================ ====================================================== body An ``OFPExperimenterMultipart`` instance ================ ====================================================== """ def __init__(self, datapath, type_=None, **kwargs): super(OFPExperimenterStatsReply, self).__init__(datapath, **kwargs) @_set_msg_type(ofproto.OFPT_BARRIER_REQUEST) class OFPBarrierRequest(MsgBase): """ Barrier request message The controller sends this message to ensure message dependencies have been met or receive notifications for completed operations. Example:: def send_barrier_request(self, datapath): ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPBarrierRequest(datapath) datapath.send_msg(req) """ def __init__(self, datapath): super(OFPBarrierRequest, self).__init__(datapath) @_register_parser @_set_msg_type(ofproto.OFPT_BARRIER_REPLY) class OFPBarrierReply(MsgBase): """ Barrier reply message The switch responds with this message to a barrier request. Example:: @set_ev_cls(ofp_event.EventOFPBarrierReply, MAIN_DISPATCHER) def barrier_reply_handler(self, ev): self.logger.debug('OFPBarrierReply received') """ def __init__(self, datapath): super(OFPBarrierReply, self).__init__(datapath) @_set_msg_type(ofproto.OFPT_QUEUE_GET_CONFIG_REQUEST) class OFPQueueGetConfigRequest(MsgBase): """ Queue configuration request message ================ ====================================================== Attribute Description ================ ====================================================== port Port to be queried (OFPP_ANY to all configured queues) ================ ====================================================== Example:: def send_queue_get_config_request(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPQueueGetConfigRequest(datapath, ofp.OFPP_ANY) datapath.send_msg(req) """ def __init__(self, datapath, port): super(OFPQueueGetConfigRequest, self).__init__(datapath) self.port = port def _serialize_body(self): msg_pack_into(ofproto.OFP_QUEUE_GET_CONFIG_REQUEST_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.port) class OFPQueuePropHeader(StringifyMixin): def __init__(self, property_, len_): self.property = property_ self.len = len_ def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_QUEUE_PROP_HEADER_PACK_STR, buf, offset, self.property, self.len) class OFPQueueProp(OFPQueuePropHeader): _QUEUE_PROP_PROPERTIES = {} @staticmethod def register_property(property_, len_=None): def _register_property(cls): cls.cls_property = property_ cls.cls_len = len_ OFPQueueProp._QUEUE_PROP_PROPERTIES[property_] = cls return cls return _register_property def __init__(self): cls = self.__class__ super(OFPQueueProp, self).__init__(cls.cls_property, cls.cls_len) @classmethod def parser(cls, buf, offset): (property_, len_) = struct.unpack_from( ofproto.OFP_QUEUE_PROP_HEADER_PACK_STR, buf, offset) cls_ = cls._QUEUE_PROP_PROPERTIES.get(property_) if cls_ is not None: p = cls_.parser(buf, offset + ofproto.OFP_QUEUE_PROP_HEADER_SIZE) p.property = property_ p.len = len_ if property_ == ofproto.OFPQT_EXPERIMENTER: rest = buf[offset + ofproto.OFP_QUEUE_PROP_EXPERIMENTER_SIZE: offset + len_] p.parse_experimenter_data(rest) return p return None @OFPQueueProp.register_property(ofproto.OFPQT_MIN_RATE, ofproto.OFP_QUEUE_PROP_MIN_RATE_SIZE) class OFPQueuePropMinRate(OFPQueueProp): def __init__(self, rate, property_=None, len_=None): super(OFPQueuePropMinRate, self).__init__() self.rate = rate @classmethod def parser(cls, buf, offset): (rate,) = struct.unpack_from( ofproto.OFP_QUEUE_PROP_MIN_RATE_PACK_STR, buf, offset) return cls(rate) @OFPQueueProp.register_property(ofproto.OFPQT_MAX_RATE, ofproto.OFP_QUEUE_PROP_MAX_RATE_SIZE) class OFPQueuePropMaxRate(OFPQueueProp): def __init__(self, rate, property_=None, len_=None): super(OFPQueuePropMaxRate, self).__init__() self.rate = rate @classmethod def parser(cls, buf, offset): (rate,) = struct.unpack_from( ofproto.OFP_QUEUE_PROP_MAX_RATE_PACK_STR, buf, offset) return cls(rate) @OFPQueueProp.register_property(ofproto.OFPQT_EXPERIMENTER) class OFPQueuePropExperimenter(OFPQueueProp): _EXPERIMENTER_DATA_PACK_STR = '!B' _EXPERIMENTER_DATA_SIZE = 1 def __init__(self, experimenter, data=None, property_=None, len_=None): super(OFPQueuePropExperimenter, self).__init__() self.experimenter = experimenter self.data = data @classmethod def parser(cls, buf, offset): (experimenter,) = struct.unpack_from( ofproto.OFP_QUEUE_PROP_EXPERIMENTER_PACK_STR, buf, offset) return cls(experimenter) def parse_experimenter_data(self, rest): data = [] while rest: (d,) = struct.unpack_from( self._EXPERIMENTER_DATA_PACK_STR, rest, 0) data.append(d) rest = rest[self._EXPERIMENTER_DATA_SIZE:] self.data = data class OFPPacketQueue(StringifyMixin): def __init__(self, queue_id, port, properties, len_=None): super(OFPPacketQueue, self).__init__() self.queue_id = queue_id self.port = port self.len = len_ self.properties = properties @classmethod def parser(cls, buf, offset): (queue_id, port, len_) = struct.unpack_from( ofproto.OFP_PACKET_QUEUE_PACK_STR, buf, offset) length = ofproto.OFP_PACKET_QUEUE_SIZE offset += ofproto.OFP_PACKET_QUEUE_SIZE properties = [] while length < len_: queue_prop = OFPQueueProp.parser(buf, offset) if queue_prop is not None: properties.append(queue_prop) offset += queue_prop.len length += queue_prop.len o = cls(queue_id, port, properties) o.len = len_ return o @_register_parser @_set_msg_type(ofproto.OFPT_QUEUE_GET_CONFIG_REPLY) class OFPQueueGetConfigReply(MsgBase): """ Queue configuration reply message The switch responds with this message to a queue configuration request. ================ ====================================================== Attribute Description ================ ====================================================== queues list of ``OFPPacketQueue`` instance port Port which was queried ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPQueueGetConfigReply, MAIN_DISPATCHER) def queue_get_config_reply_handler(self, ev): msg = ev.msg self.logger.debug('OFPQueueGetConfigReply received: ' 'port=%s queues=%s', msg.port, msg.queues) """ def __init__(self, datapath, queues=None, port=None): super(OFPQueueGetConfigReply, self).__init__(datapath) self.queues = queues self.port = port @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPQueueGetConfigReply, cls).parser(datapath, version, msg_type, msg_len, xid, buf) (msg.port,) = struct.unpack_from( ofproto.OFP_QUEUE_GET_CONFIG_REPLY_PACK_STR, msg.buf, ofproto.OFP_HEADER_SIZE) msg.queues = [] offset = ofproto.OFP_QUEUE_GET_CONFIG_REPLY_SIZE while offset < msg_len: queue = OFPPacketQueue.parser(msg.buf, offset) msg.queues.append(queue) offset += queue.len return msg @_set_msg_type(ofproto.OFPT_ROLE_REQUEST) class OFPRoleRequest(MsgBase): """ Role request message The controller uses this message to change its role. ================ ====================================================== Attribute Description ================ ====================================================== role One of the following values. | OFPCR_ROLE_NOCHANGE | OFPCR_ROLE_EQUAL | OFPCR_ROLE_MASTER | OFPCR_ROLE_SLAVE generation_id Master Election Generation ID ================ ====================================================== Example:: def send_role_request(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPRoleRequest(datapath, ofp.OFPCR_ROLE_EQUAL, 0) datapath.send_msg(req) """ def __init__(self, datapath, role=None, generation_id=None): super(OFPRoleRequest, self).__init__(datapath) self.role = role self.generation_id = generation_id def _serialize_body(self): assert self.role is not None assert self.generation_id is not None msg_pack_into(ofproto.OFP_ROLE_REQUEST_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.role, self.generation_id) @_register_parser @_set_msg_type(ofproto.OFPT_ROLE_REPLY) class OFPRoleReply(MsgBase): """ Role reply message The switch responds with this message to a role request. ================ ====================================================== Attribute Description ================ ====================================================== role One of the following values. | OFPCR_ROLE_NOCHANGE | OFPCR_ROLE_EQUAL | OFPCR_ROLE_MASTER | OFPCR_ROLE_SLAVE generation_id Master Election Generation ID ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPRoleReply, MAIN_DISPATCHER) def role_reply_handler(self, ev): msg = ev.msg dp = msg.datapath ofp = dp.ofproto if msg.role == ofp.OFPCR_ROLE_NOCHANGE: role = 'NOCHANGE' elif msg.role == ofp.OFPCR_ROLE_EQUAL: role = 'EQUAL' elif msg.role == ofp.OFPCR_ROLE_MASTER: role = 'MASTER' elif msg.role == ofp.OFPCR_ROLE_SLAVE: role = 'SLAVE' else: role = 'unknown' self.logger.debug('OFPRoleReply received: ' 'role=%s generation_id=%d', role, msg.generation_id) """ def __init__(self, datapath, role=None, generation_id=None): super(OFPRoleReply, self).__init__(datapath) self.role = role self.generation_id = generation_id @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPRoleReply, cls).parser(datapath, version, msg_type, msg_len, xid, buf) (msg.role, msg.generation_id) = struct.unpack_from( ofproto.OFP_ROLE_REQUEST_PACK_STR, msg.buf, ofproto.OFP_HEADER_SIZE) return msg @_set_msg_type(ofproto.OFPT_GET_ASYNC_REQUEST) class OFPGetAsyncRequest(MsgBase): """ Get asynchronous configuration request message The controller uses this message to query the asynchronous message. Example:: def send_get_async_request(self, datapath): ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPGetAsyncRequest(datapath) datapath.send_msg(req) """ def __init__(self, datapath): super(OFPGetAsyncRequest, self).__init__(datapath) @_register_parser @_set_msg_type(ofproto.OFPT_GET_ASYNC_REPLY) class OFPGetAsyncReply(MsgBase): """ Get asynchronous configuration reply message The switch responds with this message to a get asynchronous configuration request. ================== ==================================================== Attribute Description ================== ==================================================== packet_in_mask 2-element array: element 0, when the controller has a OFPCR_ROLE_EQUAL or OFPCR_ROLE_MASTER role. element 1, OFPCR_ROLE_SLAVE role controller. Bitmasks of following values. | OFPR_NO_MATCH | OFPR_ACTION | OFPR_INVALID_TTL port_status_mask 2-element array. Bitmasks of following values. | OFPPR_ADD | OFPPR_DELETE | OFPPR_MODIFY flow_removed_mask 2-element array. Bitmasks of following values. | OFPRR_IDLE_TIMEOUT | OFPRR_HARD_TIMEOUT | OFPRR_DELETE | OFPRR_GROUP_DELETE ================== ==================================================== Example:: @set_ev_cls(ofp_event.EventOFPGetAsyncReply, MAIN_DISPATCHER) def get_async_reply_handler(self, ev): msg = ev.msg self.logger.debug('OFPGetAsyncReply received: ' 'packet_in_mask=0x%08x:0x%08x ' 'port_status_mask=0x%08x:0x%08x ' 'flow_removed_mask=0x%08x:0x%08x', msg.packet_in_mask[0], msg.packet_in_mask[1], msg.port_status_mask[0], msg.port_status_mask[1], msg.flow_removed_mask[0], msg.flow_removed_mask[1]) """ def __init__(self, datapath, packet_in_mask=None, port_status_mask=None, flow_removed_mask=None): super(OFPGetAsyncReply, self).__init__(datapath) self.packet_in_mask = packet_in_mask self.port_status_mask = port_status_mask self.flow_removed_mask = flow_removed_mask @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPGetAsyncReply, cls).parser(datapath, version, msg_type, msg_len, xid, buf) (packet_in_mask_m, packet_in_mask_s, port_status_mask_m, port_status_mask_s, flow_removed_mask_m, flow_removed_mask_s) = struct.unpack_from( ofproto.OFP_ASYNC_CONFIG_PACK_STR, msg.buf, ofproto.OFP_HEADER_SIZE) msg.packet_in_mask = [packet_in_mask_m, packet_in_mask_s] msg.port_status_mask = [port_status_mask_m, port_status_mask_s] msg.flow_removed_mask = [flow_removed_mask_m, flow_removed_mask_s] return msg @_set_msg_type(ofproto.OFPT_SET_ASYNC) class OFPSetAsync(MsgBase): """ Set asynchronous configuration message The controller sends this message to set the asynchronous messages that it wants to receive on a given OpneFlow channel. ================== ==================================================== Attribute Description ================== ==================================================== packet_in_mask 2-element array: element 0, when the controller has a OFPCR_ROLE_EQUAL or OFPCR_ROLE_MASTER role. element 1, OFPCR_ROLE_SLAVE role controller. Bitmasks of following values. | OFPR_NO_MATCH | OFPR_ACTION | OFPR_INVALID_TTL port_status_mask 2-element array. Bitmasks of following values. | OFPPR_ADD | OFPPR_DELETE | OFPPR_MODIFY flow_removed_mask 2-element array. Bitmasks of following values. | OFPRR_IDLE_TIMEOUT | OFPRR_HARD_TIMEOUT | OFPRR_DELETE | OFPRR_GROUP_DELETE ================== ==================================================== Example:: def send_set_async(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser packet_in_mask = 1 << ofp.OFPR_ACTION | 1 << ofp.OFPR_INVALID_TTL port_status_mask = (1 << ofp.OFPPR_ADD | 1 << ofp.OFPPR_DELETE | 1 << ofp.OFPPR_MODIFY) flow_removed_mask = (1 << ofp.OFPRR_IDLE_TIMEOUT | 1 << ofp.OFPRR_HARD_TIMEOUT | 1 << ofp.OFPRR_DELETE) req = ofp_parser.OFPSetAsync(datapath, [packet_in_mask, 0], [port_status_mask, 0], [flow_removed_mask, 0]) datapath.send_msg(req) """ def __init__(self, datapath, packet_in_mask, port_status_mask, flow_removed_mask): super(OFPSetAsync, self).__init__(datapath) self.packet_in_mask = packet_in_mask self.port_status_mask = port_status_mask self.flow_removed_mask = flow_removed_mask def _serialize_body(self): msg_pack_into(ofproto.OFP_ASYNC_CONFIG_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.packet_in_mask[0], self.packet_in_mask[1], self.port_status_mask[0], self.port_status_mask[1], self.flow_removed_mask[0], self.flow_removed_mask[1]) class OFPBundleProp(OFPPropBase): _TYPES = {} @_register_exp_type(ofproto_common.ONF_EXPERIMENTER_ID, ofproto.ONF_ET_BUNDLE_CONTROL) class ONFBundleCtrlMsg(OFPExperimenter): """ Bundle control message The controller uses this message to create, destroy and commit bundles ================ ====================================================== Attribute Description ================ ====================================================== bundle_id Id of the bundle type One of the following values. | ONF_BCT_OPEN_REQUEST | ONF_BCT_OPEN_REPLY | ONF_BCT_CLOSE_REQUEST | ONF_BCT_CLOSE_REPLY | ONF_BCT_COMMIT_REQUEST | ONF_BCT_COMMIT_REPLY | ONF_BCT_DISCARD_REQUEST | ONF_BCT_DISCARD_REPLY flags Bitmap of the following flags. | ONF_BF_ATOMIC | ONF_BF_ORDERED properties List of ``OFPBundleProp`` subclass instance ================ ====================================================== Example:: def send_bundle_control(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser req = ofp_parser.ONFBundleCtrlMsg(datapath, 7, ofp.ONF_BCT_OPEN_REQUEST, ofp.ONF_BF_ATOMIC, []) datapath.send_msg(req) """ def __init__(self, datapath, bundle_id=None, type_=None, flags=None, properties=None): super(ONFBundleCtrlMsg, self).__init__( datapath, ofproto_common.ONF_EXPERIMENTER_ID, ofproto.ONF_ET_BUNDLE_CONTROL) self.bundle_id = bundle_id self.type = type_ self.flags = flags self.properties = properties def _serialize_body(self): bin_props = bytearray() for p in self.properties: bin_props += p.serialize() msg_pack_into(ofproto.OFP_EXPERIMENTER_HEADER_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.experimenter, self.exp_type) msg_pack_into(ofproto.ONF_BUNDLE_CTRL_PACK_STR, self.buf, ofproto.OFP_EXPERIMENTER_HEADER_SIZE, self.bundle_id, self.type, self.flags) self.buf += bin_props @classmethod def parser_subtype(cls, super_msg): (bundle_id, type_, flags) = struct.unpack_from( ofproto.ONF_BUNDLE_CTRL_PACK_STR, super_msg.data) msg = cls(super_msg.datapath, bundle_id, type_, flags) msg.properties = [] rest = super_msg.data[ofproto.ONF_BUNDLE_CTRL_SIZE:] while rest: p, rest = OFPBundleProp.parse(rest) msg.properties.append(p) return msg class ONFBundleAddMsg(OFPExperimenter): """ Bundle add message The controller uses this message to add a message to a bundle ================ ====================================================== Attribute Description ================ ====================================================== bundle_id Id of the bundle flags Bitmap of the following flags. | ONF_BF_ATOMIC | ONF_BF_ORDERED message ``MsgBase`` subclass instance properties List of ``OFPBundleProp`` subclass instance ================ ====================================================== Example:: def send_bundle_add_message(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser msg = ofp_parser.OFPRoleRequest(datapath, ofp.OFPCR_ROLE_EQUAL, 0) req = ofp_parser.OFPBundleAddMsg(datapath, 7, ofp.ONF_BF_ATOMIC, msg, []) datapath.send_msg(req) """ def __init__(self, datapath, bundle_id, flags, message, properties): super(ONFBundleAddMsg, self).__init__( datapath, ofproto_common.ONF_EXPERIMENTER_ID, ofproto.ONF_ET_BUNDLE_ADD_MESSAGE) self.bundle_id = bundle_id self.flags = flags self.message = message self.properties = properties def _serialize_body(self): # The xid of the inner message must be the same as # that of the outer message (OF1.3 Bundle Extension 3.3) if self.message.xid != self.xid: self.message.set_xid(self.xid) # Message self.message.serialize() tail_buf = self.message.buf # Pad if len(self.properties) > 0: message_len = len(tail_buf) pad_len = utils.round_up(message_len, 8) - message_len msg_pack_into("%dx" % pad_len, tail_buf, message_len) # Properties for p in self.properties: tail_buf += p.serialize() # Head msg_pack_into(ofproto.OFP_EXPERIMENTER_HEADER_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.experimenter, self.exp_type) msg_pack_into(ofproto.ONF_BUNDLE_ADD_MSG_PACK_STR, self.buf, ofproto.OFP_EXPERIMENTER_HEADER_SIZE, self.bundle_id, self.flags) # Finish self.buf += tail_buf @_register_exp_type(ofproto_common.NX_EXPERIMENTER_ID, nicira_ext.NXT_SET_PACKET_IN_FORMAT) class NXTSetPacketInFormatMsg(OFPExperimenter): def __init__(self, datapath, packet_in_format): super(NXTSetPacketInFormatMsg, self).__init__( datapath, ofproto_common.NX_EXPERIMENTER_ID, nicira_ext.NXT_SET_PACKET_IN_FORMAT) self.packet_in_format = packet_in_format def _serialize_body(self): msg_pack_into(ofproto.OFP_EXPERIMENTER_HEADER_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.experimenter, self.exp_type) msg_pack_into(nicira_ext.NX_SET_PACKET_IN_FORMAT_PACK_STR, self.buf, ofproto.OFP_EXPERIMENTER_HEADER_SIZE, self.packet_in_format) @classmethod def parser_subtype(cls, super_msg): packet_in_format = struct.unpack_from( nicira_ext.NX_SET_PACKET_IN_FORMAT_PACK_STR, super_msg.data)[0] msg = cls(super_msg.datapath, packet_in_format) msg.properties = [] return msg @_register_exp_type(ofproto_common.NX_EXPERIMENTER_ID, nicira_ext.NXT_PACKET_IN2) class NXTPacketIn2(OFPExperimenter): def __init__(self, datapath, properties=None): super(NXTPacketIn2, self).__init__( datapath, ofproto_common.NX_EXPERIMENTER_ID, nicira_ext.NXT_PACKET_IN2) self.properties = properties or [] self.data = None self.total_len = None self.buffer_id = None self.table_id = None self.cookie = None self.reason = None self.metadata = None self.userdata = None self.continuation = None def _serialize_body(self): bin_props = bytearray() for p in self.properties: bin_props += p.serialize() msg_pack_into(ofproto.OFP_EXPERIMENTER_HEADER_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.experimenter, self.exp_type) self.buf += bin_props @classmethod def parser_subtype(cls, super_msg): msg = cls(super_msg.datapath) rest = super_msg.data while rest: p, rest = NXTPacketIn2Prop.parse(rest) msg.properties.append(p) msg._parse_property(p) return msg def _parse_property(self, p): if p.type == nicira_ext.NXPINT_PACKET: self.data = p.data # Note: here total_len is length of packet but not msg self.total_len = p.length elif p.type == nicira_ext.NXPINT_FULL_LEN: self.total_len = struct.unpack_from('!I', p.data)[0] elif p.type == nicira_ext.NXPINT_BUFFER_ID: self.buffer_id = struct.unpack_from('!I', p.data)[0] elif p.type == nicira_ext.NXPINT_TABLE_ID: self.table_id = struct.unpack_from('B', p.data)[0] elif p.type == nicira_ext.NXPINT_COOKIE: self.cookie = struct.unpack_from('!Q', p.data)[0] elif p.type == nicira_ext.NXPINT_REASON: self.reason = struct.unpack_from('!B', p.data)[0] elif p.type == nicira_ext.NXPINT_METADATA: self.metadata = p.data elif p.type == nicira_ext.NXPINT_USERDATA: self.userdata = p.data elif p.type == nicira_ext.NXPINT_CONTINUATION: self.continuation = p.data class NXTPacketIn2Prop(OFPPropBase): _TYPES = {} _PROP_TYPE = None def __init__(self, type_=None, length=None, data=None): super(NXTPacketIn2Prop, self).__init__(type_, length) self.data = data @classmethod def parse(cls, buf): (type_, length) = struct.unpack_from(cls._PACK_STR, buf, 0) if not length: raise ValueError rest = buf[utils.round_up(length, 8):] try: subcls = cls._TYPES[type_] except KeyError: subcls = OFPPropUnknown prop = subcls.sub_parser(buf, type, length) prop.type = type_ prop.length = length return prop, rest def serialize_body(self): return self.data @classmethod def sub_parser(cls, buf, type, length): p = cls(type, length - 4, buf[4:length]) return p @NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_PACKET) class NXTPacketIn2PropPacket(NXTPacketIn2Prop): _PROP_TYPE = nicira_ext.NXPINT_PACKET @NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_FULL_LEN) class NXTPacketIn2PropFullLen(NXTPacketIn2Prop): _PROP_TYPE = nicira_ext.NXPINT_FULL_LEN @NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_BUFFER_ID) class NXTPacketIn2PropBufferId(NXTPacketIn2Prop): _PROP_TYPE = nicira_ext.NXPINT_BUFFER_ID @NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_TABLE_ID) class NXTPacketIn2PropTableId(NXTPacketIn2Prop): _PROP_TYPE = nicira_ext.NXPINT_TABLE_ID @NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_COOKIE) class NXTPacketIn2PropCookie(NXTPacketIn2Prop): _PROP_TYPE = nicira_ext.NXPINT_COOKIE @NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_REASON) class NXTPacketIn2PropReason(NXTPacketIn2Prop): _PROP_TYPE = nicira_ext.NXPINT_REASON @NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_METADATA) class NXTPacketIn2PropMetadata(NXTPacketIn2Prop): _PROP_TYPE = nicira_ext.NXPINT_METADATA @NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_USERDATA) class NXTPacketIn2PropUserData(NXTPacketIn2Prop): _PROP_TYPE = nicira_ext.NXPINT_USERDATA @NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_CONTINUATION) class NXTPacketIn2PropContinuation(NXTPacketIn2Prop): _PROP_TYPE = nicira_ext.NXPINT_CONTINUATION nx_actions.generate( 'os_ken.ofproto.ofproto_v1_3', 'os_ken.ofproto.ofproto_v1_3_parser' ) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/ofproto/ofproto_v1_4.py0000664000175000017500000017251500000000000020665 0ustar00zuulzuul00000000000000# Copyright (C) 2012,2013 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2012 Isaku Yamahata # # 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. """ OpenFlow 1.4 definitions. """ from os_ken.lib import type_desc from os_ken.ofproto import nicira_ext from os_ken.ofproto import ofproto_utils from os_ken.ofproto import oxm_fields from struct import calcsize # enum ofp_port_no # Port numbering. Ports are numbered starting from 1. OFPP_MAX = 0xffffff00 # Maximum number of physical and logical # switch ports. OFPP_IN_PORT = 0xfffffff8 # Send the packet out the input port. This # reserved port must be explicitly used in # order to send back out of the input port. OFPP_TABLE = 0xfffffff9 # Submit the packet to the first flow table # NB: This destination port can only be used # in packet-out messages. OFPP_NORMAL = 0xfffffffa # Process with normal L2/L3 switching. OFPP_FLOOD = 0xfffffffb # All physical ports in VLAN, except input # port and those blocked or link down. OFPP_ALL = 0xfffffffc # All physical ports except input port. OFPP_CONTROLLER = 0xfffffffd # Send to controller. OFPP_LOCAL = 0xfffffffe # Local openflow "port". OFPP_ANY = 0xffffffff # Wildcard port used only for flow mod # (delete) and flow stats requests. Selects # all flows regardless of output port # (including flows with no output port). # enum ofp_type # Immutable messages. OFPT_HELLO = 0 # Symmetric message OFPT_ERROR = 1 # Symmetric message OFPT_ECHO_REQUEST = 2 # Symmetric message OFPT_ECHO_REPLY = 3 # Symmetric message OFPT_EXPERIMENTER = 4 # Symmetric message # Switch configuration messages. OFPT_FEATURES_REQUEST = 5 # Controller/switch message OFPT_FEATURES_REPLY = 6 # Controller/switch message OFPT_GET_CONFIG_REQUEST = 7 # Controller/switch message OFPT_GET_CONFIG_REPLY = 8 # Controller/switch message OFPT_SET_CONFIG = 9 # Controller/switch message # Asynchronous messages. OFPT_PACKET_IN = 10 # Async message OFPT_FLOW_REMOVED = 11 # Async message OFPT_PORT_STATUS = 12 # Async message # Controller command messages. OFPT_PACKET_OUT = 13 # Controller/switch message OFPT_FLOW_MOD = 14 # Controller/switch message OFPT_GROUP_MOD = 15 # Controller/switch message OFPT_PORT_MOD = 16 # Controller/switch message OFPT_TABLE_MOD = 17 # Controller/switch message # Multipart messages. OFPT_MULTIPART_REQUEST = 18 # Controller/switch message OFPT_MULTIPART_REPLY = 19 # Controller/switch message # Barrier messages. OFPT_BARRIER_REQUEST = 20 # Controller/switch message OFPT_BARRIER_REPLY = 21 # Controller/switch message # Controller role change request messages. OFPT_ROLE_REQUEST = 24 # Controller/switch message OFPT_ROLE_REPLY = 25 # Controller/switch message # Asynchronous message configuration. OFPT_GET_ASYNC_REQUEST = 26 # Controller/switch message OFPT_GET_ASYNC_REPLY = 27 # Controller/switch message OFPT_SET_ASYNC = 28 # Controller/switch message # Meters and rate limiters configuration messages. OFPT_METER_MOD = 29 # Controller/switch message # Controller role change event messages. OFPT_ROLE_STATUS = 30 # Async message # Asynchronous messages. OFPT_TABLE_STATUS = 31 # Async message # Request forwarding by the switch. OFPT_REQUESTFORWARD = 32 # Async message # Bundle operations (multiple messages as a single operation). OFPT_BUNDLE_CONTROL = 33 OFPT_BUNDLE_ADD_MESSAGE = 34 _OFP_HEADER_PACK_STR = 'BBHI' OFP_HEADER_PACK_STR = '!' + _OFP_HEADER_PACK_STR OFP_HEADER_SIZE = 8 # struct ofp_hello OFP_HELLO_HEADER_SIZE = 8 # struct ofp_hello_elem_header OFP_HELLO_ELEM_HEADER_PACK_STR = '!HH' OFP_HELLO_ELEM_HEADER_SIZE = 4 assert (calcsize(OFP_HELLO_ELEM_HEADER_PACK_STR) == OFP_HELLO_ELEM_HEADER_SIZE) # enum ofp_hello_elem_type OFPHET_VERSIONBITMAP = 1 # struct ofp_hello_elem_versionbitmap OFP_HELLO_ELEM_VERSIONBITMAP_HEADER_PACK_STR = '!HH' OFP_HELLO_ELEM_VERSIONBITMAP_HEADER_SIZE = 4 assert (calcsize(OFP_HELLO_ELEM_VERSIONBITMAP_HEADER_PACK_STR) == OFP_HELLO_ELEM_VERSIONBITMAP_HEADER_SIZE) OFP_DEFAULT_MISS_SEND_LEN = 128 # enum ofp_config_flags # Handling of IP fragments. OFPC_FRAG_NORMAL = 0 # No special handling for fragments. OFPC_FRAG_DROP = 1 << 0 # Drop fragments. OFPC_FRAG_REASM = 1 << 1 # Reassemble (only if OFPC_IP_REASM set). OFPC_FRAG_MASK = 3 # struct ofp_switch_config OFP_SWITCH_CONFIG_PACK_STR = '!HH' OFP_SWITCH_CONFIG_SIZE = 12 assert (calcsize(OFP_SWITCH_CONFIG_PACK_STR) + OFP_HEADER_SIZE == OFP_SWITCH_CONFIG_SIZE) # enum ofp_table OFPTT_MAX = 0xfe # Last usable table number. OFPTT_ALL = 0xff # Wildcard table used for table config, flow stats # and flow deletes. # enum ofp_table_config OFPTC_DEPRECATED_MASK = 3 # Deprecated bits OFPTC_EVICTION = 1 << 2 # Authorise table to evict flows. OFPTC_VACANCY_EVENTS = 1 << 3 # Enable vacancy events. # enum ofp_table_mod_prop_type OFPTMPT_EVICTION = 0x2 # Eviction property. OFPTMPT_VACANCY = 0x3 # Vacancy property. OFPTMPT_EXPERIMENTER = 0xFFFF # Experimenter property. # enum ofp_table_mod_prop_eviction_flag OFPTMPEF_OTHER = 1 << 0 # Using other factors. OFPTMPEF_IMPORTANCE = 1 << 1 # Using flow entry importance. OFPTMPEF_LIFETIME = 1 << 2 # Using flow entry lifetime. # struct ofp_table_mod_prop_eviction OFP_TABLE_MOD_PROP_EVICTION_PACK_STR = '!HHI' OFP_TABLE_MOD_PROP_EVICTION_SIZE = 8 assert(calcsize(OFP_TABLE_MOD_PROP_EVICTION_PACK_STR) == OFP_TABLE_MOD_PROP_EVICTION_SIZE) # struct ofp_table_mod_prop_vacancy OFP_TABLE_MOD_PROP_VACANCY_PACK_STR = '!HHBBBx' OFP_TABLE_MOD_PROP_VACANCY_SIZE = 8 assert(calcsize(OFP_TABLE_MOD_PROP_VACANCY_PACK_STR) == OFP_TABLE_MOD_PROP_VACANCY_SIZE) # struct ofp_table_mod_prop_experimenter OFP_TABLE_MOD_PROP_EXPERIMENTER_PACK_STR = '!HHII' OFP_TABLE_MOD_PROP_EXPERIMENTER_SIZE = 12 assert(calcsize(OFP_TABLE_MOD_PROP_EXPERIMENTER_PACK_STR) == OFP_TABLE_MOD_PROP_EXPERIMENTER_SIZE) # struct ofp_table_mod OFP_TABLE_MOD_PACK_STR = '!B3xI' OFP_TABLE_MOD_SIZE = 16 assert (calcsize(OFP_TABLE_MOD_PACK_STR) + OFP_HEADER_SIZE == OFP_TABLE_MOD_SIZE) # enum ofp_capabilities OFPC_FLOW_STATS = 1 << 0 # Flow statistics. OFPC_TABLE_STATS = 1 << 1 # Table statistics. OFPC_PORT_STATS = 1 << 2 # Port statistics. OFPC_GROUP_STATS = 1 << 3 # Group statistics. OFPC_IP_REASM = 1 << 5 # Can reassemble IP fragments. OFPC_QUEUE_STATS = 1 << 6 # Queue statistics. OFPC_PORT_BLOCKED = 1 << 8 # Switch will block looping ports. # enum ofp_port_config OFPPC_PORT_DOWN = 1 << 0 # Port is administratively down. OFPPC_NO_RECV = 1 << 2 # Drop all packets recieved by port. OFPPC_NO_FWD = 1 << 5 # Drop packets forwarded to port. OFPPC_NO_PACKET_IN = 1 << 6 # Do not send packet-in msgs for port. # enum ofp_port_state OFPPS_LINK_DOWN = 1 << 0 # No physical link present. OFPPS_BLOCKED = 1 << 1 # Port is blocked OFPPS_LIVE = 1 << 2 # Live for Fast Failover Group. # enum ofp_port_features OFPPF_10MB_HD = 1 << 0 # 10 Mb half-duplex rate support. OFPPF_10MB_FD = 1 << 1 # 10 Mb full-duplex rate support. OFPPF_100MB_HD = 1 << 2 # 100 Mb half-duplex rate support. OFPPF_100MB_FD = 1 << 3 # 100 Mb full-duplex rate support. OFPPF_1GB_HD = 1 << 4 # 1 Gb half-duplex rate support. OFPPF_1GB_FD = 1 << 5 # 1 Gb full-duplex rate support. OFPPF_10GB_FD = 1 << 6 # 10 Gb full-duplex rate support. OFPPF_40GB_FD = 1 << 7 # 40 Gb full-duplex rate support. OFPPF_100GB_FD = 1 << 8 # 100 Gb full-duplex rate support. OFPPF_1TB_FD = 1 << 9 # 1 Tb full-duplex rate support. OFPPF_OTHER = 1 << 10 # Other rate, not in the list. OFPPF_COPPER = 1 << 11 # Copper medium. OFPPF_FIBER = 1 << 12 # Fiber medium. OFPPF_AUTONEG = 1 << 13 # Auto-negotiation. OFPPF_PAUSE = 1 << 14 # Pause. OFPPF_PAUSE_ASYM = 1 << 15 # Asymmetric pause. # enum ofp_port_desc_prop_type OFPPDPT_ETHERNET = 0 # Ethernet property. OFPPDPT_OPTICAL = 1 # Optical property. OFPPDPT_EXPERIMENTER = 0xFFFF # Experimenter property. # struct ofp_port_desc_prop_ethernet OFP_PORT_DESC_PROP_ETHERNET_PACK_STR = '!HH4xIIIIII' OFP_PORT_DESC_PROP_ETHERNET_SIZE = 32 assert (calcsize(OFP_PORT_DESC_PROP_ETHERNET_PACK_STR) == OFP_PORT_DESC_PROP_ETHERNET_SIZE) # enum ofp_optical_port_features OFPOPF_RX_TUNE = 1 << 0 # Receiver is tunable OFPOPF_TX_TUNE = 1 << 1 # Transmit is tunable OFPOPF_TX_PWR = 1 << 2 # Power is configurable OFPOPF_USE_FREQ = 1 << 3 # Use Frequency, not wavelength # struct ofp_port_desc_prop_optical OFP_PORT_DESC_PROP_OPTICAL_PACK_STR = '!HH4xIIIIIIIHH' OFP_PORT_DESC_PROP_OPTICAL_SIZE = 40 assert (calcsize(OFP_PORT_DESC_PROP_OPTICAL_PACK_STR) == OFP_PORT_DESC_PROP_OPTICAL_SIZE) # struct ofp_port_desc_prop_experimenter OFP_PORT_DESC_PROP_EXPERIMENTER_PACK_STR = '!HHII' OFP_PORT_DESC_PROP_EXPERIMENTER_SIZE = 12 assert (calcsize(OFP_PORT_DESC_PROP_EXPERIMENTER_PACK_STR) == OFP_PORT_DESC_PROP_EXPERIMENTER_SIZE) # struct ofp_port OFP_MAX_PORT_NAME_LEN = 16 OFP_ETH_ALEN = 6 OFP_ETH_ALEN_STR = str(OFP_ETH_ALEN) _OFP_PORT_PACK_STR = 'IH2x' + OFP_ETH_ALEN_STR + 's' + '2x' + \ str(OFP_MAX_PORT_NAME_LEN) + 's' + 'II' OFP_PORT_PACK_STR = '!' + _OFP_PORT_PACK_STR OFP_PORT_SIZE = 40 assert (calcsize(OFP_PORT_PACK_STR) == OFP_PORT_SIZE) # struct ofp_switch_features OFP_SWITCH_FEATURES_PACK_STR = '!QIBB2xII' OFP_SWITCH_FEATURES_SIZE = 32 assert (calcsize(OFP_SWITCH_FEATURES_PACK_STR) + OFP_HEADER_SIZE == OFP_SWITCH_FEATURES_SIZE) # enum ofp_port_reason OFPPR_ADD = 0 # The port was added. OFPPR_DELETE = 1 # The port was removed. OFPPR_MODIFY = 2 # Some attribute of the port has changed. # struct ofp_port_status OFP_PORT_STATUS_PACK_STR = '!B7x' + _OFP_PORT_PACK_STR OFP_PORT_STATUS_SIZE = 56 assert (calcsize(OFP_PORT_STATUS_PACK_STR) + OFP_HEADER_SIZE == OFP_PORT_STATUS_SIZE) # enum ofp_port_mod_prop_type OFPPMPT_ETHERNET = 0 # Ethernet property. OFPPMPT_OPTICAL = 1 # Optical property. OFPPMPT_EXPERIMENTER = 0xFFFF # Experimenter property. # struct ofp_port_mod_prop_ethernet OFP_PORT_MOD_PROP_ETHERNET_PACK_STR = '!HHI' OFP_PORT_MOD_PROP_ETHERNET_SIZE = 8 assert (calcsize(OFP_PORT_MOD_PROP_ETHERNET_PACK_STR) == OFP_PORT_MOD_PROP_ETHERNET_SIZE) # struct ofp_port_mod_prop_optical OFP_PORT_MOD_PROP_OPTICAL_PACK_STR = '!HHIIIII' OFP_PORT_MOD_PROP_OPTICAL_SIZE = 24 assert (calcsize(OFP_PORT_MOD_PROP_OPTICAL_PACK_STR) == OFP_PORT_MOD_PROP_OPTICAL_SIZE) # struct ofp_port_mod_prop_experimenter OFP_PORT_MOD_PROP_EXPERIMENTER_PACK_STR = '!HHII' OFP_PORT_MOD_PROP_EXPERIMENTER_SIZE = 12 assert (calcsize(OFP_PORT_MOD_PROP_EXPERIMENTER_PACK_STR) == OFP_PORT_MOD_PROP_EXPERIMENTER_SIZE) # struct ofp_port_mod OFP_PORT_MOD_PACK_STR = '!I4x' + OFP_ETH_ALEN_STR + 's2xII' OFP_PORT_MOD_SIZE = 32 assert (calcsize(OFP_PORT_MOD_PACK_STR) + OFP_HEADER_SIZE == OFP_PORT_MOD_SIZE) # enum ofp_match_type OFPMT_STANDARD = 0 # Deprecated OFPMT_OXM = 1 # OpenFlow Extensible Match # struct ofp_match _OFP_MATCH_PACK_STR = 'HH4x' OFP_MATCH_PACK_STR = '!' + _OFP_MATCH_PACK_STR OFP_MATCH_SIZE = 8 assert calcsize(OFP_MATCH_PACK_STR) == OFP_MATCH_SIZE # enum ofp_oxm_class OFPXMC_NXM_0 = 0x0000 # Backward compatibility with NXM OFPXMC_NXM_1 = 0x0001 # Backward compatibility with NXM OFPXMC_OPENFLOW_BASIC = 0x8000 # Basic class for OpenFlow OFPXMC_EXPERIMENTER = 0xFFFF # Experimenter class # enum ofp_vlan_id OFPVID_PRESENT = 0x1000 # bit that indicate that a VLAN id is set. OFPVID_NONE = 0X0000 # No VLAN id was set. def _oxm_tlv_header(class_, field, hasmask, length): return (class_ << 16) | (field << 9) | (hasmask << 8) | length def oxm_tlv_header(field, length): return _oxm_tlv_header(OFPXMC_OPENFLOW_BASIC, field, 0, length) def oxm_tlv_header_w(field, length): return _oxm_tlv_header(OFPXMC_OPENFLOW_BASIC, field, 1, length * 2) def oxm_tlv_header_extract_hasmask(header): return (header >> 8) & 1 def oxm_tlv_header_extract_length(header): if oxm_tlv_header_extract_hasmask(header): length = (header & 0xff) // 2 else: length = header & 0xff return length oxm_types = [ oxm_fields.OpenFlowBasic('in_port', 0, type_desc.Int4), oxm_fields.OpenFlowBasic('in_phy_port', 1, type_desc.Int4), oxm_fields.OpenFlowBasic('metadata', 2, type_desc.Int8), oxm_fields.OpenFlowBasic('eth_dst', 3, type_desc.MacAddr), oxm_fields.OpenFlowBasic('eth_src', 4, type_desc.MacAddr), oxm_fields.OpenFlowBasic('eth_type', 5, type_desc.Int2), oxm_fields.OpenFlowBasic('vlan_vid', 6, type_desc.Int2), oxm_fields.OpenFlowBasic('vlan_pcp', 7, type_desc.Int1), oxm_fields.OpenFlowBasic('ip_dscp', 8, type_desc.Int1), oxm_fields.OpenFlowBasic('ip_ecn', 9, type_desc.Int1), oxm_fields.OpenFlowBasic('ip_proto', 10, type_desc.Int1), oxm_fields.OpenFlowBasic('ipv4_src', 11, type_desc.IPv4Addr), oxm_fields.OpenFlowBasic('ipv4_dst', 12, type_desc.IPv4Addr), oxm_fields.OpenFlowBasic('tcp_src', 13, type_desc.Int2), oxm_fields.OpenFlowBasic('tcp_dst', 14, type_desc.Int2), oxm_fields.OpenFlowBasic('udp_src', 15, type_desc.Int2), oxm_fields.OpenFlowBasic('udp_dst', 16, type_desc.Int2), oxm_fields.OpenFlowBasic('sctp_src', 17, type_desc.Int2), oxm_fields.OpenFlowBasic('sctp_dst', 18, type_desc.Int2), oxm_fields.OpenFlowBasic('icmpv4_type', 19, type_desc.Int1), oxm_fields.OpenFlowBasic('icmpv4_code', 20, type_desc.Int1), oxm_fields.OpenFlowBasic('arp_op', 21, type_desc.Int2), oxm_fields.OpenFlowBasic('arp_spa', 22, type_desc.IPv4Addr), oxm_fields.OpenFlowBasic('arp_tpa', 23, type_desc.IPv4Addr), oxm_fields.OpenFlowBasic('arp_sha', 24, type_desc.MacAddr), oxm_fields.OpenFlowBasic('arp_tha', 25, type_desc.MacAddr), oxm_fields.OpenFlowBasic('ipv6_src', 26, type_desc.IPv6Addr), oxm_fields.OpenFlowBasic('ipv6_dst', 27, type_desc.IPv6Addr), oxm_fields.OpenFlowBasic('ipv6_flabel', 28, type_desc.Int4), oxm_fields.OpenFlowBasic('icmpv6_type', 29, type_desc.Int1), oxm_fields.OpenFlowBasic('icmpv6_code', 30, type_desc.Int1), oxm_fields.OpenFlowBasic('ipv6_nd_target', 31, type_desc.IPv6Addr), oxm_fields.OpenFlowBasic('ipv6_nd_sll', 32, type_desc.MacAddr), oxm_fields.OpenFlowBasic('ipv6_nd_tll', 33, type_desc.MacAddr), oxm_fields.OpenFlowBasic('mpls_label', 34, type_desc.Int4), oxm_fields.OpenFlowBasic('mpls_tc', 35, type_desc.Int1), oxm_fields.OpenFlowBasic('mpls_bos', 36, type_desc.Int1), oxm_fields.OpenFlowBasic('pbb_isid', 37, type_desc.Int3), oxm_fields.OpenFlowBasic('tunnel_id', 38, type_desc.Int8), oxm_fields.OpenFlowBasic('ipv6_exthdr', 39, type_desc.Int2), oxm_fields.OpenFlowBasic('pbb_uca', 41, type_desc.Int1), # EXT-109 TCP flags match field Extension oxm_fields.ONFExperimenter('tcp_flags', 42, type_desc.Int2), # EXT-233 Output match Extension # NOTE(yamamoto): The spec says uint64_t but I assume it's an error. oxm_fields.ONFExperimenter('actset_output', 43, type_desc.Int4), # Support for matching/setting xreg0-7 oxm_fields.PacketRegs('xreg0', 0, type_desc.Int8), oxm_fields.PacketRegs('xreg1', 1, type_desc.Int8), oxm_fields.PacketRegs('xreg2', 2, type_desc.Int8), oxm_fields.PacketRegs('xreg3', 3, type_desc.Int8), oxm_fields.PacketRegs('xreg4', 4, type_desc.Int8), oxm_fields.PacketRegs('xreg5', 5, type_desc.Int8), oxm_fields.PacketRegs('xreg6', 6, type_desc.Int8), oxm_fields.PacketRegs('xreg7', 7, type_desc.Int8), ] + nicira_ext.oxm_types oxm_fields.generate(__name__) # enum ofp_action_type OFPAT_OUTPUT = 0 # Output to switch port. OFPAT_COPY_TTL_OUT = 11 # Copy TTL "outwards" -- from # next-to-outermost to outermost OFPAT_COPY_TTL_IN = 12 # Copy TTL "inwards" -- from outermost to # next-to-outermost OFPAT_SET_MPLS_TTL = 15 # MPLS TTL. OFPAT_DEC_MPLS_TTL = 16 # Decrement MPLS TTL OFPAT_PUSH_VLAN = 17 # Push a new VLAN tag OFPAT_POP_VLAN = 18 # Pop the outer VLAN tag OFPAT_PUSH_MPLS = 19 # Push a new MPLS tag OFPAT_POP_MPLS = 20 # Pop the outer MPLS tag OFPAT_SET_QUEUE = 21 # Set queue id when outputting to a port OFPAT_GROUP = 22 # Apply group OFPAT_SET_NW_TTL = 23 # IP TTL. OFPAT_DEC_NW_TTL = 24 # Decrement IP TTL. OFPAT_SET_FIELD = 25 # Set a header field using OXM TLV format. OFPAT_PUSH_PBB = 26 # Push a new PBB service tag (I-TAG) OFPAT_POP_PBB = 27 # Pop the outer PBB service tag (I-TAG) OFPAT_EXPERIMENTER = 0xffff # struct ofp_action_header OFP_ACTION_HEADER_PACK_STR = '!HH4x' OFP_ACTION_HEADER_SIZE = 8 assert calcsize(OFP_ACTION_HEADER_PACK_STR) == OFP_ACTION_HEADER_SIZE # enum ofp_controller_max_len OFPCML_MAX = 0xffe5 # maximum max_len value which can be used to # request a specific byte length. OFPCML_NO_BUFFER = 0xffff # indicates that no buffering should be # applied and the whole packet is to be # sent to the controller. # struct ofp_action_output OFP_ACTION_OUTPUT_PACK_STR = '!HHIH6x' OFP_ACTION_OUTPUT_SIZE = 16 assert calcsize(OFP_ACTION_OUTPUT_PACK_STR) == OFP_ACTION_OUTPUT_SIZE # struct ofp_action_generic OFP_ACTION_GENERIC_PACK_STR = '!HH4x' OFP_ACTION_GENERIC_SIZE = 8 assert (calcsize(OFP_ACTION_GENERIC_PACK_STR) == OFP_ACTION_GENERIC_SIZE) # struct ofp_action_mpls_ttl OFP_ACTION_MPLS_TTL_PACK_STR = '!HHB3x' OFP_ACTION_MPLS_TTL_SIZE = 8 assert calcsize(OFP_ACTION_MPLS_TTL_PACK_STR) == OFP_ACTION_MPLS_TTL_SIZE # struct ofp_action_push OFP_ACTION_PUSH_PACK_STR = '!HHH2x' OFP_ACTION_PUSH_SIZE = 8 assert calcsize(OFP_ACTION_PUSH_PACK_STR) == OFP_ACTION_PUSH_SIZE # struct ofp_action_pop_mpls OFP_ACTION_POP_MPLS_PACK_STR = '!HHH2x' OFP_ACTION_POP_MPLS_SIZE = 8 assert calcsize(OFP_ACTION_POP_MPLS_PACK_STR) == OFP_ACTION_POP_MPLS_SIZE # struct ofp_action_set_queue OFP_ACTION_SET_QUEUE_PACK_STR = '!HHI' OFP_ACTION_SET_QUEUE_SIZE = 8 assert calcsize(OFP_ACTION_SET_QUEUE_PACK_STR) == OFP_ACTION_SET_QUEUE_SIZE # struct ofp_action_group OFP_ACTION_GROUP_PACK_STR = '!HHI' OFP_ACTION_GROUP_SIZE = 8 assert calcsize(OFP_ACTION_GROUP_PACK_STR) == OFP_ACTION_GROUP_SIZE # struct ofp_action_nw_ttl OFP_ACTION_NW_TTL_PACK_STR = '!HHB3x' OFP_ACTION_NW_TTL_SIZE = 8 assert calcsize(OFP_ACTION_NW_TTL_PACK_STR) == OFP_ACTION_NW_TTL_SIZE # struct ofp_action_set_field OFP_ACTION_SET_FIELD_PACK_STR = '!HH4x' OFP_ACTION_SET_FIELD_SIZE = 8 assert calcsize(OFP_ACTION_SET_FIELD_PACK_STR) == OFP_ACTION_SET_FIELD_SIZE # struct ofp_action_experimenter_header OFP_ACTION_EXPERIMENTER_HEADER_PACK_STR = '!HHI' OFP_ACTION_EXPERIMENTER_HEADER_SIZE = 8 assert (calcsize(OFP_ACTION_EXPERIMENTER_HEADER_PACK_STR) == OFP_ACTION_EXPERIMENTER_HEADER_SIZE) # enum ofp_instruction_type OFPIT_GOTO_TABLE = 1 # Setup the next table in the lookup pipeline. OFPIT_WRITE_METADATA = 2 # Setup the metadata field for use later in # pipeline. OFPIT_WRITE_ACTIONS = 3 # Write the action(s) onto the datapath # action set OFPIT_APPLY_ACTIONS = 4 # Applies the action(s) immediately OFPIT_CLEAR_ACTIONS = 5 # Clears all actions from the datapath action # set OFPIT_METER = 6 # Apply meter (rate limiter) OFPIT_EXPERIMENTER = 0xFFFF # Experimenter instruction # struct ofp_instruction_goto_table OFP_INSTRUCTION_GOTO_TABLE_PACK_STR = '!HHB3x' OFP_INSTRUCTION_GOTO_TABLE_SIZE = 8 assert (calcsize(OFP_INSTRUCTION_GOTO_TABLE_PACK_STR) == OFP_INSTRUCTION_GOTO_TABLE_SIZE) # struct ofp_instruction_write_metadata OFP_INSTRUCTION_WRITE_METADATA_PACK_STR = '!HH4xQQ' OFP_INSTRUCTION_WRITE_METADATA_SIZE = 24 assert (calcsize(OFP_INSTRUCTION_WRITE_METADATA_PACK_STR) == OFP_INSTRUCTION_WRITE_METADATA_SIZE) # struct ofp_instruction_actions OFP_INSTRUCTION_ACTIONS_PACK_STR = '!HH4x' OFP_INSTRUCTION_ACTIONS_SIZE = 8 assert (calcsize(OFP_INSTRUCTION_ACTIONS_PACK_STR) == OFP_INSTRUCTION_ACTIONS_SIZE) # struct ofp_instruction_meter OFP_INSTRUCTION_METER_PACK_STR = '!HHI' OFP_INSTRUCTION_METER_SIZE = 8 assert calcsize(OFP_INSTRUCTION_METER_PACK_STR) == OFP_INSTRUCTION_METER_SIZE # struct ofp_instruction_experimenter_header OFP_INSTRUCTION_EXPERIMENTER_HEADER_PACK_STR = '!HHI' OFP_INSTRUCTION_EXPERIMENTER_HEADER_SIZE = 8 assert (calcsize(OFP_INSTRUCTION_EXPERIMENTER_HEADER_PACK_STR) == OFP_INSTRUCTION_EXPERIMENTER_HEADER_SIZE) # enum ofp_flow_mod_command OFPFC_ADD = 0 # New flow. OFPFC_MODIFY = 1 # Modify all matching flows. OFPFC_MODIFY_STRICT = 2 # Modify entry strictly matching wildcards OFPFC_DELETE = 3 # Delete all matching flows. OFPFC_DELETE_STRICT = 4 # Strictly match wildcards and priority. # Value used in "idle_timeout" and "hard_timeout" to indicate that the # entry is permanent. */ OFP_FLOW_PERMANENT = 0 # By default, choose a priority in the middle. OFP_DEFAULT_PRIORITY = 0x8000 # enum ofp_flow_mod_flags OFPFF_SEND_FLOW_REM = 1 << 0 # Send flow removed message when flow # expires or is deleted. OFPFF_CHECK_OVERLAP = 1 << 1 # Check for overlapping entries first. OFPFF_RESET_COUNTS = 1 << 2 # Reset flow packet and byte counts. OFPFF_NO_PKT_COUNTS = 1 << 3 # Don't keep track of packet count. OFPFF_NO_BYT_COUNTS = 1 << 4 # Don't keep track of byte count. # struct ofp_flow_mod _OFP_FLOW_MOD_PACK_STR0 = 'QQBBHHHIIIHH' OFP_FLOW_MOD_PACK_STR = '!' + _OFP_FLOW_MOD_PACK_STR0 + _OFP_MATCH_PACK_STR OFP_FLOW_MOD_PACK_STR0 = '!' + _OFP_FLOW_MOD_PACK_STR0 OFP_FLOW_MOD_SIZE = 56 assert (calcsize(OFP_FLOW_MOD_PACK_STR) + OFP_HEADER_SIZE == OFP_FLOW_MOD_SIZE) # enum ofp_group OFPG_MAX = 0xffffff00 # Last usable group number. OFPG_ALL = 0xfffffffc # Represents all groups for group delete commands. OFPG_ANY = 0xffffffff # Wildcard group used only for flow stats requests. # Selects all flows regardless of group # (including flows with no group). # enum ofp_group_mod_command OFPGC_ADD = 0 # New group. OFPGC_MODIFY = 1 # Modify all matching groups. OFPGC_DELETE = 2 # Delete all matching groups. # struct ofp_bucket OFP_BUCKET_PACK_STR = '!HHII4x' OFP_BUCKET_SIZE = 16 assert calcsize(OFP_BUCKET_PACK_STR) == OFP_BUCKET_SIZE # struct ofp_group_mod OFP_GROUP_MOD_PACK_STR = '!HBxI' OFP_GROUP_MOD_SIZE = 16 assert (calcsize(OFP_GROUP_MOD_PACK_STR) + OFP_HEADER_SIZE == OFP_GROUP_MOD_SIZE) # enum ofp_group_type OFPGT_ALL = 0 # All (multicast/broadcast) group. OFPGT_SELECT = 1 # Select group. OFPGT_INDIRECT = 2 # Indirect group. OFPGT_FF = 3 # Fast failover group. OFP_NO_BUFFER = 0xffffffff # Special buffer-id to indicate 'no buffer' # struct ofp_packet_out OFP_PACKET_OUT_PACK_STR = '!IIH6x' OFP_PACKET_OUT_SIZE = 24 assert (calcsize(OFP_PACKET_OUT_PACK_STR) + OFP_HEADER_SIZE == OFP_PACKET_OUT_SIZE) # enum ofp_packet_in_reason OFPR_TABLE_MISS = 0 # No matching flow (table-miss flow entry). OFPR_APPLY_ACTION = 1 # Output to controller in apply-actions. OFPR_INVALID_TTL = 2 # Packet has invalid TTL. OFPR_ACTION_SET = 3 # Output to controller in action set. OFPR_GROUP = 4 # Output to controller in group bucket. OFPR_PACKET_OUT = 5 # Output to controller in packet-out. # struct ofp_packet_in OFP_PACKET_IN_PACK_STR = '!IHBBQ' OFP_PACKET_IN_SIZE = 32 assert (calcsize(OFP_PACKET_IN_PACK_STR) + OFP_MATCH_SIZE + OFP_HEADER_SIZE == OFP_PACKET_IN_SIZE) # enum ofp_flow_removed_reason OFPRR_IDLE_TIMEOUT = 0 # Flow idle time exceeded idle_timeout. OFPRR_HARD_TIMEOUT = 1 # Time exceeded hard_timeout. OFPRR_DELETE = 2 # Evicted by a DELETE flow mod. OFPRR_GROUP_DELETE = 3 # Group was removed. OFPRR_METER_DELETE = 4 # Meter was removed. OFPRR_EVICTION = 5 # Switch eviction to free resources. # struct ofp_port_status OFP_PORT_STATUS_PACK_STR = '!B7x' + _OFP_PORT_PACK_STR OFP_PORT_STATUS_DESC_OFFSET = OFP_HEADER_SIZE + 8 OFP_PORT_STATUS_SIZE = 56 assert (calcsize(OFP_PORT_STATUS_PACK_STR) + OFP_HEADER_SIZE == OFP_PORT_STATUS_SIZE) # struct ofp_flow_removed _OFP_FLOW_REMOVED_PACK_STR0 = 'QHBBIIHHQQ' OFP_FLOW_REMOVED_PACK_STR = '!' + _OFP_FLOW_REMOVED_PACK_STR0 + \ _OFP_MATCH_PACK_STR OFP_FLOW_REMOVED_PACK_STR0 = '!' + _OFP_FLOW_REMOVED_PACK_STR0 OFP_FLOW_REMOVED_SIZE = 56 assert (calcsize(OFP_FLOW_REMOVED_PACK_STR) + OFP_HEADER_SIZE == OFP_FLOW_REMOVED_SIZE) # enum ofp_meter OFPM_MAX = 0xffff0000 OFPM_SLOWPATH = 0xfffffffd # Meter for slow datapath, if any. OFPM_CONTROLLER = 0xfffffffe # Meter for controller connection. OFPM_ALL = 0xffffffff # Represents all meters for stat requests # commands. # enum ofp_meter_band_type OFPMBT_DROP = 1 # Drop packet. OFPMBT_DSCP_REMARK = 2 # Remark DSCP in the IP header. OFPMBT_EXPERIMENTER = 0xFFFF # Experimenter meter band. # struct ofp_meter_band_drop OFP_METER_BAND_DROP_PACK_STR = '!HHII4x' OFP_METER_BAND_DROP_SIZE = 16 assert (calcsize(OFP_METER_BAND_DROP_PACK_STR) == OFP_METER_BAND_DROP_SIZE) # struct ofp_meter_band_dscp_remark OFP_METER_BAND_DSCP_REMARK_PACK_STR = '!HHIIB3x' OFP_METER_BAND_DSCP_REMARK_SIZE = 16 assert (calcsize(OFP_METER_BAND_DSCP_REMARK_PACK_STR) == OFP_METER_BAND_DSCP_REMARK_SIZE) # struct ofp_meter_band_experimenter OFP_METER_BAND_EXPERIMENTER_PACK_STR = '!HHIII' OFP_METER_BAND_EXPERIMENTER_SIZE = 16 assert (calcsize(OFP_METER_BAND_EXPERIMENTER_PACK_STR) == OFP_METER_BAND_EXPERIMENTER_SIZE) # enum ofp_meter_mod_command OFPMC_ADD = 0 # New meter. OFPMC_MODIFY = 1 # Modify specified meter. OFPMC_DELETE = 2 # Delete specified meter. # enum ofp_meter_flags OFPMF_KBPS = 1 << 0 # Rate value in kb/s (kilo-bit per second). OFPMF_PKTPS = 1 << 1 # Rate value in packet/sec. OFPMF_BURST = 1 << 2 # Do burst size. OFPMF_STATS = 1 << 3 # Collect statistics. # struct ofp_meter_band_header OFP_METER_BAND_HEADER_PACK_STR = '!HHII' OFP_METER_BAND_HEADER_SIZE = 12 assert (calcsize(OFP_METER_BAND_HEADER_PACK_STR) == OFP_METER_BAND_HEADER_SIZE) # struct ofp_meter_mod OFP_METER_MOD_PACK_STR = '!HHI' OFP_METER_MOD_SIZE = 16 assert (calcsize(OFP_METER_MOD_PACK_STR) + OFP_HEADER_SIZE == OFP_METER_MOD_SIZE) # enum ofp_error_type OFPET_HELLO_FAILED = 0 # Hello protocol failed. OFPET_BAD_REQUEST = 1 # Request was not understood. OFPET_BAD_ACTION = 2 # Error in action description. OFPET_BAD_INSTRUCTION = 3 # Error in instruction list. OFPET_BAD_MATCH = 4 # Error in match. OFPET_FLOW_MOD_FAILED = 5 # Problem modifying flow entry. OFPET_GROUP_MOD_FAILED = 6 # Problem modifying group entry. OFPET_PORT_MOD_FAILED = 7 # OFPT_PORT_MOD failed. OFPET_TABLE_MOD_FAILED = 8 # Table mod request failed. OFPET_QUEUE_OP_FAILED = 9 # Queue operation failed. OFPET_SWITCH_CONFIG_FAILED = 10 # Switch config request failed. OFPET_ROLE_REQUEST_FAILED = 11 # Controller Role request failed. OFPET_METER_MOD_FAILED = 12 # Error in meter. OFPET_TABLE_FEATURES_FAILED = 13 # Setting table features failed. OFPET_BAD_PROPERTY = 14 # Some property is invalid. OFPET_ASYNC_CONFIG_FAILED = 15 # Asynchronous config request failed. OFPET_FLOW_MONITOR_FAILED = 16 # Setting flow monitor failed. OFPET_BUNDLE_FAILED = 17 # Bundle operation failed. OFPET_EXPERIMENTER = 0xffff # Experimenter error messages. # enum ofp_hello_failed_code OFPHFC_INCOMPATIBLE = 0 # No compatible version. OFPHFC_EPERM = 1 # Permissions error. # enum ofp_bad_request_code OFPBRC_BAD_VERSION = 0 # ofp_header.version not supported. OFPBRC_BAD_TYPE = 1 # ofp_header.type not supported. OFPBRC_BAD_MULTIPART = 2 # ofp_multipart_request.type not # supported. OFPBRC_BAD_EXPERIMENTER = 3 # Experimenter id not supported # (in ofp_experimenter_header # or ofp_multipart_request or # ofp_multipart_reply). OFPBRC_BAD_EXP_TYPE = 4 # Experimenter type not supported. OFPBRC_EPERM = 5 # Permissions error. OFPBRC_BAD_LEN = 6 # Wrong request length for type. OFPBRC_BUFFER_EMPTY = 7 # Specified buffer has already been # used. OFPBRC_BUFFER_UNKNOWN = 8 # Specified buffer does not exist. OFPBRC_BAD_TABLE_ID = 9 # Specified table-id invalid or does # not exist. OFPBRC_IS_SLAVE = 10 # Denied because controller is slave. OFPBRC_BAD_PORT = 11 # Invalid port. OFPBRC_BAD_PACKET = 12 # Invalid packet in packet-out OFPBRC_MULTIPART_BUFFER_OVERFLOW = 13 # ofp_multipart_request # overflowed the assigned buffer. OFPBRC_MULTIPART_REQUEST_TIMEOUT = 14 # Timeout during multipart request. OFPBRC_MULTIPART_REPLY_TIMEOUT = 15 # Timeout during multipart reply. # enum ofp_bad_action_code OFPBAC_BAD_TYPE = 0 # Unknown action type. OFPBAC_BAD_LEN = 1 # Length problem in actions. OFPBAC_BAD_EXPERIMENTER = 2 # Unknown experimenter id specified. OFPBAC_BAD_EXP_TYPE = 3 # Unknown action type for experimenter id. OFPBAC_BAD_OUT_PORT = 4 # Problem validating output action. OFPBAC_BAD_ARGUMENT = 5 # Bad action argument. OFPBAC_EPERM = 6 # Permissions error. OFPBAC_TOO_MANY = 7 # Can't handle this many actions. OFPBAC_BAD_QUEUE = 8 # Problem validating output queue. OFPBAC_BAD_OUT_GROUP = 9 # Invalid group id in forward action. OFPBAC_MATCH_INCONSISTENT = 10 # Action can't apply for this match, # or Set-Field missing prerequisite. OFPBAC_UNSUPPORTED_ORDER = 11 # Action order is unsupported for # the action list in an Apply-Actions # instruction OFPBAC_BAD_TAG = 12 # Actions uses an unsupported tag/encap. OFPBAC_BAD_SET_TYPE = 13 # Unsupported type in SET_FIELD action. OFPBAC_BAD_SET_LEN = 14 # Length problem in SET_FIELD action. OFPBAC_BAD_SET_ARGUMENT = 15 # Bad arguement in SET_FIELD action. # enum ofp_bad_instruction_code OFPBIC_UNKNOWN_INST = 0 # Unknown instruction. OFPBIC_UNSUP_INST = 1 # Switch or table does not support # the instruction. OFPBIC_BAD_TABLE_ID = 2 # Invalid Table-Id specified OFPBIC_UNSUP_METADATA = 3 # Metadata value unsupported by datapath. OFPBIC_UNSUP_METADATA_MASK = 4 # Metadata mask value unsupported by # datapath. OFPBIC_BAD_EXPERIMENTER = 5 # Unknown experimenter id specified. OFPBIC_BAD_EXP_TYPE = 6 # Unknown instruction for experimenter id. OFPBIC_BAD_LEN = 7 # Length problem in instrucitons. OFPBIC_EPERM = 8 # Permissions error. OFPBIC_DUP_INST = 9 # Duplicate instruction. # enum ofp_bad_match_code OFPBMC_BAD_TYPE = 0 # Unsupported match type apecified by # the match. OFPBMC_BAD_LEN = 1 # Length problem in math. OFPBMC_BAD_TAG = 2 # Match uses an unsupported tag/encap. OFPBMC_BAD_DL_ADDR_MASK = 3 # Unsupported datalink addr mask - # switch does not support arbitrary # datalink address mask. OFPBMC_BAD_NW_ADDR_MASK = 4 # Unsupported network addr mask - # switch does not support arbitrary # network addres mask. OFPBMC_BAD_WILDCARDS = 5 # Unsupported combination of fields # masked or omitted in the match. OFPBMC_BAD_FIELD = 6 # Unsupported field type in the match. OFPBMC_BAD_VALUE = 7 # Unsupported value in a match field. OFPBMC_BAD_MASK = 8 # Unsupported mask specified in the # match. OFPBMC_BAD_PREREQ = 9 # A prerequisite was not met. OFPBMC_DUP_FIELD = 10 # A field type was duplicated. OFPBMC_EPERM = 11 # Permissions error. # enum ofp_flow_mod_failed_code OFPFMFC_UNKNOWN = 0 # Unspecified error. OFPFMFC_TABLE_FULL = 1 # Flow not added because table was full. OFPFMFC_BAD_TABLE_ID = 2 # Table does not exist OFPFMFC_OVERLAP = 3 # Attempted to add overlapping flow with # CHECK_OVERLAP flag set. OFPFMFC_EPERM = 4 # Permissions error. OFPFMFC_BAD_TIMEOUT = 5 # Flow not added because of unsupported # idle/hard timeout. OFPFMFC_BAD_COMMAND = 6 # Unsupported or unknown command. OFPFMFC_BAD_FLAGS = 7 # Unsupported or unknown flags. OFPFMFC_CANT_SYNC = 8 # Problem in table synchronisation. OFPFMFC_BAD_PRIORITY = 9 # Unsupported priority value. # enum ofp_group_mod_failed_code OFPGMFC_GROUP_EXISTS = 0 # Group not added because a group ADD # attempted to replace an already-present # group. OFPGMFC_INVALID_GROUP = 1 # Group not added because Group specified # is invalid. OFPGMFC_WEIGHT_UNSUPPORTED = 2 # Switch does not support unequal load # sharing with select groups. OFPGMFC_OUT_OF_GROUPS = 3 # The group table is full. OFPGMFC_OUT_OF_BUCKETS = 4 # The maximum number of action buckets # for a group has been exceeded. OFPGMFC_CHAINING_UNSUPPORTED = 5 # Switch does not support groups that # forward to groups. OFPGMFC_WATCH_UNSUPPORTED = 6 # This group cannot watch the # watch_port or watch_group specified. OFPGMFC_LOOP = 7 # Group entry would cause a loop. OFPGMFC_UNKNOWN_GROUP = 8 # Group not modified because a group MODIFY # attempted to modify a non-existent group. OFPGMFC_CHAINED_GROUP = 9 # Group not deleted because another group # is forwarding to it. OFPGMFC_BAD_TYPE = 10 # Unsupported or unknown group type. OFPGMFC_BAD_COMMAND = 11 # Unsupported or unknown command. OFPGMFC_BAD_BUCKET = 12 # Error in bucket. OFPGMFC_BAD_WATCH = 13 # Error in watch port/group. OFPGMFC_EPERM = 14 # Permissions error. # enum ofp_port_mod_failed_code OFPPMFC_BAD_PORT = 0 # Specified port does not exist. OFPPMFC_BAD_HW_ADDR = 1 # Specified hardware address does not match # the port number. OFPPMFC_BAD_CONFIG = 2 # Specified config is invalid. OFPPMFC_BAD_ADVERTISE = 3 # Specified advertise is invalid. OFPPMFC_EPERM = 4 # Permissions error. # enum ofp_table_mod_failed_code OFPTMFC_BAD_TABLE = 0 # Specified table does not exist. OFPTMFC_BAD_CONFIG = 1 # Specified config is invalid. OFPTMFC_EPERM = 2 # Permissions error # enum ofp_queue_op_failed_code OFPQOFC_BAD_PORT = 0 # Invalid port (or port does not exist). OFPQOFC_BAD_QUEUE = 1 # Queue does not exist. OFPQOFC_EPERM = 2 # Permissions error. # enum ofp_switch_config_failed_code OFPSCFC_BAD_FLAGS = 0 # Specified flags is invalid. OFPSCFC_BAD_LEN = 1 # Specified len is invalid. OFPSCFC_EPERM = 2 # Permissions error. # enum ofp_role_request_failed_code OFPRRFC_STALE = 0 # Stale Message: old generation_id. OFPRRFC_UNSUP = 1 # Controller role change unsupported. OFPRRFC_BAD_ROLE = 2 # Invalid role. # enum ofp_meter_mod_failed_code OFPMMFC_UNKNOWN = 0 # Unspecified error. OFPMMFC_METER_EXISTS = 1 # Meter not added because a Meter ADD # attempted to replace an existing Meter. OFPMMFC_INVALID_METER = 2 # Meter not added because Meter specified # is invalid. OFPMMFC_UNKNOWN_METER = 3 # Meter not modified because a Meter MODIFY # attempted to modify a non-existent Meter. OFPMMFC_BAD_COMMAND = 4 # Unsupported or unknown command. OFPMMFC_BAD_FLAGS = 5 # Flag configuration unsupported. OFPMMFC_BAD_RATE = 6 # Rate unsupported. OFPMMFC_BAD_BURST = 7 # Burst size unsupported. OFPMMFC_BAD_BAND = 8 # Band unsupported. OFPMMFC_BAD_BAND_VALUE = 9 # Band value unsupported. OFPMMFC_OUT_OF_METERS = 10 # No more meters availabile. OFPMMFC_OUT_OF_BANDS = 11 # The maximum number of properties for a # meter has been exceeded. # enum ofp_table_features_failed_code OFPTFFC_BAD_TABLE = 0 # Specified table does not exist. OFPTFFC_BAD_METADATA = 1 # Invalid metadata mask. OFPTFFC_EPERM = 5 # Permissions error. # enum ofp_bad_property_code OFPBPC_BAD_TYPE = 0 # Unknown property type. OFPBPC_BAD_LEN = 1 # Length problem in property. OFPBPC_BAD_VALUE = 2 # Unsupported property value. OFPBPC_TOO_MANY = 3 # Can't handle this many properties. OFPBPC_DUP_TYPE = 4 # A property type was duplicated. OFPBPC_BAD_EXPERIMENTER = 5 # Unknown experimenter id specified. OFPBPC_BAD_EXP_TYPE = 6 # Unknown exp_type for experimenter id. OFPBPC_BAD_EXP_VALUE = 7 # Unknown value for experimenter id. OFPBPC_EPERM = 8 # Permissions error. # enum ofp_async_config_failed_code OFPACFC_INVALID = 0 # One mask is invalid. OFPACFC_UNSUPPORTED = 1 # Requested configuration not supported. OFPACFC_EPERM = 2 # Permissions error. # enum ofp_flow_monitor_failed_code OFPMOFC_UNKNOWN = 0 # Unspecified error. OFPMOFC_MONITOR_EXISTS = 1 # Monitor not added because a Monitor ADD # attempted to replace an existing # Monitor. OFPMOFC_INVALID_MONITOR = 2 # Monitor not added because Monitor # specified is invalid. OFPMOFC_UNKNOWN_MONITOR = 3 # Monitor not modified because a Monitor # MODIFY attempted to modify a non-existent # Monitor. OFPMOFC_BAD_COMMAND = 4 # Unsupported or unknown command. OFPMOFC_BAD_FLAGS = 5 # Flag configuration unsupported. OFPMOFC_BAD_TABLE_ID = 6 # Specified table does not exist. OFPMOFC_BAD_OUT = 7 # Error in output port/group. # enum ofp_bundle_failed_code OFPBFC_UNKNOWN = 0 # Unspecified error. OFPBFC_EPERM = 1 # Permissions error. OFPBFC_BAD_ID = 2 # Bundle ID doesn't exist. OFPBFC_BUNDLE_EXIST = 3 # Bundle ID already exist. OFPBFC_BUNDLE_CLOSED = 4 # Bundle ID is closed. OFPBFC_OUT_OF_BUNDLES = 5 # Too many bundles IDs. OFPBFC_BAD_TYPE = 6 # Unsupported or unknown message control type. OFPBFC_BAD_FLAGS = 7 # Unsupported, unknown, or inconsistent flags. OFPBFC_MSG_BAD_LEN = 8 # Length problem in included message. OFPBFC_MSG_BAD_XID = 9 # Inconsistent or duplicate XID. OFPBFC_MSG_UNSUP = 10 # Unsupported message in this bundle. OFPBFC_MSG_CONFLICT = 11 # Unsupported message combination in this # bundle. OFPBFC_MSG_TOO_MANY = 12 # Can't handle this many messages in bundle. OFPBFC_MSG_FAILED = 13 # One message in bundle failed. OFPBFC_TIMEOUT = 14 # Bundle is taking too long. OFPBFC_BUNDLE_IN_PROGRESS = 15 # Bundle is locking the resource. # struct ofp_error_msg OFP_ERROR_MSG_PACK_STR = '!HH' OFP_ERROR_MSG_SIZE = 12 assert (calcsize(OFP_ERROR_MSG_PACK_STR) + OFP_HEADER_SIZE == OFP_ERROR_MSG_SIZE) # struct ofp_error_experimenter_msg OFP_ERROR_EXPERIMENTER_MSG_PACK_STR = '!HHI' OFP_ERROR_EXPERIMENTER_MSG_SIZE = 16 assert (calcsize(OFP_ERROR_EXPERIMENTER_MSG_PACK_STR) + OFP_HEADER_SIZE) == OFP_ERROR_EXPERIMENTER_MSG_SIZE # struct ofp_experimenter_header OFP_EXPERIMENTER_HEADER_PACK_STR = '!II' OFP_EXPERIMENTER_HEADER_SIZE = 16 assert (calcsize(OFP_EXPERIMENTER_HEADER_PACK_STR) + OFP_HEADER_SIZE == OFP_EXPERIMENTER_HEADER_SIZE) # enum ofp_multipart_type OFPMP_DESC = 0 OFPMP_FLOW = 1 OFPMP_AGGREGATE = 2 OFPMP_TABLE = 3 OFPMP_PORT_STATS = 4 OFPMP_QUEUE_STATS = 5 OFPMP_GROUP = 6 OFPMP_GROUP_DESC = 7 OFPMP_GROUP_FEATURES = 8 OFPMP_METER = 9 OFPMP_METER_CONFIG = 10 OFPMP_METER_FEATURES = 11 OFPMP_TABLE_FEATURES = 12 OFPMP_PORT_DESC = 13 OFPMP_TABLE_DESC = 14 OFPMP_QUEUE_DESC = 15 OFPMP_FLOW_MONITOR = 16 OFPMP_EXPERIMENTER = 0xffff # struct ofp_multipart_request OFP_MULTIPART_REQUEST_PACK_STR = '!HH4x' OFP_MULTIPART_REQUEST_SIZE = 16 assert (calcsize(OFP_MULTIPART_REQUEST_PACK_STR) + OFP_HEADER_SIZE == OFP_MULTIPART_REQUEST_SIZE) # enum ofp_multipart_reply_flags OFPMPF_REPLY_MORE = 1 << 0 # More requests to follow. # struct ofp_multipart_reply OFP_MULTIPART_REPLY_PACK_STR = '!HH4x' OFP_MULTIPART_REPLY_SIZE = 16 assert (calcsize(OFP_MULTIPART_REPLY_PACK_STR) + OFP_HEADER_SIZE == OFP_MULTIPART_REPLY_SIZE) DESC_STR_LEN = 256 DESC_STR_LEN_STR = str(DESC_STR_LEN) SERIAL_NUM_LEN = 32 SERIAL_NUM_LEN_STR = str(SERIAL_NUM_LEN) OFP_DESC_PACK_STR = '!' + \ DESC_STR_LEN_STR + 's' + \ DESC_STR_LEN_STR + 's' + \ DESC_STR_LEN_STR + 's' + \ SERIAL_NUM_LEN_STR + 's' + \ DESC_STR_LEN_STR + 's' OFP_DESC_SIZE = 1056 assert calcsize(OFP_DESC_PACK_STR) == OFP_DESC_SIZE # struct ofp_flow_stats_request _OFP_FLOW_STATS_REQUEST_0_PACK_STR = 'B3xII4xQQ' OFP_FLOW_STATS_REQUEST_0_PACK_STR = '!' + _OFP_FLOW_STATS_REQUEST_0_PACK_STR OFP_FLOW_STATS_REQUEST_0_SIZE = 32 assert (calcsize(OFP_FLOW_STATS_REQUEST_0_PACK_STR) == OFP_FLOW_STATS_REQUEST_0_SIZE) OFP_FLOW_STATS_REQUEST_PACK_STR = (OFP_FLOW_STATS_REQUEST_0_PACK_STR + _OFP_MATCH_PACK_STR) OFP_FLOW_STATS_REQUEST_SIZE = 40 assert (calcsize(OFP_FLOW_STATS_REQUEST_PACK_STR) == OFP_FLOW_STATS_REQUEST_SIZE) # struct ofp_flow_stats _OFP_FLOW_STATS_0_PACK_STR = 'HBxIIHHHHH2xQQQ' OFP_FLOW_STATS_0_PACK_STR = '!' + _OFP_FLOW_STATS_0_PACK_STR OFP_FLOW_STATS_0_SIZE = 48 assert calcsize(OFP_FLOW_STATS_0_PACK_STR) == OFP_FLOW_STATS_0_SIZE OFP_FLOW_STATS_PACK_STR = (OFP_FLOW_STATS_0_PACK_STR + _OFP_MATCH_PACK_STR) OFP_FLOW_STATS_SIZE = 56 assert calcsize(OFP_FLOW_STATS_PACK_STR) == OFP_FLOW_STATS_SIZE # struct ofp_aggregate_stats_request OFP_AGGREGATE_STATS_REQUEST_PACK_STR = '!B3xII4xQQ' + _OFP_MATCH_PACK_STR OFP_AGGREGATE_STATS_REQUEST_SIZE = 40 assert (calcsize(OFP_AGGREGATE_STATS_REQUEST_PACK_STR) == OFP_AGGREGATE_STATS_REQUEST_SIZE) # struct ofp_aggregate_stats_reply OFP_AGGREGATE_STATS_REPLY_PACK_STR = '!QQI4x' OFP_AGGREGATE_STATS_REPLY_SIZE = 24 assert (calcsize(OFP_AGGREGATE_STATS_REPLY_PACK_STR) == OFP_AGGREGATE_STATS_REPLY_SIZE) # enum ofp_table_feature_prop_type OFPTFPT_INSTRUCTIONS = 0 OFPTFPT_INSTRUCTIONS_MISS = 1 OFPTFPT_NEXT_TABLES = 2 OFPTFPT_NEXT_TABLES_MISS = 3 OFPTFPT_WRITE_ACTIONS = 4 OFPTFPT_WRITE_ACTIONS_MISS = 5 OFPTFPT_APPLY_ACTIONS = 6 OFPTFPT_APPLY_ACTIONS_MISS = 7 OFPTFPT_MATCH = 8 OFPTFPT_WILDCARDS = 10 OFPTFPT_WRITE_SETFIELD = 12 OFPTFPT_WRITE_SETFIELD_MISS = 13 OFPTFPT_APPLY_SETFIELD = 14 OFPTFPT_APPLY_SETFIELD_MISS = 15 OFPTFPT_TABLE_SYNC_FROM = 16 OFPTFPT_EXPERIMENTER = 0xFFFE OFPTFPT_EXPERIMENTER_MISS = 0xFFFF # struct ofp_instruction_id OFP_INSTRUCTION_ID_PACK_STR = '!HH' OFP_INSTRUCTION_ID_SIZE = 4 assert calcsize(OFP_INSTRUCTION_ID_PACK_STR) == OFP_INSTRUCTION_ID_SIZE # struct ofp_table_feature_prop_instructions OFP_TABLE_FEATURE_PROP_INSTRUCTIONS_PACK_STR = '!HH' OFP_TABLE_FEATURE_PROP_INSTRUCTIONS_SIZE = 4 assert (calcsize(OFP_TABLE_FEATURE_PROP_INSTRUCTIONS_PACK_STR) == OFP_TABLE_FEATURE_PROP_INSTRUCTIONS_SIZE) # struct ofp_table_feature_prop_actions OFP_TABLE_FEATURE_PROP_ACTIONS_PACK_STR = '!HH' OFP_TABLE_FEATURE_PROP_ACTIONS_SIZE = 4 assert (calcsize(OFP_TABLE_FEATURE_PROP_ACTIONS_PACK_STR) == OFP_TABLE_FEATURE_PROP_ACTIONS_SIZE) # struct ofp_table_feature_prop_oxm OFP_TABLE_FEATURE_PROP_OXM_PACK_STR = '!HH' OFP_TABLE_FEATURE_PROP_OXM_SIZE = 4 assert (calcsize(OFP_TABLE_FEATURE_PROP_OXM_PACK_STR) == OFP_TABLE_FEATURE_PROP_OXM_SIZE) # struct ofp_table_feature_prop_experimenter OFP_TABLE_FEATURE_PROP_EXPERIMENTER_PACK_STR = '!HHII' OFP_TABLE_FEATURE_PROP_EXPERIMENTER_SIZE = 12 assert (calcsize(OFP_TABLE_FEATURE_PROP_EXPERIMENTER_PACK_STR) == OFP_TABLE_FEATURE_PROP_EXPERIMENTER_SIZE) # struct ofp_table_features OFP_MAX_TABLE_NAME_LEN = 32 OFP_MAX_TABLE_NAME_LEN_STR = str(OFP_MAX_TABLE_NAME_LEN) OFP_TABLE_FEATURES_PACK_STR = '!HB5x' + OFP_MAX_TABLE_NAME_LEN_STR + \ 's' + 'QQII' OFP_TABLE_FEATURES_SIZE = 64 assert (calcsize(OFP_TABLE_FEATURES_PACK_STR) == OFP_TABLE_FEATURES_SIZE) # struct ofp_table_stats OFP_TABLE_STATS_PACK_STR = '!B3xIQQ' OFP_TABLE_STATS_SIZE = 24 assert calcsize(OFP_TABLE_STATS_PACK_STR) == OFP_TABLE_STATS_SIZE # struct ofp_table_desc _OFP_TABLE_DESC_PACK_STR = 'HBxI' OFP_TABLE_DESC_PACK_STR = '!' + _OFP_TABLE_DESC_PACK_STR OFP_TABLE_DESC_SIZE = 8 assert calcsize(OFP_TABLE_DESC_PACK_STR) == OFP_TABLE_DESC_SIZE # struct ofp_port_stats_request OFP_PORT_STATS_REQUEST_PACK_STR = '!I4x' OFP_PORT_STATS_REQUEST_SIZE = 8 assert (calcsize(OFP_PORT_STATS_REQUEST_PACK_STR) == OFP_PORT_STATS_REQUEST_SIZE) # enum ofp_port_stats_prop_type OFPPSPT_ETHERNET = 0 # Ethernet property. OFPPSPT_OPTICAL = 1 # Optical property. OFPPSPT_EXPERIMENTER = 0xFFFF # Experimenter property. # struct ofp_port_stats_prop_ethernet OFP_PORT_STATS_PROP_ETHERNET_PACK_STR = '!HH4xQQQQ' OFP_PORT_STATS_PROP_ETHERNET_SIZE = 40 assert (calcsize(OFP_PORT_STATS_PROP_ETHERNET_PACK_STR) == OFP_PORT_STATS_PROP_ETHERNET_SIZE) # struct ofp_port_stats_prop_optical OFP_PORT_STATS_PROP_OPTICAL_PACK_STR = '!HH4xIIIIIIIHHHH' OFP_PORT_STATS_PROP_OPTICAL_SIZE = 44 assert (calcsize(OFP_PORT_STATS_PROP_OPTICAL_PACK_STR) == OFP_PORT_STATS_PROP_OPTICAL_SIZE) # enum ofp_port_stats_optical_flags OFPOSF_RX_TUNE = 1 << 0 # Receiver tune info valid OFPOSF_TX_TUNE = 1 << 1 # Transmit tune info valid OFPOSF_TX_PWR = 1 << 2 # TX Power is valid OFPOSF_RX_PWR = 1 << 4 # RX power is valid OFPOSF_TX_BIAS = 1 << 5 # Transmit bias is valid OFPOSF_TX_TEMP = 1 << 6 # TX Temp is valid # struct ofp_port_stats_prop_experimenter OFP_PORT_STATS_PROP_EXPERIMENTER_PACK_STR = '!HHII' OFP_PORT_STATS_PROP_EXPERIMENTER_SIZE = 12 assert (calcsize(OFP_PORT_STATS_PROP_EXPERIMENTER_PACK_STR) == OFP_PORT_STATS_PROP_EXPERIMENTER_SIZE) # struct ofp_port_stats OFP_PORT_STATS_PACK_STR = '!H2xIIIQQQQQQQQ' OFP_PORT_STATS_SIZE = 80 assert calcsize(OFP_PORT_STATS_PACK_STR) == OFP_PORT_STATS_SIZE # struct ofp_group_stats_request OFP_GROUP_STATS_REQUEST_PACK_STR = '!I4x' OFP_GROUP_STATS_REQUEST_SIZE = 8 assert (calcsize(OFP_GROUP_STATS_REQUEST_PACK_STR) == OFP_GROUP_STATS_REQUEST_SIZE) # struct ofp_bucket_counter OFP_BUCKET_COUNTER_PACK_STR = '!QQ' OFP_BUCKET_COUNTER_SIZE = 16 assert calcsize(OFP_BUCKET_COUNTER_PACK_STR) == OFP_BUCKET_COUNTER_SIZE # struct ofp_group_stats OFP_GROUP_STATS_PACK_STR = '!H2xII4xQQII' OFP_GROUP_STATS_SIZE = 40 assert calcsize(OFP_GROUP_STATS_PACK_STR) == OFP_GROUP_STATS_SIZE # struct ofp_group_desc OFP_GROUP_DESC_PACK_STR = '!HBxI' OFP_GROUP_DESC_SIZE = 8 assert calcsize(OFP_GROUP_DESC_PACK_STR) == OFP_GROUP_DESC_SIZE # struct ofp_group_desc_stats # Backward compatibility with 1.3.1 - avoid breaking the API. OFP_GROUP_DESC_STATS_PACK_STR = OFP_GROUP_DESC_PACK_STR OFP_GROUP_DESC_STATS_SIZE = OFP_GROUP_DESC_SIZE assert calcsize(OFP_GROUP_DESC_STATS_PACK_STR) == OFP_GROUP_DESC_STATS_SIZE # enum ofp_group_capabilities OFPGFC_SELECT_WEIGHT = 1 << 0 # Support weight for select groups. OFPGFC_SELECT_LIVENESS = 1 << 1 # Support liveness for select groups. OFPGFC_CHAINING = 1 << 2 # Support chaining groups. OFPGFC_CHAINING_CHECKS = 1 << 3 # Check chaining for loops and delete # struct ofp_group_features OFP_GROUP_FEATURES_PACK_STR = '!II4I4I' OFP_GROUP_FEATURES_SIZE = 40 assert calcsize(OFP_GROUP_FEATURES_PACK_STR) == OFP_GROUP_FEATURES_SIZE # struct ofp_meter_multipart_request OFP_METER_MULTIPART_REQUEST_PACK_STR = '!I4x' OFP_METER_MULTIPART_REQUEST_SIZE = 8 assert (calcsize(OFP_METER_MULTIPART_REQUEST_PACK_STR) == OFP_METER_MULTIPART_REQUEST_SIZE) # struct ofp_meter_stats OFP_METER_STATS_PACK_STR = '!IH6xIQQII' OFP_METER_STATS_SIZE = 40 assert calcsize(OFP_METER_STATS_PACK_STR) == OFP_METER_STATS_SIZE # struct ofp_meter_band_stats OFP_METER_BAND_STATS_PACK_STR = '!QQ' OFP_METER_BAND_STATS_SIZE = 16 assert (calcsize(OFP_METER_BAND_STATS_PACK_STR) == OFP_METER_BAND_STATS_SIZE) # struct ofp_meter_config OFP_METER_CONFIG_PACK_STR = '!HHI' OFP_METER_CONFIG_SIZE = 8 assert calcsize(OFP_METER_CONFIG_PACK_STR) == OFP_METER_CONFIG_SIZE # struct ofp_meter_features OFP_METER_FEATURES_PACK_STR = '!IIIBB2x' OFP_METER_FEATURES_SIZE = 16 assert (calcsize(OFP_METER_FEATURES_PACK_STR) == OFP_METER_FEATURES_SIZE) # All ones is used to indicate all queues in a port (for stats retrieval). OFPQ_ALL = 0xffffffff # Min rate > 1000 means not configured. OFPQ_MIN_RATE_UNCFG = 0xffff # Max rate > 1000 means not configured. OFPQ_MAX_RATE_UNCFG = 0xffff # enum ofp_queue_desc_prop_type OFPQDPT_MIN_RATE = 1 # Minimum datarate guaranteed. OFPQDPT_MAX_RATE = 2 # Maximum datarate. OFPQDPT_EXPERIMENTER = 0xffff # Experimenter defined property. # struct ofp_queue_desc_prop_min_rate OFP_QUEUE_DESC_PROP_MIN_RATE_PACK_STR = '!HHH2x' OFP_QUEUE_DESC_PROP_MIN_RATE_SIZE = 8 assert (calcsize(OFP_QUEUE_DESC_PROP_MIN_RATE_PACK_STR) == OFP_QUEUE_DESC_PROP_MIN_RATE_SIZE) # ofp_queue_desc_prop_max_rate OFP_QUEUE_DESC_PROP_MAX_RATE_PACK_STR = '!HHH2x' OFP_QUEUE_DESC_PROP_MAX_RATE_SIZE = 8 assert (calcsize(OFP_QUEUE_DESC_PROP_MAX_RATE_PACK_STR) == OFP_QUEUE_DESC_PROP_MAX_RATE_SIZE) # struct ofp_queue_desc_prop_experimenter OFP_QUEUE_DESC_PROP_EXPERIMENTER_PACK_STR = '!HHII' OFP_QUEUE_DESC_PROP_EXPERIMENTER_SIZE = 12 assert (calcsize(OFP_QUEUE_DESC_PROP_EXPERIMENTER_PACK_STR) == OFP_QUEUE_DESC_PROP_EXPERIMENTER_SIZE) # struct ofp_queue_desc_request OFP_QUEUE_DESC_REQUEST_PACK_STR = '!II' OFP_QUEUE_DESC_REQUEST_SIZE = 8 assert (calcsize(OFP_QUEUE_DESC_REQUEST_PACK_STR) == OFP_QUEUE_DESC_REQUEST_SIZE) # struct ofp_queue_desc OFP_QUEUE_DESC_PACK_STR = '!IIH6x' OFP_QUEUE_DESC_SIZE = 16 assert calcsize(OFP_QUEUE_DESC_PACK_STR) == OFP_QUEUE_DESC_SIZE # struct ofp_queue_stats_request OFP_QUEUE_STATS_REQUEST_PACK_STR = '!II' OFP_QUEUE_STATS_REQUEST_SIZE = 8 assert (calcsize(OFP_QUEUE_STATS_REQUEST_PACK_STR) == OFP_QUEUE_STATS_REQUEST_SIZE) # enum ofp_queue_stats_prop_type OFPQSPT_EXPERIMENTER = 0xffff # Experimenter defined property. # struct ofp_queue_stats_prop_experimenter OFP_QUEUE_STATS_PROP_EXPERIMENTER_PACK_STR = '!HHII' OFP_QUEUE_STATS_PROP_EXPERIMENTER_SIZE = 12 assert (calcsize(OFP_QUEUE_STATS_PROP_EXPERIMENTER_PACK_STR) == OFP_QUEUE_STATS_PROP_EXPERIMENTER_SIZE) # struct ofp_queue_stats OFP_QUEUE_STATS_PACK_STR = '!H6xIIQQQII' OFP_QUEUE_STATS_SIZE = 48 assert calcsize(OFP_QUEUE_STATS_PACK_STR) == OFP_QUEUE_STATS_SIZE # struct ofp_flow_monitor_request _OFP_FLOW_MONITOR_REQUEST_0_PACK_STR = 'IIIHBB' OFP_FLOW_MONITOR_REQUEST_0_PACK_STR = ('!' + _OFP_FLOW_MONITOR_REQUEST_0_PACK_STR) OFP_FLOW_MONITOR_REQUEST_0_SIZE = 16 OFP_FLOW_MONITOR_REQUEST_PACK_STR = (OFP_FLOW_MONITOR_REQUEST_0_PACK_STR + _OFP_MATCH_PACK_STR) OFP_FLOW_MONITOR_REQUEST_SIZE = 24 assert (calcsize(OFP_FLOW_MONITOR_REQUEST_PACK_STR) == OFP_FLOW_MONITOR_REQUEST_SIZE) # enum ofp_flow_monitor_command OFPFMC_ADD = 0 # New flow monitor. OFPFMC_MODIFY = 1 # Modify existing flow monitor. OFPFMC_DELETE = 2 # Delete/cancel existing flow monitor. # enum ofp_flow_monitor_flags # When to send updates. OFPFMF_INITIAL = 1 << 0 # Initially matching flows. OFPFMF_ADD = 1 << 1 # New matching flows as they are added. OFPFMF_REMOVED = 1 << 2 # Old matching flows as they are removed. OFPFMF_MODIFY = 1 << 3 # Matching flows as they are changed. # What to include in updates. OFPFMF_INSTRUCTIONS = 1 << 4 # If set, instructions are included. OFPFMF_NO_ABBREV = 1 << 5 # If set, include own changes in full. OFPFMF_ONLY_OWN = 1 << 6 # If set, don't include other controllers. # struct ofp_flow_update_header OFP_FLOW_UPDATE_HEADER_PACK_STR = '!HH' OFP_FLOW_UPDATE_HEADER_SIZE = 4 assert (calcsize(OFP_FLOW_UPDATE_HEADER_PACK_STR) == OFP_FLOW_UPDATE_HEADER_SIZE) # enum ofp_flow_update_event # struct ofp_flow_update_full. OFPFME_INITIAL = 0 # Flow present when flow monitor created. OFPFME_ADDED = 1 # Flow was added. OFPFME_REMOVED = 2 # Flow was removed. OFPFME_MODIFIED = 3 # Flow instructions were changed. # struct ofp_flow_update_abbrev. OFPFME_ABBREV = 4 # Abbreviated reply. # struct ofp_flow_update_header. OFPFME_PAUSED = 5 # Monitoring paused (out of buffer space). OFPFME_RESUMED = 6 # Monitoring resumed. # struct ofp_flow_update_full _OFP_FLOW_UPDATE_FULL_0_PACK_STR = 'HHBBHHH4xQ' OFP_FLOW_UPDATE_FULL_0_PACK_STR = '!' + _OFP_FLOW_UPDATE_FULL_0_PACK_STR OFP_FLOW_UPDATE_FULL_0_SIZE = 24 OFP_FLOW_UPDATE_FULL_PACK_STR = (OFP_FLOW_UPDATE_FULL_0_PACK_STR + _OFP_MATCH_PACK_STR) OFP_FLOW_UPDATE_FULL_SIZE = 32 assert (calcsize(OFP_FLOW_UPDATE_FULL_PACK_STR) == OFP_FLOW_UPDATE_FULL_SIZE) # struct ofp_flow_update_abbrev OFP_FLOW_UPDATE_ABBREV_PACK_STR = '!HHI' OFP_FLOW_UPDATE_ABBREV_SIZE = 8 assert (calcsize(OFP_FLOW_UPDATE_ABBREV_PACK_STR) == OFP_FLOW_UPDATE_ABBREV_SIZE) # struct ofp_flow_update_paused OFP_FLOW_UPDATE_PAUSED_PACK_STR = '!HH4x' OFP_FLOW_UPDATE_PAUSED_SIZE = 8 assert (calcsize(OFP_FLOW_UPDATE_PAUSED_PACK_STR) == OFP_FLOW_UPDATE_PAUSED_SIZE) # struct ofp_experimenter_multipart_header OFP_EXPERIMENTER_MULTIPART_HEADER_PACK_STR = '!II' OFP_EXPERIMENTER_MULTIPART_HEADER_SIZE = 8 assert (calcsize(OFP_EXPERIMENTER_MULTIPART_HEADER_PACK_STR) == OFP_EXPERIMENTER_MULTIPART_HEADER_SIZE) # struct ofp_experimenter_structure OFP_EXPERIMENTER_STRUCTURE_PACK_STR = '!II' OFP_EXPERIMENTER_STRUCTURE_SIZE = 8 assert (calcsize(OFP_EXPERIMENTER_STRUCTURE_PACK_STR) == OFP_EXPERIMENTER_STRUCTURE_SIZE) # struct ofp_error_experimenter_msg OFP_ERROR_EXPERIMENTER_MSG_PACK_STR = '!HHI' OFP_ERROR_EXPERIMENTER_MSG_SIZE = 16 assert (calcsize(OFP_ERROR_EXPERIMENTER_MSG_PACK_STR) + OFP_HEADER_SIZE) == OFP_ERROR_EXPERIMENTER_MSG_SIZE # enum ofp_controller_role OFPCR_ROLE_NOCHANGE = 0 # Don't change current role. OFPCR_ROLE_EQUAL = 1 # Default role, full access. OFPCR_ROLE_MASTER = 2 # Full access, at most one master. OFPCR_ROLE_SLAVE = 3 # Read-only access. # struct ofp_role_request OFP_ROLE_REQUEST_PACK_STR = '!I4xQ' OFP_ROLE_REQUEST_SIZE = 24 assert (calcsize(OFP_ROLE_REQUEST_PACK_STR) + OFP_HEADER_SIZE == OFP_ROLE_REQUEST_SIZE) # enum ofp_role_prop_type OFPRPT_EXPERIMENTER = 0xFFFF # Experimenter property. # struct ofp_role_prop_experimenter OFP_ROLE_PROP_EXPERIMENTER_PACK_STR = '!HHII' OFP_ROLE_PROP_EXPERIMENTER_SIZE = 12 assert (calcsize(OFP_ROLE_PROP_EXPERIMENTER_PACK_STR) == OFP_ROLE_PROP_EXPERIMENTER_SIZE) # enum ofp_controller_role_reason OFPCRR_MASTER_REQUEST = 0 # Another controller asked to be master. OFPCRR_CONFIG = 1 # Configuration changed on the switch. OFPCRR_EXPERIMENTER = 2 # Experimenter data changed. # struct ofp_role_status OFP_ROLE_STATUS_PACK_STR = '!IB3xQ' OFP_ROLE_STATUS_SIZE = 24 assert (calcsize(OFP_ROLE_STATUS_PACK_STR) + OFP_HEADER_SIZE == OFP_ROLE_STATUS_SIZE) # enum ofp_async_config_prop_type OFPACPT_PACKET_IN_SLAVE = 0 # Packet-in mask for slave. OFPACPT_PACKET_IN_MASTER = 1 # Packet-in mask for master. OFPACPT_PORT_STATUS_SLAVE = 2 # Port-status mask for slave. OFPACPT_PORT_STATUS_MASTER = 3 # Port-status mask for master. OFPACPT_FLOW_REMOVED_SLAVE = 4 # Flow removed mask for slave. OFPACPT_FLOW_REMOVED_MASTER = 5 # Flow removed mask for master. OFPACPT_ROLE_STATUS_SLAVE = 6 # Role status mask for slave. OFPACPT_ROLE_STATUS_MASTER = 7 # Role status mask for master. OFPACPT_TABLE_STATUS_SLAVE = 8 # Table status mask for slave. OFPACPT_TABLE_STATUS_MASTER = 9 # Table status mask for master. OFPACPT_REQUESTFORWARD_SLAVE = 10 # RequestForward mask for slave. OFPACPT_REQUESTFORWARD_MASTER = 11 # RequestForward mask for master. OFPTFPT_EXPERIMENTER_SLAVE = 0xFFFE # Experimenter for slave (depracated). OFPTFPT_EXPERIMENTER_MASTER = 0xFFFF # Experimenter for master (depracated). # New or updated OSKen applications shall use # OFPACPT_EXPERIMENTER_SLAVE and OFPACPT_EXPERIMENTER_MASTER. # The variable name is a typo of in specifications before v1.5.0. OFPACPT_EXPERIMENTER_SLAVE = 0xFFFE # Experimenter for slave. OFPACPT_EXPERIMENTER_MASTER = 0xFFFF # Experimenter for master. # Backporting from ofproto_v1_5 for consistency with # later OF specs. # struct ofp_async_config_prop_reasons OFP_ASYNC_CONFIG_PROP_REASONS_PACK_STR = '!HHI' OFP_ASYNC_CONFIG_PROP_REASONS_SIZE = 8 assert (calcsize(OFP_ASYNC_CONFIG_PROP_REASONS_PACK_STR) == OFP_ASYNC_CONFIG_PROP_REASONS_SIZE) # struct ofp_async_config_prop_experimenter OFP_ASYNC_CONFIG_PROP_EXPERIMENTER_PACK_STR = '!HHII' OFP_ASYNC_CONFIG_PROP_EXPERIMENTER_SIZE = 12 assert (calcsize(OFP_ASYNC_CONFIG_PROP_EXPERIMENTER_PACK_STR) == OFP_ASYNC_CONFIG_PROP_EXPERIMENTER_SIZE) # enum ofp_table_reason OFPTR_VACANCY_DOWN = 3 # Vacancy down threshold event. OFPTR_VACANCY_UP = 4 # Vacancy up threshold event. # struct ofp_table_status _OFP_TABLE_STATUS_0_PACK_STR = 'B7x' OFP_TABLE_STATUS_0_PACK_STR = '!' + _OFP_TABLE_STATUS_0_PACK_STR OFP_TABLE_STATUS_0_SIZE = 16 OFP_TABLE_STATUS_PACK_STR = (OFP_TABLE_STATUS_0_PACK_STR + _OFP_TABLE_DESC_PACK_STR) OFP_TABLE_STATUS_SIZE = 24 assert (calcsize(OFP_TABLE_STATUS_PACK_STR) + OFP_HEADER_SIZE == OFP_TABLE_STATUS_SIZE) # enum ofp_requestforward_reason OFPRFR_GROUP_MOD = 0 # Forward group mod requests. OFPRFR_METER_MOD = 1 # Forward meter mod requests. # enum ofp_bundle_prop_type OFPBPT_EXPERIMENTER = 0xFFFF # Experimenter property. # struct ofp_bundle_prop_experimenter OFP_BUNDLE_PROP_EXPERIMENTER_PACK_STR = '!HHII' OFP_BUNDLE_PROP_EXPERIMENTER_SIZE = 12 assert (calcsize(OFP_BUNDLE_PROP_EXPERIMENTER_PACK_STR) == OFP_BUNDLE_PROP_EXPERIMENTER_SIZE) # enum ofp_bundle_ctrl_type OFPBCT_OPEN_REQUEST = 0 OFPBCT_OPEN_REPLY = 1 OFPBCT_CLOSE_REQUEST = 2 OFPBCT_CLOSE_REPLY = 3 OFPBCT_COMMIT_REQUEST = 4 OFPBCT_COMMIT_REPLY = 5 OFPBCT_DISCARD_REQUEST = 6 OFPBCT_DISCARD_REPLY = 7 # enum ofp_bundle_flags OFPBF_ATOMIC = 1 << 0 # Execute atomically. OFPBF_ORDERED = 1 << 1 # Execute in specified order. # struct ofp_bundle_ctrl_msg OFP_BUNDLE_CTRL_MSG_PACK_STR = '!IHH' OFP_BUNDLE_CTRL_MSG_SIZE = 16 assert (calcsize(OFP_BUNDLE_CTRL_MSG_PACK_STR) + OFP_HEADER_SIZE == OFP_BUNDLE_CTRL_MSG_SIZE) # struct ofp_bundle_add_msg _OFP_BUNDLE_ADD_MSG_0_PACK_STR = 'I2xH' OFP_BUNDLE_ADD_MSG_0_PACK_STR = '!' + _OFP_BUNDLE_ADD_MSG_0_PACK_STR OFP_BUNDLE_ADD_MSG_PACK_STR = (OFP_BUNDLE_ADD_MSG_0_PACK_STR + _OFP_HEADER_PACK_STR) OFP_BUNDLE_ADD_MSG_SIZE = 24 assert (calcsize(OFP_BUNDLE_ADD_MSG_PACK_STR) + OFP_HEADER_SIZE == OFP_BUNDLE_ADD_MSG_SIZE) # Note: struct ofp_prop_experimenter is specific to this implementation. # It does not have a corresponding structure in the specification. # This structure defines common structure for ofp_*_prop_experimenter. # struct ofp_prop_experimenter OFP_PROP_EXPERIMENTER_PACK_STR = '!HHII' OFP_PROP_EXPERIMENTER_SIZE = 12 assert (calcsize(OFP_PROP_EXPERIMENTER_PACK_STR) == OFP_PROP_EXPERIMENTER_SIZE) # generate utility methods ofproto_utils.generate(__name__) # define constants OFP_VERSION = 0x05 OFP_TCP_PORT = 6653 OFP_SSL_PORT = 6653 MAX_XID = 0xffffffff ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/ofproto/ofproto_v1_4_parser.py0000664000175000017500000065140400000000000022240 0ustar00zuulzuul00000000000000# Copyright (C) 2012, 2013, 2014 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2012, 2013 Isaku Yamahata # # 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. """ Decoder/Encoder implementations of OpenFlow 1.4. """ import struct import base64 from os_ken.lib import addrconv from os_ken.lib.pack_utils import msg_pack_into from os_ken.lib.packet import packet from os_ken import utils from os_ken.ofproto.ofproto_parser import StringifyMixin, MsgBase, MsgInMsgBase from os_ken.ofproto import ether from os_ken.ofproto import nicira_ext from os_ken.ofproto import nx_actions from os_ken.ofproto import ofproto_parser from os_ken.ofproto import ofproto_common from os_ken.ofproto import ofproto_v1_4 as ofproto _MSG_PARSERS = {} def _set_msg_type(msg_type): def _set_cls_msg_type(cls): cls.cls_msg_type = msg_type return cls return _set_cls_msg_type def _register_parser(cls): '''class decorator to register msg parser''' assert cls.cls_msg_type is not None assert cls.cls_msg_type not in _MSG_PARSERS _MSG_PARSERS[cls.cls_msg_type] = cls.parser return cls def _register_exp_type(experimenter, exp_type): assert exp_type not in OFPExperimenter._subtypes def _wrapper(cls): OFPExperimenter._subtypes[(experimenter, exp_type)] = cls return cls return _wrapper @ofproto_parser.register_msg_parser(ofproto.OFP_VERSION) def msg_parser(datapath, version, msg_type, msg_len, xid, buf): parser = _MSG_PARSERS.get(msg_type) return parser(datapath, version, msg_type, msg_len, xid, buf) @_register_parser @_set_msg_type(ofproto.OFPT_HELLO) class OFPHello(MsgBase): """ Hello message When connection is started, the hello message is exchanged between a switch and a controller. This message is handled by the OSKen framework, so the OSKen application do not need to process this typically. ========== ========================================================= Attribute Description ========== ========================================================= elements list of ``OFPHelloElemVersionBitmap`` instance ========== ========================================================= """ def __init__(self, datapath, elements=None): elements = elements if elements else [] super(OFPHello, self).__init__(datapath) self.elements = elements @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPHello, cls).parser(datapath, version, msg_type, msg_len, xid, buf) offset = ofproto.OFP_HELLO_HEADER_SIZE elems = [] while offset < msg.msg_len: type_, length = struct.unpack_from( ofproto.OFP_HELLO_ELEM_HEADER_PACK_STR, msg.buf, offset) # better to register Hello Element classes but currently # Only VerisonBitmap is supported so let's be simple. if type_ == ofproto.OFPHET_VERSIONBITMAP: elem = OFPHelloElemVersionBitmap.parser(msg.buf, offset) elems.append(elem) offset += length msg.elements = elems return msg class OFPHelloElemVersionBitmap(StringifyMixin): """ Version bitmap Hello Element ========== ========================================================= Attribute Description ========== ========================================================= versions list of versions of OpenFlow protocol a device supports ========== ========================================================= """ def __init__(self, versions, type_=None, length=None): super(OFPHelloElemVersionBitmap, self).__init__() self.type = ofproto.OFPHET_VERSIONBITMAP self.length = None self._bitmaps = None self.versions = versions @classmethod def parser(cls, buf, offset): type_, length = struct.unpack_from( ofproto.OFP_HELLO_ELEM_VERSIONBITMAP_HEADER_PACK_STR, buf, offset) assert type_ == ofproto.OFPHET_VERSIONBITMAP bitmaps_len = (length - ofproto.OFP_HELLO_ELEM_VERSIONBITMAP_HEADER_SIZE) offset += ofproto.OFP_HELLO_ELEM_VERSIONBITMAP_HEADER_SIZE bitmaps = [] while bitmaps_len >= 4: bitmap = struct.unpack_from('!I', buf, offset) bitmaps.append(bitmap[0]) offset += 4 bitmaps_len -= 4 versions = [i * 32 + shift for i, bitmap in enumerate(bitmaps) for shift in range(31) if bitmap & (1 << shift)] elem = cls(versions) elem.length = length elem._bitmaps = bitmaps return elem @_register_parser @_set_msg_type(ofproto.OFPT_ECHO_REQUEST) class OFPEchoRequest(MsgBase): """ Echo request message This message is handled by the OSKen framework, so the OSKen application do not need to process this typically. ========== ========================================================= Attribute Description ========== ========================================================= data An arbitrary length data ========== ========================================================= Example:: def send_echo_request(self, datapath, data): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPEchoRequest(datapath, data) datapath.send_msg(req) @set_ev_cls(ofp_event.EventOFPEchoRequest, [HANDSHAKE_DISPATCHER, CONFIG_DISPATCHER, MAIN_DISPATCHER]) def echo_request_handler(self, ev): self.logger.debug('OFPEchoRequest received: data=%s', utils.hex_array(ev.msg.data)) """ def __init__(self, datapath, data=None): super(OFPEchoRequest, self).__init__(datapath) self.data = data @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPEchoRequest, cls).parser(datapath, version, msg_type, msg_len, xid, buf) msg.data = msg.buf[ofproto.OFP_HEADER_SIZE:] return msg def _serialize_body(self): if self.data is not None: self.buf += self.data @_register_parser @_set_msg_type(ofproto.OFPT_ERROR) class OFPErrorMsg(MsgBase): """ Error message The switch notifies controller of problems by this message. ========== ========================================================= Attribute Description ========== ========================================================= type High level type of error code Details depending on the type data Variable length data depending on the type and code ========== ========================================================= ``type`` attribute corresponds to ``type_`` parameter of __init__. Types and codes are defined in ``os_ken.ofproto.ofproto``. ============================= =========== Type Code ============================= =========== OFPET_HELLO_FAILED OFPHFC_* OFPET_BAD_REQUEST OFPBRC_* OFPET_BAD_ACTION OFPBAC_* OFPET_BAD_INSTRUCTION OFPBIC_* OFPET_BAD_MATCH OFPBMC_* OFPET_FLOW_MOD_FAILED OFPFMFC_* OFPET_GROUP_MOD_FAILED OFPGMFC_* OFPET_PORT_MOD_FAILED OFPPMFC_* OFPET_TABLE_MOD_FAILED OFPTMFC_* OFPET_QUEUE_OP_FAILED OFPQOFC_* OFPET_SWITCH_CONFIG_FAILED OFPSCFC_* OFPET_ROLE_REQUEST_FAILED OFPRRFC_* OFPET_METER_MOD_FAILED OFPMMFC_* OFPET_TABLE_FEATURES_FAILED OFPTFFC_* OFPET_EXPERIMENTER N/A ============================= =========== If ``type == OFPET_EXPERIMENTER``, this message has also the following attributes. ============= ====================================================== Attribute Description ============= ====================================================== exp_type Experimenter defined type experimenter Experimenter ID ============= ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPErrorMsg, [HANDSHAKE_DISPATCHER, CONFIG_DISPATCHER, MAIN_DISPATCHER]) def error_msg_handler(self, ev): msg = ev.msg self.logger.debug('OFPErrorMsg received: type=0x%02x code=0x%02x ' 'message=%s', msg.type, msg.code, utils.hex_array(msg.data)) """ def __init__(self, datapath, type_=None, code=None, data=None, **kwargs): super(OFPErrorMsg, self).__init__(datapath) self.type = type_ self.code = code if isinstance(data, str): data = data.encode('ascii') self.data = data if self.type == ofproto.OFPET_EXPERIMENTER: self.exp_type = kwargs.get('exp_type', None) self.experimenter = kwargs.get('experimenter', None) @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): type_, = struct.unpack_from('!H', bytes(buf), ofproto.OFP_HEADER_SIZE) msg = super(OFPErrorMsg, cls).parser(datapath, version, msg_type, msg_len, xid, buf) if type_ == ofproto.OFPET_EXPERIMENTER: (msg.type, msg.exp_type, msg.experimenter, msg.data) = cls.parse_experimenter_body(buf) else: (msg.type, msg.code, msg.data) = cls.parse_body(buf) return msg @classmethod def parse_body(cls, buf): type_, code = struct.unpack_from( ofproto.OFP_ERROR_MSG_PACK_STR, buf, ofproto.OFP_HEADER_SIZE) data = buf[ofproto.OFP_ERROR_MSG_SIZE:] return type_, code, data @classmethod def parse_experimenter_body(cls, buf): type_, exp_type, experimenter = struct.unpack_from( ofproto.OFP_ERROR_EXPERIMENTER_MSG_PACK_STR, buf, ofproto.OFP_HEADER_SIZE) data = buf[ofproto.OFP_ERROR_EXPERIMENTER_MSG_SIZE:] return type_, exp_type, experimenter, data def _serialize_body(self): assert self.data is not None if self.type == ofproto.OFPET_EXPERIMENTER: msg_pack_into(ofproto.OFP_ERROR_EXPERIMENTER_MSG_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.type, self.exp_type, self.experimenter) self.buf += self.data else: msg_pack_into(ofproto.OFP_ERROR_MSG_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.type, self.code) self.buf += self.data # For the backward compatibility def OFPErrorExperimenterMsg(datapath, type_=None, exp_type=None, experimenter=None, data=None): msg = OFPErrorMsg(datapath, data=data) msg.type = ofproto.OFPET_EXPERIMENTER msg.exp_type = exp_type msg.experimenter = experimenter return msg @_register_parser @_set_msg_type(ofproto.OFPT_ECHO_REPLY) class OFPEchoReply(MsgBase): """ Echo reply message This message is handled by the OSKen framework, so the OSKen application do not need to process this typically. ========== ========================================================= Attribute Description ========== ========================================================= data An arbitrary length data ========== ========================================================= Example:: def send_echo_reply(self, datapath, data): ofp_parser = datapath.ofproto_parser reply = ofp_parser.OFPEchoReply(datapath, data) datapath.send_msg(reply) @set_ev_cls(ofp_event.EventOFPEchoReply, [HANDSHAKE_DISPATCHER, CONFIG_DISPATCHER, MAIN_DISPATCHER]) def echo_reply_handler(self, ev): self.logger.debug('OFPEchoReply received: data=%s', utils.hex_array(ev.msg.data)) """ def __init__(self, datapath, data=None): super(OFPEchoReply, self).__init__(datapath) self.data = data @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPEchoReply, cls).parser(datapath, version, msg_type, msg_len, xid, buf) msg.data = msg.buf[ofproto.OFP_HEADER_SIZE:] return msg def _serialize_body(self): assert self.data is not None self.buf += self.data @_set_msg_type(ofproto.OFPT_FEATURES_REQUEST) class OFPFeaturesRequest(MsgBase): """ Features request message The controller sends a feature request to the switch upon session establishment. This message is handled by the OSKen framework, so the OSKen application do not need to process this typically. Example:: def send_features_request(self, datapath): ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPFeaturesRequest(datapath) datapath.send_msg(req) """ def __init__(self, datapath): super(OFPFeaturesRequest, self).__init__(datapath) @_register_parser @_set_msg_type(ofproto.OFPT_EXPERIMENTER) class OFPExperimenter(MsgBase): """ Experimenter extension message ============= ========================================================= Attribute Description ============= ========================================================= experimenter Experimenter ID exp_type Experimenter defined data Experimenter defined arbitrary additional data ============= ========================================================= """ _subtypes = {} def __init__(self, datapath, experimenter=None, exp_type=None, data=None): super(OFPExperimenter, self).__init__(datapath) self.experimenter = experimenter self.exp_type = exp_type self.data = data @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPExperimenter, cls).parser(datapath, version, msg_type, msg_len, xid, buf) (msg.experimenter, msg.exp_type) = struct.unpack_from( ofproto.OFP_EXPERIMENTER_HEADER_PACK_STR, msg.buf, ofproto.OFP_HEADER_SIZE) msg.data = msg.buf[ofproto.OFP_EXPERIMENTER_HEADER_SIZE:] if (msg.experimenter, msg.exp_type) in cls._subtypes: new_msg = cls._subtypes[ (msg.experimenter, msg.exp_type)].parser_subtype(msg) new_msg.set_headers(msg.version, msg.msg_type, msg.msg_len, msg.xid) new_msg.set_buf(msg.buf) return new_msg return msg def _serialize_body(self): assert self.data is not None msg_pack_into(ofproto.OFP_EXPERIMENTER_HEADER_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.experimenter, self.exp_type) self.buf += self.data @_register_parser @_set_msg_type(ofproto.OFPT_FEATURES_REPLY) class OFPSwitchFeatures(MsgBase): """ Features reply message The switch responds with a features reply message to a features request. This message is handled by the OSKen framework, so the OSKen application do not need to process this typically. Example:: @set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER) def switch_features_handler(self, ev): msg = ev.msg self.logger.debug('OFPSwitchFeatures received: ' 'datapath_id=0x%016x n_buffers=%d ' 'n_tables=%d auxiliary_id=%d ' 'capabilities=0x%08x', msg.datapath_id, msg.n_buffers, msg.n_tables, msg.auxiliary_id, msg.capabilities) """ def __init__(self, datapath, datapath_id=None, n_buffers=None, n_tables=None, auxiliary_id=None, capabilities=None): super(OFPSwitchFeatures, self).__init__(datapath) self.datapath_id = datapath_id self.n_buffers = n_buffers self.n_tables = n_tables self.auxiliary_id = auxiliary_id self.capabilities = capabilities @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPSwitchFeatures, cls).parser(datapath, version, msg_type, msg_len, xid, buf) (msg.datapath_id, msg.n_buffers, msg.n_tables, msg.auxiliary_id, msg.capabilities, msg._reserved) = struct.unpack_from( ofproto.OFP_SWITCH_FEATURES_PACK_STR, msg.buf, ofproto.OFP_HEADER_SIZE) return msg @_set_msg_type(ofproto.OFPT_GET_CONFIG_REQUEST) class OFPGetConfigRequest(MsgBase): """ Get config request message The controller sends a get config request to query configuration parameters in the switch. Example:: def send_get_config_request(self, datapath): ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPGetConfigRequest(datapath) datapath.send_msg(req) """ def __init__(self, datapath): super(OFPGetConfigRequest, self).__init__(datapath) @_register_parser @_set_msg_type(ofproto.OFPT_GET_CONFIG_REPLY) class OFPGetConfigReply(MsgBase): """ Get config reply message The switch responds to a configuration request with a get config reply message. ============= ========================================================= Attribute Description ============= ========================================================= flags Bitmap of the following flags. | OFPC_FRAG_NORMAL | OFPC_FRAG_DROP | OFPC_FRAG_REASM miss_send_len Max bytes of new flow that datapath should send to the controller ============= ========================================================= Example:: @set_ev_cls(ofp_event.EventOFPGetConfigReply, MAIN_DISPATCHER) def get_config_reply_handler(self, ev): msg = ev.msg dp = msg.datapath ofp = dp.ofproto flags = [] if msg.flags & ofp.OFPC_FRAG_NORMAL: flags.append('NORMAL') if msg.flags & ofp.OFPC_FRAG_DROP: flags.append('DROP') if msg.flags & ofp.OFPC_FRAG_REASM: flags.append('REASM') self.logger.debug('OFPGetConfigReply received: ' 'flags=%s miss_send_len=%d', ','.join(flags), msg.miss_send_len) """ def __init__(self, datapath, flags=None, miss_send_len=None): super(OFPGetConfigReply, self).__init__(datapath) self.flags = flags self.miss_send_len = miss_send_len @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPGetConfigReply, cls).parser(datapath, version, msg_type, msg_len, xid, buf) msg.flags, msg.miss_send_len = struct.unpack_from( ofproto.OFP_SWITCH_CONFIG_PACK_STR, msg.buf, ofproto.OFP_HEADER_SIZE) return msg @_set_msg_type(ofproto.OFPT_SET_CONFIG) class OFPSetConfig(MsgBase): """ Set config request message The controller sends a set config request message to set configuraion parameters. ============= ========================================================= Attribute Description ============= ========================================================= flags Bitmap of the following flags. | OFPC_FRAG_NORMAL | OFPC_FRAG_DROP | OFPC_FRAG_REASM miss_send_len Max bytes of new flow that datapath should send to the controller ============= ========================================================= Example:: def send_set_config(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPSetConfig(datapath, ofp.OFPC_FRAG_NORMAL, 256) datapath.send_msg(req) """ def __init__(self, datapath, flags=0, miss_send_len=0): super(OFPSetConfig, self).__init__(datapath) self.flags = flags self.miss_send_len = miss_send_len def _serialize_body(self): assert self.flags is not None assert self.miss_send_len is not None msg_pack_into(ofproto.OFP_SWITCH_CONFIG_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.flags, self.miss_send_len) class OFPMatch(StringifyMixin): """ Flow Match Structure This class is implementation of the flow match structure having compose/query API. You can define the flow match by the keyword arguments. The following arguments are available. ================ =============== ================================== Argument Value Description ================ =============== ================================== in_port Integer 32bit Switch input port in_phy_port Integer 32bit Switch physical input port metadata Integer 64bit Metadata passed between tables eth_dst MAC address Ethernet destination address eth_src MAC address Ethernet source address eth_type Integer 16bit Ethernet frame type vlan_vid Integer 16bit VLAN id vlan_pcp Integer 8bit VLAN priority ip_dscp Integer 8bit IP DSCP (6 bits in ToS field) ip_ecn Integer 8bit IP ECN (2 bits in ToS field) ip_proto Integer 8bit IP protocol ipv4_src IPv4 address IPv4 source address ipv4_dst IPv4 address IPv4 destination address tcp_src Integer 16bit TCP source port tcp_dst Integer 16bit TCP destination port udp_src Integer 16bit UDP source port udp_dst Integer 16bit UDP destination port sctp_src Integer 16bit SCTP source port sctp_dst Integer 16bit SCTP destination port icmpv4_type Integer 8bit ICMP type icmpv4_code Integer 8bit ICMP code arp_op Integer 16bit ARP opcode arp_spa IPv4 address ARP source IPv4 address arp_tpa IPv4 address ARP target IPv4 address arp_sha MAC address ARP source hardware address arp_tha MAC address ARP target hardware address ipv6_src IPv6 address IPv6 source address ipv6_dst IPv6 address IPv6 destination address ipv6_flabel Integer 32bit IPv6 Flow Label icmpv6_type Integer 8bit ICMPv6 type icmpv6_code Integer 8bit ICMPv6 code ipv6_nd_target IPv6 address Target address for ND ipv6_nd_sll MAC address Source link-layer for ND ipv6_nd_tll MAC address Target link-layer for ND mpls_label Integer 32bit MPLS label mpls_tc Integer 8bit MPLS TC mpls_bos Integer 8bit MPLS BoS bit pbb_isid Integer 24bit PBB I-SID tunnel_id Integer 64bit Logical Port Metadata ipv6_exthdr Integer 16bit IPv6 Extension Header pseudo-field pbb_uca Integer 8bit PBB UCA header field tcp_flags Integer 16bit TCP flags (EXT-109 ONF Extension) actset_output Integer 32bit Output port from action set metadata (EXT-233 ONF Extension) ================ =============== ================================== Example:: >>> # compose >>> match = parser.OFPMatch( ... in_port=1, ... eth_type=0x86dd, ... ipv6_src=('2001:db8:bd05:1d2:288a:1fc0:1:10ee', ... 'ffff:ffff:ffff:ffff::'), ... ipv6_dst='2001:db8:bd05:1d2:288a:1fc0:1:10ee') >>> # query >>> if 'ipv6_src' in match: ... print match['ipv6_src'] ... ('2001:db8:bd05:1d2:288a:1fc0:1:10ee', 'ffff:ffff:ffff:ffff::') .. Note:: For the list of the supported Nicira experimenter matches, please refer to :ref:`os_ken.ofproto.nx_match `. .. Note:: For VLAN id match field, special values are defined in OpenFlow Spec. 1) Packets with and without a VLAN tag - Example:: match = parser.OFPMatch() - Packet Matching ====================== ===== non-VLAN-tagged MATCH VLAN-tagged(vlan_id=3) MATCH VLAN-tagged(vlan_id=5) MATCH ====================== ===== 2) Only packets without a VLAN tag - Example:: match = parser.OFPMatch(vlan_vid=0x0000) - Packet Matching ====================== ===== non-VLAN-tagged MATCH VLAN-tagged(vlan_id=3) x VLAN-tagged(vlan_id=5) x ====================== ===== 3) Only packets with a VLAN tag regardless of its value - Example:: match = parser.OFPMatch(vlan_vid=(0x1000, 0x1000)) - Packet Matching ====================== ===== non-VLAN-tagged x VLAN-tagged(vlan_id=3) MATCH VLAN-tagged(vlan_id=5) MATCH ====================== ===== 4) Only packets with VLAN tag and VID equal - Example:: match = parser.OFPMatch(vlan_vid=(0x1000 | 3)) - Packet Matching ====================== ===== non-VLAN-tagged x VLAN-tagged(vlan_id=3) MATCH VLAN-tagged(vlan_id=5) x ====================== ===== """ def __init__(self, type_=None, length=None, _ordered_fields=None, **kwargs): super(OFPMatch, self).__init__() self.type = ofproto.OFPMT_OXM self.length = length if _ordered_fields is not None: assert not kwargs self._fields2 = _ordered_fields else: kwargs = dict(ofproto.oxm_normalize_user(k, v) for (k, v) in kwargs.items()) fields = [ofproto.oxm_from_user(k, v) for (k, v) in kwargs.items()] # assumption: sorting by OXM type values makes fields # meet ordering requirements (eg. eth_type before ipv4_src) fields.sort( key=lambda x: x[0][0] if isinstance(x[0], tuple) else x[0]) self._fields2 = [ofproto.oxm_to_user(n, v, m) for (n, v, m) in fields] @classmethod def parser(cls, buf, offset): """ Returns an object which is generated from a buffer including the expression of the wire protocol of the flow match. """ match = OFPMatch() type_, length = struct.unpack_from('!HH', buf, offset) match.type = type_ match.length = length # ofp_match adjustment offset += 4 length -= 4 fields = [] while length > 0: n, value, mask, field_len = ofproto.oxm_parse(buf, offset) k, uv = ofproto.oxm_to_user(n, value, mask) fields.append((k, uv)) offset += field_len length -= field_len match._fields2 = fields return match def serialize(self, buf, offset): """ Outputs the expression of the wire protocol of the flow match into the buf. Returns the output length. """ fields = [ofproto.oxm_from_user(k, uv) for (k, uv) in self._fields2] hdr_pack_str = '!HH' field_offset = offset + struct.calcsize(hdr_pack_str) for (n, value, mask) in fields: field_offset += ofproto.oxm_serialize(n, value, mask, buf, field_offset) length = field_offset - offset msg_pack_into(hdr_pack_str, buf, offset, ofproto.OFPMT_OXM, length) self.length = length pad_len = utils.round_up(length, 8) - length msg_pack_into("%dx" % pad_len, buf, field_offset) return length + pad_len def __getitem__(self, key): return dict(self._fields2)[key] def __contains__(self, key): return key in dict(self._fields2) def iteritems(self): return iter(dict(self._fields2).items()) def items(self): return self._fields2 def get(self, key, default=None): return dict(self._fields2).get(key, default) def stringify_attrs(self): yield "oxm_fields", dict(self._fields2) def to_jsondict(self): """ Returns a dict expressing the flow match. """ body = {"oxm_fields": [ofproto.oxm_to_jsondict(k, uv) for k, uv in self._fields2], "length": self.length, "type": self.type} return {self.__class__.__name__: body} @classmethod def from_jsondict(cls, dict_): """ Returns an object which is generated from a dict. Exception raises: KeyError -- Unknown match field is defined in dict """ fields = [ofproto.oxm_from_jsondict(f) for f in dict_['oxm_fields']] return OFPMatch(_ordered_fields=fields) class OFPPropUnknown(StringifyMixin): def __init__(self, type_=None, length=None, buf=None): self.buf = buf @classmethod def parser(cls, buf): return cls(buf=buf) class OFPPropBase(StringifyMixin): _PACK_STR = '!HH' # _TYPES = {} must be an attribute of subclass def __init__(self, type_, length=None): self.type = type_ self.length = length @classmethod def register_type(cls, type_): def _register_type(subcls): cls._TYPES[type_] = subcls return subcls return _register_type @classmethod def parse(cls, buf): (type_, length) = struct.unpack_from(cls._PACK_STR, buf, 0) if not length: raise ValueError rest = buf[utils.round_up(length, 8):] try: subcls = cls._TYPES[type_] except KeyError: subcls = OFPPropUnknown prop = subcls.parser(buf) prop.type = type_ prop.length = length return prop, rest @classmethod def get_rest(cls, buf): (type_, length) = struct.unpack_from(cls._PACK_STR, buf, 0) offset = struct.calcsize(cls._PACK_STR) return buf[offset:length] def serialize(self): # Body # serialize_body should be implemented by subclass body = bytearray() body += self.serialize_body() # fixup self.length = len(body) + struct.calcsize(self._PACK_STR) # Header buf = bytearray() msg_pack_into(self._PACK_STR, buf, 0, self.type, self.length) buf += body # Pad pad_len = utils.round_up(self.length, 8) - self.length msg_pack_into("%dx" % pad_len, buf, len(buf)) return buf class OFPPropCommonExperimenter4ByteData(StringifyMixin): _PACK_STR = '!HHII' _EXPERIMENTER_DATA_PACK_STR = '!I' _EXPERIMENTER_DATA_SIZE = 4 def __init__(self, type_=None, length=None, experimenter=None, exp_type=None, data=bytearray()): self.type = type_ self.length = length self.experimenter = experimenter self.exp_type = exp_type self.data = data @classmethod def parser(cls, buf): (type_, length, experimenter, exp_type) = struct.unpack_from( ofproto.OFP_PROP_EXPERIMENTER_PACK_STR, buf, 0) rest = buf[ofproto.OFP_PROP_EXPERIMENTER_SIZE:length] data = [] while rest: (d,) = struct.unpack_from( cls._EXPERIMENTER_DATA_PACK_STR, rest, 0) data.append(d) rest = rest[cls._EXPERIMENTER_DATA_SIZE:] return cls(type_, length, experimenter, exp_type, data) def serialize(self): offset = 0 bin_data = bytearray() for d in self.data: msg_pack_into(self._EXPERIMENTER_DATA_PACK_STR, bin_data, offset, d) offset += self._EXPERIMENTER_DATA_SIZE # fixup self.length = struct.calcsize(self._PACK_STR) self.length += len(bin_data) buf = bytearray() msg_pack_into(self._PACK_STR, buf, 0, self.type, self.length, self.experimenter, self.exp_type) buf += bin_data # Pad pad_len = utils.round_up(self.length, 8) - self.length msg_pack_into("%dx" % pad_len, buf, len(buf)) return buf class OFPPortDescProp(OFPPropBase): _TYPES = {} @OFPPortDescProp.register_type(ofproto.OFPPDPT_ETHERNET) class OFPPortDescPropEthernet(OFPPortDescProp): def __init__(self, type_=None, length=None, curr=None, advertised=None, supported=None, peer=None, curr_speed=None, max_speed=None): self.type = type_ self.length = length self.curr = curr self.advertised = advertised self.supported = supported self.peer = peer self.curr_speed = curr_speed self.max_speed = max_speed @classmethod def parser(cls, buf): ether = cls() (ether.type, ether.length, ether.curr, ether.advertised, ether.supported, ether.peer, ether.curr_speed, ether.max_speed) = struct.unpack_from( ofproto.OFP_PORT_DESC_PROP_ETHERNET_PACK_STR, buf, 0) return ether @OFPPortDescProp.register_type(ofproto.OFPPDPT_OPTICAL) class OFPPortDescPropOptical(OFPPortDescProp): def __init__(self, type_=None, length=None, supported=None, tx_min_freq_lmda=None, tx_max_freq_lmda=None, tx_grid_freq_lmda=None, rx_min_freq_lmda=None, rx_max_freq_lmda=None, rx_grid_freq_lmda=None, tx_pwr_min=None, tx_pwr_max=None): self.type = type_ self.length = length self.supported = supported self.tx_min_freq_lmda = tx_min_freq_lmda self.tx_max_freq_lmda = tx_max_freq_lmda self.tx_grid_freq_lmda = tx_grid_freq_lmda self.rx_min_freq_lmda = rx_min_freq_lmda self.rx_max_freq_lmda = rx_max_freq_lmda self.rx_grid_freq_lmda = rx_grid_freq_lmda self.tx_pwr_min = tx_pwr_min self.tx_pwr_max = tx_pwr_max @classmethod def parser(cls, buf): optical = cls() (optical.type, optical.length, optical.supported, optical.tx_min_freq_lmda, optical.tx_max_freq_lmda, optical.tx_grid_freq_lmda, optical.rx_min_freq_lmda, optical.rx_max_freq_lmda, optical.rx_grid_freq_lmda, optical.tx_pwr_min, optical.tx_pwr_max) = struct.unpack_from( ofproto.OFP_PORT_DESC_PROP_OPTICAL_PACK_STR, buf, 0) return optical @OFPPortDescProp.register_type(ofproto.OFPPDPT_EXPERIMENTER) class OFPPortDescPropExperimenter(OFPPropCommonExperimenter4ByteData): pass class OFPTableModProp(OFPPropBase): _TYPES = {} @OFPTableModProp.register_type(ofproto.OFPTMPT_EVICTION) class OFPTableModPropEviction(OFPTableModProp): def __init__(self, type_=None, length=None, flags=None): self.type = type_ self.length = length self.flags = flags @classmethod def parser(cls, buf): eviction = cls() (eviction.type, eviction.length, eviction.flags) = struct.unpack_from( ofproto.OFP_TABLE_MOD_PROP_EVICTION_PACK_STR, buf, 0) return eviction def serialize(self): # fixup self.length = ofproto.OFP_TABLE_MOD_PROP_EVICTION_SIZE buf = bytearray() msg_pack_into(ofproto.OFP_TABLE_MOD_PROP_EVICTION_PACK_STR, buf, 0, self.type, self.length, self.flags) return buf @OFPTableModProp.register_type(ofproto.OFPTMPT_VACANCY) class OFPTableModPropVacancy(OFPTableModProp): def __init__(self, type_=None, length=None, vacancy_down=None, vacancy_up=None, vacancy=None): self.type = type_ self.length = length self.vacancy_down = vacancy_down self.vacancy_up = vacancy_up self.vacancy = vacancy @classmethod def parser(cls, buf): vacancy = cls() (vacancy.type, vacancy.length, vacancy.vacancy_down, vacancy.vacancy_up, vacancy.vacancy) = struct.unpack_from( ofproto.OFP_TABLE_MOD_PROP_VACANCY_PACK_STR, buf, 0) return vacancy def serialize(self): # fixup self.length = ofproto.OFP_TABLE_MOD_PROP_VACANCY_SIZE buf = bytearray() msg_pack_into(ofproto.OFP_TABLE_MOD_PROP_VACANCY_PACK_STR, buf, 0, self.type, self.length, self.vacancy_down, self.vacancy_up, self.vacancy) return buf @OFPTableModProp.register_type(ofproto.OFPTMPT_EXPERIMENTER) class OFPTableModPropExperimenter(OFPPropCommonExperimenter4ByteData): pass class OFPQueueDescProp(OFPPropBase): _TYPES = {} @OFPQueueDescProp.register_type(ofproto.OFPQDPT_MIN_RATE) class OFPQueueDescPropMinRate(OFPQueueDescProp): def __init__(self, type_=None, length=None, rate=None): self.type = type_ self.length = length self.rate = rate @classmethod def parser(cls, buf): minrate = cls() (minrate.type, minrate.length, minrate.rate) = struct.unpack_from( ofproto.OFP_QUEUE_DESC_PROP_MIN_RATE_PACK_STR, buf, 0) return minrate @OFPQueueDescProp.register_type(ofproto.OFPQDPT_MAX_RATE) class OFPQueueDescPropMaxRate(OFPQueueDescProp): def __init__(self, type_=None, length=None, rate=None): self.type = type_ self.length = length self.rate = rate @classmethod def parser(cls, buf): maxrate = cls() (maxrate.type, maxrate.length, maxrate.rate) = struct.unpack_from( ofproto.OFP_QUEUE_DESC_PROP_MAX_RATE_PACK_STR, buf, 0) return maxrate @OFPQueueDescProp.register_type(ofproto.OFPQDPT_EXPERIMENTER) class OFPQueueDescPropExperimenter(OFPPropCommonExperimenter4ByteData): pass class OFPRoleProp(OFPPropBase): _TYPES = {} @OFPRoleProp.register_type(ofproto.OFPRPT_EXPERIMENTER) class OFPRolePropExperimenter(OFPPropCommonExperimenter4ByteData): pass class OFPBundleProp(OFPPropBase): _TYPES = {} @OFPBundleProp.register_type(ofproto.OFPRPT_EXPERIMENTER) class OFPBundlePropExperimenter(OFPPropCommonExperimenter4ByteData): pass @_register_parser @_set_msg_type(ofproto.OFPT_PACKET_IN) class OFPPacketIn(MsgBase): """ Packet-In message The switch sends the packet that received to the controller by this message. ============= ========================================================= Attribute Description ============= ========================================================= buffer_id ID assigned by datapath total_len Full length of frame reason Reason packet is being sent. | OFPR_TABLE_MISS | OFPR_APPLY_ACTION | OFPR_INVALID_TTL | OFPR_ACTION_SET | OFPR_GROUP | OFPR_PACKET_OUT table_id ID of the table that was looked up cookie Cookie of the flow entry that was looked up match Instance of ``OFPMatch`` data Ethernet frame ============= ========================================================= Example:: @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER) def packet_in_handler(self, ev): msg = ev.msg dp = msg.datapath ofp = dp.ofproto if msg.reason == ofp.TABLE_MISS: reason = 'TABLE MISS' elif msg.reason == ofp.OFPR_APPLY_ACTION: reason = 'APPLY ACTION' elif msg.reason == ofp.OFPR_INVALID_TTL: reason = 'INVALID TTL' elif msg.reason == ofp.OFPR_ACTION_SET: reason = 'ACTION SET' elif msg.reason == ofp.OFPR_GROUP: reason = 'GROUP' elif msg.reason == ofp.OFPR_PACKET_OUT: reason = 'PACKET OUT' else: reason = 'unknown' self.logger.debug('OFPPacketIn received: ' 'buffer_id=%x total_len=%d reason=%s ' 'table_id=%d cookie=%d match=%s data=%s', msg.buffer_id, msg.total_len, reason, msg.table_id, msg.cookie, msg.match, utils.hex_array(msg.data)) """ def __init__(self, datapath, buffer_id=None, total_len=None, reason=None, table_id=None, cookie=None, match=None, data=None): super(OFPPacketIn, self).__init__(datapath) self.buffer_id = buffer_id self.total_len = total_len self.reason = reason self.table_id = table_id self.cookie = cookie self.match = match self.data = data @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPPacketIn, cls).parser(datapath, version, msg_type, msg_len, xid, buf) (msg.buffer_id, msg.total_len, msg.reason, msg.table_id, msg.cookie) = struct.unpack_from( ofproto.OFP_PACKET_IN_PACK_STR, msg.buf, ofproto.OFP_HEADER_SIZE) msg.match = OFPMatch.parser(msg.buf, ofproto.OFP_PACKET_IN_SIZE - ofproto.OFP_MATCH_SIZE) match_len = utils.round_up(msg.match.length, 8) msg.data = msg.buf[(ofproto.OFP_PACKET_IN_SIZE - ofproto.OFP_MATCH_SIZE + match_len + 2):] if msg.total_len < len(msg.data): # discard padding for 8-byte alignment of OFP packet msg.data = msg.data[:msg.total_len] return msg @_register_parser @_set_msg_type(ofproto.OFPT_FLOW_REMOVED) class OFPFlowRemoved(MsgBase): """ Flow removed message When flow entries time out or are deleted, the switch notifies controller with this message. ================ ====================================================== Attribute Description ================ ====================================================== cookie Opaque controller-issued identifier priority Priority level of flow entry reason One of the following values. | OFPRR_IDLE_TIMEOUT | OFPRR_HARD_TIMEOUT | OFPRR_DELETE | OFPRR_GROUP_DELETE | OFPRR_METER_DELETE | OFPRR_EVICTION table_id ID of the table duration_sec Time flow was alive in seconds duration_nsec Time flow was alive in nanoseconds beyond duration_sec idle_timeout Idle timeout from original flow mod hard_timeout Hard timeout from original flow mod packet_count Number of packets that was associated with the flow byte_count Number of bytes that was associated with the flow match Instance of ``OFPMatch`` ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPFlowRemoved, MAIN_DISPATCHER) def flow_removed_handler(self, ev): msg = ev.msg dp = msg.datapath ofp = dp.ofproto if msg.reason == ofp.OFPRR_IDLE_TIMEOUT: reason = 'IDLE TIMEOUT' elif msg.reason == ofp.OFPRR_HARD_TIMEOUT: reason = 'HARD TIMEOUT' elif msg.reason == ofp.OFPRR_DELETE: reason = 'DELETE' elif msg.reason == ofp.OFPRR_GROUP_DELETE: reason = 'GROUP DELETE' else: reason = 'unknown' self.logger.debug('OFPFlowRemoved received: ' 'cookie=%d priority=%d reason=%s table_id=%d ' 'duration_sec=%d duration_nsec=%d ' 'idle_timeout=%d hard_timeout=%d ' 'packet_count=%d byte_count=%d match.fields=%s', msg.cookie, msg.priority, reason, msg.table_id, msg.duration_sec, msg.duration_nsec, msg.idle_timeout, msg.hard_timeout, msg.packet_count, msg.byte_count, msg.match) """ def __init__(self, datapath, cookie=None, priority=None, reason=None, table_id=None, duration_sec=None, duration_nsec=None, idle_timeout=None, hard_timeout=None, packet_count=None, byte_count=None, match=None): super(OFPFlowRemoved, self).__init__(datapath) self.cookie = cookie self.priority = priority self.reason = reason self.table_id = table_id self.duration_sec = duration_sec self.duration_nsec = duration_nsec self.idle_timeout = idle_timeout self.hard_timeout = hard_timeout self.packet_count = packet_count self.byte_count = byte_count self.match = match @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPFlowRemoved, cls).parser(datapath, version, msg_type, msg_len, xid, buf) (msg.cookie, msg.priority, msg.reason, msg.table_id, msg.duration_sec, msg.duration_nsec, msg.idle_timeout, msg.hard_timeout, msg.packet_count, msg.byte_count) = struct.unpack_from( ofproto.OFP_FLOW_REMOVED_PACK_STR0, msg.buf, ofproto.OFP_HEADER_SIZE) offset = (ofproto.OFP_FLOW_REMOVED_SIZE - ofproto.OFP_MATCH_SIZE) msg.match = OFPMatch.parser(msg.buf, offset) return msg class OFPPort(StringifyMixin): """ Description of a port ========== ========================================================= Attribute Description ========== ========================================================= port_no Port number and it uniquely identifies a port within a switch. length Length of ofp_port (excluding padding). hw_addr MAC address for the port. name Null-terminated string containing a human-readable name for the interface. config Bitmap of port configuration flags. | OFPPC_PORT_DOWN | OFPPC_NO_RECV | OFPPC_NO_FWD | OFPPC_NO_PACKET_IN state Bitmap of port state flags. | OFPPS_LINK_DOWN | OFPPS_BLOCKED | OFPPS_LIVE properties List of ``OFPPortDescProp`` subclass instance ========== ========================================================= """ _TYPE = { 'ascii': [ 'hw_addr', ], 'utf-8': [ # OF spec is unclear about the encoding of name. # we assumes UTF-8, which is used by OVS. 'name', ] } def __init__(self, port_no=None, length=None, hw_addr=None, name=None, config=None, state=None, properties=None): super(OFPPort, self).__init__() self.port_no = port_no self.length = length self.hw_addr = hw_addr self.name = name self.config = config self.state = state self.properties = properties @classmethod def parser(cls, buf, offset): (port_no, length, hw_addr, name, config, state) = struct.unpack_from( ofproto.OFP_PORT_PACK_STR, buf, offset) hw_addr = addrconv.mac.bin_to_text(hw_addr) name = name.rstrip(b'\0') props = [] rest = buf[offset + ofproto.OFP_PORT_SIZE:offset + length] while rest: p, rest = OFPPortDescProp.parse(rest) props.append(p) ofpport = cls(port_no, length, hw_addr, name, config, state, props) return ofpport class OFPTableDesc(StringifyMixin): def __init__(self, length=None, table_id=None, config=None, properties=None): super(OFPTableDesc, self).__init__() self.table_id = table_id self.length = length self.config = config self.properties = properties @classmethod def parser(cls, buf, offset): (length, table_id, config) = struct.unpack_from( ofproto.OFP_TABLE_DESC_PACK_STR, buf, offset) props = [] rest = buf[offset + ofproto.OFP_TABLE_DESC_SIZE:offset + length] while rest: p, rest = OFPTableModProp.parse(rest) props.append(p) ofptabledesc = cls(length, table_id, config, props) return ofptabledesc class OFPQueueDesc(StringifyMixin): def __init__(self, port_no=None, queue_id=None, len_=None, properties=None): super(OFPQueueDesc, self).__init__() self.port_no = port_no self.queue_id = queue_id self.len = len_ self.properties = properties @classmethod def parser(cls, buf, offset): (port_no, queue_id, len_) = struct.unpack_from( ofproto.OFP_QUEUE_DESC_PACK_STR, buf, offset) props = [] rest = buf[offset + ofproto.OFP_QUEUE_DESC_SIZE:offset + len_] while rest: p, rest = OFPQueueDescProp.parse(rest) props.append(p) ofpqueuedesc = cls(port_no, queue_id, len_, props) return ofpqueuedesc def _set_stats_type(stats_type, stats_body_cls): def _set_cls_stats_type(cls): cls.cls_stats_type = stats_type cls.cls_stats_body_cls = stats_body_cls return cls return _set_cls_stats_type @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPMultipartRequest(MsgBase): def __init__(self, datapath, flags): super(OFPMultipartRequest, self).__init__(datapath) self.type = self.__class__.cls_stats_type self.flags = flags def _serialize_stats_body(self): pass def _serialize_body(self): msg_pack_into(ofproto.OFP_MULTIPART_REQUEST_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.type, self.flags) self._serialize_stats_body() @_register_parser @_set_msg_type(ofproto.OFPT_METER_MOD) class OFPMeterMod(MsgBase): """ Meter modification message The controller sends this message to modify the meter. ================ ====================================================== Attribute Description ================ ====================================================== command One of the following values. | OFPMC_ADD | OFPMC_MODIFY | OFPMC_DELETE flags Bitmap of the following flags. | OFPMF_KBPS | OFPMF_PKTPS | OFPMF_BURST | OFPMF_STATS meter_id Meter instance bands list of the following class instance. | OFPMeterBandDrop | OFPMeterBandDscpRemark | OFPMeterBandExperimenter ================ ====================================================== """ def __init__(self, datapath, command=ofproto.OFPMC_ADD, flags=ofproto.OFPMF_KBPS, meter_id=1, bands=None): bands = bands if bands else [] super(OFPMeterMod, self).__init__(datapath) self.command = command self.flags = flags self.meter_id = meter_id self.bands = bands @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPMeterMod, cls).parser( datapath, version, msg_type, msg_len, xid, buf) (msg.command, msg.flags, msg.meter_id) = struct.unpack_from( ofproto.OFP_METER_MOD_PACK_STR, buf, ofproto.OFP_HEADER_SIZE) offset = ofproto.OFP_METER_MOD_SIZE msg.bands = [] while offset < msg.msg_len: band = OFPMeterBandHeader.parser(buf, offset) msg.bands.append(band) offset += band.len return msg def _serialize_body(self): msg_pack_into(ofproto.OFP_METER_MOD_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.command, self.flags, self.meter_id) offset = ofproto.OFP_METER_MOD_SIZE for b in self.bands: b.serialize(self.buf, offset) offset += b.len @_set_msg_type(ofproto.OFPT_TABLE_MOD) class OFPTableMod(MsgBase): """ Flow table configuration message The controller sends this message to configure table state. ================ ====================================================== Attribute Description ================ ====================================================== table_id ID of the table (OFPTT_ALL indicates all tables) config Bitmap of configuration flags. | OFPTC_EVICTION | OFPTC_VACANCY_EVENTS properties List of ``OFPTableModProp`` subclass instance ================ ====================================================== Example:: def send_table_mod(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPTableMod(datapath, 1, 3) flags = ofp.OFPTC_VACANCY_EVENTS properties = [ofp_parser.OFPTableModPropEviction(flags)] req = ofp_parser.OFPTableMod(datapath, 1, 3, properties) datapath.send_msg(req) """ def __init__(self, datapath, table_id, config, properties): super(OFPTableMod, self).__init__(datapath) self.table_id = table_id self.config = config self.properties = properties def _serialize_body(self): props_buf = bytearray() for p in self.properties: props_buf += p.serialize() msg_pack_into(ofproto.OFP_TABLE_MOD_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.table_id, self.config) self.buf += props_buf @_register_parser @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPMultipartReply(MsgBase): _STATS_MSG_TYPES = {} @staticmethod def register_stats_type(body_single_struct=False): def _register_stats_type(cls): assert cls.cls_stats_type is not None assert cls.cls_stats_type not in OFPMultipartReply._STATS_MSG_TYPES assert cls.cls_stats_body_cls is not None cls.cls_body_single_struct = body_single_struct OFPMultipartReply._STATS_MSG_TYPES[cls.cls_stats_type] = cls return cls return _register_stats_type def __init__(self, datapath, body=None, flags=None): super(OFPMultipartReply, self).__init__(datapath) self.body = body self.flags = flags @classmethod def parser_stats_body(cls, buf, msg_len, offset): body_cls = cls.cls_stats_body_cls body = [] while offset < msg_len: entry = body_cls.parser(buf, offset) body.append(entry) offset += entry.length if cls.cls_body_single_struct: return body[0] return body @classmethod def parser_stats(cls, datapath, version, msg_type, msg_len, xid, buf): msg = MsgBase.parser.__func__( cls, datapath, version, msg_type, msg_len, xid, buf) msg.body = msg.parser_stats_body(msg.buf, msg.msg_len, ofproto.OFP_MULTIPART_REPLY_SIZE) return msg @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): type_, flags = struct.unpack_from( ofproto.OFP_MULTIPART_REPLY_PACK_STR, bytes(buf), ofproto.OFP_HEADER_SIZE) stats_type_cls = cls._STATS_MSG_TYPES.get(type_) msg = super(OFPMultipartReply, stats_type_cls).parser( datapath, version, msg_type, msg_len, xid, buf) msg.type = type_ msg.flags = flags offset = ofproto.OFP_MULTIPART_REPLY_SIZE body = [] while offset < msg_len: b = stats_type_cls.cls_stats_body_cls.parser(msg.buf, offset) body.append(b) offset += b.length if hasattr(b, 'length') else b.len if stats_type_cls.cls_body_single_struct: msg.body = body[0] else: msg.body = body return msg class OFPDescStats(ofproto_parser.namedtuple('OFPDescStats', ( 'mfr_desc', 'hw_desc', 'sw_desc', 'serial_num', 'dp_desc'))): _TYPE = { 'ascii': [ 'mfr_desc', 'hw_desc', 'sw_desc', 'serial_num', 'dp_desc', ] } @classmethod def parser(cls, buf, offset): desc = struct.unpack_from(ofproto.OFP_DESC_PACK_STR, buf, offset) desc = list(desc) desc = [x.rstrip(b'\0') for x in desc] stats = cls(*desc) stats.length = ofproto.OFP_DESC_SIZE return stats @_set_stats_type(ofproto.OFPMP_DESC, OFPDescStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPDescStatsRequest(OFPMultipartRequest): """ Description statistics request message The controller uses this message to query description of the switch. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or ``OFPMPF_REQ_MORE`` ================ ====================================================== Example:: def send_desc_stats_request(self, datapath): ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPDescStatsRequest(datapath, 0) datapath.send_msg(req) """ def __init__(self, datapath, flags=0, type_=None): super(OFPDescStatsRequest, self).__init__(datapath, flags) @OFPMultipartReply.register_stats_type(body_single_struct=True) @_set_stats_type(ofproto.OFPMP_DESC, OFPDescStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPDescStatsReply(OFPMultipartReply): """ Description statistics reply message The switch responds with this message to a description statistics request. ================ ====================================================== Attribute Description ================ ====================================================== body Instance of ``OFPDescStats`` ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPDescStatsReply, MAIN_DISPATCHER) def desc_stats_reply_handler(self, ev): body = ev.msg.body self.logger.debug('DescStats: mfr_desc=%s hw_desc=%s sw_desc=%s ' 'serial_num=%s dp_desc=%s', body.mfr_desc, body.hw_desc, body.sw_desc, body.serial_num, body.dp_desc) """ def __init__(self, datapath, type_=None, **kwargs): super(OFPDescStatsReply, self).__init__(datapath, **kwargs) class OFPTableFeaturesStats(StringifyMixin): _TYPE = { 'utf-8': [ # OF spec is unclear about the encoding of name. # we assumes UTF-8. 'name', ] } def __init__(self, table_id=None, name=None, metadata_match=None, metadata_write=None, config=None, max_entries=None, properties=None, length=None): super(OFPTableFeaturesStats, self).__init__() self.length = None self.table_id = table_id self.name = name self.metadata_match = metadata_match self.metadata_write = metadata_write self.config = config self.max_entries = max_entries self.properties = properties @classmethod def parser(cls, buf, offset): table_features = cls() (table_features.length, table_features.table_id, name, table_features.metadata_match, table_features.metadata_write, table_features.config, table_features.max_entries ) = struct.unpack_from(ofproto.OFP_TABLE_FEATURES_PACK_STR, buf, offset) table_features.name = name.rstrip(b'\0') props = [] rest = buf[offset + ofproto.OFP_TABLE_FEATURES_SIZE: offset + table_features.length] while rest: p, rest = OFPTableFeatureProp.parse(rest) props.append(p) table_features.properties = props return table_features def serialize(self): # fixup bin_props = bytearray() for p in self.properties: bin_props += p.serialize() self.length = ofproto.OFP_TABLE_FEATURES_SIZE + len(bin_props) buf = bytearray() msg_pack_into(ofproto.OFP_TABLE_FEATURES_PACK_STR, buf, 0, self.length, self.table_id, self.name, self.metadata_match, self.metadata_write, self.config, self.max_entries) return buf + bin_props class OFPTableFeatureProp(OFPPropBase): _TYPES = {} class OFPInstructionId(StringifyMixin): _PACK_STR = '!HH' # type, len def __init__(self, type_, len_=None): self.type = type_ self.len = len_ # XXX experimenter @classmethod def parse(cls, buf): (type_, len_,) = struct.unpack_from(cls._PACK_STR, bytes(buf), 0) rest = buf[len_:] return cls(type_=type_, len_=len_), rest def serialize(self): # fixup self.len = struct.calcsize(self._PACK_STR) buf = bytearray() msg_pack_into(self._PACK_STR, buf, 0, self.type, self.len) return buf @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_INSTRUCTIONS) @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_INSTRUCTIONS_MISS) class OFPTableFeaturePropInstructions(OFPTableFeatureProp): def __init__(self, type_=None, length=None, instruction_ids=None): instruction_ids = instruction_ids if instruction_ids else [] super(OFPTableFeaturePropInstructions, self).__init__(type_, length) self.instruction_ids = instruction_ids @classmethod def parser(cls, buf): rest = cls.get_rest(buf) ids = [] while rest: i, rest = OFPInstructionId.parse(rest) ids.append(i) return cls(instruction_ids=ids) def serialize_body(self): bin_ids = bytearray() for i in self.instruction_ids: bin_ids += i.serialize() return bin_ids # Implementation note: While OpenFlow 1.3.2 shares the same ofp_action_header # for flow_mod and table_features, we have separate classes. We named this # class to match with OpenFlow 1.4's name. (ofp_action_id) class OFPActionId(StringifyMixin): _PACK_STR = '!HH' # type, len def __init__(self, type_, len_=None): self.type = type_ self.len = len_ # XXX experimenter @classmethod def parse(cls, buf): (type_, len_,) = struct.unpack_from(cls._PACK_STR, bytes(buf), 0) rest = buf[len_:] return cls(type_=type_, len_=len_), rest def serialize(self): # fixup self.len = struct.calcsize(self._PACK_STR) buf = bytearray() msg_pack_into(self._PACK_STR, buf, 0, self.type, self.len) return buf @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_WRITE_ACTIONS) @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_WRITE_ACTIONS_MISS) @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_APPLY_ACTIONS) @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_APPLY_ACTIONS_MISS) class OFPTableFeaturePropActions(OFPTableFeatureProp): def __init__(self, type_=None, length=None, action_ids=None): action_ids = action_ids if action_ids else [] super(OFPTableFeaturePropActions, self).__init__(type_, length) self.action_ids = action_ids @classmethod def parser(cls, buf): rest = cls.get_rest(buf) ids = [] while rest: i, rest = OFPActionId.parse(rest) ids.append(i) return cls(action_ids=ids) def serialize_body(self): bin_ids = bytearray() for i in self.action_ids: bin_ids += i.serialize() return bin_ids @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_NEXT_TABLES) @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_NEXT_TABLES_MISS) @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_TABLE_SYNC_FROM) class OFPTableFeaturePropNextTables(OFPTableFeatureProp): _TABLE_ID_PACK_STR = '!B' def __init__(self, type_=None, length=None, table_ids=None): table_ids = table_ids if table_ids else [] super(OFPTableFeaturePropNextTables, self).__init__(type_, length) self.table_ids = table_ids @classmethod def parser(cls, buf): rest = cls.get_rest(buf) ids = [] while rest: (i,) = struct.unpack_from(cls._TABLE_ID_PACK_STR, bytes(rest), 0) rest = rest[struct.calcsize(cls._TABLE_ID_PACK_STR):] ids.append(i) return cls(table_ids=ids) def serialize_body(self): bin_ids = bytearray() for i in self.table_ids: bin_id = bytearray() msg_pack_into(self._TABLE_ID_PACK_STR, bin_id, 0, i) bin_ids += bin_id return bin_ids # Implementation note: OFPOxmId is specific to this implementation. # It does not have a corresponding structure in the specification. # (the specification uses plain uint32_t for non-experimenter OXMs # and uint64_t for experimenter OXMs.) # # i have taken a look at some of software switch implementations # but they all look broken or incomplete. according to the spec, # oxm_hasmask should be 1 if a switch supports masking for the type. # the right value for oxm_length is not clear from the spec. # update: OpenFlow 1.3.3 "clarified" that oxm_length here is the payload # length. it's still unclear if it should be doubled for hasmask or not, # though. # ofsoftswitch13 # oxm_hasmask always 0 # oxm_length same as ofp_match etc (as without mask) # linc/of_protocol # oxm_hasmask always 0 # oxm_length always 0 # ovs: # seems in flux as of writing this [20141003] class OFPOxmId(StringifyMixin): _PACK_STR = '!I' # oxm header _EXPERIMENTER_ID_PACK_STR = '!I' _TYPE = { 'ascii': [ 'type', ], } def __init__(self, type_, hasmask=False, length=None): self.type = type_ self.hasmask = hasmask self.length = length @classmethod def parse(cls, buf): (oxm,) = struct.unpack_from(cls._PACK_STR, bytes(buf), 0) # oxm (32 bit) == class (16) | field (7) | hasmask (1) | length (8) # in case of experimenter OXMs, another 32 bit value # (experimenter id) follows. (type_, _v) = ofproto.oxm_to_user(oxm >> (1 + 8), None, None) rest = buf[struct.calcsize(cls._PACK_STR):] hasmask = ofproto.oxm_tlv_header_extract_hasmask(oxm) length = oxm & 0xff # XXX see the comment on OFPOxmId class_ = oxm >> (7 + 1 + 8) if class_ == ofproto.OFPXMC_EXPERIMENTER: (exp_id,) = struct.unpack_from(cls._EXPERIMENTER_ID_PACK_STR, bytes(rest), 0) rest = rest[struct.calcsize(cls._EXPERIMENTER_ID_PACK_STR):] subcls = OFPExperimenterOxmId return subcls(type_=type_, exp_id=exp_id, hasmask=hasmask, length=length), rest else: return cls(type_=type_, hasmask=hasmask, length=length), rest def serialize(self): # fixup self.length = 0 # XXX see the comment on OFPOxmId (n, _v, _m) = ofproto.oxm_from_user(self.type, None) oxm = (n << (1 + 8)) | (self.hasmask << 8) | self.length buf = bytearray() msg_pack_into(self._PACK_STR, buf, 0, oxm) assert n >> 7 != ofproto.OFPXMC_EXPERIMENTER return buf class OFPExperimenterOxmId(OFPOxmId): def __init__(self, type_, exp_id, hasmask=False, length=None): super(OFPExperimenterOxmId, self).__init__(type_=type_, hasmask=hasmask, length=length) self.exp_id = exp_id def serialize(self): buf = super(OFPExperimenterOxmId, self).serialize() msg_pack_into(self._EXPERIMENTER_ID_PACK_STR, buf, struct.calcsize(self._PACK_STR), self.exp_id) @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_MATCH) @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_WILDCARDS) @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_WRITE_SETFIELD) @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_WRITE_SETFIELD_MISS) @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_APPLY_SETFIELD) @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_APPLY_SETFIELD_MISS) class OFPTableFeaturePropOxm(OFPTableFeatureProp): def __init__(self, type_=None, length=None, oxm_ids=None): oxm_ids = oxm_ids if oxm_ids else [] super(OFPTableFeaturePropOxm, self).__init__(type_, length) self.oxm_ids = oxm_ids @classmethod def parser(cls, buf): rest = cls.get_rest(buf) ids = [] while rest: i, rest = OFPOxmId.parse(rest) ids.append(i) return cls(oxm_ids=ids) def serialize_body(self): bin_ids = bytearray() for i in self.oxm_ids: bin_ids += i.serialize() return bin_ids @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_EXPERIMENTER) @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_EXPERIMENTER_MISS) class OFPTableFeaturePropExperimenter(OFPPropCommonExperimenter4ByteData): pass @_set_stats_type(ofproto.OFPMP_TABLE_FEATURES, OFPTableFeaturesStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPTableFeaturesStatsRequest(OFPMultipartRequest): """ Table features statistics request message The controller uses this message to query table features. ================ ====================================================== Attribute Description ================ ====================================================== body List of ``OFPTableFeaturesStats`` instances. The default is []. ================ ====================================================== """ def __init__(self, datapath, flags=0, body=None, type_=None): body = body if body else [] super(OFPTableFeaturesStatsRequest, self).__init__(datapath, flags) self.body = body def _serialize_stats_body(self): bin_body = bytearray() for p in self.body: bin_body += p.serialize() self.buf += bin_body @OFPMultipartReply.register_stats_type() @_set_stats_type(ofproto.OFPMP_TABLE_FEATURES, OFPTableFeaturesStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPTableFeaturesStatsReply(OFPMultipartReply): """ Table features statistics reply message The switch responds with this message to a table features statistics request. ================ ====================================================== Attribute Description ================ ====================================================== body List of ``OFPTableFeaturesStats`` instance ================ ====================================================== """ def __init__(self, datapath, type_=None, **kwargs): super(OFPTableFeaturesStatsReply, self).__init__(datapath, **kwargs) @_set_stats_type(ofproto.OFPMP_PORT_DESC, OFPPort) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPPortDescStatsRequest(OFPMultipartRequest): """ Port description request message The controller uses this message to query description of all the ports. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or ``OFPMPF_REQ_MORE`` ================ ====================================================== Example:: def send_port_desc_stats_request(self, datapath): ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPPortDescStatsRequest(datapath, 0) datapath.send_msg(req) """ def __init__(self, datapath, flags=0, type_=None): super(OFPPortDescStatsRequest, self).__init__(datapath, flags) @OFPMultipartReply.register_stats_type() @_set_stats_type(ofproto.OFPMP_PORT_DESC, OFPPort) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPPortDescStatsReply(OFPMultipartReply): """ Port description reply message The switch responds with this message to a port description request. ================ ====================================================== Attribute Description ================ ====================================================== body List of ``OFPPort`` instance ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPPortDescStatsReply, MAIN_DISPATCHER) def port_desc_stats_reply_handler(self, ev): ports = [] for p in ev.msg.body: ports.append('port_no=%d hw_addr=%s name=%s config=0x%08x ' 'state=0x%08x properties=%s' % (p.port_no, p.hw_addr, p.name, p.config, p.state, repr(p.properties))) self.logger.debug('OFPPortDescStatsReply received: %s', ports) """ def __init__(self, datapath, type_=None, **kwargs): super(OFPPortDescStatsReply, self).__init__(datapath, **kwargs) @_set_stats_type(ofproto.OFPMP_TABLE_DESC, OFPTableDesc) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPTableDescStatsRequest(OFPMultipartRequest): """ Table description request message The controller uses this message to query description of all the tables. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or ``OFPMPF_REQ_MORE`` ================ ====================================================== Example:: def send_table_desc_stats_request(self, datapath): ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPTableDescStatsRequest(datapath, 0) datapath.send_msg(req) """ def __init__(self, datapath, flags=0, type_=None): super(OFPTableDescStatsRequest, self).__init__(datapath, flags) @OFPMultipartReply.register_stats_type() @_set_stats_type(ofproto.OFPMP_TABLE_DESC, OFPTableDesc) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPTableDescStatsReply(OFPMultipartReply): """ Table description reply message The switch responds with this message to a table description request. ================ ====================================================== Attribute Description ================ ====================================================== body List of ``OFPTableDesc`` instance ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPTableDescStatsReply, MAIN_DISPATCHER) def table_desc_stats_reply_handler(self, ev): tables = [] for p in ev.msg.body: tables.append('table_id=%d config=0x%08x properties=%s' % (p.table_id, p.config, repr(p.properties))) self.logger.debug('OFPTableDescStatsReply received: %s', tables) """ def __init__(self, datapath, type_=None, **kwargs): super(OFPTableDescStatsReply, self).__init__(datapath, **kwargs) @_set_stats_type(ofproto.OFPMP_QUEUE_DESC, OFPQueueDesc) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPQueueDescStatsRequest(OFPMultipartRequest): """ Queue description request message The controller uses this message to query description of all the queues. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or ``OFPMPF_REQ_MORE`` port_no Port number to read (OFPP_ANY for all ports) queue_id ID of queue to read (OFPQ_ALL for all queues) ================ ====================================================== Example:: def send_queue_desc_stats_request(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPQueueDescStatsRequest(datapath, 0, ofp.OFPP_ANY, ofp.OFPQ_ALL) datapath.send_msg(req) """ def __init__(self, datapath, flags=0, port_no=ofproto.OFPP_ANY, queue_id=ofproto.OFPQ_ALL, type_=None): super(OFPQueueDescStatsRequest, self).__init__(datapath, flags) self.port_no = port_no self.queue_id = queue_id def _serialize_stats_body(self): msg_pack_into(ofproto.OFP_QUEUE_DESC_REQUEST_PACK_STR, self.buf, ofproto.OFP_MULTIPART_REQUEST_SIZE, self.port_no, self.queue_id) @OFPMultipartReply.register_stats_type() @_set_stats_type(ofproto.OFPMP_QUEUE_DESC, OFPQueueDesc) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPQueueDescStatsReply(OFPMultipartReply): """ Queue description reply message The switch responds with this message to a queue description request. ================ ====================================================== Attribute Description ================ ====================================================== body List of ``OFPQueueDesc`` instance ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPQueueDescStatsReply, MAIN_DISPATCHER) def queue_desc_stats_reply_handler(self, ev): queues = [] for q in ev.msg.body: queues.append('port_no=%d queue_id=0x%08x properties=%s' % (q.port_no, q.queue_id, repr(q.properties))) self.logger.debug('OFPQueueDescStatsReply received: %s', queues) """ def __init__(self, datapath, type_=None, **kwargs): super(OFPQueueDescStatsReply, self).__init__(datapath, **kwargs) class OFPQueueStatsProp(OFPPropBase): _TYPES = {} @OFPQueueStatsProp.register_type(ofproto.OFPQSPT_EXPERIMENTER) class OFPQueueStatsPropExperimenter(OFPPropCommonExperimenter4ByteData): pass class OFPQueueStats(StringifyMixin): def __init__(self, length=None, port_no=None, queue_id=None, tx_bytes=None, tx_packets=None, tx_errors=None, duration_sec=None, duration_nsec=None, properties=None): super(OFPQueueStats, self).__init__() self.length = length self.port_no = port_no self.queue_id = queue_id self.tx_bytes = tx_bytes self.tx_packets = tx_packets self.tx_errors = tx_errors self.duration_sec = duration_sec self.duration_nsec = duration_nsec self.properties = properties @classmethod def parser(cls, buf, offset): (length, port_no, queue_id, tx_bytes, tx_packets, tx_errors, duration_sec, duration_nsec) = struct.unpack_from( ofproto.OFP_QUEUE_STATS_PACK_STR, buf, offset) props = [] rest = buf[offset + ofproto.OFP_QUEUE_STATS_SIZE:offset + length] while rest: p, rest = OFPQueueStatsProp.parse(rest) props.append(p) stats = cls(length, port_no, queue_id, tx_bytes, tx_packets, tx_errors, duration_sec, duration_nsec, props) return stats @_set_stats_type(ofproto.OFPMP_QUEUE_STATS, OFPQueueStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPQueueStatsRequest(OFPMultipartRequest): """ Queue statistics request message The controller uses this message to query queue statictics. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or ``OFPMPF_REQ_MORE`` port_no Port number to read queue_id ID of queue to read ================ ====================================================== Example:: def send_queue_stats_request(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPQueueStatsRequest(datapath, 0, ofp.OFPP_ANY, ofp.OFPQ_ALL) datapath.send_msg(req) """ def __init__(self, datapath, flags=0, port_no=ofproto.OFPP_ANY, queue_id=ofproto.OFPQ_ALL, type_=None): super(OFPQueueStatsRequest, self).__init__(datapath, flags) self.port_no = port_no self.queue_id = queue_id def _serialize_stats_body(self): msg_pack_into(ofproto.OFP_QUEUE_STATS_REQUEST_PACK_STR, self.buf, ofproto.OFP_MULTIPART_REQUEST_SIZE, self.port_no, self.queue_id) @OFPMultipartReply.register_stats_type() @_set_stats_type(ofproto.OFPMP_QUEUE_STATS, OFPQueueStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPQueueStatsReply(OFPMultipartReply): """ Queue statistics reply message The switch responds with this message to an aggregate flow statistics request. ================ ====================================================== Attribute Description ================ ====================================================== body List of ``OFPQueueStats`` instance ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPQueueStatsReply, MAIN_DISPATCHER) def queue_stats_reply_handler(self, ev): queues = [] for stat in ev.msg.body: queues.append('port_no=%d queue_id=%d ' 'tx_bytes=%d tx_packets=%d tx_errors=%d ' 'duration_sec=%d duration_nsec=%d' 'properties=%s' % (stat.port_no, stat.queue_id, stat.tx_bytes, stat.tx_packets, stat.tx_errors, stat.duration_sec, stat.duration_nsec, repr(stat.properties))) self.logger.debug('QueueStats: %s', queues) """ def __init__(self, datapath, type_=None, **kwargs): super(OFPQueueStatsReply, self).__init__(datapath, **kwargs) class OFPBucketCounter(StringifyMixin): def __init__(self, packet_count, byte_count): super(OFPBucketCounter, self).__init__() self.packet_count = packet_count self.byte_count = byte_count @classmethod def parser(cls, buf, offset): packet_count, byte_count = struct.unpack_from( ofproto.OFP_BUCKET_COUNTER_PACK_STR, buf, offset) return cls(packet_count, byte_count) class OFPGroupStats(StringifyMixin): def __init__(self, length=None, group_id=None, ref_count=None, packet_count=None, byte_count=None, duration_sec=None, duration_nsec=None, bucket_stats=None): super(OFPGroupStats, self).__init__() self.length = length self.group_id = group_id self.ref_count = ref_count self.packet_count = packet_count self.byte_count = byte_count self.duration_sec = duration_sec self.duration_nsec = duration_nsec self.bucket_stats = bucket_stats @classmethod def parser(cls, buf, offset): group = struct.unpack_from(ofproto.OFP_GROUP_STATS_PACK_STR, buf, offset) group_stats = cls(*group) group_stats.bucket_stats = [] total_len = group_stats.length + offset offset += ofproto.OFP_GROUP_STATS_SIZE while total_len > offset: b = OFPBucketCounter.parser(buf, offset) group_stats.bucket_stats.append(b) offset += ofproto.OFP_BUCKET_COUNTER_SIZE return group_stats @_set_stats_type(ofproto.OFPMP_GROUP, OFPGroupStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPGroupStatsRequest(OFPMultipartRequest): """ Group statistics request message The controller uses this message to query statistics of one or more groups. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or ``OFPMPF_REQ_MORE`` group_id ID of group to read (OFPG_ALL to all groups) ================ ====================================================== Example:: def send_group_stats_request(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPGroupStatsRequest(datapath, 0, ofp.OFPG_ALL) datapath.send_msg(req) """ def __init__(self, datapath, flags=0, group_id=ofproto.OFPG_ALL, type_=None): super(OFPGroupStatsRequest, self).__init__(datapath, flags) self.group_id = group_id def _serialize_stats_body(self): msg_pack_into(ofproto.OFP_GROUP_STATS_REQUEST_PACK_STR, self.buf, ofproto.OFP_MULTIPART_REQUEST_SIZE, self.group_id) @OFPMultipartReply.register_stats_type() @_set_stats_type(ofproto.OFPMP_GROUP, OFPGroupStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPGroupStatsReply(OFPMultipartReply): """ Group statistics reply message The switch responds with this message to a group statistics request. ================ ====================================================== Attribute Description ================ ====================================================== body List of ``OFPGroupStats`` instance ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPGroupStatsReply, MAIN_DISPATCHER) def group_stats_reply_handler(self, ev): groups = [] for stat in ev.msg.body: groups.append('length=%d group_id=%d ' 'ref_count=%d packet_count=%d byte_count=%d ' 'duration_sec=%d duration_nsec=%d' % (stat.length, stat.group_id, stat.ref_count, stat.packet_count, stat.byte_count, stat.duration_sec, stat.duration_nsec)) self.logger.debug('GroupStats: %s', groups) """ def __init__(self, datapath, type_=None, **kwargs): super(OFPGroupStatsReply, self).__init__(datapath, **kwargs) class OFPGroupDescStats(StringifyMixin): def __init__(self, type_=None, group_id=None, buckets=None, length=None): super(OFPGroupDescStats, self).__init__() self.type = type_ self.group_id = group_id self.buckets = buckets @classmethod def parser(cls, buf, offset): stats = cls() (stats.length, stats.type, stats.group_id) = struct.unpack_from( ofproto.OFP_GROUP_DESC_STATS_PACK_STR, buf, offset) offset += ofproto.OFP_GROUP_DESC_STATS_SIZE stats.buckets = [] length = ofproto.OFP_GROUP_DESC_STATS_SIZE while length < stats.length: bucket = OFPBucket.parser(buf, offset) stats.buckets.append(bucket) offset += bucket.len length += bucket.len return stats @_set_stats_type(ofproto.OFPMP_GROUP_DESC, OFPGroupDescStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPGroupDescStatsRequest(OFPMultipartRequest): """ Group description request message The controller uses this message to list the set of groups on a switch. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or ``OFPMPF_REQ_MORE`` ================ ====================================================== Example:: def send_group_desc_stats_request(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPGroupDescStatsRequest(datapath, 0) datapath.send_msg(req) """ def __init__(self, datapath, flags=0, type_=None): super(OFPGroupDescStatsRequest, self).__init__(datapath, flags) @OFPMultipartReply.register_stats_type() @_set_stats_type(ofproto.OFPMP_GROUP_DESC, OFPGroupDescStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPGroupDescStatsReply(OFPMultipartReply): """ Group description reply message The switch responds with this message to a group description request. ================ ====================================================== Attribute Description ================ ====================================================== body List of ``OFPGroupDescStats`` instance ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPGroupDescStatsReply, MAIN_DISPATCHER) def group_desc_stats_reply_handler(self, ev): descs = [] for stat in ev.msg.body: descs.append('length=%d type=%d group_id=%d ' 'buckets=%s' % (stat.length, stat.type, stat.group_id, stat.bucket)) self.logger.debug('GroupDescStats: %s', descs) """ def __init__(self, datapath, type_=None, **kwargs): super(OFPGroupDescStatsReply, self).__init__(datapath, **kwargs) class OFPGroupFeaturesStats(ofproto_parser.namedtuple('OFPGroupFeaturesStats', ('types', 'capabilities', 'max_groups', 'actions'))): @classmethod def parser(cls, buf, offset): group_features = struct.unpack_from( ofproto.OFP_GROUP_FEATURES_PACK_STR, buf, offset) types = group_features[0] capabilities = group_features[1] max_groups = list(group_features[2:6]) actions = list(group_features[6:10]) stats = cls(types, capabilities, max_groups, actions) stats.length = ofproto.OFP_GROUP_FEATURES_SIZE return stats @_set_stats_type(ofproto.OFPMP_GROUP_FEATURES, OFPGroupFeaturesStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPGroupFeaturesStatsRequest(OFPMultipartRequest): """ Group features request message The controller uses this message to list the capabilities of groups on a switch. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or ``OFPMPF_REQ_MORE`` ================ ====================================================== Example:: def send_group_features_stats_request(self, datapath): ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPGroupFeaturesStatsRequest(datapath, 0) datapath.send_msg(req) """ def __init__(self, datapath, flags=0, type_=None): super(OFPGroupFeaturesStatsRequest, self).__init__(datapath, flags) @OFPMultipartReply.register_stats_type(body_single_struct=True) @_set_stats_type(ofproto.OFPMP_GROUP_FEATURES, OFPGroupFeaturesStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPGroupFeaturesStatsReply(OFPMultipartReply): """ Group features reply message The switch responds with this message to a group features request. ================ ====================================================== Attribute Description ================ ====================================================== body Instance of ``OFPGroupFeaturesStats`` ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPGroupFeaturesStatsReply, MAIN_DISPATCHER) def group_features_stats_reply_handler(self, ev): body = ev.msg.body self.logger.debug('GroupFeaturesStats: types=%d ' 'capabilities=0x%08x max_groups=%s ' 'actions=%s', body.types, body.capabilities, body.max_groups, body.actions) """ def __init__(self, datapath, type_=None, **kwargs): super(OFPGroupFeaturesStatsReply, self).__init__(datapath, **kwargs) class OFPMeterBandStats(StringifyMixin): def __init__(self, packet_band_count, byte_band_count): super(OFPMeterBandStats, self).__init__() self.packet_band_count = packet_band_count self.byte_band_count = byte_band_count @classmethod def parser(cls, buf, offset): band_stats = struct.unpack_from( ofproto.OFP_METER_BAND_STATS_PACK_STR, buf, offset) return cls(*band_stats) class OFPMeterStats(StringifyMixin): def __init__(self, meter_id=None, flow_count=None, packet_in_count=None, byte_in_count=None, duration_sec=None, duration_nsec=None, band_stats=None, len_=None): super(OFPMeterStats, self).__init__() self.meter_id = meter_id self.len = 0 self.flow_count = flow_count self.packet_in_count = packet_in_count self.byte_in_count = byte_in_count self.duration_sec = duration_sec self.duration_nsec = duration_nsec self.band_stats = band_stats @classmethod def parser(cls, buf, offset): meter_stats = cls() (meter_stats.meter_id, meter_stats.len, meter_stats.flow_count, meter_stats.packet_in_count, meter_stats.byte_in_count, meter_stats.duration_sec, meter_stats.duration_nsec) = struct.unpack_from( ofproto.OFP_METER_STATS_PACK_STR, buf, offset) offset += ofproto.OFP_METER_STATS_SIZE meter_stats.band_stats = [] length = ofproto.OFP_METER_STATS_SIZE while length < meter_stats.len: band_stats = OFPMeterBandStats.parser(buf, offset) meter_stats.band_stats.append(band_stats) offset += ofproto.OFP_METER_BAND_STATS_SIZE length += ofproto.OFP_METER_BAND_STATS_SIZE return meter_stats @_set_stats_type(ofproto.OFPMP_METER, OFPMeterStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPMeterStatsRequest(OFPMultipartRequest): """ Meter statistics request message The controller uses this message to query statistics for one or more meters. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or ``OFPMPF_REQ_MORE`` meter_id ID of meter to read (OFPM_ALL to all meters) ================ ====================================================== Example:: def send_meter_stats_request(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPMeterStatsRequest(datapath, 0, ofp.OFPM_ALL) datapath.send_msg(req) """ def __init__(self, datapath, flags=0, meter_id=ofproto.OFPM_ALL, type_=None): super(OFPMeterStatsRequest, self).__init__(datapath, flags) self.meter_id = meter_id def _serialize_stats_body(self): msg_pack_into(ofproto.OFP_METER_MULTIPART_REQUEST_PACK_STR, self.buf, ofproto.OFP_MULTIPART_REQUEST_SIZE, self.meter_id) @OFPMultipartReply.register_stats_type() @_set_stats_type(ofproto.OFPMP_METER, OFPMeterStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPMeterStatsReply(OFPMultipartReply): """ Meter statistics reply message The switch responds with this message to a meter statistics request. ================ ====================================================== Attribute Description ================ ====================================================== body List of ``OFPMeterStats`` instance ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPMeterStatsReply, MAIN_DISPATCHER) def meter_stats_reply_handler(self, ev): meters = [] for stat in ev.msg.body: meters.append('meter_id=0x%08x len=%d flow_count=%d ' 'packet_in_count=%d byte_in_count=%d ' 'duration_sec=%d duration_nsec=%d ' 'band_stats=%s' % (stat.meter_id, stat.len, stat.flow_count, stat.packet_in_count, stat.byte_in_count, stat.duration_sec, stat.duration_nsec, stat.band_stats)) self.logger.debug('MeterStats: %s', meters) """ def __init__(self, datapath, type_=None, **kwargs): super(OFPMeterStatsReply, self).__init__(datapath, **kwargs) class OFPMeterBand(StringifyMixin): def __init__(self, type_, len_): super(OFPMeterBand, self).__init__() self.type = type_ self.len = len_ class OFPMeterBandHeader(OFPMeterBand): _METER_BAND = {} @staticmethod def register_meter_band_type(type_, len_): def _register_meter_band_type(cls): OFPMeterBandHeader._METER_BAND[type_] = cls cls.cls_meter_band_type = type_ cls.cls_meter_band_len = len_ return cls return _register_meter_band_type def __init__(self): cls = self.__class__ super(OFPMeterBandHeader, self).__init__(cls.cls_meter_band_type, cls.cls_meter_band_len) @classmethod def parser(cls, buf, offset): type_, len_, _rate, _burst_size = struct.unpack_from( ofproto.OFP_METER_BAND_HEADER_PACK_STR, buf, offset) cls_ = cls._METER_BAND[type_] assert cls_.cls_meter_band_len == len_ return cls_.parser(buf, offset) @OFPMeterBandHeader.register_meter_band_type( ofproto.OFPMBT_DROP, ofproto.OFP_METER_BAND_DROP_SIZE) class OFPMeterBandDrop(OFPMeterBandHeader): def __init__(self, rate=0, burst_size=0, type_=None, len_=None): super(OFPMeterBandDrop, self).__init__() self.rate = rate self.burst_size = burst_size def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_METER_BAND_DROP_PACK_STR, buf, offset, self.type, self.len, self.rate, self.burst_size) @classmethod def parser(cls, buf, offset): type_, len_, rate, burst_size = struct.unpack_from( ofproto.OFP_METER_BAND_DROP_PACK_STR, buf, offset) assert cls.cls_meter_band_type == type_ assert cls.cls_meter_band_len == len_ return cls(rate, burst_size) @OFPMeterBandHeader.register_meter_band_type( ofproto.OFPMBT_DSCP_REMARK, ofproto.OFP_METER_BAND_DSCP_REMARK_SIZE) class OFPMeterBandDscpRemark(OFPMeterBandHeader): def __init__(self, rate=0, burst_size=0, prec_level=0, type_=None, len_=None): super(OFPMeterBandDscpRemark, self).__init__() self.rate = rate self.burst_size = burst_size self.prec_level = prec_level def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_METER_BAND_DSCP_REMARK_PACK_STR, buf, offset, self.type, self.len, self.rate, self.burst_size, self.prec_level) @classmethod def parser(cls, buf, offset): type_, len_, rate, burst_size, prec_level = struct.unpack_from( ofproto.OFP_METER_BAND_DSCP_REMARK_PACK_STR, buf, offset) assert cls.cls_meter_band_type == type_ assert cls.cls_meter_band_len == len_ return cls(rate, burst_size, prec_level) @OFPMeterBandHeader.register_meter_band_type( ofproto.OFPMBT_EXPERIMENTER, ofproto.OFP_METER_BAND_EXPERIMENTER_SIZE) class OFPMeterBandExperimenter(OFPMeterBandHeader): def __init__(self, rate=0, burst_size=0, experimenter=None, type_=None, len_=None): super(OFPMeterBandExperimenter, self).__init__() self.rate = rate self.burst_size = burst_size self.experimenter = experimenter def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_METER_BAND_EXPERIMENTER_PACK_STR, buf, offset, self.type, self.len, self.rate, self.burst_size, self.experimenter) @classmethod def parser(cls, buf, offset): type_, len_, rate, burst_size, experimenter = struct.unpack_from( ofproto.OFP_METER_BAND_EXPERIMENTER_PACK_STR, buf, offset) assert cls.cls_meter_band_type == type_ assert cls.cls_meter_band_len == len_ return cls(rate, burst_size, experimenter) class OFPMeterConfigStats(StringifyMixin): def __init__(self, flags=None, meter_id=None, bands=None, length=None): super(OFPMeterConfigStats, self).__init__() self.length = None self.flags = flags self.meter_id = meter_id self.bands = bands @classmethod def parser(cls, buf, offset): meter_config = cls() (meter_config.length, meter_config.flags, meter_config.meter_id) = struct.unpack_from( ofproto.OFP_METER_CONFIG_PACK_STR, buf, offset) offset += ofproto.OFP_METER_CONFIG_SIZE meter_config.bands = [] length = ofproto.OFP_METER_CONFIG_SIZE while length < meter_config.length: band = OFPMeterBandHeader.parser(buf, offset) meter_config.bands.append(band) offset += band.len length += band.len return meter_config @_set_stats_type(ofproto.OFPMP_METER_CONFIG, OFPMeterConfigStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPMeterConfigStatsRequest(OFPMultipartRequest): """ Meter configuration statistics request message The controller uses this message to query configuration for one or more meters. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or ``OFPMPF_REQ_MORE`` meter_id ID of meter to read (OFPM_ALL to all meters) ================ ====================================================== Example:: def send_meter_config_stats_request(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPMeterConfigStatsRequest(datapath, 0, ofp.OFPM_ALL) datapath.send_msg(req) """ def __init__(self, datapath, flags=0, meter_id=ofproto.OFPM_ALL, type_=None): super(OFPMeterConfigStatsRequest, self).__init__(datapath, flags) self.meter_id = meter_id def _serialize_stats_body(self): msg_pack_into(ofproto.OFP_METER_MULTIPART_REQUEST_PACK_STR, self.buf, ofproto.OFP_MULTIPART_REQUEST_SIZE, self.meter_id) @OFPMultipartReply.register_stats_type() @_set_stats_type(ofproto.OFPMP_METER_CONFIG, OFPMeterConfigStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPMeterConfigStatsReply(OFPMultipartReply): """ Meter configuration statistics reply message The switch responds with this message to a meter configuration statistics request. ================ ====================================================== Attribute Description ================ ====================================================== body List of ``OFPMeterConfigStats`` instance ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPMeterConfigStatsReply, MAIN_DISPATCHER) def meter_config_stats_reply_handler(self, ev): configs = [] for stat in ev.msg.body: configs.append('length=%d flags=0x%04x meter_id=0x%08x ' 'bands=%s' % (stat.length, stat.flags, stat.meter_id, stat.bands)) self.logger.debug('MeterConfigStats: %s', configs) """ def __init__(self, datapath, type_=None, **kwargs): super(OFPMeterConfigStatsReply, self).__init__(datapath, **kwargs) class OFPMeterFeaturesStats(ofproto_parser.namedtuple('OFPMeterFeaturesStats', ('max_meter', 'band_types', 'capabilities', 'max_bands', 'max_color'))): @classmethod def parser(cls, buf, offset): meter_features = struct.unpack_from( ofproto.OFP_METER_FEATURES_PACK_STR, buf, offset) stats = cls(*meter_features) stats.length = ofproto.OFP_METER_FEATURES_SIZE return stats @_set_stats_type(ofproto.OFPMP_METER_FEATURES, OFPMeterFeaturesStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPMeterFeaturesStatsRequest(OFPMultipartRequest): """ Meter features statistics request message The controller uses this message to query the set of features of the metering subsystem. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or ``OFPMPF_REQ_MORE`` ================ ====================================================== Example:: def send_meter_features_stats_request(self, datapath): ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPMeterFeaturesStatsRequest(datapath, 0) datapath.send_msg(req) """ def __init__(self, datapath, flags=0, type_=None): super(OFPMeterFeaturesStatsRequest, self).__init__(datapath, flags) @OFPMultipartReply.register_stats_type() @_set_stats_type(ofproto.OFPMP_METER_FEATURES, OFPMeterFeaturesStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPMeterFeaturesStatsReply(OFPMultipartReply): """ Meter features statistics reply message The switch responds with this message to a meter features statistics request. ================ ====================================================== Attribute Description ================ ====================================================== body List of ``OFPMeterFeaturesStats`` instance ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPMeterFeaturesStatsReply, MAIN_DISPATCHER) def meter_features_stats_reply_handler(self, ev): features = [] for stat in ev.msg.body: features.append('max_meter=%d band_types=0x%08x ' 'capabilities=0x%08x max_bands=%d ' 'max_color=%d' % (stat.max_meter, stat.band_types, stat.capabilities, stat.max_bands, stat.max_color)) self.logger.debug('MeterFeaturesStats: %s', features) """ def __init__(self, datapath, type_=None, **kwargs): super(OFPMeterFeaturesStatsReply, self).__init__(datapath, **kwargs) class OFPFlowUpdate(StringifyMixin): def __init__(self, length, event): super(OFPFlowUpdate, self).__init__() self.length = length self.event = event class OFPFlowUpdateHeader(OFPFlowUpdate): _EVENT = {} @staticmethod def register_flow_update_event(event, length): def _register_flow_update_event(cls): OFPFlowUpdateHeader._EVENT[event] = cls cls.cls_flow_update_event = event cls.cls_flow_update_length = length return cls return _register_flow_update_event def __init__(self, length=None, event=None): cls = self.__class__ super(OFPFlowUpdateHeader, self).__init__(length, cls.cls_flow_update_event) self.length = length @classmethod def parser(cls, buf, offset): length, event = struct.unpack_from( ofproto.OFP_FLOW_UPDATE_HEADER_PACK_STR, buf, offset) cls_ = cls._EVENT[event] return cls_.parser(buf, offset) @OFPFlowUpdateHeader.register_flow_update_event( ofproto.OFPFME_INITIAL, ofproto.OFP_FLOW_UPDATE_FULL_SIZE) @OFPFlowUpdateHeader.register_flow_update_event( ofproto.OFPFME_ADDED, ofproto.OFP_FLOW_UPDATE_FULL_SIZE) @OFPFlowUpdateHeader.register_flow_update_event( ofproto.OFPFME_REMOVED, ofproto.OFP_FLOW_UPDATE_FULL_SIZE) @OFPFlowUpdateHeader.register_flow_update_event( ofproto.OFPFME_MODIFIED, ofproto.OFP_FLOW_UPDATE_FULL_SIZE) class OFPFlowUpdateFull(OFPFlowUpdateHeader): def __init__(self, length=None, event=None, table_id=None, reason=None, idle_timeout=None, hard_timeout=None, priority=None, cookie=None, match=None, instructions=None): instructions = instructions if instructions else [] super(OFPFlowUpdateFull, self).__init__(length, event) self.table_id = table_id self.reason = reason self.idle_timeout = idle_timeout self.hard_timeout = hard_timeout self.priority = priority self.cookie = cookie self.match = match assert (event != ofproto.OFPFME_REMOVED or len(instructions) == 0) for i in instructions: assert isinstance(i, OFPInstruction) self.instructions = instructions @classmethod def parser(cls, buf, offset): (length, event, table_id, reason, idle_timeout, hard_timeout, priority, cookie) = struct.unpack_from(ofproto.OFP_FLOW_UPDATE_FULL_0_PACK_STR, buf, offset) offset += ofproto.OFP_FLOW_UPDATE_FULL_0_SIZE assert cls.cls_flow_update_length <= length assert cls.cls_flow_update_event == event match = OFPMatch.parser(buf, offset) match_length = utils.round_up(match.length, 8) offset += match_length inst_length = (length - ofproto.OFP_FLOW_UPDATE_FULL_0_SIZE - match_length) instructions = [] while inst_length > 0: inst = OFPInstruction.parser(buf, offset) instructions.append(inst) offset += inst.len inst_length -= inst.len return cls(length, event, table_id, reason, idle_timeout, hard_timeout, priority, cookie, match, instructions) @OFPFlowUpdateHeader.register_flow_update_event( ofproto.OFPFME_ABBREV, ofproto.OFP_FLOW_UPDATE_ABBREV_SIZE) class OFPFlowUpdateAbbrev(OFPFlowUpdateHeader): def __init__(self, length=None, event=None, xid=None): super(OFPFlowUpdateAbbrev, self).__init__(length, event) self.xid = xid @classmethod def parser(cls, buf, offset): length, event, xid = struct.unpack_from( ofproto.OFP_FLOW_UPDATE_ABBREV_PACK_STR, buf, offset) assert cls.cls_flow_update_length == length assert cls.cls_flow_update_event == event return cls(length, event, xid) @OFPFlowUpdateHeader.register_flow_update_event( ofproto.OFPFME_PAUSED, ofproto.OFP_FLOW_UPDATE_PAUSED_SIZE) @OFPFlowUpdateHeader.register_flow_update_event( ofproto.OFPFME_RESUMED, ofproto.OFP_FLOW_UPDATE_PAUSED_SIZE) class OFPFlowUpdatePaused(OFPFlowUpdateHeader): @classmethod def parser(cls, buf, offset): length, event = struct.unpack_from( ofproto.OFP_FLOW_UPDATE_PAUSED_PACK_STR, buf, offset) assert cls.cls_flow_update_length == length assert cls.cls_flow_update_event == event return cls(length, event) class OFPFlowMonitorRequestBase(OFPMultipartRequest): def __init__(self, datapath, flags, monitor_id, out_port, out_group, monitor_flags, table_id, command, match): super(OFPFlowMonitorRequestBase, self).__init__(datapath, flags) self.monitor_id = monitor_id self.out_port = out_port self.out_group = out_group self.monitor_flags = monitor_flags self.table_id = table_id self.command = command self.match = match def _serialize_stats_body(self): offset = ofproto.OFP_MULTIPART_REQUEST_SIZE msg_pack_into(ofproto.OFP_FLOW_MONITOR_REQUEST_0_PACK_STR, self.buf, offset, self.monitor_id, self.out_port, self.out_group, self.monitor_flags, self.table_id, self.command) offset += ofproto.OFP_FLOW_MONITOR_REQUEST_0_SIZE self.match.serialize(self.buf, offset) @_set_stats_type(ofproto.OFPMP_FLOW_MONITOR, OFPFlowUpdateHeader) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPFlowMonitorRequest(OFPFlowMonitorRequestBase): """ Flow monitor request message The controller uses this message to query flow monitors. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or ``OFPMPF_REQ_MORE`` monitor_id Controller-assigned ID for this monitor out_port Require matching entries to include this as an output port out_group Require matching entries to include this as an output group monitor_flags Bitmap of the following flags. | OFPFMF_INITIAL | OFPFMF_ADD | OFPFMF_REMOVED | OFPFMF_MODIFY | OFPFMF_INSTRUCTIONS | OFPFMF_NO_ABBREV | OFPFMF_ONLY_OWN table_id ID of table to monitor command One of the following values. | OFPFMC_ADD | OFPFMC_MODIFY | OFPFMC_DELETE match Instance of ``OFPMatch`` ================ ====================================================== Example:: def send_flow_monitor_request(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser monitor_flags = [ofp.OFPFMF_INITIAL, ofp.OFPFMF_ONLY_OWN] match = ofp_parser.OFPMatch(in_port=1) req = ofp_parser.OFPFlowMonitorRequest(datapath, 0, 10000, ofp.OFPP_ANY, ofp.OFPG_ANY, monitor_flags, ofp.OFPTT_ALL, ofp.OFPFMC_ADD, match) datapath.send_msg(req) """ def __init__(self, datapath, flags=0, monitor_id=0, out_port=ofproto.OFPP_ANY, out_group=ofproto.OFPG_ANY, monitor_flags=0, table_id=ofproto.OFPTT_ALL, command=ofproto.OFPFMC_ADD, match=None, type_=None): if match is None: match = OFPMatch() super(OFPFlowMonitorRequest, self).__init__(datapath, flags, monitor_id, out_port, out_group, monitor_flags, table_id, command, match) @OFPMultipartReply.register_stats_type() @_set_stats_type(ofproto.OFPMP_FLOW_MONITOR, OFPFlowUpdateHeader) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPFlowMonitorReply(OFPMultipartReply): """ Flow monitor reply message The switch responds with this message to a flow monitor request. ================ ====================================================== Attribute Description ================ ====================================================== body List of list of the following class instance. | OFPFlowMonitorFull | OFPFlowMonitorAbbrev | OFPFlowMonitorPaused ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPFlowMonitorReply, MAIN_DISPATCHER) def flow_monitor_reply_handler(self, ev): msg = ev.msg dp = msg.datapath ofp = dp.ofproto flow_updates = [] for update in msg.body: update_str = 'length=%d event=%d' % (update.length, update.event) if (update.event == ofp.OFPFME_INITIAL or update.event == ofp.OFPFME_ADDED or update.event == ofp.OFPFME_REMOVED or update.event == ofp.OFPFME_MODIFIED): update_str += 'table_id=%d reason=%d idle_timeout=%d ' 'hard_timeout=%d priority=%d cookie=%d ' 'match=%d instructions=%s' % (update.table_id, update.reason, update.idle_timeout, update.hard_timeout, update.priority, update.cookie, update.match, update.instructions) elif update.event == ofp.OFPFME_ABBREV: update_str += 'xid=%d' % (update.xid) flow_updates.append(update_str) self.logger.debug('FlowUpdates: %s', flow_updates) """ def __init__(self, datapath, type_=None, **kwargs): super(OFPFlowMonitorReply, self).__init__(datapath, **kwargs) class OFPExperimenterMultipart(ofproto_parser.namedtuple( 'OFPExperimenterMultipart', ('experimenter', 'exp_type', 'data'))): """ The body of OFPExperimenterStatsReply multipart messages. ================ ====================================================== Attribute Description ================ ====================================================== experimenter Experimenter ID exp_type Experimenter defined data Experimenter defined additional data ================ ====================================================== """ @classmethod def parser(cls, buf, offset): args = struct.unpack_from( ofproto.OFP_EXPERIMENTER_MULTIPART_HEADER_PACK_STR, buf, offset) args = list(args) args.append(buf[offset + ofproto.OFP_EXPERIMENTER_MULTIPART_HEADER_SIZE:]) stats = cls(*args) stats.length = ofproto.OFP_METER_FEATURES_SIZE return stats def serialize(self): buf = bytearray() msg_pack_into(ofproto.OFP_EXPERIMENTER_MULTIPART_HEADER_PACK_STR, buf, 0, self.experimenter, self.exp_type) return buf + self.data class OFPExperimenterStatsRequestBase(OFPMultipartRequest): def __init__(self, datapath, flags, experimenter, exp_type, type_=None): super(OFPExperimenterStatsRequestBase, self).__init__(datapath, flags) self.experimenter = experimenter self.exp_type = exp_type @_set_stats_type(ofproto.OFPMP_EXPERIMENTER, OFPExperimenterMultipart) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPExperimenterStatsRequest(OFPExperimenterStatsRequestBase): """ Experimenter multipart request message ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or ``OFPMPF_REQ_MORE`` experimenter Experimenter ID exp_type Experimenter defined data Experimenter defined additional data ================ ====================================================== """ def __init__(self, datapath, flags, experimenter, exp_type, data, type_=None): super(OFPExperimenterStatsRequest, self).__init__(datapath, flags, experimenter, exp_type, type_) self.data = data def _serialize_stats_body(self): body = OFPExperimenterMultipart(experimenter=self.experimenter, exp_type=self.exp_type, data=self.data) self.buf += body.serialize() @OFPMultipartReply.register_stats_type(body_single_struct=True) @_set_stats_type(ofproto.OFPMP_EXPERIMENTER, OFPExperimenterMultipart) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPExperimenterStatsReply(OFPMultipartReply): """ Experimenter multipart reply message ================ ====================================================== Attribute Description ================ ====================================================== body An ``OFPExperimenterMultipart`` instance ================ ====================================================== """ def __init__(self, datapath, type_=None, **kwargs): super(OFPExperimenterStatsReply, self).__init__(datapath, **kwargs) class OFPFlowStats(StringifyMixin): def __init__(self, table_id=None, duration_sec=None, duration_nsec=None, priority=None, idle_timeout=None, hard_timeout=None, flags=None, importance=None, cookie=None, packet_count=None, byte_count=None, match=None, instructions=None, length=None): super(OFPFlowStats, self).__init__() self.table_id = table_id self.duration_sec = duration_sec self.duration_nsec = duration_nsec self.priority = priority self.idle_timeout = idle_timeout self.hard_timeout = hard_timeout self.flags = flags self.importance = importance self.cookie = cookie self.packet_count = packet_count self.byte_count = byte_count self.match = match self.instructions = instructions self.length = length @classmethod def parser(cls, buf, offset): flow_stats = cls() (flow_stats.length, flow_stats.table_id, flow_stats.duration_sec, flow_stats.duration_nsec, flow_stats.priority, flow_stats.idle_timeout, flow_stats.hard_timeout, flow_stats.flags, flow_stats.importance, flow_stats.cookie, flow_stats.packet_count, flow_stats.byte_count) = struct.unpack_from( ofproto.OFP_FLOW_STATS_0_PACK_STR, buf, offset) offset += ofproto.OFP_FLOW_STATS_0_SIZE flow_stats.match = OFPMatch.parser(buf, offset) match_length = utils.round_up(flow_stats.match.length, 8) inst_length = (flow_stats.length - (ofproto.OFP_FLOW_STATS_SIZE - ofproto.OFP_MATCH_SIZE + match_length)) offset += match_length instructions = [] while inst_length > 0: inst = OFPInstruction.parser(buf, offset) instructions.append(inst) offset += inst.len inst_length -= inst.len flow_stats.instructions = instructions return flow_stats class OFPFlowStatsRequestBase(OFPMultipartRequest): def __init__(self, datapath, flags, table_id, out_port, out_group, cookie, cookie_mask, match): super(OFPFlowStatsRequestBase, self).__init__(datapath, flags) self.table_id = table_id self.out_port = out_port self.out_group = out_group self.cookie = cookie self.cookie_mask = cookie_mask self.match = match def _serialize_stats_body(self): offset = ofproto.OFP_MULTIPART_REQUEST_SIZE msg_pack_into(ofproto.OFP_FLOW_STATS_REQUEST_0_PACK_STR, self.buf, offset, self.table_id, self.out_port, self.out_group, self.cookie, self.cookie_mask) offset += ofproto.OFP_FLOW_STATS_REQUEST_0_SIZE self.match.serialize(self.buf, offset) @_set_stats_type(ofproto.OFPMP_FLOW, OFPFlowStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPFlowStatsRequest(OFPFlowStatsRequestBase): """ Individual flow statistics request message The controller uses this message to query individual flow statistics. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or ``OFPMPF_REQ_MORE`` table_id ID of table to read out_port Require matching entries to include this as an output port out_group Require matching entries to include this as an output group cookie Require matching entries to contain this cookie value cookie_mask Mask used to restrict the cookie bits that must match match Instance of ``OFPMatch`` ================ ====================================================== Example:: def send_flow_stats_request(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser cookie = cookie_mask = 0 match = ofp_parser.OFPMatch(in_port=1) req = ofp_parser.OFPFlowStatsRequest(datapath, 0, ofp.OFPTT_ALL, ofp.OFPP_ANY, ofp.OFPG_ANY, cookie, cookie_mask, match) datapath.send_msg(req) """ def __init__(self, datapath, flags=0, table_id=ofproto.OFPTT_ALL, out_port=ofproto.OFPP_ANY, out_group=ofproto.OFPG_ANY, cookie=0, cookie_mask=0, match=None, type_=None): if match is None: match = OFPMatch() super(OFPFlowStatsRequest, self).__init__(datapath, flags, table_id, out_port, out_group, cookie, cookie_mask, match) @OFPMultipartReply.register_stats_type() @_set_stats_type(ofproto.OFPMP_FLOW, OFPFlowStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPFlowStatsReply(OFPMultipartReply): """ Individual flow statistics reply message The switch responds with this message to an individual flow statistics request. ================ ====================================================== Attribute Description ================ ====================================================== body List of ``OFPFlowStats`` instance ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPFlowStatsReply, MAIN_DISPATCHER) def flow_stats_reply_handler(self, ev): flows = [] for stat in ev.msg.body: flows.append('table_id=%s ' 'duration_sec=%d duration_nsec=%d ' 'priority=%d ' 'idle_timeout=%d hard_timeout=%d flags=0x%04x ' 'importance=%d cookie=%d packet_count=%d ' 'byte_count=%d match=%s instructions=%s' % (stat.table_id, stat.duration_sec, stat.duration_nsec, stat.priority, stat.idle_timeout, stat.hard_timeout, stat.flags, stat.importance, stat.cookie, stat.packet_count, stat.byte_count, stat.match, stat.instructions)) self.logger.debug('FlowStats: %s', flows) """ def __init__(self, datapath, type_=None, **kwargs): super(OFPFlowStatsReply, self).__init__(datapath, **kwargs) class OFPAggregateStats(ofproto_parser.namedtuple('OFPAggregateStats', ( 'packet_count', 'byte_count', 'flow_count'))): @classmethod def parser(cls, buf, offset): agg = struct.unpack_from( ofproto.OFP_AGGREGATE_STATS_REPLY_PACK_STR, buf, offset) stats = cls(*agg) stats.length = ofproto.OFP_AGGREGATE_STATS_REPLY_SIZE return stats @_set_stats_type(ofproto.OFPMP_AGGREGATE, OFPAggregateStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPAggregateStatsRequest(OFPFlowStatsRequestBase): """ Aggregate flow statistics request message The controller uses this message to query aggregate flow statictics. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or ``OFPMPF_REQ_MORE`` table_id ID of table to read out_port Require matching entries to include this as an output port out_group Require matching entries to include this as an output group cookie Require matching entries to contain this cookie value cookie_mask Mask used to restrict the cookie bits that must match match Instance of ``OFPMatch`` ================ ====================================================== Example:: def send_aggregate_stats_request(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser cookie = cookie_mask = 0 match = ofp_parser.OFPMatch(in_port=1) req = ofp_parser.OFPAggregateStatsRequest(datapath, 0, ofp.OFPTT_ALL, ofp.OFPP_ANY, ofp.OFPG_ANY, cookie, cookie_mask, match) datapath.send_msg(req) """ def __init__(self, datapath, flags, table_id, out_port, out_group, cookie, cookie_mask, match, type_=None): super(OFPAggregateStatsRequest, self).__init__(datapath, flags, table_id, out_port, out_group, cookie, cookie_mask, match) @OFPMultipartReply.register_stats_type(body_single_struct=True) @_set_stats_type(ofproto.OFPMP_AGGREGATE, OFPAggregateStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPAggregateStatsReply(OFPMultipartReply): """ Aggregate flow statistics reply message The switch responds with this message to an aggregate flow statistics request. ================ ====================================================== Attribute Description ================ ====================================================== body Instance of ``OFPAggregateStats`` ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPAggregateStatsReply, MAIN_DISPATCHER) def aggregate_stats_reply_handler(self, ev): body = ev.msg.body self.logger.debug('AggregateStats: packet_count=%d byte_count=%d ' 'flow_count=%d', body.packet_count, body.byte_count, body.flow_count) """ def __init__(self, datapath, type_=None, **kwargs): super(OFPAggregateStatsReply, self).__init__(datapath, **kwargs) class OFPTableStats(ofproto_parser.namedtuple('OFPTableStats', ( 'table_id', 'active_count', 'lookup_count', 'matched_count'))): @classmethod def parser(cls, buf, offset): tbl = struct.unpack_from(ofproto.OFP_TABLE_STATS_PACK_STR, buf, offset) stats = cls(*tbl) stats.length = ofproto.OFP_TABLE_STATS_SIZE return stats @_set_stats_type(ofproto.OFPMP_TABLE, OFPTableStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPTableStatsRequest(OFPMultipartRequest): """ Table statistics request message The controller uses this message to query flow table statictics. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or ``OFPMPF_REQ_MORE`` ================ ====================================================== Example:: def send_table_stats_request(self, datapath): ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPTableStatsRequest(datapath, 0) datapath.send_msg(req) """ def __init__(self, datapath, flags, type_=None): super(OFPTableStatsRequest, self).__init__(datapath, flags) @OFPMultipartReply.register_stats_type() @_set_stats_type(ofproto.OFPMP_TABLE, OFPTableStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPTableStatsReply(OFPMultipartReply): """ Table statistics reply message The switch responds with this message to a table statistics request. ================ ====================================================== Attribute Description ================ ====================================================== body List of ``OFPTableStats`` instance ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPTableStatsReply, MAIN_DISPATCHER) def table_stats_reply_handler(self, ev): tables = [] for stat in ev.msg.body: tables.append('table_id=%d active_count=%d lookup_count=%d ' ' matched_count=%d' % (stat.table_id, stat.active_count, stat.lookup_count, stat.matched_count)) self.logger.debug('TableStats: %s', tables) """ def __init__(self, datapath, type_=None, **kwargs): super(OFPTableStatsReply, self).__init__(datapath, **kwargs) class OFPPortStatsProp(OFPPropBase): _TYPES = {} @OFPPortStatsProp.register_type(ofproto.OFPPSPT_ETHERNET) class OFPPortStatsPropEthernet(OFPPortStatsProp): def __init__(self, type_=None, length=None, rx_frame_err=None, rx_over_err=None, rx_crc_err=None, collisions=None): self.type = type_ self.length = length self.rx_frame_err = rx_frame_err self.rx_over_err = rx_over_err self.rx_crc_err = rx_crc_err self.collisions = collisions @classmethod def parser(cls, buf): ether = cls() (ether.type, ether.length, ether.rx_frame_err, ether.rx_over_err, ether.rx_crc_err, ether.collisions) = struct.unpack_from( ofproto.OFP_PORT_STATS_PROP_ETHERNET_PACK_STR, buf, 0) return ether @OFPPortStatsProp.register_type(ofproto.OFPPSPT_OPTICAL) class OFPPortStatsPropOptical(OFPPortStatsProp): def __init__(self, type_=None, length=None, flags=None, tx_freq_lmda=None, tx_offset=None, tx_grid_span=None, rx_freq_lmda=None, rx_offset=None, rx_grid_span=None, tx_pwr=None, rx_pwr=None, bias_current=None, temperature=None): self.type = type_ self.length = length self.flags = flags self.tx_freq_lmda = tx_freq_lmda self.tx_offset = tx_offset self.tx_grid_span = tx_grid_span self.rx_freq_lmda = rx_freq_lmda self.rx_offset = rx_offset self.rx_grid_span = rx_grid_span self.tx_pwr = tx_pwr self.rx_pwr = rx_pwr self.bias_current = bias_current self.temperature = temperature @classmethod def parser(cls, buf): optical = cls() (optical.type, optical.length, optical.flags, optical.tx_freq_lmda, optical.tx_offset, optical.tx_grid_span, optical.rx_freq_lmda, optical.rx_offset, optical.rx_grid_span, optical.tx_pwr, optical.rx_pwr, optical.bias_current, optical.temperature) = struct.unpack_from( ofproto.OFP_PORT_STATS_PROP_OPTICAL_PACK_STR, buf, 0) return optical @OFPPortStatsProp.register_type(ofproto.OFPPSPT_EXPERIMENTER) class OFPPortStatsPropExperimenter(OFPPropCommonExperimenter4ByteData): pass class OFPPortStats(StringifyMixin): def __init__(self, length=None, port_no=None, duration_sec=None, duration_nsec=None, rx_packets=None, tx_packets=None, rx_bytes=None, tx_bytes=None, rx_dropped=None, tx_dropped=None, rx_errors=None, tx_errors=None, properties=None): super(OFPPortStats, self).__init__() self.length = length self.port_no = port_no self.duration_sec = duration_sec self.duration_nsec = duration_nsec self.rx_packets = rx_packets self.tx_packets = tx_packets self.rx_bytes = rx_bytes self.tx_bytes = tx_bytes self.rx_dropped = rx_dropped self.tx_dropped = tx_dropped self.rx_errors = rx_errors self.tx_errors = tx_errors self.properties = properties @classmethod def parser(cls, buf, offset): (length, port_no, duration_sec, duration_nsec, rx_packets, tx_packets, rx_bytes, tx_bytes, rx_dropped, tx_dropped, rx_errors, tx_errors) = struct.unpack_from( ofproto.OFP_PORT_STATS_PACK_STR, buf, offset) props = [] rest = buf[offset + ofproto.OFP_PORT_STATS_SIZE:offset + length] while rest: p, rest = OFPPortStatsProp.parse(rest) props.append(p) stats = cls(length, port_no, duration_sec, duration_nsec, rx_packets, tx_packets, rx_bytes, tx_bytes, rx_dropped, tx_dropped, rx_errors, tx_errors, props) return stats @_set_stats_type(ofproto.OFPMP_PORT_STATS, OFPPortStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPPortStatsRequest(OFPMultipartRequest): """ Port statistics request message The controller uses this message to query information about ports statistics. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or ``OFPMPF_REQ_MORE`` port_no Port number to read (OFPP_ANY to all ports) ================ ====================================================== Example:: def send_port_stats_request(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPPortStatsRequest(datapath, 0, ofp.OFPP_ANY) datapath.send_msg(req) """ def __init__(self, datapath, flags, port_no, type_=None): super(OFPPortStatsRequest, self).__init__(datapath, flags) self.port_no = port_no def _serialize_stats_body(self): msg_pack_into(ofproto.OFP_PORT_STATS_REQUEST_PACK_STR, self.buf, ofproto.OFP_MULTIPART_REQUEST_SIZE, self.port_no) @OFPMultipartReply.register_stats_type() @_set_stats_type(ofproto.OFPMP_PORT_STATS, OFPPortStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPPortStatsReply(OFPMultipartReply): """ Port statistics reply message The switch responds with this message to a port statistics request. ================ ====================================================== Attribute Description ================ ====================================================== body List of ``OFPPortStats`` instance ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPPortStatsReply, MAIN_DISPATCHER) def port_stats_reply_handler(self, ev): ports = [] for stat in ev.msg.body: ports.append(stat.length, stat.port_no, stat.duration_sec, stat.duration_nsec, stat.rx_packets, stat.tx_packets, stat.rx_bytes, stat.tx_bytes, stat.rx_dropped, stat.tx_dropped, stat.rx_errors, stat.tx_errors, repr(stat.properties)) self.logger.debug('PortStats: %s', ports) """ def __init__(self, datapath, type_=None, **kwargs): super(OFPPortStatsReply, self).__init__(datapath, **kwargs) @_set_msg_type(ofproto.OFPT_BARRIER_REQUEST) class OFPBarrierRequest(MsgBase): """ Barrier request message The controller sends this message to ensure message dependencies have been met or receive notifications for completed operations. Example:: def send_barrier_request(self, datapath): ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPBarrierRequest(datapath) datapath.send_msg(req) """ def __init__(self, datapath): super(OFPBarrierRequest, self).__init__(datapath) @_register_parser @_set_msg_type(ofproto.OFPT_BARRIER_REPLY) class OFPBarrierReply(MsgBase): """ Barrier reply message The switch responds with this message to a barrier request. Example:: @set_ev_cls(ofp_event.EventOFPBarrierReply, MAIN_DISPATCHER) def barrier_reply_handler(self, ev): self.logger.debug('OFPBarrierReply received') """ def __init__(self, datapath): super(OFPBarrierReply, self).__init__(datapath) @_register_parser @_set_msg_type(ofproto.OFPT_PORT_STATUS) class OFPPortStatus(MsgBase): """ Port status message The switch notifies controller of change of ports. ================ ====================================================== Attribute Description ================ ====================================================== reason One of the following values. | OFPPR_ADD | OFPPR_DELETE | OFPPR_MODIFY desc instance of ``OFPPort`` ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPPortStatus, MAIN_DISPATCHER) def port_status_handler(self, ev): msg = ev.msg dp = msg.datapath ofp = dp.ofproto if msg.reason == ofp.OFPPR_ADD: reason = 'ADD' elif msg.reason == ofp.OFPPR_DELETE: reason = 'DELETE' elif msg.reason == ofp.OFPPR_MODIFY: reason = 'MODIFY' else: reason = 'unknown' self.logger.debug('OFPPortStatus received: reason=%s desc=%s', reason, msg.desc) """ def __init__(self, datapath, reason=None, desc=None): super(OFPPortStatus, self).__init__(datapath) self.reason = reason self.desc = desc @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPPortStatus, cls).parser(datapath, version, msg_type, msg_len, xid, buf) msg.reason = struct.unpack_from( ofproto.OFP_PORT_STATUS_PACK_STR, msg.buf, ofproto.OFP_HEADER_SIZE)[0] msg.desc = OFPPort.parser(msg.buf, ofproto.OFP_PORT_STATUS_DESC_OFFSET) return msg @_register_parser @_set_msg_type(ofproto.OFPT_ROLE_STATUS) class OFPRoleStatus(MsgBase): """ Role status message The switch notifies controller of change of role. ================ ====================================================== Attribute Description ================ ====================================================== role One of the following values. | OFPCR_ROLE_NOCHANGE | OFPCR_ROLE_EQUAL | OFPCR_ROLE_MASTER reason One of the following values. | OFPCRR_MASTER_REQUEST | OFPCRR_CONFIG | OFPCRR_EXPERIMENTER generation_id Master Election Generation ID properties List of ``OFPRoleProp`` subclass instance ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPRoleStatus, MAIN_DISPATCHER) def role_status_handler(self, ev): msg = ev.msg dp = msg.datapath ofp = dp.ofproto if msg.role == ofp.OFPCR_ROLE_NOCHANGE: role = 'ROLE NOCHANGE' elif msg.role == ofp.OFPCR_ROLE_EQUAL: role = 'ROLE EQUAL' elif msg.role == ofp.OFPCR_ROLE_MASTER: role = 'ROLE MASTER' else: role = 'unknown' if msg.reason == ofp.OFPCRR_MASTER_REQUEST: reason = 'MASTER REQUEST' elif msg.reason == ofp.OFPCRR_CONFIG: reason = 'CONFIG' elif msg.reason == ofp.OFPCRR_EXPERIMENTER: reason = 'EXPERIMENTER' else: reason = 'unknown' self.logger.debug('OFPRoleStatus received: role=%s reason=%s ' 'generation_id=%d properties=%s', role, reason, msg.generation_id, repr(msg.properties)) """ def __init__(self, datapath, role=None, reason=None, generation_id=None, properties=None): super(OFPRoleStatus, self).__init__(datapath) self.role = role self.reason = reason self.generation_id = generation_id self.properties = properties @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPRoleStatus, cls).parser(datapath, version, msg_type, msg_len, xid, buf) (msg.role, msg.reason, msg.generation_id) = struct.unpack_from( ofproto.OFP_ROLE_STATUS_PACK_STR, msg.buf, ofproto.OFP_HEADER_SIZE) msg.properties = [] rest = msg.buf[ofproto.OFP_ROLE_STATUS_SIZE:] while rest: p, rest = OFPRoleProp.parse(rest) msg.properties.append(p) return msg @_register_parser @_set_msg_type(ofproto.OFPT_TABLE_STATUS) class OFPTableStatus(MsgBase): """ Table status message The switch notifies controller of change of table status. ================ ====================================================== Attribute Description ================ ====================================================== reason One of the following values. | OFPTR_VACANCY_DOWN | OFPTR_VACANCY_UP table ``OFPTableDesc`` instance ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPTableStatus, MAIN_DISPATCHER) def table(self, ev): msg = ev.msg dp = msg.datapath ofp = dp.ofproto if msg.reason == ofp.OFPTR_VACANCY_DOWN: reason = 'VACANCY_DOWN' elif msg.reason == ofp.OFPTR_VACANCY_UP: reason = 'VACANCY_UP' else: reason = 'unknown' self.logger.debug('OFPTableStatus received: reason=%s ' 'table_id=%d config=0x%08x properties=%s', reason, msg.table.table_id, msg.table.config, repr(msg.table.properties)) """ def __init__(self, datapath, reason=None, table=None): super(OFPTableStatus, self).__init__(datapath) self.reason = reason self.table = table @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPTableStatus, cls).parser(datapath, version, msg_type, msg_len, xid, buf) (msg.reason,) = struct.unpack_from(ofproto.OFP_TABLE_STATUS_0_PACK_STR, msg.buf, ofproto.OFP_HEADER_SIZE) msg.table = OFPTableDesc.parser(msg.buf, ofproto.OFP_TABLE_STATUS_0_SIZE) return msg @_register_parser @_set_msg_type(ofproto.OFPT_REQUESTFORWARD) class OFPRequestForward(MsgInMsgBase): """ Forwarded request message The swtich forwards request messages from one controller to other controllers. ================ ====================================================== Attribute Description ================ ====================================================== request ``OFPGroupMod`` or ``OFPMeterMod`` instance ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPRequestForward, MAIN_DISPATCHER) def request_forward_handler(self, ev): msg = ev.msg dp = msg.datapath ofp = dp.ofproto if msg.request.msg_type == ofp.OFPT_GROUP_MOD: self.logger.debug( 'OFPRequestForward received: request=OFPGroupMod(' 'command=%d, type=%d, group_id=%d, buckets=%s)', msg.request.command, msg.request.type, msg.request.group_id, msg.request.buckets) elif msg.request.msg_type == ofp.OFPT_METER_MOD: self.logger.debug( 'OFPRequestForward received: request=OFPMeterMod(' 'command=%d, flags=%d, meter_id=%d, bands=%s)', msg.request.command, msg.request.flags, msg.request.meter_id, msg.request.bands) else: self.logger.debug( 'OFPRequestForward received: request=Unknown') """ def __init__(self, datapath, request=None): super(OFPRequestForward, self).__init__(datapath) self.request = request @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPRequestForward, cls).parser( datapath, version, msg_type, msg_len, xid, buf) req_buf = buf[ofproto.OFP_HEADER_SIZE:] (_ver, _type, _len, _xid) = ofproto_parser.header(req_buf) msg.request = ofproto_parser.msg( datapath, _ver, _type, _len, _xid, req_buf) return msg def _serialize_body(self): assert isinstance(self.request, (OFPGroupMod, OFPMeterMod)) self.request.serialize() self.buf += self.request.buf @_set_msg_type(ofproto.OFPT_PACKET_OUT) class OFPPacketOut(MsgBase): """ Packet-Out message The controller uses this message to send a packet out throught the switch. ================ ====================================================== Attribute Description ================ ====================================================== buffer_id ID assigned by datapath (OFP_NO_BUFFER if none) in_port Packet's input port or ``OFPP_CONTROLLER`` actions list of OpenFlow action class data Packet data of a binary type value or an instances of packet.Packet. ================ ====================================================== Example:: def send_packet_out(self, datapath, buffer_id, in_port): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser actions = [ofp_parser.OFPActionOutput(ofp.OFPP_FLOOD, 0)] req = ofp_parser.OFPPacketOut(datapath, buffer_id, in_port, actions) datapath.send_msg(req) """ def __init__(self, datapath, buffer_id=None, in_port=None, actions=None, data=None, actions_len=None): assert in_port is not None super(OFPPacketOut, self).__init__(datapath) self.buffer_id = buffer_id self.in_port = in_port self.actions_len = 0 self.actions = actions self.data = data def _serialize_body(self): self.actions_len = 0 offset = ofproto.OFP_PACKET_OUT_SIZE for a in self.actions: a.serialize(self.buf, offset) offset += a.len self.actions_len += a.len if self.data is not None: assert self.buffer_id == 0xffffffff if isinstance(self.data, packet.Packet): self.data.serialize() self.buf += self.data.data else: self.buf += self.data msg_pack_into(ofproto.OFP_PACKET_OUT_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.buffer_id, self.in_port, self.actions_len) @classmethod def from_jsondict(cls, dict_, decode_string=base64.b64decode, **additional_args): if isinstance(dict_['data'], dict): data = dict_.pop('data') ins = super(OFPPacketOut, cls).from_jsondict(dict_, decode_string, **additional_args) ins.data = packet.Packet.from_jsondict(data['Packet']) dict_['data'] = data else: ins = super(OFPPacketOut, cls).from_jsondict(dict_, decode_string, **additional_args) return ins @_register_parser @_set_msg_type(ofproto.OFPT_FLOW_MOD) class OFPFlowMod(MsgBase): """ Modify Flow entry message The controller sends this message to modify the flow table. ================ ====================================================== Attribute Description ================ ====================================================== cookie Opaque controller-issued identifier cookie_mask Mask used to restrict the cookie bits that must match when the command is ``OPFFC_MODIFY*`` or ``OFPFC_DELETE*`` table_id ID of the table to put the flow in command One of the following values. | OFPFC_ADD | OFPFC_MODIFY | OFPFC_MODIFY_STRICT | OFPFC_DELETE | OFPFC_DELETE_STRICT idle_timeout Idle time before discarding (seconds) hard_timeout Max time before discarding (seconds) priority Priority level of flow entry buffer_id Buffered packet to apply to (or OFP_NO_BUFFER) out_port For ``OFPFC_DELETE*`` commands, require matching entries to include this as an output port out_group For ``OFPFC_DELETE*`` commands, require matching entries to include this as an output group flags Bitmap of the following flags. | OFPFF_SEND_FLOW_REM | OFPFF_CHECK_OVERLAP | OFPFF_RESET_COUNTS | OFPFF_NO_PKT_COUNTS | OFPFF_NO_BYT_COUNTS importance Eviction precedence match Instance of ``OFPMatch`` instructions list of ``OFPInstruction*`` instance ================ ====================================================== Example:: def send_flow_mod(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser cookie = cookie_mask = 0 table_id = 0 idle_timeout = hard_timeout = 0 priority = 32768 buffer_id = ofp.OFP_NO_BUFFER importance = 0 match = ofp_parser.OFPMatch(in_port=1, eth_dst='ff:ff:ff:ff:ff:ff') actions = [ofp_parser.OFPActionOutput(ofp.OFPP_NORMAL, 0)] inst = [ofp_parser.OFPInstructionActions(ofp.OFPIT_APPLY_ACTIONS, actions)] req = ofp_parser.OFPFlowMod(datapath, cookie, cookie_mask, table_id, ofp.OFPFC_ADD, idle_timeout, hard_timeout, priority, buffer_id, ofp.OFPP_ANY, ofp.OFPG_ANY, ofp.OFPFF_SEND_FLOW_REM, importance, match, inst) datapath.send_msg(req) """ def __init__(self, datapath, cookie=0, cookie_mask=0, table_id=0, command=ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=0, priority=ofproto.OFP_DEFAULT_PRIORITY, buffer_id=ofproto.OFP_NO_BUFFER, out_port=0, out_group=0, flags=0, importance=0, match=None, instructions=None): instructions = instructions if instructions else [] super(OFPFlowMod, self).__init__(datapath) self.cookie = cookie self.cookie_mask = cookie_mask self.table_id = table_id self.command = command self.idle_timeout = idle_timeout self.hard_timeout = hard_timeout self.priority = priority self.buffer_id = buffer_id self.out_port = out_port self.out_group = out_group self.flags = flags self.importance = importance if match is None: match = OFPMatch() assert isinstance(match, OFPMatch) self.match = match for i in instructions: assert isinstance(i, OFPInstruction) self.instructions = instructions def _serialize_body(self): msg_pack_into(ofproto.OFP_FLOW_MOD_PACK_STR0, self.buf, ofproto.OFP_HEADER_SIZE, self.cookie, self.cookie_mask, self.table_id, self.command, self.idle_timeout, self.hard_timeout, self.priority, self.buffer_id, self.out_port, self.out_group, self.flags, self.importance) offset = (ofproto.OFP_FLOW_MOD_SIZE - ofproto.OFP_MATCH_SIZE) match_len = self.match.serialize(self.buf, offset) offset += match_len for inst in self.instructions: inst.serialize(self.buf, offset) offset += inst.len @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPFlowMod, cls).parser( datapath, version, msg_type, msg_len, xid, buf) (msg.cookie, msg.cookie_mask, msg.table_id, msg.command, msg.idle_timeout, msg.hard_timeout, msg.priority, msg.buffer_id, msg.out_port, msg.out_group, msg.flags, msg.importance) = struct.unpack_from( ofproto.OFP_FLOW_MOD_PACK_STR0, msg.buf, ofproto.OFP_HEADER_SIZE) offset = ofproto.OFP_FLOW_MOD_SIZE - ofproto.OFP_HEADER_SIZE msg.match = OFPMatch.parser(buf, offset) offset += utils.round_up(msg.match.length, 8) instructions = [] while offset < msg_len: i = OFPInstruction.parser(buf, offset) instructions.append(i) offset += i.len msg.instructions = instructions return msg class OFPInstruction(StringifyMixin): _INSTRUCTION_TYPES = {} @staticmethod def register_instruction_type(types): def _register_instruction_type(cls): for type_ in types: OFPInstruction._INSTRUCTION_TYPES[type_] = cls return cls return _register_instruction_type @classmethod def parser(cls, buf, offset): (type_, len_) = struct.unpack_from('!HH', buf, offset) cls_ = cls._INSTRUCTION_TYPES.get(type_) return cls_.parser(buf, offset) @OFPInstruction.register_instruction_type([ofproto.OFPIT_GOTO_TABLE]) class OFPInstructionGotoTable(OFPInstruction): """ Goto table instruction This instruction indicates the next table in the processing pipeline. ================ ====================================================== Attribute Description ================ ====================================================== table_id Next table ================ ====================================================== """ def __init__(self, table_id, type_=None, len_=None): super(OFPInstructionGotoTable, self).__init__() self.type = ofproto.OFPIT_GOTO_TABLE self.len = ofproto.OFP_INSTRUCTION_GOTO_TABLE_SIZE self.table_id = table_id @classmethod def parser(cls, buf, offset): (type_, len_, table_id) = struct.unpack_from( ofproto.OFP_INSTRUCTION_GOTO_TABLE_PACK_STR, buf, offset) return cls(table_id) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_INSTRUCTION_GOTO_TABLE_PACK_STR, buf, offset, self.type, self.len, self.table_id) @OFPInstruction.register_instruction_type([ofproto.OFPIT_WRITE_METADATA]) class OFPInstructionWriteMetadata(OFPInstruction): """ Write metadata instruction This instruction writes the masked metadata value into the metadata field. ================ ====================================================== Attribute Description ================ ====================================================== metadata Metadata value to write metadata_mask Metadata write bitmask ================ ====================================================== """ def __init__(self, metadata, metadata_mask, type_=None, len_=None): super(OFPInstructionWriteMetadata, self).__init__() self.type = ofproto.OFPIT_WRITE_METADATA self.len = ofproto.OFP_INSTRUCTION_WRITE_METADATA_SIZE self.metadata = metadata self.metadata_mask = metadata_mask @classmethod def parser(cls, buf, offset): (type_, len_, metadata, metadata_mask) = struct.unpack_from( ofproto.OFP_INSTRUCTION_WRITE_METADATA_PACK_STR, buf, offset) return cls(metadata, metadata_mask) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_INSTRUCTION_WRITE_METADATA_PACK_STR, buf, offset, self.type, self.len, self.metadata, self.metadata_mask) @OFPInstruction.register_instruction_type([ofproto.OFPIT_WRITE_ACTIONS, ofproto.OFPIT_APPLY_ACTIONS, ofproto.OFPIT_CLEAR_ACTIONS]) class OFPInstructionActions(OFPInstruction): """ Actions instruction This instruction writes/applies/clears the actions. ================ ====================================================== Attribute Description ================ ====================================================== type One of following values. | OFPIT_WRITE_ACTIONS | OFPIT_APPLY_ACTIONS | OFPIT_CLEAR_ACTIONS actions list of OpenFlow action class ================ ====================================================== ``type`` attribute corresponds to ``type_`` parameter of __init__. """ def __init__(self, type_, actions=None, len_=None): super(OFPInstructionActions, self).__init__() self.type = type_ for a in actions: assert isinstance(a, OFPAction) self.actions = actions @classmethod def parser(cls, buf, offset): (type_, len_) = struct.unpack_from( ofproto.OFP_INSTRUCTION_ACTIONS_PACK_STR, buf, offset) offset += ofproto.OFP_INSTRUCTION_ACTIONS_SIZE actions = [] actions_len = len_ - ofproto.OFP_INSTRUCTION_ACTIONS_SIZE while actions_len > 0: a = OFPAction.parser(buf, offset) actions.append(a) actions_len -= a.len offset += a.len inst = cls(type_, actions) inst.len = len_ return inst def serialize(self, buf, offset): action_offset = offset + ofproto.OFP_INSTRUCTION_ACTIONS_SIZE if self.actions: for a in self.actions: a.serialize(buf, action_offset) action_offset += a.len self.len = action_offset - offset pad_len = utils.round_up(self.len, 8) - self.len msg_pack_into("%dx" % pad_len, buf, action_offset) self.len += pad_len msg_pack_into(ofproto.OFP_INSTRUCTION_ACTIONS_PACK_STR, buf, offset, self.type, self.len) @OFPInstruction.register_instruction_type([ofproto.OFPIT_METER]) class OFPInstructionMeter(OFPInstruction): """ Meter instruction This instruction applies the meter. ================ ====================================================== Attribute Description ================ ====================================================== meter_id Meter instance ================ ====================================================== """ def __init__(self, meter_id=1, type_=None, len_=None): super(OFPInstructionMeter, self).__init__() self.type = ofproto.OFPIT_METER self.len = ofproto.OFP_INSTRUCTION_METER_SIZE self.meter_id = meter_id @classmethod def parser(cls, buf, offset): (type_, len_, meter_id) = struct.unpack_from( ofproto.OFP_INSTRUCTION_METER_PACK_STR, buf, offset) return cls(meter_id) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_INSTRUCTION_METER_PACK_STR, buf, offset, self.type, self.len, self.meter_id) class OFPActionHeader(StringifyMixin): def __init__(self, type_, len_): self.type = type_ self.len = len_ def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_HEADER_PACK_STR, buf, offset, self.type, self.len) class OFPAction(OFPActionHeader): _ACTION_TYPES = {} @staticmethod def register_action_type(type_, len_): def _register_action_type(cls): cls.cls_action_type = type_ cls.cls_action_len = len_ OFPAction._ACTION_TYPES[cls.cls_action_type] = cls return cls return _register_action_type def __init__(self): cls = self.__class__ super(OFPAction, self).__init__(cls.cls_action_type, cls.cls_action_len) @classmethod def parser(cls, buf, offset): type_, len_ = struct.unpack_from( ofproto.OFP_ACTION_HEADER_PACK_STR, buf, offset) cls_ = cls._ACTION_TYPES.get(type_) assert cls_ is not None return cls_.parser(buf, offset) @OFPAction.register_action_type(ofproto.OFPAT_OUTPUT, ofproto.OFP_ACTION_OUTPUT_SIZE) class OFPActionOutput(OFPAction): """ Output action This action indicates output a packet to the switch port. ================ ====================================================== Attribute Description ================ ====================================================== port Output port max_len Max length to send to controller ================ ====================================================== """ def __init__(self, port, max_len=ofproto.OFPCML_MAX, type_=None, len_=None): super(OFPActionOutput, self).__init__() self.port = port self.max_len = max_len @classmethod def parser(cls, buf, offset): type_, len_, port, max_len = struct.unpack_from( ofproto.OFP_ACTION_OUTPUT_PACK_STR, buf, offset) return cls(port, max_len) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_OUTPUT_PACK_STR, buf, offset, self.type, self.len, self.port, self.max_len) @OFPAction.register_action_type(ofproto.OFPAT_GROUP, ofproto.OFP_ACTION_GROUP_SIZE) class OFPActionGroup(OFPAction): """ Group action This action indicates the group used to process the packet. ================ ====================================================== Attribute Description ================ ====================================================== group_id Group identifier ================ ====================================================== """ def __init__(self, group_id=0, type_=None, len_=None): super(OFPActionGroup, self).__init__() self.group_id = group_id @classmethod def parser(cls, buf, offset): (type_, len_, group_id) = struct.unpack_from( ofproto.OFP_ACTION_GROUP_PACK_STR, buf, offset) return cls(group_id) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_GROUP_PACK_STR, buf, offset, self.type, self.len, self.group_id) @OFPAction.register_action_type(ofproto.OFPAT_SET_QUEUE, ofproto.OFP_ACTION_SET_QUEUE_SIZE) class OFPActionSetQueue(OFPAction): """ Set queue action This action sets the queue id that will be used to map a flow to an already-configured queue on a port. ================ ====================================================== Attribute Description ================ ====================================================== queue_id Queue ID for the packets ================ ====================================================== """ def __init__(self, queue_id, type_=None, len_=None): super(OFPActionSetQueue, self).__init__() self.queue_id = queue_id @classmethod def parser(cls, buf, offset): (type_, len_, queue_id) = struct.unpack_from( ofproto.OFP_ACTION_SET_QUEUE_PACK_STR, buf, offset) return cls(queue_id) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_SET_QUEUE_PACK_STR, buf, offset, self.type, self.len, self.queue_id) @OFPAction.register_action_type(ofproto.OFPAT_SET_MPLS_TTL, ofproto.OFP_ACTION_MPLS_TTL_SIZE) class OFPActionSetMplsTtl(OFPAction): """ Set MPLS TTL action This action sets the MPLS TTL. ================ ====================================================== Attribute Description ================ ====================================================== mpls_ttl MPLS TTL ================ ====================================================== """ def __init__(self, mpls_ttl, type_=None, len_=None): super(OFPActionSetMplsTtl, self).__init__() self.mpls_ttl = mpls_ttl @classmethod def parser(cls, buf, offset): (type_, len_, mpls_ttl) = struct.unpack_from( ofproto.OFP_ACTION_MPLS_TTL_PACK_STR, buf, offset) return cls(mpls_ttl) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_MPLS_TTL_PACK_STR, buf, offset, self.type, self.len, self.mpls_ttl) @OFPAction.register_action_type(ofproto.OFPAT_DEC_MPLS_TTL, ofproto.OFP_ACTION_HEADER_SIZE) class OFPActionDecMplsTtl(OFPAction): """ Decrement MPLS TTL action This action decrements the MPLS TTL. """ def __init__(self, type_=None, len_=None): super(OFPActionDecMplsTtl, self).__init__() @classmethod def parser(cls, buf, offset): (type_, len_) = struct.unpack_from( ofproto.OFP_ACTION_HEADER_PACK_STR, buf, offset) return cls() @OFPAction.register_action_type(ofproto.OFPAT_SET_NW_TTL, ofproto.OFP_ACTION_NW_TTL_SIZE) class OFPActionSetNwTtl(OFPAction): """ Set IP TTL action This action sets the IP TTL. ================ ====================================================== Attribute Description ================ ====================================================== nw_ttl IP TTL ================ ====================================================== """ def __init__(self, nw_ttl, type_=None, len_=None): super(OFPActionSetNwTtl, self).__init__() self.nw_ttl = nw_ttl @classmethod def parser(cls, buf, offset): (type_, len_, nw_ttl) = struct.unpack_from( ofproto.OFP_ACTION_NW_TTL_PACK_STR, buf, offset) return cls(nw_ttl) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_NW_TTL_PACK_STR, buf, offset, self.type, self.len, self.nw_ttl) @OFPAction.register_action_type(ofproto.OFPAT_DEC_NW_TTL, ofproto.OFP_ACTION_HEADER_SIZE) class OFPActionDecNwTtl(OFPAction): """ Decrement IP TTL action This action decrements the IP TTL. """ def __init__(self, type_=None, len_=None): super(OFPActionDecNwTtl, self).__init__() @classmethod def parser(cls, buf, offset): (type_, len_) = struct.unpack_from( ofproto.OFP_ACTION_HEADER_PACK_STR, buf, offset) return cls() @OFPAction.register_action_type(ofproto.OFPAT_COPY_TTL_OUT, ofproto.OFP_ACTION_HEADER_SIZE) class OFPActionCopyTtlOut(OFPAction): """ Copy TTL Out action This action copies the TTL from the next-to-outermost header with TTL to the outermost header with TTL. """ def __init__(self, type_=None, len_=None): super(OFPActionCopyTtlOut, self).__init__() @classmethod def parser(cls, buf, offset): (type_, len_) = struct.unpack_from( ofproto.OFP_ACTION_HEADER_PACK_STR, buf, offset) return cls() @OFPAction.register_action_type(ofproto.OFPAT_COPY_TTL_IN, ofproto.OFP_ACTION_HEADER_SIZE) class OFPActionCopyTtlIn(OFPAction): """ Copy TTL In action This action copies the TTL from the outermost header with TTL to the next-to-outermost header with TTL. """ def __init__(self, type_=None, len_=None): super(OFPActionCopyTtlIn, self).__init__() @classmethod def parser(cls, buf, offset): (type_, len_) = struct.unpack_from( ofproto.OFP_ACTION_HEADER_PACK_STR, buf, offset) return cls() @OFPAction.register_action_type(ofproto.OFPAT_PUSH_VLAN, ofproto.OFP_ACTION_PUSH_SIZE) class OFPActionPushVlan(OFPAction): """ Push VLAN action This action pushes a new VLAN tag to the packet. ================ ====================================================== Attribute Description ================ ====================================================== ethertype Ether type. The default is 802.1Q. (0x8100) ================ ====================================================== """ def __init__(self, ethertype=ether.ETH_TYPE_8021Q, type_=None, len_=None): super(OFPActionPushVlan, self).__init__() self.ethertype = ethertype @classmethod def parser(cls, buf, offset): (type_, len_, ethertype) = struct.unpack_from( ofproto.OFP_ACTION_PUSH_PACK_STR, buf, offset) return cls(ethertype) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_PUSH_PACK_STR, buf, offset, self.type, self.len, self.ethertype) @OFPAction.register_action_type(ofproto.OFPAT_PUSH_MPLS, ofproto.OFP_ACTION_PUSH_SIZE) class OFPActionPushMpls(OFPAction): """ Push MPLS action This action pushes a new MPLS header to the packet. ================ ====================================================== Attribute Description ================ ====================================================== ethertype Ether type ================ ====================================================== """ def __init__(self, ethertype=ether.ETH_TYPE_MPLS, type_=None, len_=None): super(OFPActionPushMpls, self).__init__() self.ethertype = ethertype @classmethod def parser(cls, buf, offset): (type_, len_, ethertype) = struct.unpack_from( ofproto.OFP_ACTION_PUSH_PACK_STR, buf, offset) return cls(ethertype) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_PUSH_PACK_STR, buf, offset, self.type, self.len, self.ethertype) @OFPAction.register_action_type(ofproto.OFPAT_POP_VLAN, ofproto.OFP_ACTION_HEADER_SIZE) class OFPActionPopVlan(OFPAction): """ Pop VLAN action This action pops the outermost VLAN tag from the packet. """ def __init__(self, type_=None, len_=None): super(OFPActionPopVlan, self).__init__() @classmethod def parser(cls, buf, offset): (type_, len_) = struct.unpack_from( ofproto.OFP_ACTION_HEADER_PACK_STR, buf, offset) return cls() @OFPAction.register_action_type(ofproto.OFPAT_POP_MPLS, ofproto.OFP_ACTION_POP_MPLS_SIZE) class OFPActionPopMpls(OFPAction): """ Pop MPLS action This action pops the MPLS header from the packet. """ def __init__(self, ethertype=ether.ETH_TYPE_IP, type_=None, len_=None): super(OFPActionPopMpls, self).__init__() self.ethertype = ethertype @classmethod def parser(cls, buf, offset): (type_, len_, ethertype) = struct.unpack_from( ofproto.OFP_ACTION_POP_MPLS_PACK_STR, buf, offset) return cls(ethertype) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_POP_MPLS_PACK_STR, buf, offset, self.type, self.len, self.ethertype) @OFPAction.register_action_type(ofproto.OFPAT_SET_FIELD, ofproto.OFP_ACTION_SET_FIELD_SIZE) class OFPActionSetField(OFPAction): """ Set field action This action modifies a header field in the packet. The set of keywords available for this is same as OFPMatch. Example:: set_field = OFPActionSetField(eth_src="00:00:00:00:00:00") """ def __init__(self, field=None, **kwargs): super(OFPActionSetField, self).__init__() assert len(kwargs) == 1 key = list(kwargs.keys())[0] value = kwargs[key] assert isinstance(key, (str, str)) assert not isinstance(value, tuple) # no mask self.key = key self.value = value @classmethod def parser(cls, buf, offset): (type_, len_) = struct.unpack_from( ofproto.OFP_ACTION_SET_FIELD_PACK_STR, buf, offset) (n, value, mask, _len) = ofproto.oxm_parse(buf, offset + 4) k, uv = ofproto.oxm_to_user(n, value, mask) action = cls(**{k: uv}) action.len = len_ return action def serialize(self, buf, offset): n, value, mask = ofproto.oxm_from_user(self.key, self.value) len_ = ofproto.oxm_serialize(n, value, mask, buf, offset + 4) self.len = utils.round_up(4 + len_, 8) msg_pack_into('!HH', buf, offset, self.type, self.len) pad_len = self.len - (4 + len_) msg_pack_into("%dx" % pad_len, buf, offset + 4 + len_) def to_jsondict(self): return { self.__class__.__name__: { 'field': ofproto.oxm_to_jsondict(self.key, self.value), "len": self.len, "type": self.type } } @classmethod def from_jsondict(cls, dict_): k, v = ofproto.oxm_from_jsondict(dict_['field']) return OFPActionSetField(**{k: v}) def stringify_attrs(self): yield (self.key, self.value) @OFPAction.register_action_type(ofproto.OFPAT_PUSH_PBB, ofproto.OFP_ACTION_PUSH_SIZE) class OFPActionPushPbb(OFPAction): """ Push PBB action This action pushes a new PBB header to the packet. ================ ====================================================== Attribute Description ================ ====================================================== ethertype Ether type ================ ====================================================== """ def __init__(self, ethertype, type_=None, len_=None): super(OFPActionPushPbb, self).__init__() self.ethertype = ethertype @classmethod def parser(cls, buf, offset): (type_, len_, ethertype) = struct.unpack_from( ofproto.OFP_ACTION_PUSH_PACK_STR, buf, offset) return cls(ethertype) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_PUSH_PACK_STR, buf, offset, self.type, self.len, self.ethertype) @OFPAction.register_action_type(ofproto.OFPAT_POP_PBB, ofproto.OFP_ACTION_HEADER_SIZE) class OFPActionPopPbb(OFPAction): """ Pop PBB action This action pops the outermost PBB service instance header from the packet. """ def __init__(self, type_=None, len_=None): super(OFPActionPopPbb, self).__init__() @classmethod def parser(cls, buf, offset): (type_, len_) = struct.unpack_from( ofproto.OFP_ACTION_HEADER_PACK_STR, buf, offset) return cls() @OFPAction.register_action_type( ofproto.OFPAT_EXPERIMENTER, ofproto.OFP_ACTION_EXPERIMENTER_HEADER_SIZE) class OFPActionExperimenter(OFPAction): """ Experimenter action This action is an extensible action for the experimenter. ================ ====================================================== Attribute Description ================ ====================================================== experimenter Experimenter ID ================ ====================================================== .. Note:: For the list of the supported Nicira experimenter actions, please refer to :ref:`os_ken.ofproto.nx_actions `. """ def __init__(self, experimenter): super(OFPActionExperimenter, self).__init__() self.type = ofproto.OFPAT_EXPERIMENTER self.experimenter = experimenter self.len = None @classmethod def parser(cls, buf, offset): (type_, len_, experimenter) = struct.unpack_from( ofproto.OFP_ACTION_EXPERIMENTER_HEADER_PACK_STR, buf, offset) data = buf[(offset + ofproto.OFP_ACTION_EXPERIMENTER_HEADER_SIZE ): offset + len_] if experimenter == ofproto_common.NX_EXPERIMENTER_ID: obj = NXAction.parse(data) # noqa else: obj = OFPActionExperimenterUnknown(experimenter, data) obj.len = len_ return obj def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_EXPERIMENTER_HEADER_PACK_STR, buf, offset, self.type, self.len, self.experimenter) class OFPActionExperimenterUnknown(OFPActionExperimenter): def __init__(self, experimenter, data=None, type_=None, len_=None): super(OFPActionExperimenterUnknown, self).__init__(experimenter=experimenter) self.data = data def serialize(self, buf, offset): # fixup data = self.data if data is None: data = bytearray() self.len = (utils.round_up(len(data), 8) + ofproto.OFP_ACTION_EXPERIMENTER_HEADER_SIZE) super(OFPActionExperimenterUnknown, self).serialize(buf, offset) msg_pack_into('!%ds' % len(self.data), buf, offset + ofproto.OFP_ACTION_EXPERIMENTER_HEADER_SIZE, self.data) @_register_parser @_set_msg_type(ofproto.OFPT_GROUP_MOD) class OFPGroupMod(MsgBase): """ Modify group entry message The controller sends this message to modify the group table. ================ ====================================================== Attribute Description ================ ====================================================== command One of the following values. | OFPGC_ADD | OFPGC_MODIFY | OFPGC_DELETE type One of the following values. | OFPGT_ALL | OFPGT_SELECT | OFPGT_INDIRECT | OFPGT_FF group_id Group identifier buckets list of ``OFPBucket`` ================ ====================================================== ``type`` attribute corresponds to ``type_`` parameter of __init__. Example:: def send_group_mod(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser port = 1 max_len = 2000 actions = [ofp_parser.OFPActionOutput(port, max_len)] weight = 100 watch_port = 0 watch_group = 0 buckets = [ofp_parser.OFPBucket(weight, watch_port, watch_group, actions)] group_id = 1 req = ofp_parser.OFPGroupMod(datapath, ofp.OFPGC_ADD, ofp.OFPGT_SELECT, group_id, buckets) datapath.send_msg(req) """ def __init__(self, datapath, command=ofproto.OFPGC_ADD, type_=ofproto.OFPGT_ALL, group_id=0, buckets=None): buckets = buckets if buckets else [] super(OFPGroupMod, self).__init__(datapath) self.command = command self.type = type_ self.group_id = group_id self.buckets = buckets @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPGroupMod, cls).parser( datapath, version, msg_type, msg_len, xid, buf) (msg.command, msg.type, msg.group_id) = struct.unpack_from( ofproto.OFP_GROUP_MOD_PACK_STR, buf, ofproto.OFP_HEADER_SIZE) offset = ofproto.OFP_GROUP_MOD_SIZE msg.buckets = [] while offset < msg.msg_len: bucket = OFPBucket.parser(buf, offset) msg.buckets.append(bucket) offset += bucket.len return msg def _serialize_body(self): msg_pack_into(ofproto.OFP_GROUP_MOD_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.command, self.type, self.group_id) offset = ofproto.OFP_GROUP_MOD_SIZE for b in self.buckets: b.serialize(self.buf, offset) offset += b.len class OFPPortModProp(OFPPropBase): _TYPES = {} class OFPPortModPropEthernet(OFPPortModProp): def __init__(self, type_=None, length=None, advertise=None): self.type = type_ self.advertise = advertise def serialize(self): # fixup self.length = struct.calcsize( ofproto.OFP_PORT_MOD_PROP_ETHERNET_PACK_STR) buf = bytearray() msg_pack_into(ofproto.OFP_PORT_MOD_PROP_ETHERNET_PACK_STR, buf, 0, self.type, self.length, self.advertise) return buf class OFPPortModPropOptical(OFPPortModProp): def __init__(self, type_=None, length=None, configure=None, freq_lmda=None, fl_offset=None, grid_span=None, tx_pwr=None): self.type = type_ self.length = length self.configure = configure self.freq_lmda = freq_lmda self.fl_offset = fl_offset self.grid_span = grid_span self.tx_pwr = tx_pwr def serialize(self): # fixup self.length = struct.calcsize( ofproto.OFP_PORT_MOD_PROP_OPTICAL_PACK_STR) buf = bytearray() msg_pack_into(ofproto.OFP_PORT_MOD_PROP_OPTICAL_PACK_STR, buf, 0, self.type, self.length, self.configure, self.freq_lmda, self.fl_offset, self.grid_span, self.tx_pwr) return buf class OFPPortModPropExperimenter(OFPPropCommonExperimenter4ByteData): pass @_set_msg_type(ofproto.OFPT_PORT_MOD) class OFPPortMod(MsgBase): """ Port modification message The controller sneds this message to modify the behavior of the port. ================ ====================================================== Attribute Description ================ ====================================================== port_no Port number to modify hw_addr The hardware address that must be the same as hw_addr of ``OFPPort`` of ``OFPSwitchFeatures`` config Bitmap of configuration flags. | OFPPC_PORT_DOWN | OFPPC_NO_RECV | OFPPC_NO_FWD | OFPPC_NO_PACKET_IN mask Bitmap of configuration flags above to be changed properties List of ``OFPPortModProp`` subclass instance ================ ====================================================== Example:: def send_port_mod(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser port_no = 3 hw_addr = 'fa:c8:e8:76:1d:7e' config = 0 mask = (ofp.OFPPC_PORT_DOWN | ofp.OFPPC_NO_RECV | ofp.OFPPC_NO_FWD | ofp.OFPPC_NO_PACKET_IN) advertise = (ofp.OFPPF_10MB_HD | ofp.OFPPF_100MB_FD | ofp.OFPPF_1GB_FD | ofp.OFPPF_COPPER | ofp.OFPPF_AUTONEG | ofp.OFPPF_PAUSE | ofp.OFPPF_PAUSE_ASYM) properties = [ofp_parser.OFPPortModPropEthernet(advertise)] req = ofp_parser.OFPPortMod(datapath, port_no, hw_addr, config, mask, properties) datapath.send_msg(req) """ _TYPE = { 'ascii': [ 'hw_addr', ] } def __init__(self, datapath, port_no=0, hw_addr='00:00:00:00:00:00', config=0, mask=0, properties=None): super(OFPPortMod, self).__init__(datapath) self.port_no = port_no self.hw_addr = hw_addr self.config = config self.mask = mask self.properties = properties or [] def _serialize_body(self): bin_props = bytearray() for p in self.properties: bin_props += p.serialize() msg_pack_into(ofproto.OFP_PORT_MOD_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.port_no, addrconv.mac.text_to_bin(self.hw_addr), self.config, self.mask) self.buf += bin_props class OFPBucket(StringifyMixin): def __init__(self, weight=0, watch_port=ofproto.OFPP_ANY, watch_group=ofproto.OFPG_ANY, actions=None, len_=None): super(OFPBucket, self).__init__() self.weight = weight self.watch_port = watch_port self.watch_group = watch_group self.actions = actions @classmethod def parser(cls, buf, offset): (len_, weight, watch_port, watch_group) = struct.unpack_from( ofproto.OFP_BUCKET_PACK_STR, buf, offset) msg = cls(weight, watch_port, watch_group, []) msg.len = len_ length = ofproto.OFP_BUCKET_SIZE offset += ofproto.OFP_BUCKET_SIZE while length < msg.len: action = OFPAction.parser(buf, offset) msg.actions.append(action) offset += action.len length += action.len return msg def serialize(self, buf, offset): action_offset = offset + ofproto.OFP_BUCKET_SIZE action_len = 0 for a in self.actions: a.serialize(buf, action_offset) action_offset += a.len action_len += a.len self.len = utils.round_up(ofproto.OFP_BUCKET_SIZE + action_len, 8) msg_pack_into(ofproto.OFP_BUCKET_PACK_STR, buf, offset, self.len, self.weight, self.watch_port, self.watch_group) @_set_msg_type(ofproto.OFPT_ROLE_REQUEST) class OFPRoleRequest(MsgBase): """ Role request message The controller uses this message to change its role. ================ ====================================================== Attribute Description ================ ====================================================== role One of the following values. | OFPCR_ROLE_NOCHANGE | OFPCR_ROLE_EQUAL | OFPCR_ROLE_MASTER | OFPCR_ROLE_SLAVE generation_id Master Election Generation ID ================ ====================================================== Example:: def send_role_request(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPRoleRequest(datapath, ofp.OFPCR_ROLE_EQUAL, 0) datapath.send_msg(req) """ def __init__(self, datapath, role=None, generation_id=None): super(OFPRoleRequest, self).__init__(datapath) self.role = role self.generation_id = generation_id def _serialize_body(self): assert self.role is not None assert self.generation_id is not None msg_pack_into(ofproto.OFP_ROLE_REQUEST_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.role, self.generation_id) @_register_parser @_set_msg_type(ofproto.OFPT_ROLE_REPLY) class OFPRoleReply(MsgBase): """ Role reply message The switch responds with this message to a role request. ================ ====================================================== Attribute Description ================ ====================================================== role One of the following values. | OFPCR_ROLE_NOCHANGE | OFPCR_ROLE_EQUAL | OFPCR_ROLE_MASTER | OFPCR_ROLE_SLAVE generation_id Master Election Generation ID ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPRoleReply, MAIN_DISPATCHER) def role_reply_handler(self, ev): msg = ev.msg dp = msg.datapath ofp = dp.ofproto if msg.role == ofp.OFPCR_ROLE_NOCHANGE: role = 'NOCHANGE' elif msg.role == ofp.OFPCR_ROLE_EQUAL: role = 'EQUAL' elif msg.role == ofp.OFPCR_ROLE_MASTER: role = 'MASTER' elif msg.role == ofp.OFPCR_ROLE_SLAVE: role = 'SLAVE' else: role = 'unknown' self.logger.debug('OFPRoleReply received: ' 'role=%s generation_id=%d', role, msg.generation_id) """ def __init__(self, datapath, role=None, generation_id=None): super(OFPRoleReply, self).__init__(datapath) self.role = role self.generation_id = generation_id @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPRoleReply, cls).parser(datapath, version, msg_type, msg_len, xid, buf) (msg.role, msg.generation_id) = struct.unpack_from( ofproto.OFP_ROLE_REQUEST_PACK_STR, msg.buf, ofproto.OFP_HEADER_SIZE) return msg class OFPAsyncConfigProp(OFPPropBase): _TYPES = {} @OFPAsyncConfigProp.register_type(ofproto.OFPACPT_PACKET_IN_SLAVE) @OFPAsyncConfigProp.register_type(ofproto.OFPACPT_PACKET_IN_MASTER) @OFPAsyncConfigProp.register_type(ofproto.OFPACPT_PORT_STATUS_SLAVE) @OFPAsyncConfigProp.register_type(ofproto.OFPACPT_PORT_STATUS_MASTER) @OFPAsyncConfigProp.register_type(ofproto.OFPACPT_FLOW_REMOVED_SLAVE) @OFPAsyncConfigProp.register_type(ofproto.OFPACPT_FLOW_REMOVED_MASTER) @OFPAsyncConfigProp.register_type(ofproto.OFPACPT_ROLE_STATUS_SLAVE) @OFPAsyncConfigProp.register_type(ofproto.OFPACPT_ROLE_STATUS_MASTER) @OFPAsyncConfigProp.register_type(ofproto.OFPACPT_TABLE_STATUS_SLAVE) @OFPAsyncConfigProp.register_type(ofproto.OFPACPT_TABLE_STATUS_MASTER) @OFPAsyncConfigProp.register_type(ofproto.OFPACPT_REQUESTFORWARD_SLAVE) @OFPAsyncConfigProp.register_type(ofproto.OFPACPT_REQUESTFORWARD_MASTER) class OFPAsyncConfigPropReasons(OFPAsyncConfigProp): def __init__(self, type_=None, length=None, mask=None): self.type = type_ self.length = length self.mask = mask @classmethod def parser(cls, buf): reasons = cls() (reasons.type, reasons.length, reasons.mask) = struct.unpack_from( ofproto.OFP_ASYNC_CONFIG_PROP_REASONS_PACK_STR, buf, 0) return reasons def serialize(self): # fixup self.length = ofproto.OFP_ASYNC_CONFIG_PROP_REASONS_SIZE buf = bytearray() msg_pack_into(ofproto.OFP_ASYNC_CONFIG_PROP_REASONS_PACK_STR, buf, 0, self.type, self.length, self.mask) return buf @OFPAsyncConfigProp.register_type(ofproto.OFPACPT_EXPERIMENTER_SLAVE) @OFPAsyncConfigProp.register_type(ofproto.OFPACPT_EXPERIMENTER_MASTER) class OFPAsyncConfigPropExperimenter(OFPPropCommonExperimenter4ByteData): pass @_set_msg_type(ofproto.OFPT_GET_ASYNC_REQUEST) class OFPGetAsyncRequest(MsgBase): """ Get asynchronous configuration request message The controller uses this message to query the asynchronous message. Example:: def send_get_async_request(self, datapath): ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPGetAsyncRequest(datapath) datapath.send_msg(req) """ def __init__(self, datapath): super(OFPGetAsyncRequest, self).__init__(datapath) @_register_parser @_set_msg_type(ofproto.OFPT_GET_ASYNC_REPLY) class OFPGetAsyncReply(MsgBase): """ Get asynchronous configuration reply message The switch responds with this message to a get asynchronous configuration request. ================== ==================================================== Attribute Description ================== ==================================================== properties List of ``OFPAsyncConfigProp`` subclass instances ================== ==================================================== Example:: @set_ev_cls(ofp_event.EventOFPGetAsyncReply, MAIN_DISPATCHER) def get_async_reply_handler(self, ev): msg = ev.msg self.logger.debug('OFPGetAsyncReply received: ' 'properties=%s', repr(msg.properties)) """ def __init__(self, datapath, properties=None): super(OFPGetAsyncReply, self).__init__(datapath) self.properties = properties @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPGetAsyncReply, cls).parser(datapath, version, msg_type, msg_len, xid, buf) msg.properties = [] rest = msg.buf[ofproto.OFP_HEADER_SIZE:] while rest: p, rest = OFPAsyncConfigProp.parse(rest) msg.properties.append(p) return msg @_set_msg_type(ofproto.OFPT_SET_ASYNC) class OFPSetAsync(MsgBase): """ Set asynchronous configuration message The controller sends this message to set the asynchronous messages that it wants to receive on a given OpneFlow channel. ================== ==================================================== Attribute Description ================== ==================================================== properties List of ``OFPAsyncConfigProp`` subclass instances ================== ==================================================== Example:: def send_set_async(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser properties = [ ofp_parser.OFPAsyncConfigPropReasons( ofp.OFPACPT_PACKET_IN_SLAVE, 8, (1 << ofp.OFPR_APPLY_ACTION | 1 << ofp.OFPR_INVALID_TTL))] req = ofp_parser.OFPSetAsync(datapath, properties) datapath.send_msg(req) """ def __init__(self, datapath, properties=None): super(OFPSetAsync, self).__init__(datapath) self.properties = properties def _serialize_body(self): bin_props = bytearray() for p in self.properties: bin_props += p.serialize() self.buf += bin_props @_register_parser @_set_msg_type(ofproto.OFPT_BUNDLE_CONTROL) class OFPBundleCtrlMsg(MsgBase): """ Bundle control message The controller uses this message to create, destroy and commit bundles ================ ====================================================== Attribute Description ================ ====================================================== bundle_id Id of the bundle type One of the following values. | OFPBCT_OPEN_REQUEST | OFPBCT_OPEN_REPLY | OFPBCT_CLOSE_REQUEST | OFPBCT_CLOSE_REPLY | OFPBCT_COMMIT_REQUEST | OFPBCT_COMMIT_REPLY | OFPBCT_DISCARD_REQUEST | OFPBCT_DISCARD_REPLY flags Bitmap of the following flags. | OFPBF_ATOMIC | OFPBF_ORDERED properties List of ``OFPBundleProp`` subclass instance ================ ====================================================== Example:: def send_bundle_control(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPBundleCtrlMsg(datapath, 7, ofp.OFPBCT_OPEN_REQUEST, ofp.OFPBF_ATOMIC, []) datapath.send_msg(req) """ def __init__(self, datapath, bundle_id=None, type_=None, flags=None, properties=None): super(OFPBundleCtrlMsg, self).__init__(datapath) self.bundle_id = bundle_id self.type = type_ self.flags = flags self.properties = properties def _serialize_body(self): bin_props = bytearray() for p in self.properties: bin_props += p.serialize() msg_pack_into(ofproto.OFP_BUNDLE_CTRL_MSG_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.bundle_id, self.type, self.flags) self.buf += bin_props @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPBundleCtrlMsg, cls).parser(datapath, version, msg_type, msg_len, xid, buf) (bundle_id, type_, flags) = struct.unpack_from( ofproto.OFP_BUNDLE_CTRL_MSG_PACK_STR, buf, ofproto.OFP_HEADER_SIZE) msg.bundle_id = bundle_id msg.type = type_ msg.flags = flags msg.properties = [] rest = msg.buf[ofproto.OFP_BUNDLE_CTRL_MSG_SIZE:] while rest: p, rest = OFPBundleProp.parse(rest) msg.properties.append(p) return msg @_set_msg_type(ofproto.OFPT_BUNDLE_ADD_MESSAGE) class OFPBundleAddMsg(MsgInMsgBase): """ Bundle add message The controller uses this message to add a message to a bundle ================ ====================================================== Attribute Description ================ ====================================================== bundle_id Id of the bundle flags Bitmap of the following flags. | OFPBF_ATOMIC | OFPBF_ORDERED message ``MsgBase`` subclass instance properties List of ``OFPBundleProp`` subclass instance ================ ====================================================== Example:: def send_bundle_add_message(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser msg = ofp_parser.OFPRoleRequest(datapath, ofp.OFPCR_ROLE_EQUAL, 0) req = ofp_parser.OFPBundleAddMsg(datapath, 7, ofp.OFPBF_ATOMIC, msg, []) datapath.send_msg(req) """ def __init__(self, datapath, bundle_id, flags, message, properties): super(OFPBundleAddMsg, self).__init__(datapath) self.bundle_id = bundle_id self.flags = flags self.message = message self.properties = properties def _serialize_body(self): # The xid of the inner message must be the same as # that of the outer message (OF1.4.0 7.3.9.2) if self.message.xid != self.xid: self.message.set_xid(self.xid) # Message self.message.serialize() tail_buf = self.message.buf # Pad if len(self.properties) > 0: message_len = len(tail_buf) pad_len = utils.round_up(message_len, 8) - message_len msg_pack_into("%dx" % pad_len, tail_buf, message_len) # Properties for p in self.properties: tail_buf += p.serialize() # Head msg_pack_into(ofproto.OFP_BUNDLE_ADD_MSG_0_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.bundle_id, self.flags) # Finish self.buf += tail_buf @_register_exp_type(ofproto_common.NX_EXPERIMENTER_ID, nicira_ext.NXT_SET_PACKET_IN_FORMAT) class NXTSetPacketInFormatMsg(OFPExperimenter): def __init__(self, datapath, packet_in_format): super(NXTSetPacketInFormatMsg, self).__init__( datapath, ofproto_common.NX_EXPERIMENTER_ID, nicira_ext.NXT_SET_PACKET_IN_FORMAT) self.packet_in_format = packet_in_format def _serialize_body(self): msg_pack_into(ofproto.OFP_EXPERIMENTER_HEADER_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.experimenter, self.exp_type) msg_pack_into(nicira_ext.NX_SET_PACKET_IN_FORMAT_PACK_STR, self.buf, ofproto.OFP_EXPERIMENTER_HEADER_SIZE, self.packet_in_format) @classmethod def parser_subtype(cls, super_msg): packet_in_format = struct.unpack_from( nicira_ext.NX_SET_PACKET_IN_FORMAT_PACK_STR, super_msg.data)[0] msg = cls(super_msg.datapath, packet_in_format) msg.properties = [] return msg @_register_exp_type(ofproto_common.NX_EXPERIMENTER_ID, nicira_ext.NXT_PACKET_IN2) class NXTPacketIn2(OFPExperimenter): def __init__(self, datapath, properties=None): super(NXTPacketIn2, self).__init__( datapath, ofproto_common.NX_EXPERIMENTER_ID, nicira_ext.NXT_PACKET_IN2) self.properties = properties or [] self.data = None self.total_len = None self.buffer_id = None self.table_id = None self.cookie = None self.reason = None self.metadata = None self.userdata = None self.continuation = None def _serialize_body(self): bin_props = bytearray() for p in self.properties: bin_props += p.serialize() msg_pack_into(ofproto.OFP_EXPERIMENTER_HEADER_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.experimenter, self.exp_type) self.buf += bin_props @classmethod def parser_subtype(cls, super_msg): msg = cls(super_msg.datapath) rest = super_msg.data while rest: p, rest = NXTPacketIn2Prop.parse(rest) msg.properties.append(p) msg._parse_property(p) return msg def _parse_property(self, p): if p.type == nicira_ext.NXPINT_PACKET: self.data = p.data # Note: here total_len is length of packet but not msg self.total_len = p.length elif p.type == nicira_ext.NXPINT_FULL_LEN: self.total_len = struct.unpack_from('!I', p.data)[0] elif p.type == nicira_ext.NXPINT_BUFFER_ID: self.buffer_id = struct.unpack_from('!I', p.data)[0] elif p.type == nicira_ext.NXPINT_TABLE_ID: self.table_id = struct.unpack_from('B', p.data)[0] elif p.type == nicira_ext.NXPINT_COOKIE: self.cookie = struct.unpack_from('!Q', p.data)[0] elif p.type == nicira_ext.NXPINT_REASON: self.reason = struct.unpack_from('!B', p.data)[0] elif p.type == nicira_ext.NXPINT_METADATA: self.metadata = p.data elif p.type == nicira_ext.NXPINT_USERDATA: self.userdata = p.data elif p.type == nicira_ext.NXPINT_CONTINUATION: self.continuation = p.data class NXTPacketIn2Prop(OFPPropBase): _TYPES = {} _PROP_TYPE = None def __init__(self, type_=None, length=None, data=None): super(NXTPacketIn2Prop, self).__init__(type_, length) self.data = data @classmethod def parse(cls, buf): (type_, length) = struct.unpack_from(cls._PACK_STR, buf, 0) if not length: raise ValueError rest = buf[utils.round_up(length, 8):] try: subcls = cls._TYPES[type_] except KeyError: subcls = OFPPropUnknown prop = subcls.sub_parser(buf, type, length) prop.type = type_ prop.length = length return prop, rest def serialize_body(self): return self.data @classmethod def sub_parser(cls, buf, type, length): p = cls(type, length - 4, buf[4:length]) return p @NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_PACKET) class NXTPacketIn2PropPacket(NXTPacketIn2Prop): _PROP_TYPE = nicira_ext.NXPINT_PACKET @NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_FULL_LEN) class NXTPacketIn2PropFullLen(NXTPacketIn2Prop): _PROP_TYPE = nicira_ext.NXPINT_FULL_LEN @NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_BUFFER_ID) class NXTPacketIn2PropBufferId(NXTPacketIn2Prop): _PROP_TYPE = nicira_ext.NXPINT_BUFFER_ID @NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_TABLE_ID) class NXTPacketIn2PropTableId(NXTPacketIn2Prop): _PROP_TYPE = nicira_ext.NXPINT_TABLE_ID @NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_COOKIE) class NXTPacketIn2PropCookie(NXTPacketIn2Prop): _PROP_TYPE = nicira_ext.NXPINT_COOKIE @NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_REASON) class NXTPacketIn2PropReason(NXTPacketIn2Prop): _PROP_TYPE = nicira_ext.NXPINT_REASON @NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_METADATA) class NXTPacketIn2PropMetadata(NXTPacketIn2Prop): _PROP_TYPE = nicira_ext.NXPINT_METADATA @NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_USERDATA) class NXTPacketIn2PropUserData(NXTPacketIn2Prop): _PROP_TYPE = nicira_ext.NXPINT_USERDATA @NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_CONTINUATION) class NXTPacketIn2PropContinuation(NXTPacketIn2Prop): _PROP_TYPE = nicira_ext.NXPINT_CONTINUATION nx_actions.generate( 'os_ken.ofproto.ofproto_v1_4', 'os_ken.ofproto.ofproto_v1_4_parser' ) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/ofproto/ofproto_v1_5.py0000664000175000017500000022564600000000000020672 0ustar00zuulzuul00000000000000# Copyright (C) 2012,2013 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2012 Isaku Yamahata # # 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. """ OpenFlow 1.5 definitions. """ from os_ken.lib import type_desc from os_ken.ofproto import nicira_ext from os_ken.ofproto import ofproto_utils from os_ken.ofproto import oxm_fields from os_ken.ofproto import oxs_fields from struct import calcsize # enum ofp_port_no # Port numbering. Ports are numbered starting from 1. OFPP_MAX = 0xffffff00 # Maximum number of physical and logical # switch ports. OFPP_UNSET = 0xfffffff7 # Output port not set in action-set. # used only in OXM_OF_ACTSET_OUTPUT. OFPP_IN_PORT = 0xfffffff8 # Send the packet out the input port. This # reserved port must be explicitly used in # order to send back out of the input port. OFPP_TABLE = 0xfffffff9 # Submit the packet to the first flow table # NB: This destination port can only be used # in packet-out messages. OFPP_NORMAL = 0xfffffffa # Forward using non-OpenFlow pipeline. OFPP_FLOOD = 0xfffffffb # Flood using non-OpenFlow pipeline. OFPP_ALL = 0xfffffffc # All standard ports except input port. OFPP_CONTROLLER = 0xfffffffd # Send to controller. OFPP_LOCAL = 0xfffffffe # Local openflow "port". OFPP_ANY = 0xffffffff # Special value used in some requests when # no port is specified (i.e. wildcarded). # enum ofp_type # Immutable messages. OFPT_HELLO = 0 # Symmetric message OFPT_ERROR = 1 # Symmetric message OFPT_ECHO_REQUEST = 2 # Symmetric message OFPT_ECHO_REPLY = 3 # Symmetric message OFPT_EXPERIMENTER = 4 # Symmetric message # Switch configuration messages. OFPT_FEATURES_REQUEST = 5 # Controller/switch message OFPT_FEATURES_REPLY = 6 # Controller/switch message OFPT_GET_CONFIG_REQUEST = 7 # Controller/switch message OFPT_GET_CONFIG_REPLY = 8 # Controller/switch message OFPT_SET_CONFIG = 9 # Controller/switch message # Asynchronous messages. OFPT_PACKET_IN = 10 # Async message OFPT_FLOW_REMOVED = 11 # Async message OFPT_PORT_STATUS = 12 # Async message # Controller command messages. OFPT_PACKET_OUT = 13 # Controller/switch message OFPT_FLOW_MOD = 14 # Controller/switch message OFPT_GROUP_MOD = 15 # Controller/switch message OFPT_PORT_MOD = 16 # Controller/switch message OFPT_TABLE_MOD = 17 # Controller/switch message # Multipart messages. OFPT_MULTIPART_REQUEST = 18 # Controller/switch message OFPT_MULTIPART_REPLY = 19 # Controller/switch message # Barrier messages. OFPT_BARRIER_REQUEST = 20 # Controller/switch message OFPT_BARRIER_REPLY = 21 # Controller/switch message # Controller role change request messages. OFPT_ROLE_REQUEST = 24 # Controller/switch message OFPT_ROLE_REPLY = 25 # Controller/switch message # Asynchronous message configuration. OFPT_GET_ASYNC_REQUEST = 26 # Controller/switch message OFPT_GET_ASYNC_REPLY = 27 # Controller/switch message OFPT_SET_ASYNC = 28 # Controller/switch message # Meters and rate limiters configuration messages. OFPT_METER_MOD = 29 # Controller/switch message # Controller role change event messages. OFPT_ROLE_STATUS = 30 # Async message # Asynchronous messages. OFPT_TABLE_STATUS = 31 # Async message # Request forwarding by the switch. OFPT_REQUESTFORWARD = 32 # Async message # Bundle operations (multiple messages as a single operation). OFPT_BUNDLE_CONTROL = 33 # Controller/switch message OFPT_BUNDLE_ADD_MESSAGE = 34 # Controller/switch message # Controller Status async message. OFPT_CONTROLLER_STATUS = 35 # Async message _OFP_HEADER_PACK_STR = 'BBHI' OFP_HEADER_PACK_STR = '!' + _OFP_HEADER_PACK_STR OFP_HEADER_SIZE = 8 # struct ofp_hello OFP_HELLO_HEADER_SIZE = 8 # struct ofp_hello_elem_header OFP_HELLO_ELEM_HEADER_PACK_STR = '!HH' OFP_HELLO_ELEM_HEADER_SIZE = 4 assert (calcsize(OFP_HELLO_ELEM_HEADER_PACK_STR) == OFP_HELLO_ELEM_HEADER_SIZE) # enum ofp_hello_elem_type OFPHET_VERSIONBITMAP = 1 # struct ofp_hello_elem_versionbitmap OFP_HELLO_ELEM_VERSIONBITMAP_HEADER_PACK_STR = '!HH' OFP_HELLO_ELEM_VERSIONBITMAP_HEADER_SIZE = 4 assert (calcsize(OFP_HELLO_ELEM_VERSIONBITMAP_HEADER_PACK_STR) == OFP_HELLO_ELEM_VERSIONBITMAP_HEADER_SIZE) OFP_DEFAULT_MISS_SEND_LEN = 128 # enum ofp_config_flags # Handling of IP fragments. OFPC_FRAG_NORMAL = 0 # No special handling for fragments. OFPC_FRAG_DROP = 1 << 0 # Drop fragments. OFPC_FRAG_REASM = 1 << 1 # Reassemble (only if OFPC_IP_REASM set). OFPC_FRAG_MASK = 3 # struct ofp_switch_config OFP_SWITCH_CONFIG_PACK_STR = '!HH' OFP_SWITCH_CONFIG_SIZE = 12 assert (calcsize(OFP_SWITCH_CONFIG_PACK_STR) + OFP_HEADER_SIZE == OFP_SWITCH_CONFIG_SIZE) # enum ofp_table OFPTT_MAX = 0xfe # Last usable table number. OFPTT_ALL = 0xff # Wildcard table used for table config, flow stats # and flow deletes. # enum ofp_table_config OFPTC_DEPRECATED_MASK = 3 # Deprecated bits OFPTC_EVICTION = 1 << 2 # Authorise table to evict flows. OFPTC_VACANCY_EVENTS = 1 << 3 # Enable vacancy events. # enum ofp_table_mod_prop_type OFPTMPT_EVICTION = 0x2 # Eviction property. OFPTMPT_VACANCY = 0x3 # Vacancy property. OFPTMPT_EXPERIMENTER = 0xFFFF # Experimenter property. # enum ofp_table_mod_prop_eviction_flag OFPTMPEF_OTHER = 1 << 0 # Using other factors. OFPTMPEF_IMPORTANCE = 1 << 1 # Using flow entry importance. OFPTMPEF_LIFETIME = 1 << 2 # Using flow entry lifetime. # struct ofp_table_mod_prop_eviction OFP_TABLE_MOD_PROP_EVICTION_PACK_STR = '!HHI' OFP_TABLE_MOD_PROP_EVICTION_SIZE = 8 assert(calcsize(OFP_TABLE_MOD_PROP_EVICTION_PACK_STR) == OFP_TABLE_MOD_PROP_EVICTION_SIZE) # struct ofp_table_mod_prop_vacancy OFP_TABLE_MOD_PROP_VACANCY_PACK_STR = '!HHBBBx' OFP_TABLE_MOD_PROP_VACANCY_SIZE = 8 assert(calcsize(OFP_TABLE_MOD_PROP_VACANCY_PACK_STR) == OFP_TABLE_MOD_PROP_VACANCY_SIZE) # struct ofp_table_mod_prop_experimenter OFP_TABLE_MOD_PROP_EXPERIMENTER_PACK_STR = '!HHII' OFP_TABLE_MOD_PROP_EXPERIMENTER_SIZE = 12 assert(calcsize(OFP_TABLE_MOD_PROP_EXPERIMENTER_PACK_STR) == OFP_TABLE_MOD_PROP_EXPERIMENTER_SIZE) # struct ofp_table_mod OFP_TABLE_MOD_PACK_STR = '!B3xI' OFP_TABLE_MOD_SIZE = 16 assert (calcsize(OFP_TABLE_MOD_PACK_STR) + OFP_HEADER_SIZE == OFP_TABLE_MOD_SIZE) # enum ofp_capabilities OFPC_FLOW_STATS = 1 << 0 # Flow statistics. OFPC_TABLE_STATS = 1 << 1 # Table statistics. OFPC_PORT_STATS = 1 << 2 # Port statistics. OFPC_GROUP_STATS = 1 << 3 # Group statistics. OFPC_IP_REASM = 1 << 5 # Can reassemble IP fragments. OFPC_QUEUE_STATS = 1 << 6 # Queue statistics. OFPC_PORT_BLOCKED = 1 << 8 # Switch will block looping ports. OFPC_BUNDLES = 1 << 9 # Switch supports bundles. OFPC_FLOW_MONITORING = 1 << 10 # Switch supports flow monitoring. # enum ofp_port_config OFPPC_PORT_DOWN = 1 << 0 # Port is administratively down. OFPPC_NO_RECV = 1 << 2 # Drop all packets recieved by port. OFPPC_NO_FWD = 1 << 5 # Drop packets forwarded to port. OFPPC_NO_PACKET_IN = 1 << 6 # Do not send packet-in msgs for port. # enum ofp_port_state OFPPS_LINK_DOWN = 1 << 0 # No physical link present. OFPPS_BLOCKED = 1 << 1 # Port is blocked OFPPS_LIVE = 1 << 2 # Live for Fast Failover Group. # enum ofp_port_features OFPPF_10MB_HD = 1 << 0 # 10 Mb half-duplex rate support. OFPPF_10MB_FD = 1 << 1 # 10 Mb full-duplex rate support. OFPPF_100MB_HD = 1 << 2 # 100 Mb half-duplex rate support. OFPPF_100MB_FD = 1 << 3 # 100 Mb full-duplex rate support. OFPPF_1GB_HD = 1 << 4 # 1 Gb half-duplex rate support. OFPPF_1GB_FD = 1 << 5 # 1 Gb full-duplex rate support. OFPPF_10GB_FD = 1 << 6 # 10 Gb full-duplex rate support. OFPPF_40GB_FD = 1 << 7 # 40 Gb full-duplex rate support. OFPPF_100GB_FD = 1 << 8 # 100 Gb full-duplex rate support. OFPPF_1TB_FD = 1 << 9 # 1 Tb full-duplex rate support. OFPPF_OTHER = 1 << 10 # Other rate, not in the list. OFPPF_COPPER = 1 << 11 # Copper medium. OFPPF_FIBER = 1 << 12 # Fiber medium. OFPPF_AUTONEG = 1 << 13 # Auto-negotiation. OFPPF_PAUSE = 1 << 14 # Pause. OFPPF_PAUSE_ASYM = 1 << 15 # Asymmetric pause. # enum ofp_port_desc_prop_type OFPPDPT_ETHERNET = 0 # Ethernet property. OFPPDPT_OPTICAL = 1 # Optical property. OFPPDPT_PIPELINE_INPUT = 2 # Ingress pipeline fields. OFPPDPT_PIPELINE_OUTPUT = 3 # Egress pipeline fields. OFPPDPT_RECIRCULATE = 4 # Recirculation property. OFPPDPT_EXPERIMENTER = 0xFFFF # Experimenter property. # struct ofp_port_desc_prop_ethernet OFP_PORT_DESC_PROP_ETHERNET_PACK_STR = '!HH4xIIIIII' OFP_PORT_DESC_PROP_ETHERNET_SIZE = 32 assert (calcsize(OFP_PORT_DESC_PROP_ETHERNET_PACK_STR) == OFP_PORT_DESC_PROP_ETHERNET_SIZE) # enum ofp_optical_port_features OFPOPF_RX_TUNE = 1 << 0 # Receiver is tunable OFPOPF_TX_TUNE = 1 << 1 # Transmit is tunable OFPOPF_TX_PWR = 1 << 2 # Power is configurable OFPOPF_USE_FREQ = 1 << 3 # Use Frequency, not wavelength # struct ofp_port_desc_prop_optical OFP_PORT_DESC_PROP_OPTICAL_PACK_STR = '!HH4xIIIIIIIHH' OFP_PORT_DESC_PROP_OPTICAL_SIZE = 40 assert (calcsize(OFP_PORT_DESC_PROP_OPTICAL_PACK_STR) == OFP_PORT_DESC_PROP_OPTICAL_SIZE) # struct ofp_port_desc_prop_oxm OFP_PORT_DESC_PROP_OXM_PACK_STR = '!HH' OFP_PORT_DESC_PROP_OXM_SIZE = 4 assert (calcsize(OFP_PORT_DESC_PROP_OXM_PACK_STR) == OFP_PORT_DESC_PROP_OXM_SIZE) # struct ofp_port_desc_prop_recirculate OFP_PORT_DESC_PROP_RECIRCULATE_PACK_STR = '!HH' OFP_PORT_DESC_PROP_RECIRCULATE_SIZE = 4 assert (calcsize(OFP_PORT_DESC_PROP_RECIRCULATE_PACK_STR) == OFP_PORT_DESC_PROP_RECIRCULATE_SIZE) # struct ofp_port_desc_prop_experimenter OFP_PORT_DESC_PROP_EXPERIMENTER_PACK_STR = '!HHII' OFP_PORT_DESC_PROP_EXPERIMENTER_SIZE = 12 assert (calcsize(OFP_PORT_DESC_PROP_EXPERIMENTER_PACK_STR) == OFP_PORT_DESC_PROP_EXPERIMENTER_SIZE) # struct ofp_port OFP_MAX_PORT_NAME_LEN = 16 OFP_ETH_ALEN = 6 OFP_ETH_ALEN_STR = str(OFP_ETH_ALEN) _OFP_PORT_PACK_STR = 'IH2x' + OFP_ETH_ALEN_STR + 's' + '2x' + \ str(OFP_MAX_PORT_NAME_LEN) + 's' + 'II' OFP_PORT_PACK_STR = '!' + _OFP_PORT_PACK_STR OFP_PORT_SIZE = 40 assert (calcsize(OFP_PORT_PACK_STR) == OFP_PORT_SIZE) # struct ofp_switch_features OFP_SWITCH_FEATURES_PACK_STR = '!QIBB2xII' OFP_SWITCH_FEATURES_SIZE = 32 assert (calcsize(OFP_SWITCH_FEATURES_PACK_STR) + OFP_HEADER_SIZE == OFP_SWITCH_FEATURES_SIZE) # enum ofp_port_reason OFPPR_ADD = 0 # The port was added. OFPPR_DELETE = 1 # The port was removed. OFPPR_MODIFY = 2 # Some attribute of the port has changed. # struct ofp_port_status OFP_PORT_STATUS_PACK_STR = '!B7x' + _OFP_PORT_PACK_STR OFP_PORT_STATUS_SIZE = 56 assert (calcsize(OFP_PORT_STATUS_PACK_STR) + OFP_HEADER_SIZE == OFP_PORT_STATUS_SIZE) # enum ofp_port_mod_prop_type OFPPMPT_ETHERNET = 0 # Ethernet property. OFPPMPT_OPTICAL = 1 # Optical property. OFPPMPT_EXPERIMENTER = 0xFFFF # Experimenter property. # struct ofp_port_mod_prop_ethernet OFP_PORT_MOD_PROP_ETHERNET_PACK_STR = '!HHI' OFP_PORT_MOD_PROP_ETHERNET_SIZE = 8 assert (calcsize(OFP_PORT_MOD_PROP_ETHERNET_PACK_STR) == OFP_PORT_MOD_PROP_ETHERNET_SIZE) # struct ofp_port_mod_prop_optical OFP_PORT_MOD_PROP_OPTICAL_PACK_STR = '!HHIIIII' OFP_PORT_MOD_PROP_OPTICAL_SIZE = 24 assert (calcsize(OFP_PORT_MOD_PROP_OPTICAL_PACK_STR) == OFP_PORT_MOD_PROP_OPTICAL_SIZE) # struct ofp_port_mod_prop_experimenter OFP_PORT_MOD_PROP_EXPERIMENTER_PACK_STR = '!HHII' OFP_PORT_MOD_PROP_EXPERIMENTER_SIZE = 12 assert (calcsize(OFP_PORT_MOD_PROP_EXPERIMENTER_PACK_STR) == OFP_PORT_MOD_PROP_EXPERIMENTER_SIZE) # struct ofp_port_mod OFP_PORT_MOD_PACK_STR = '!I4x' + OFP_ETH_ALEN_STR + 's2xII' OFP_PORT_MOD_SIZE = 32 assert (calcsize(OFP_PORT_MOD_PACK_STR) + OFP_HEADER_SIZE == OFP_PORT_MOD_SIZE) # enum ofp_header_type_namespaces OFPHTN_ONF = 0 # ONF namespace. OFPHTN_ETHERTYPE = 1 # ns_type is an Ethertype. OFPHTN_IP_PROTO = 2 # ns_type is a IP protocol number. OFPHTN_UDP_TCP_PORT = 3 # ns_type is a TCP or UDP port. OFPHTN_IPV4_OPTION = 4 # ns_type is an IPv4 option number. # enum ofp_header_type_onf OFPHTO_ETHERNET = 0 # Ethernet (DIX or IEEE 802.3) - default. OFPHTO_NO_HEADER = 1 # No header, ex. circuit switch. OFPHTO_OXM_EXPERIMENTER = 0xFFFF # Use Experimenter OXM. # struct ofp_header_type OFP_HEADER_TYPE_PACK_STR = '!HH' OFP_HEADER_TYPE_SIZE = 4 assert (calcsize(OFP_HEADER_TYPE_PACK_STR) == OFP_HEADER_TYPE_SIZE) # enum ofp_match_type OFPMT_STANDARD = 0 # Deprecated OFPMT_OXM = 1 # OpenFlow Extensible Match # struct ofp_match _OFP_MATCH_PACK_STR = 'HH4x' OFP_MATCH_PACK_STR = '!' + _OFP_MATCH_PACK_STR OFP_MATCH_SIZE = 8 assert calcsize(OFP_MATCH_PACK_STR) == OFP_MATCH_SIZE # enum ofp_oxm_class OFPXMC_NXM_0 = 0x0000 # Backward compatibility with NXM OFPXMC_NXM_1 = 0x0001 # Backward compatibility with NXM OFPXMC_OPENFLOW_BASIC = 0x8000 # Basic class for OpenFlow OFPXMC_PACKET_REGS = 0x8001 # Packet registers (pipeline fields). OFPXMC_EXPERIMENTER = 0xFFFF # Experimenter class # enum ofp_vlan_id OFPVID_PRESENT = 0x1000 # bit that indicate that a VLAN id is set. OFPVID_NONE = 0X0000 # No VLAN id was set. def _oxm_tlv_header(class_, field, hasmask, length): return (class_ << 16) | (field << 9) | (hasmask << 8) | length def oxm_tlv_header(field, length): return _oxm_tlv_header(OFPXMC_OPENFLOW_BASIC, field, 0, length) def oxm_tlv_header_w(field, length): return _oxm_tlv_header(OFPXMC_OPENFLOW_BASIC, field, 1, length * 2) def oxm_tlv_header_extract_hasmask(header): return (header >> 8) & 1 def oxm_tlv_header_extract_length(header): if oxm_tlv_header_extract_hasmask(header): length = (header & 0xff) // 2 else: length = header & 0xff return length oxm_types = [ oxm_fields.OpenFlowBasic('in_port', 0, type_desc.Int4), oxm_fields.OpenFlowBasic('in_phy_port', 1, type_desc.Int4), oxm_fields.OpenFlowBasic('metadata', 2, type_desc.Int8), oxm_fields.OpenFlowBasic('eth_dst', 3, type_desc.MacAddr), oxm_fields.OpenFlowBasic('eth_src', 4, type_desc.MacAddr), oxm_fields.OpenFlowBasic('eth_type', 5, type_desc.Int2), oxm_fields.OpenFlowBasic('vlan_vid', 6, type_desc.Int2), oxm_fields.OpenFlowBasic('vlan_pcp', 7, type_desc.Int1), oxm_fields.OpenFlowBasic('ip_dscp', 8, type_desc.Int1), oxm_fields.OpenFlowBasic('ip_ecn', 9, type_desc.Int1), oxm_fields.OpenFlowBasic('ip_proto', 10, type_desc.Int1), oxm_fields.OpenFlowBasic('ipv4_src', 11, type_desc.IPv4Addr), oxm_fields.OpenFlowBasic('ipv4_dst', 12, type_desc.IPv4Addr), oxm_fields.OpenFlowBasic('tcp_src', 13, type_desc.Int2), oxm_fields.OpenFlowBasic('tcp_dst', 14, type_desc.Int2), oxm_fields.OpenFlowBasic('udp_src', 15, type_desc.Int2), oxm_fields.OpenFlowBasic('udp_dst', 16, type_desc.Int2), oxm_fields.OpenFlowBasic('sctp_src', 17, type_desc.Int2), oxm_fields.OpenFlowBasic('sctp_dst', 18, type_desc.Int2), oxm_fields.OpenFlowBasic('icmpv4_type', 19, type_desc.Int1), oxm_fields.OpenFlowBasic('icmpv4_code', 20, type_desc.Int1), oxm_fields.OpenFlowBasic('arp_op', 21, type_desc.Int2), oxm_fields.OpenFlowBasic('arp_spa', 22, type_desc.IPv4Addr), oxm_fields.OpenFlowBasic('arp_tpa', 23, type_desc.IPv4Addr), oxm_fields.OpenFlowBasic('arp_sha', 24, type_desc.MacAddr), oxm_fields.OpenFlowBasic('arp_tha', 25, type_desc.MacAddr), oxm_fields.OpenFlowBasic('ipv6_src', 26, type_desc.IPv6Addr), oxm_fields.OpenFlowBasic('ipv6_dst', 27, type_desc.IPv6Addr), oxm_fields.OpenFlowBasic('ipv6_flabel', 28, type_desc.Int4), oxm_fields.OpenFlowBasic('icmpv6_type', 29, type_desc.Int1), oxm_fields.OpenFlowBasic('icmpv6_code', 30, type_desc.Int1), oxm_fields.OpenFlowBasic('ipv6_nd_target', 31, type_desc.IPv6Addr), oxm_fields.OpenFlowBasic('ipv6_nd_sll', 32, type_desc.MacAddr), oxm_fields.OpenFlowBasic('ipv6_nd_tll', 33, type_desc.MacAddr), oxm_fields.OpenFlowBasic('mpls_label', 34, type_desc.Int4), oxm_fields.OpenFlowBasic('mpls_tc', 35, type_desc.Int1), oxm_fields.OpenFlowBasic('mpls_bos', 36, type_desc.Int1), oxm_fields.OpenFlowBasic('pbb_isid', 37, type_desc.Int3), oxm_fields.OpenFlowBasic('tunnel_id', 38, type_desc.Int8), oxm_fields.OpenFlowBasic('ipv6_exthdr', 39, type_desc.Int2), oxm_fields.OpenFlowBasic('pbb_uca', 41, type_desc.Int1), oxm_fields.OpenFlowBasic('tcp_flags', 42, type_desc.Int2), oxm_fields.OpenFlowBasic('actset_output', 43, type_desc.Int4), oxm_fields.OpenFlowBasic('packet_type', 44, type_desc.Int4), # Support for matching/setting xreg0-7 oxm_fields.PacketRegs('xreg0', 0, type_desc.Int8), oxm_fields.PacketRegs('xreg1', 1, type_desc.Int8), oxm_fields.PacketRegs('xreg2', 2, type_desc.Int8), oxm_fields.PacketRegs('xreg3', 3, type_desc.Int8), oxm_fields.PacketRegs('xreg4', 4, type_desc.Int8), oxm_fields.PacketRegs('xreg5', 5, type_desc.Int8), oxm_fields.PacketRegs('xreg6', 6, type_desc.Int8), oxm_fields.PacketRegs('xreg7', 7, type_desc.Int8), ] + nicira_ext.oxm_types oxm_fields.generate(__name__) # struct ofp_stats _OFP_STATS_PACK_STR = 'HH4x' OFP_STATS_PACK_STR = '!' + _OFP_STATS_PACK_STR OFP_STATS_SIZE = 8 assert calcsize(OFP_STATS_PACK_STR) == OFP_STATS_SIZE # enum ofp_oxs_class OFPXSC_OPENFLOW_BASIC = 0x8002 # Basic stats class for OpenFlow OFPXSC_EXPERIMENTER = 0xFFFF # Experimenter class def _oxs_tlv_header(class_, field, reserved, length): return (class_ << 16) | (field << 9) | (reserved << 8) | length def oxs_tlv_header(field, length): return _oxs_tlv_header(OFPXSC_OPENFLOW_BASIC, field, 0, length) def oxs_tlv_header_extract_length(header): return header & 0xff oxs_types = [ oxs_fields.OpenFlowBasic('duration', 0, type_desc.Int4Double), oxs_fields.OpenFlowBasic('idle_time', 1, type_desc.Int4Double), oxs_fields.OpenFlowBasic('flow_count', 3, type_desc.Int4), oxs_fields.OpenFlowBasic('packet_count', 4, type_desc.Int8), oxs_fields.OpenFlowBasic('byte_count', 5, type_desc.Int8), ] oxs_fields.generate(__name__) # enum ofp_action_type OFPAT_OUTPUT = 0 # Output to switch port. OFPAT_COPY_TTL_OUT = 11 # Copy TTL "outwards" -- from # next-to-outermost to outermost OFPAT_COPY_TTL_IN = 12 # Copy TTL "inwards" -- from outermost to # next-to-outermost OFPAT_SET_MPLS_TTL = 15 # MPLS TTL. OFPAT_DEC_MPLS_TTL = 16 # Decrement MPLS TTL OFPAT_PUSH_VLAN = 17 # Push a new VLAN tag OFPAT_POP_VLAN = 18 # Pop the outer VLAN tag OFPAT_PUSH_MPLS = 19 # Push a new MPLS tag OFPAT_POP_MPLS = 20 # Pop the outer MPLS tag OFPAT_SET_QUEUE = 21 # Set queue id when outputting to a port OFPAT_GROUP = 22 # Apply group OFPAT_SET_NW_TTL = 23 # IP TTL. OFPAT_DEC_NW_TTL = 24 # Decrement IP TTL. OFPAT_SET_FIELD = 25 # Set a header field using OXM TLV format. OFPAT_PUSH_PBB = 26 # Push a new PBB service tag (I-TAG) OFPAT_POP_PBB = 27 # Pop the outer PBB service tag (I-TAG) OFPAT_COPY_FIELD = 28 # Copy value between header and register. OFPAT_METER = 29 # Apply meter (rate limiter) OFPAT_EXPERIMENTER = 0xffff # struct ofp_action_header OFP_ACTION_HEADER_PACK_STR = '!HH4x' OFP_ACTION_HEADER_SIZE = 8 assert calcsize(OFP_ACTION_HEADER_PACK_STR) == OFP_ACTION_HEADER_SIZE # enum ofp_controller_max_len OFPCML_MAX = 0xffe5 # maximum max_len value which can be used to # request a specific byte length. OFPCML_NO_BUFFER = 0xffff # indicates that no buffering should be # applied and the whole packet is to be # sent to the controller. # struct ofp_action_output OFP_ACTION_OUTPUT_PACK_STR = '!HHIH6x' OFP_ACTION_OUTPUT_SIZE = 16 assert calcsize(OFP_ACTION_OUTPUT_PACK_STR) == OFP_ACTION_OUTPUT_SIZE # struct ofp_action_generic OFP_ACTION_GENERIC_PACK_STR = '!HH4x' OFP_ACTION_GENERIC_SIZE = 8 assert (calcsize(OFP_ACTION_GENERIC_PACK_STR) == OFP_ACTION_GENERIC_SIZE) # struct ofp_action_mpls_ttl OFP_ACTION_MPLS_TTL_PACK_STR = '!HHB3x' OFP_ACTION_MPLS_TTL_SIZE = 8 assert calcsize(OFP_ACTION_MPLS_TTL_PACK_STR) == OFP_ACTION_MPLS_TTL_SIZE # struct ofp_action_push OFP_ACTION_PUSH_PACK_STR = '!HHH2x' OFP_ACTION_PUSH_SIZE = 8 assert calcsize(OFP_ACTION_PUSH_PACK_STR) == OFP_ACTION_PUSH_SIZE # struct ofp_action_pop_mpls OFP_ACTION_POP_MPLS_PACK_STR = '!HHH2x' OFP_ACTION_POP_MPLS_SIZE = 8 assert calcsize(OFP_ACTION_POP_MPLS_PACK_STR) == OFP_ACTION_POP_MPLS_SIZE # struct ofp_action_set_queue OFP_ACTION_SET_QUEUE_PACK_STR = '!HHI' OFP_ACTION_SET_QUEUE_SIZE = 8 assert calcsize(OFP_ACTION_SET_QUEUE_PACK_STR) == OFP_ACTION_SET_QUEUE_SIZE # struct ofp_action_group OFP_ACTION_GROUP_PACK_STR = '!HHI' OFP_ACTION_GROUP_SIZE = 8 assert calcsize(OFP_ACTION_GROUP_PACK_STR) == OFP_ACTION_GROUP_SIZE # struct ofp_action_nw_ttl OFP_ACTION_NW_TTL_PACK_STR = '!HHB3x' OFP_ACTION_NW_TTL_SIZE = 8 assert calcsize(OFP_ACTION_NW_TTL_PACK_STR) == OFP_ACTION_NW_TTL_SIZE # struct ofp_action_set_field OFP_ACTION_SET_FIELD_PACK_STR = '!HH4x' OFP_ACTION_SET_FIELD_SIZE = 8 assert calcsize(OFP_ACTION_SET_FIELD_PACK_STR) == OFP_ACTION_SET_FIELD_SIZE # struct ofp_action_copy_field OFP_ACTION_COPY_FIELD_PACK_STR = '!HHHHH2x' OFP_ACTION_COPY_FIELD_SIZE = 12 assert calcsize(OFP_ACTION_COPY_FIELD_PACK_STR) == OFP_ACTION_COPY_FIELD_SIZE # struct ofp_action_meter OFP_ACTION_METER_PACK_STR = '!HHI' OFP_ACTION_METER_SIZE = 8 assert calcsize(OFP_ACTION_METER_PACK_STR) == OFP_ACTION_METER_SIZE # struct ofp_action_experimenter_header OFP_ACTION_EXPERIMENTER_HEADER_PACK_STR = '!HHI' OFP_ACTION_EXPERIMENTER_HEADER_SIZE = 8 assert (calcsize(OFP_ACTION_EXPERIMENTER_HEADER_PACK_STR) == OFP_ACTION_EXPERIMENTER_HEADER_SIZE) # enum ofp_instruction_type OFPIT_GOTO_TABLE = 1 # Setup the next table in the lookup pipeline. OFPIT_WRITE_METADATA = 2 # Setup the metadata field for use later in # pipeline. OFPIT_WRITE_ACTIONS = 3 # Write the action(s) onto the datapath # action set OFPIT_APPLY_ACTIONS = 4 # Applies the action(s) immediately OFPIT_CLEAR_ACTIONS = 5 # Clears all actions from the datapath action # set OFPIT_DEPRECATED = 6 # Deprecated (was apply meter) OFPIT_STAT_TRIGGER = 7 # Statistics triggers OFPIT_EXPERIMENTER = 0xFFFF # Experimenter instruction # struct ofp_instruction_goto_table OFP_INSTRUCTION_GOTO_TABLE_PACK_STR = '!HHB3x' OFP_INSTRUCTION_GOTO_TABLE_SIZE = 8 assert (calcsize(OFP_INSTRUCTION_GOTO_TABLE_PACK_STR) == OFP_INSTRUCTION_GOTO_TABLE_SIZE) # struct ofp_instruction_write_metadata OFP_INSTRUCTION_WRITE_METADATA_PACK_STR = '!HH4xQQ' OFP_INSTRUCTION_WRITE_METADATA_SIZE = 24 assert (calcsize(OFP_INSTRUCTION_WRITE_METADATA_PACK_STR) == OFP_INSTRUCTION_WRITE_METADATA_SIZE) # struct ofp_instruction_actions OFP_INSTRUCTION_ACTIONS_PACK_STR = '!HH4x' OFP_INSTRUCTION_ACTIONS_SIZE = 8 assert (calcsize(OFP_INSTRUCTION_ACTIONS_PACK_STR) == OFP_INSTRUCTION_ACTIONS_SIZE) # enum ofp_stat_trigger_flags OFPSTF_PERIODIC = 1 << 0 # Trigger for all multiples of thresholds. OFPSTF_ONLY_FIRST = 1 << 1 # Trigger on only first reach threshold. # struct ofp_instruction_stat_trigger _OFP_INSTRUCTION_STAT_TRIGGER_PACK_STR0 = 'HHI' OFP_INSTRUCTION_STAT_TRIGGER_PACK_STR = ( '!' + _OFP_INSTRUCTION_STAT_TRIGGER_PACK_STR0 + _OFP_STATS_PACK_STR) OFP_INSTRUCTION_STAT_TRIGGER_PACK_STR0 = ( '!' + _OFP_INSTRUCTION_STAT_TRIGGER_PACK_STR0) OFP_INSTRUCTION_STAT_TRIGGER_PACK_SIZE = 16 assert (calcsize(OFP_INSTRUCTION_STAT_TRIGGER_PACK_STR) == OFP_INSTRUCTION_STAT_TRIGGER_PACK_SIZE) # struct ofp_instruction_experimenter_header OFP_INSTRUCTION_EXPERIMENTER_HEADER_PACK_STR = '!HHI' OFP_INSTRUCTION_EXPERIMENTER_HEADER_SIZE = 8 assert (calcsize(OFP_INSTRUCTION_EXPERIMENTER_HEADER_PACK_STR) == OFP_INSTRUCTION_EXPERIMENTER_HEADER_SIZE) # enum ofp_flow_mod_command OFPFC_ADD = 0 # New flow. OFPFC_MODIFY = 1 # Modify all matching flows. OFPFC_MODIFY_STRICT = 2 # Modify entry strictly matching wildcards OFPFC_DELETE = 3 # Delete all matching flows. OFPFC_DELETE_STRICT = 4 # Strictly match wildcards and priority. # Value used in "idle_timeout" and "hard_timeout" to indicate that the # entry is permanent. */ OFP_FLOW_PERMANENT = 0 # By default, choose a priority in the middle. OFP_DEFAULT_PRIORITY = 0x8000 # enum ofp_flow_mod_flags OFPFF_SEND_FLOW_REM = 1 << 0 # Send flow removed message when flow # expires or is deleted. OFPFF_CHECK_OVERLAP = 1 << 1 # Check for overlapping entries first. OFPFF_RESET_COUNTS = 1 << 2 # Reset flow packet and byte counts. OFPFF_NO_PKT_COUNTS = 1 << 3 # Don't keep track of packet count. OFPFF_NO_BYT_COUNTS = 1 << 4 # Don't keep track of byte count. # struct ofp_flow_mod _OFP_FLOW_MOD_PACK_STR0 = 'QQBBHHHIIIHH' OFP_FLOW_MOD_PACK_STR = '!' + _OFP_FLOW_MOD_PACK_STR0 + _OFP_MATCH_PACK_STR OFP_FLOW_MOD_PACK_STR0 = '!' + _OFP_FLOW_MOD_PACK_STR0 OFP_FLOW_MOD_SIZE = 56 assert (calcsize(OFP_FLOW_MOD_PACK_STR) + OFP_HEADER_SIZE == OFP_FLOW_MOD_SIZE) # enum ofp_group OFPG_MAX = 0xffffff00 # Last usable group number. OFPG_ALL = 0xfffffffc # Represents all groups for group delete commands. OFPG_ANY = 0xffffffff # Special wildcard: no group specified. # enum ofp_group_mod_command OFPGC_ADD = 0 # New group. OFPGC_MODIFY = 1 # Modify all matching groups. OFPGC_DELETE = 2 # Delete all matching groups. OFPGC_INSERT_BUCKET = 3 # Insert action buckets to the already available # list of action buckets in a matching group # OFPGC_??? = 4 # Reserved for future use. OFPGC_REMOVE_BUCKET = 5 # Remove all action buckets or any specific action # bucket from matching group # enum ofp_group_bucket_prop_type OFPGBPT_WEIGHT = 0 # Select groups only. OFPGBPT_WATCH_PORT = 1 # Fast failover groups only. OFPGBPT_WATCH_GROUP = 2 # Fast failover groups only. OFPGBPT_EXPERIMENTER = 0xFFFF # Experimenter defined. # struct ofp_group_bucket_prop_header OFP_GROUP_BUCKET_PROP_HEADER_PACK_STR = '!HH' OFP_GROUP_BUCKET_PROP_HEADER_SIZE = 4 assert (calcsize(OFP_GROUP_BUCKET_PROP_HEADER_PACK_STR) == OFP_GROUP_BUCKET_PROP_HEADER_SIZE) # struct ofp_group_bucket_prop_weight OFP_GROUP_BUCKET_PROP_WEIGHT_PACK_STR = '!HHH2x' OFP_GROUP_BUCKET_PROP_WEIGHT_SIZE = 8 assert (calcsize(OFP_GROUP_BUCKET_PROP_WEIGHT_PACK_STR) == OFP_GROUP_BUCKET_PROP_WEIGHT_SIZE) # struct ofp_group_bucket_prop_watch OFP_GROUP_BUCKET_PROP_WATCH_PACK_STR = '!HHI' OFP_GROUP_BUCKET_PROP_WATCH_SIZE = 8 assert (calcsize(OFP_GROUP_BUCKET_PROP_WATCH_PACK_STR) == OFP_GROUP_BUCKET_PROP_WATCH_SIZE) # struct ofp_group_bucket_prop_experimenter OFP_GROUP_BUCKET_PROP_EXPERIMENTER_PACK_STR = '!HHII' OFP_GROUP_BUCKET_PROP_EXPERIMENTER_SIZE = 12 assert (calcsize(OFP_GROUP_BUCKET_PROP_EXPERIMENTER_PACK_STR) == OFP_GROUP_BUCKET_PROP_EXPERIMENTER_SIZE) # struct ofp_bucket OFP_BUCKET_PACK_STR = '!HHI' OFP_BUCKET_SIZE = 8 assert calcsize(OFP_BUCKET_PACK_STR) == OFP_BUCKET_SIZE # enum ofp_group_bucket OFPG_BUCKET_MAX = 0xffffff00 # Last usable bucket ID. OFPG_BUCKET_FIRST = 0xfffffffd # First bucket ID in the list of action # buckets of a group. This is applicable # for OFPGC_INSERT_BUCKET and # OFPGC_REMOVE_BUCKET commands. OFPG_BUCKET_LAST = 0xfffffffe # Last bucket ID in the list of action # buckets of a group. This is applicable # for OFPGC_INSERT_BUCKET and # OFPGC_REMOVE_BUCKET commands. OFPG_BUCKET_ALL = 0xffffffff # All action buckets in a group, # This is applicable for # only OFPGC_REMOVE_BUCKET command. # enum ofp_group_prop_type OFPGPT_EXPERIMENTER = 0xFFFF # Experimenter defined. # struct ofp_group_prop_header OFP_GROUP_PROP_HEADER_PACK_STR = '!HH' OFP_GROUP_PROP_HEADER_SIZE = 4 assert (calcsize(OFP_GROUP_PROP_HEADER_PACK_STR) == OFP_GROUP_PROP_HEADER_SIZE) # struct ofp_group_prop_experimenter OFP_GROUP_PROP_EXPERIMENTER_PACK_STR = '!HHII' OFP_GROUP_PROP_EXPERIMENTER_SIZE = 12 assert (calcsize(OFP_GROUP_PROP_EXPERIMENTER_PACK_STR) == OFP_GROUP_PROP_EXPERIMENTER_SIZE) # struct ofp_group_mod OFP_GROUP_MOD_PACK_STR = '!HBxIH2xI' OFP_GROUP_MOD_SIZE = 24 assert (calcsize(OFP_GROUP_MOD_PACK_STR) + OFP_HEADER_SIZE == OFP_GROUP_MOD_SIZE) # enum ofp_group_type OFPGT_ALL = 0 # All (multicast/broadcast) group. OFPGT_SELECT = 1 # Select group. OFPGT_INDIRECT = 2 # Indirect group. OFPGT_FF = 3 # Fast failover group. OFP_NO_BUFFER = 0xffffffff # Special buffer-id to indicate 'no buffer' # struct ofp_packet_out OFP_PACKET_OUT_0_PACK_STR = '!IH2x' OFP_PACKET_OUT_0_SIZE = 16 OFP_PACKET_OUT_SIZE = 24 assert (calcsize(OFP_PACKET_OUT_0_PACK_STR) + OFP_MATCH_SIZE + OFP_HEADER_SIZE == OFP_PACKET_OUT_SIZE) # enum ofp_packet_in_reason OFPR_TABLE_MISS = 0 # No matching flow (table-miss flow entry). OFPR_APPLY_ACTION = 1 # Output to controller in apply-actions. OFPR_INVALID_TTL = 2 # Packet has invalid TTL. OFPR_ACTION_SET = 3 # Output to controller in action set. OFPR_GROUP = 4 # Output to controller in group bucket. OFPR_PACKET_OUT = 5 # Output to controller in packet-out. # struct ofp_packet_in OFP_PACKET_IN_PACK_STR = '!IHBBQ' OFP_PACKET_IN_SIZE = 32 assert (calcsize(OFP_PACKET_IN_PACK_STR) + OFP_MATCH_SIZE + OFP_HEADER_SIZE == OFP_PACKET_IN_SIZE) # enum ofp_flow_removed_reason OFPRR_IDLE_TIMEOUT = 0 # Flow idle time exceeded idle_timeout. OFPRR_HARD_TIMEOUT = 1 # Time exceeded hard_timeout. OFPRR_DELETE = 2 # Evicted by a DELETE flow mod. OFPRR_GROUP_DELETE = 3 # Group was removed. OFPRR_METER_DELETE = 4 # Meter was removed. OFPRR_EVICTION = 5 # Switch eviction to free resources. # struct ofp_port_status OFP_PORT_STATUS_PACK_STR = '!B7x' + _OFP_PORT_PACK_STR OFP_PORT_STATUS_DESC_OFFSET = OFP_HEADER_SIZE + 8 OFP_PORT_STATUS_SIZE = 56 assert (calcsize(OFP_PORT_STATUS_PACK_STR) + OFP_HEADER_SIZE == OFP_PORT_STATUS_SIZE) # struct ofp_flow_removed _OFP_FLOW_REMOVED_PACK_STR0 = 'BBHHHQ' OFP_FLOW_REMOVED_PACK_STR = '!' + _OFP_FLOW_REMOVED_PACK_STR0 + \ _OFP_MATCH_PACK_STR OFP_FLOW_REMOVED_PACK_STR0 = '!' + _OFP_FLOW_REMOVED_PACK_STR0 OFP_FLOW_REMOVED_SIZE = 32 assert (calcsize(OFP_FLOW_REMOVED_PACK_STR) + OFP_HEADER_SIZE == OFP_FLOW_REMOVED_SIZE) # enum ofp_meter OFPM_MAX = 0xffff0000 OFPM_SLOWPATH = 0xfffffffd # Meter for slow datapath, if any. OFPM_CONTROLLER = 0xfffffffe # Meter for controller connection. OFPM_ALL = 0xffffffff # Represents all meters for stat requests # commands. # enum ofp_meter_band_type OFPMBT_DROP = 1 # Drop packet. OFPMBT_DSCP_REMARK = 2 # Remark DSCP in the IP header. OFPMBT_EXPERIMENTER = 0xFFFF # Experimenter meter band. # struct ofp_meter_band_drop OFP_METER_BAND_DROP_PACK_STR = '!HHII4x' OFP_METER_BAND_DROP_SIZE = 16 assert (calcsize(OFP_METER_BAND_DROP_PACK_STR) == OFP_METER_BAND_DROP_SIZE) # struct ofp_meter_band_dscp_remark OFP_METER_BAND_DSCP_REMARK_PACK_STR = '!HHIIB3x' OFP_METER_BAND_DSCP_REMARK_SIZE = 16 assert (calcsize(OFP_METER_BAND_DSCP_REMARK_PACK_STR) == OFP_METER_BAND_DSCP_REMARK_SIZE) # struct ofp_meter_band_experimenter OFP_METER_BAND_EXPERIMENTER_PACK_STR = '!HHIII' OFP_METER_BAND_EXPERIMENTER_SIZE = 16 assert (calcsize(OFP_METER_BAND_EXPERIMENTER_PACK_STR) == OFP_METER_BAND_EXPERIMENTER_SIZE) # enum ofp_meter_mod_command OFPMC_ADD = 0 # New meter. OFPMC_MODIFY = 1 # Modify specified meter. OFPMC_DELETE = 2 # Delete specified meter. # enum ofp_meter_flags OFPMF_KBPS = 1 << 0 # Rate value in kb/s (kilo-bit per second). OFPMF_PKTPS = 1 << 1 # Rate value in packet/sec. OFPMF_BURST = 1 << 2 # Do burst size. OFPMF_STATS = 1 << 3 # Collect statistics. # struct ofp_meter_band_header OFP_METER_BAND_HEADER_PACK_STR = '!HHII' OFP_METER_BAND_HEADER_SIZE = 12 assert (calcsize(OFP_METER_BAND_HEADER_PACK_STR) == OFP_METER_BAND_HEADER_SIZE) # struct ofp_meter_mod OFP_METER_MOD_PACK_STR = '!HHI' OFP_METER_MOD_SIZE = 16 assert (calcsize(OFP_METER_MOD_PACK_STR) + OFP_HEADER_SIZE == OFP_METER_MOD_SIZE) # enum ofp_error_type OFPET_HELLO_FAILED = 0 # Hello protocol failed. OFPET_BAD_REQUEST = 1 # Request was not understood. OFPET_BAD_ACTION = 2 # Error in action description. OFPET_BAD_INSTRUCTION = 3 # Error in instruction list. OFPET_BAD_MATCH = 4 # Error in match. OFPET_FLOW_MOD_FAILED = 5 # Problem modifying flow entry. OFPET_GROUP_MOD_FAILED = 6 # Problem modifying group entry. OFPET_PORT_MOD_FAILED = 7 # OFPT_PORT_MOD failed. OFPET_TABLE_MOD_FAILED = 8 # Table mod request failed. OFPET_QUEUE_OP_FAILED = 9 # Queue operation failed. OFPET_SWITCH_CONFIG_FAILED = 10 # Switch config request failed. OFPET_ROLE_REQUEST_FAILED = 11 # Controller Role request failed. OFPET_METER_MOD_FAILED = 12 # Error in meter. OFPET_TABLE_FEATURES_FAILED = 13 # Setting table features failed. OFPET_BAD_PROPERTY = 14 # Some property is invalid. OFPET_ASYNC_CONFIG_FAILED = 15 # Asynchronous config request failed. OFPET_FLOW_MONITOR_FAILED = 16 # Setting flow monitor failed. OFPET_BUNDLE_FAILED = 17 # Bundle operation failed. OFPET_EXPERIMENTER = 0xffff # Experimenter error messages. # enum ofp_hello_failed_code OFPHFC_INCOMPATIBLE = 0 # No compatible version. OFPHFC_EPERM = 1 # Permissions error. # enum ofp_bad_request_code OFPBRC_BAD_VERSION = 0 # ofp_header.version not supported. OFPBRC_BAD_TYPE = 1 # ofp_header.type not supported. OFPBRC_BAD_MULTIPART = 2 # ofp_multipart_request.type not # supported. OFPBRC_BAD_EXPERIMENTER = 3 # Experimenter id not supported # (in ofp_experimenter_header # or ofp_multipart_request or # ofp_multipart_reply). OFPBRC_BAD_EXP_TYPE = 4 # Experimenter type not supported. OFPBRC_EPERM = 5 # Permissions error. OFPBRC_BAD_LEN = 6 # Wrong request length for type. OFPBRC_BUFFER_EMPTY = 7 # Specified buffer has already been # used. OFPBRC_BUFFER_UNKNOWN = 8 # Specified buffer does not exist. OFPBRC_BAD_TABLE_ID = 9 # Specified table-id invalid or does # not exist. OFPBRC_IS_SLAVE = 10 # Denied because controller is slave. OFPBRC_BAD_PORT = 11 # Invalid port or missing port. OFPBRC_BAD_PACKET = 12 # Invalid packet in packet-out OFPBRC_MULTIPART_BUFFER_OVERFLOW = 13 # ofp_multipart_request # overflowed the assigned buffer. OFPBRC_MULTIPART_REQUEST_TIMEOUT = 14 # Timeout during multipart request. OFPBRC_MULTIPART_REPLY_TIMEOUT = 15 # Timeout during multipart reply. OFPBRC_MULTIPART_BAD_SCHED = 16 # Switch received a # OFPMP_BUNDLE_FEATURES request and # failed to update the scheduling # tolerance. OFPBRC_PIPELINE_FIELDS_ONLY = 17 # Match fields must include only # pipeline fields. OFPBRC_UNKNOWN = 18 # Unspecified error. # enum ofp_bad_action_code OFPBAC_BAD_TYPE = 0 # Unknown or unsupported action type. OFPBAC_BAD_LEN = 1 # Length problem in actions. OFPBAC_BAD_EXPERIMENTER = 2 # Unknown experimenter id specified. OFPBAC_BAD_EXP_TYPE = 3 # Unknown action type for experimenter id. OFPBAC_BAD_OUT_PORT = 4 # Problem validating output action. OFPBAC_BAD_ARGUMENT = 5 # Bad action argument. OFPBAC_EPERM = 6 # Permissions error. OFPBAC_TOO_MANY = 7 # Can't handle this many actions. OFPBAC_BAD_QUEUE = 8 # Problem validating output queue. OFPBAC_BAD_OUT_GROUP = 9 # Invalid group id in forward action. OFPBAC_MATCH_INCONSISTENT = 10 # Action can't apply for this match, # or Set-Field missing prerequisite. OFPBAC_UNSUPPORTED_ORDER = 11 # Action order is unsupported for # the action list in an Apply-Actions # instruction OFPBAC_BAD_TAG = 12 # Actions uses an unsupported tag/encap. OFPBAC_BAD_SET_TYPE = 13 # Unsupported type in SET_FIELD action. OFPBAC_BAD_SET_LEN = 14 # Length problem in SET_FIELD action. OFPBAC_BAD_SET_ARGUMENT = 15 # Bad arguement in SET_FIELD action. OFPBAC_BAD_SET_MASK = 16 # Bad mask in SET_FIELD action. OFPBAC_BAD_METER = 17 # Invalid meter id in meter action. # enum ofp_bad_instruction_code OFPBIC_UNKNOWN_INST = 0 # Unknown instruction. OFPBIC_UNSUP_INST = 1 # Switch or table does not support # the instruction. OFPBIC_BAD_TABLE_ID = 2 # Invalid Table-Id specified OFPBIC_UNSUP_METADATA = 3 # Metadata value unsupported by datapath. OFPBIC_UNSUP_METADATA_MASK = 4 # Metadata mask value unsupported by # datapath. OFPBIC_BAD_EXPERIMENTER = 5 # Unknown experimenter id specified. OFPBIC_BAD_EXP_TYPE = 6 # Unknown instruction for experimenter id. OFPBIC_BAD_LEN = 7 # Length problem in instrucitons. OFPBIC_EPERM = 8 # Permissions error. OFPBIC_DUP_INST = 9 # Duplicate instruction. # enum ofp_bad_match_code OFPBMC_BAD_TYPE = 0 # Unsupported match type apecified by # the match. OFPBMC_BAD_LEN = 1 # Length problem in math. OFPBMC_BAD_TAG = 2 # Match uses an unsupported tag/encap. OFPBMC_BAD_DL_ADDR_MASK = 3 # Unsupported datalink addr mask - # switch does not support arbitrary # datalink address mask. OFPBMC_BAD_NW_ADDR_MASK = 4 # Unsupported network addr mask - # switch does not support arbitrary # network addres mask. OFPBMC_BAD_WILDCARDS = 5 # Unsupported combination of fields # masked or omitted in the match. OFPBMC_BAD_FIELD = 6 # Unsupported field type in the match. OFPBMC_BAD_VALUE = 7 # Unsupported value in a match field. OFPBMC_BAD_MASK = 8 # Unsupported mask specified in the match. OFPBMC_BAD_PREREQ = 9 # A prerequisite was not met. OFPBMC_DUP_FIELD = 10 # A field type was duplicated. OFPBMC_EPERM = 11 # Permissions error. # enum ofp_flow_mod_failed_code OFPFMFC_UNKNOWN = 0 # Unspecified error. OFPFMFC_TABLE_FULL = 1 # Flow not added because table was full. OFPFMFC_BAD_TABLE_ID = 2 # Table does not exist OFPFMFC_OVERLAP = 3 # Attempted to add overlapping flow with # CHECK_OVERLAP flag set. OFPFMFC_EPERM = 4 # Permissions error. OFPFMFC_BAD_TIMEOUT = 5 # Flow not added because of unsupported # idle/hard timeout. OFPFMFC_BAD_COMMAND = 6 # Unsupported or unknown command. OFPFMFC_BAD_FLAGS = 7 # Unsupported or unknown flags. OFPFMFC_CANT_SYNC = 8 # Problem in table synchronisation. OFPFMFC_BAD_PRIORITY = 9 # Unsupported priority value. OFPFMFC_IS_SYNC = 10 # Synchronised flow entry is read only. # enum ofp_group_mod_failed_code OFPGMFC_GROUP_EXISTS = 0 # Group not added because a group ADD # attempted to replace an already-present # group. OFPGMFC_INVALID_GROUP = 1 # Group not added because Group specified # is invalid. OFPGMFC_WEIGHT_UNSUPPORTED = 2 # Switch does not support unequal load # sharing with select groups. OFPGMFC_OUT_OF_GROUPS = 3 # The group table is full. OFPGMFC_OUT_OF_BUCKETS = 4 # The maximum number of action buckets # for a group has been exceeded. OFPGMFC_CHAINING_UNSUPPORTED = 5 # Switch does not support groups that # forward to groups. OFPGMFC_WATCH_UNSUPPORTED = 6 # This group cannot watch the # watch_port or watch_group specified. OFPGMFC_LOOP = 7 # Group entry would cause a loop. OFPGMFC_UNKNOWN_GROUP = 8 # Group not modified because a group MODIFY # attempted to modify a non-existent group. OFPGMFC_CHAINED_GROUP = 9 # Group not deleted because another group # is forwarding to it. OFPGMFC_BAD_TYPE = 10 # Unsupported or unknown group type. OFPGMFC_BAD_COMMAND = 11 # Unsupported or unknown command. OFPGMFC_BAD_BUCKET = 12 # Error in bucket. OFPGMFC_BAD_WATCH = 13 # Error in watch port/group. OFPGMFC_EPERM = 14 # Permissions error. OFPGMFC_UNKNOWN_BUCKET = 15 # Invalid bucket identifier used in # INSERT BUCKET or REMOVE BUCKET command. OFPGMFC_BUCKET_EXISTS = 16 # Can't insert bucket because a bucket # already exist with that bucket-id. # enum ofp_port_mod_failed_code OFPPMFC_BAD_PORT = 0 # Specified port does not exist. OFPPMFC_BAD_HW_ADDR = 1 # Specified hardware address does not match # the port number. OFPPMFC_BAD_CONFIG = 2 # Specified config is invalid. OFPPMFC_BAD_ADVERTISE = 3 # Specified advertise is invalid. OFPPMFC_EPERM = 4 # Permissions error. # enum ofp_table_mod_failed_code OFPTMFC_BAD_TABLE = 0 # Specified table does not exist. OFPTMFC_BAD_CONFIG = 1 # Specified config is invalid. OFPTMFC_EPERM = 2 # Permissions error # enum ofp_queue_op_failed_code OFPQOFC_BAD_PORT = 0 # Invalid port (or port does not exist). OFPQOFC_BAD_QUEUE = 1 # Queue does not exist. OFPQOFC_EPERM = 2 # Permissions error. # enum ofp_switch_config_failed_code OFPSCFC_BAD_FLAGS = 0 # Specified flags is invalid. OFPSCFC_BAD_LEN = 1 # Specified miss send len is invalid. OFPSCFC_EPERM = 2 # Permissions error. # enum ofp_role_request_failed_code OFPRRFC_STALE = 0 # Stale Message: old generation_id. OFPRRFC_UNSUP = 1 # Controller role change unsupported. OFPRRFC_BAD_ROLE = 2 # Invalid role. OFPRRFC_ID_UNSUP = 3 # Switch doesn't support changing ID. OFPRRFC_ID_IN_USE = 4 # Requested ID is in use. # enum ofp_meter_mod_failed_code OFPMMFC_UNKNOWN = 0 # Unspecified error. OFPMMFC_METER_EXISTS = 1 # Meter not added because a Meter ADD # attempted to replace an existing Meter. OFPMMFC_INVALID_METER = 2 # Meter not added because Meter specified # is invalid, or invalid meter in meter action. OFPMMFC_UNKNOWN_METER = 3 # Meter not modified because a Meter MODIFY # attempted to modify a non-existent Meter, # or bad meter in meter action. OFPMMFC_BAD_COMMAND = 4 # Unsupported or unknown command. OFPMMFC_BAD_FLAGS = 5 # Flag configuration unsupported. OFPMMFC_BAD_RATE = 6 # Rate unsupported. OFPMMFC_BAD_BURST = 7 # Burst size unsupported. OFPMMFC_BAD_BAND = 8 # Band unsupported. OFPMMFC_BAD_BAND_VALUE = 9 # Band value unsupported. OFPMMFC_OUT_OF_METERS = 10 # No more meters availabile. OFPMMFC_OUT_OF_BANDS = 11 # The maximum number of properties for a # meter has been exceeded. # enum ofp_table_features_failed_code OFPTFFC_BAD_TABLE = 0 # Specified table does not exist. OFPTFFC_BAD_METADATA = 1 # Invalid metadata mask. OFPTFFC_EPERM = 5 # Permissions error. OFPTFFC_BAD_CAP = 6 # Invalid capability field. OFPTFFC_BAD_MAX_ENT = 7 # Invalid max_entries field. OFPTFFC_BAD_FEATURES = 8 # Invalid features field. OFPTFFC_BAD_COMMAND = 9 # Invalid command. OFPTFFC_TOO_MANY = 10 # Can't handle this many flow tables. # enum ofp_bad_property_code OFPBPC_BAD_TYPE = 0 # Unknown or unsupported property type. OFPBPC_BAD_LEN = 1 # Length problem in property. OFPBPC_BAD_VALUE = 2 # Unsupported property value. OFPBPC_TOO_MANY = 3 # Can't handle this many properties. OFPBPC_DUP_TYPE = 4 # A property type was duplicated. OFPBPC_BAD_EXPERIMENTER = 5 # Unknown experimenter id specified. OFPBPC_BAD_EXP_TYPE = 6 # Unknown exp_type for experimenter id. OFPBPC_BAD_EXP_VALUE = 7 # Unknown value for experimenter id. OFPBPC_EPERM = 8 # Permissions error. # enum ofp_async_config_failed_code OFPACFC_INVALID = 0 # One mask is invalid. OFPACFC_UNSUPPORTED = 1 # Requested configuration not supported. OFPACFC_EPERM = 2 # Permissions error. # enum ofp_flow_monitor_failed_code OFPMOFC_UNKNOWN = 0 # Unspecified error. OFPMOFC_MONITOR_EXISTS = 1 # Monitor not added because a Monitor ADD # attempted to replace an existing # Monitor. OFPMOFC_INVALID_MONITOR = 2 # Monitor not added because Monitor # specified is invalid. OFPMOFC_UNKNOWN_MONITOR = 3 # Monitor not modified because a Monitor # MODIFY attempted to modify a non-existent # Monitor. OFPMOFC_BAD_COMMAND = 4 # Unsupported or unknown command. OFPMOFC_BAD_FLAGS = 5 # Flag configuration unsupported. OFPMOFC_BAD_TABLE_ID = 6 # Specified table does not exist. OFPMOFC_BAD_OUT = 7 # Error in output port/group. # enum ofp_bundle_failed_code OFPBFC_UNKNOWN = 0 # Unspecified error. OFPBFC_EPERM = 1 # Permissions error. OFPBFC_BAD_ID = 2 # Bundle ID doesn't exist. OFPBFC_BUNDLE_EXIST = 3 # Bundle ID already exist. OFPBFC_BUNDLE_CLOSED = 4 # Bundle ID is closed. OFPBFC_OUT_OF_BUNDLES = 5 # Too many bundles IDs. OFPBFC_BAD_TYPE = 6 # Unsupported or unknown message control type. OFPBFC_BAD_FLAGS = 7 # Unsupported, unknown, or inconsistent flags. OFPBFC_MSG_BAD_LEN = 8 # Length problem in included message. OFPBFC_MSG_BAD_XID = 9 # Inconsistent or duplicate XID. OFPBFC_MSG_UNSUP = 10 # Unsupported message in this bundle. OFPBFC_MSG_CONFLICT = 11 # Unsupported message combination in this # bundle. OFPBFC_MSG_TOO_MANY = 12 # Can't handle this many messages in bundle. OFPBFC_MSG_FAILED = 13 # One message in bundle failed. OFPBFC_TIMEOUT = 14 # Bundle is taking too long. OFPBFC_BUNDLE_IN_PROGRESS = 15 # Bundle is locking the resource. OFPBFC_SCHED_NOT_SUPPORTED = 16 # Scheduled commit was received and # scheduling is not supported. OFPBFC_SCHED_FUTURE = 17 # Scheduled commit time exceeds upper bound. OFPBFC_SCHED_PAST = 18 # Scheduled commit time exceeds lower bound. # struct ofp_error_msg OFP_ERROR_MSG_PACK_STR = '!HH' OFP_ERROR_MSG_SIZE = 12 assert (calcsize(OFP_ERROR_MSG_PACK_STR) + OFP_HEADER_SIZE == OFP_ERROR_MSG_SIZE) # struct ofp_error_experimenter_msg OFP_ERROR_EXPERIMENTER_MSG_PACK_STR = '!HHI' OFP_ERROR_EXPERIMENTER_MSG_SIZE = 16 assert (calcsize(OFP_ERROR_EXPERIMENTER_MSG_PACK_STR) + OFP_HEADER_SIZE) == OFP_ERROR_EXPERIMENTER_MSG_SIZE # struct ofp_experimenter_header OFP_EXPERIMENTER_HEADER_PACK_STR = '!II' OFP_EXPERIMENTER_HEADER_SIZE = 16 assert (calcsize(OFP_EXPERIMENTER_HEADER_PACK_STR) + OFP_HEADER_SIZE == OFP_EXPERIMENTER_HEADER_SIZE) # enum ofp_multipart_type OFPMP_DESC = 0 OFPMP_FLOW_DESC = 1 OFPMP_AGGREGATE_STATS = 2 OFPMP_TABLE_STATS = 3 OFPMP_PORT_STATS = 4 OFPMP_QUEUE_STATS = 5 OFPMP_GROUP_STATS = 6 OFPMP_GROUP_DESC = 7 OFPMP_GROUP_FEATURES = 8 OFPMP_METER_STATS = 9 OFPMP_METER_DESC = 10 OFPMP_METER_FEATURES = 11 OFPMP_TABLE_FEATURES = 12 OFPMP_PORT_DESC = 13 OFPMP_TABLE_DESC = 14 OFPMP_QUEUE_DESC = 15 OFPMP_FLOW_MONITOR = 16 OFPMP_FLOW_STATS = 17 OFPMP_CONTROLLER_STATUS = 18 OFPMP_BUNDLE_FEATURES = 19 OFPMP_EXPERIMENTER = 0xffff # struct ofp_multipart_request OFP_MULTIPART_REQUEST_PACK_STR = '!HH4x' OFP_MULTIPART_REQUEST_SIZE = 16 assert (calcsize(OFP_MULTIPART_REQUEST_PACK_STR) + OFP_HEADER_SIZE == OFP_MULTIPART_REQUEST_SIZE) # enum ofp_multipart_reply_flags OFPMPF_REPLY_MORE = 1 << 0 # More requests to follow. # struct ofp_multipart_reply OFP_MULTIPART_REPLY_PACK_STR = '!HH4x' OFP_MULTIPART_REPLY_SIZE = 16 assert (calcsize(OFP_MULTIPART_REPLY_PACK_STR) + OFP_HEADER_SIZE == OFP_MULTIPART_REPLY_SIZE) DESC_STR_LEN = 256 DESC_STR_LEN_STR = str(DESC_STR_LEN) SERIAL_NUM_LEN = 32 SERIAL_NUM_LEN_STR = str(SERIAL_NUM_LEN) OFP_DESC_PACK_STR = '!' + \ DESC_STR_LEN_STR + 's' + \ DESC_STR_LEN_STR + 's' + \ DESC_STR_LEN_STR + 's' + \ SERIAL_NUM_LEN_STR + 's' + \ DESC_STR_LEN_STR + 's' OFP_DESC_SIZE = 1056 assert calcsize(OFP_DESC_PACK_STR) == OFP_DESC_SIZE # struct ofp_flow_stats_request _OFP_FLOW_STATS_REQUEST_0_PACK_STR = 'B3xII4xQQ' OFP_FLOW_STATS_REQUEST_0_PACK_STR = '!' + _OFP_FLOW_STATS_REQUEST_0_PACK_STR OFP_FLOW_STATS_REQUEST_0_SIZE = 32 assert (calcsize(OFP_FLOW_STATS_REQUEST_0_PACK_STR) == OFP_FLOW_STATS_REQUEST_0_SIZE) OFP_FLOW_STATS_REQUEST_PACK_STR = (OFP_FLOW_STATS_REQUEST_0_PACK_STR + _OFP_MATCH_PACK_STR) OFP_FLOW_STATS_REQUEST_SIZE = 40 assert (calcsize(OFP_FLOW_STATS_REQUEST_PACK_STR) == OFP_FLOW_STATS_REQUEST_SIZE) # struct ofp_flow_desc _OFP_FLOW_DESC_0_PACK_STR = 'H2xBxHHHHHQ' OFP_FLOW_DESC_0_PACK_STR = '!' + _OFP_FLOW_DESC_0_PACK_STR OFP_FLOW_DESC_0_SIZE = 24 assert calcsize(OFP_FLOW_DESC_0_PACK_STR) == OFP_FLOW_DESC_0_SIZE OFP_FLOW_DESC_PACK_STR = OFP_FLOW_DESC_0_PACK_STR + _OFP_MATCH_PACK_STR OFP_FLOW_DESC_SIZE = 32 assert calcsize(OFP_FLOW_DESC_PACK_STR) == OFP_FLOW_DESC_SIZE # enum ofp_flow_stats_reason OFPFSR_STATS_REQUEST = 0 # Reply to a OFPMP_FLOW_STATS request. OFPFSR_STAT_TRIGGER = 1 # Status generated by OFPIT_STAT_TRIGGER. # struct ofp_flow_stats _OFP_FLOW_STATS_0_PACK_STR = 'H2xBBH' OFP_FLOW_STATS_0_PACK_STR = '!' + _OFP_FLOW_STATS_0_PACK_STR OFP_FLOW_STATS_0_SIZE = 8 assert calcsize(OFP_FLOW_STATS_0_PACK_STR) == OFP_FLOW_STATS_0_SIZE OFP_FLOW_STATS_PACK_STR = (OFP_FLOW_STATS_0_PACK_STR + _OFP_MATCH_PACK_STR) OFP_FLOW_STATS_SIZE = 16 assert calcsize(OFP_FLOW_STATS_PACK_STR) == OFP_FLOW_STATS_SIZE # struct ofp_aggregate_stats_request OFP_AGGREGATE_STATS_REQUEST_PACK_STR = '!B3xII4xQQ' + _OFP_MATCH_PACK_STR OFP_AGGREGATE_STATS_REQUEST_SIZE = 40 assert (calcsize(OFP_AGGREGATE_STATS_REQUEST_PACK_STR) == OFP_AGGREGATE_STATS_REQUEST_SIZE) # struct ofp_aggregate_stats_reply OFP_AGGREGATE_STATS_REPLY_PACK_STR = OFP_STATS_PACK_STR OFP_AGGREGATE_STATS_REPLY_SIZE = OFP_STATS_SIZE assert (calcsize(OFP_AGGREGATE_STATS_REPLY_PACK_STR) == OFP_AGGREGATE_STATS_REPLY_SIZE) # enum ofp_table_feature_prop_type OFPTFPT_INSTRUCTIONS = 0 OFPTFPT_INSTRUCTIONS_MISS = 1 OFPTFPT_NEXT_TABLES = 2 OFPTFPT_NEXT_TABLES_MISS = 3 OFPTFPT_WRITE_ACTIONS = 4 OFPTFPT_WRITE_ACTIONS_MISS = 5 OFPTFPT_APPLY_ACTIONS = 6 OFPTFPT_APPLY_ACTIONS_MISS = 7 OFPTFPT_MATCH = 8 OFPTFPT_WILDCARDS = 10 OFPTFPT_WRITE_SETFIELD = 12 OFPTFPT_WRITE_SETFIELD_MISS = 13 OFPTFPT_APPLY_SETFIELD = 14 OFPTFPT_APPLY_SETFIELD_MISS = 15 OFPTFPT_TABLE_SYNC_FROM = 16 OFPTFPT_WRITE_COPYFIELD = 18 # Write Copy-Field property. OFPTFPT_WRITE_COPYFIELD_MISS = 19 # Write Copy-Field for table-miss. OFPTFPT_APPLY_COPYFIELD = 20 # Apply Copy-Field property. OFPTFPT_APPLY_COPYFIELD_MISS = 21 # Apply Copy-Field for table-miss. OFPTFPT_PACKET_TYPES = 22 # Packet types property. OFPTFPT_EXPERIMENTER = 0xFFFE OFPTFPT_EXPERIMENTER_MISS = 0xFFFF # struct ofp_instruction_id OFP_INSTRUCTION_ID_PACK_STR = '!HH' OFP_INSTRUCTION_ID_SIZE = 4 assert calcsize(OFP_INSTRUCTION_ID_PACK_STR) == OFP_INSTRUCTION_ID_SIZE # struct ofp_table_feature_prop_instructions OFP_TABLE_FEATURE_PROP_INSTRUCTIONS_PACK_STR = '!HH' OFP_TABLE_FEATURE_PROP_INSTRUCTIONS_SIZE = 4 assert (calcsize(OFP_TABLE_FEATURE_PROP_INSTRUCTIONS_PACK_STR) == OFP_TABLE_FEATURE_PROP_INSTRUCTIONS_SIZE) # struct ofp_table_feature_prop_actions OFP_TABLE_FEATURE_PROP_ACTIONS_PACK_STR = '!HH' OFP_TABLE_FEATURE_PROP_ACTIONS_SIZE = 4 assert (calcsize(OFP_TABLE_FEATURE_PROP_ACTIONS_PACK_STR) == OFP_TABLE_FEATURE_PROP_ACTIONS_SIZE) # struct ofp_table_feature_prop_oxm OFP_TABLE_FEATURE_PROP_OXM_PACK_STR = '!HH' OFP_TABLE_FEATURE_PROP_OXM_SIZE = 4 assert (calcsize(OFP_TABLE_FEATURE_PROP_OXM_PACK_STR) == OFP_TABLE_FEATURE_PROP_OXM_SIZE) # struct ofp_table_feature_prop_oxm_values OFP_TABLE_FEATURE_PROP_OXM_VALUES_PACK_STR = '!HH' OFP_TABLE_FEATURE_PROP_OXM_VALUES_SIZE = 4 assert (calcsize(OFP_TABLE_FEATURE_PROP_OXM_VALUES_PACK_STR) == OFP_TABLE_FEATURE_PROP_OXM_VALUES_SIZE) # struct ofp_table_feature_prop_experimenter OFP_TABLE_FEATURE_PROP_EXPERIMENTER_PACK_STR = '!HHII' OFP_TABLE_FEATURE_PROP_EXPERIMENTER_SIZE = 12 assert (calcsize(OFP_TABLE_FEATURE_PROP_EXPERIMENTER_PACK_STR) == OFP_TABLE_FEATURE_PROP_EXPERIMENTER_SIZE) # enum ofp_table_feature_flag OFPTFF_INGRESS_TABLE = 1 << 0 # Can be configured as ingress table. OFPTFF_EGRESS_TABLE = 1 << 1 # Can be configured as egress table. OFPTFF_FIRST_EGRESS = 1 << 4 # Is the first egress table. # enum ofp_table_features_command OFPTFC_REPLACE = 0 # Replace full pipeline. OFPTFC_MODIFY = 1 # Modify flow tables capabilities. OFPTFC_ENABLE = 2 # Enable flow tables in the pipeline. OFPTFC_DISABLE = 3 # Disable flow tables in pipeline. # struct ofp_table_features OFP_MAX_TABLE_NAME_LEN = 32 OFP_MAX_TABLE_NAME_LEN_STR = str(OFP_MAX_TABLE_NAME_LEN) OFP_TABLE_FEATURES_PACK_STR = '!HBBI' + OFP_MAX_TABLE_NAME_LEN_STR + \ 's' + 'QQII' OFP_TABLE_FEATURES_SIZE = 64 assert (calcsize(OFP_TABLE_FEATURES_PACK_STR) == OFP_TABLE_FEATURES_SIZE) # struct ofp_table_stats OFP_TABLE_STATS_PACK_STR = '!B3xIQQ' OFP_TABLE_STATS_SIZE = 24 assert calcsize(OFP_TABLE_STATS_PACK_STR) == OFP_TABLE_STATS_SIZE # struct ofp_table_desc _OFP_TABLE_DESC_PACK_STR = 'HBxI' OFP_TABLE_DESC_PACK_STR = '!' + _OFP_TABLE_DESC_PACK_STR OFP_TABLE_DESC_SIZE = 8 assert calcsize(OFP_TABLE_DESC_PACK_STR) == OFP_TABLE_DESC_SIZE # struct ofp_port_multipart_request OFP_PORT_MULTIPART_REQUEST_PACK_STR = '!I4x' OFP_PORT_MULTIPART_REQUEST_SIZE = 8 assert (calcsize(OFP_PORT_MULTIPART_REQUEST_PACK_STR) == OFP_PORT_MULTIPART_REQUEST_SIZE) # enum ofp_port_stats_prop_type OFPPSPT_ETHERNET = 0 # Ethernet property. OFPPSPT_OPTICAL = 1 # Optical property. OFPPSPT_EXPERIMENTER = 0xFFFF # Experimenter property. # struct ofp_port_stats_prop_ethernet OFP_PORT_STATS_PROP_ETHERNET_PACK_STR = '!HH4xQQQQ' OFP_PORT_STATS_PROP_ETHERNET_SIZE = 40 assert (calcsize(OFP_PORT_STATS_PROP_ETHERNET_PACK_STR) == OFP_PORT_STATS_PROP_ETHERNET_SIZE) # struct ofp_port_stats_prop_optical OFP_PORT_STATS_PROP_OPTICAL_PACK_STR = '!HH4xIIIIIIIHHHH' OFP_PORT_STATS_PROP_OPTICAL_SIZE = 44 assert (calcsize(OFP_PORT_STATS_PROP_OPTICAL_PACK_STR) == OFP_PORT_STATS_PROP_OPTICAL_SIZE) # enum ofp_port_stats_optical_flags OFPOSF_RX_TUNE = 1 << 0 # Receiver tune info valid OFPOSF_TX_TUNE = 1 << 1 # Transmit tune info valid OFPOSF_TX_PWR = 1 << 2 # TX Power is valid OFPOSF_RX_PWR = 1 << 4 # RX power is valid OFPOSF_TX_BIAS = 1 << 5 # Transmit bias is valid OFPOSF_TX_TEMP = 1 << 6 # TX Temp is valid # struct ofp_port_stats_prop_experimenter OFP_PORT_STATS_PROP_EXPERIMENTER_PACK_STR = '!HHII' OFP_PORT_STATS_PROP_EXPERIMENTER_SIZE = 12 assert (calcsize(OFP_PORT_STATS_PROP_EXPERIMENTER_PACK_STR) == OFP_PORT_STATS_PROP_EXPERIMENTER_SIZE) # struct ofp_port_stats OFP_PORT_STATS_PACK_STR = '!H2xIIIQQQQQQQQ' OFP_PORT_STATS_SIZE = 80 assert calcsize(OFP_PORT_STATS_PACK_STR) == OFP_PORT_STATS_SIZE # struct ofp_group_multipart_request OFP_GROUP_MULTIPART_REQUEST_PACK_STR = '!I4x' OFP_GROUP_MULTIPART_REQUEST_SIZE = 8 assert (calcsize(OFP_GROUP_MULTIPART_REQUEST_PACK_STR) == OFP_GROUP_MULTIPART_REQUEST_SIZE) # struct ofp_bucket_counter OFP_BUCKET_COUNTER_PACK_STR = '!QQ' OFP_BUCKET_COUNTER_SIZE = 16 assert calcsize(OFP_BUCKET_COUNTER_PACK_STR) == OFP_BUCKET_COUNTER_SIZE # struct ofp_group_stats OFP_GROUP_STATS_PACK_STR = '!H2xII4xQQII' OFP_GROUP_STATS_SIZE = 40 assert calcsize(OFP_GROUP_STATS_PACK_STR) == OFP_GROUP_STATS_SIZE # struct ofp_group_desc OFP_GROUP_DESC_PACK_STR = '!HBxIH6x' OFP_GROUP_DESC_SIZE = 16 assert calcsize(OFP_GROUP_DESC_PACK_STR) == OFP_GROUP_DESC_SIZE # struct ofp_group_desc_stats # Backward compatibility with 1.3.1 - avoid breaking the API. OFP_GROUP_DESC_STATS_PACK_STR = OFP_GROUP_DESC_PACK_STR OFP_GROUP_DESC_STATS_SIZE = OFP_GROUP_DESC_SIZE assert calcsize(OFP_GROUP_DESC_STATS_PACK_STR) == OFP_GROUP_DESC_STATS_SIZE # enum ofp_group_capabilities OFPGFC_SELECT_WEIGHT = 1 << 0 # Support weight for select groups. OFPGFC_SELECT_LIVENESS = 1 << 1 # Support liveness for select groups. OFPGFC_CHAINING = 1 << 2 # Support chaining groups. OFPGFC_CHAINING_CHECKS = 1 << 3 # Check chaining for loops and delete # struct ofp_group_features OFP_GROUP_FEATURES_PACK_STR = '!II4I4I' OFP_GROUP_FEATURES_SIZE = 40 assert calcsize(OFP_GROUP_FEATURES_PACK_STR) == OFP_GROUP_FEATURES_SIZE # struct ofp_meter_multipart_request OFP_METER_MULTIPART_REQUEST_PACK_STR = '!I4x' OFP_METER_MULTIPART_REQUEST_SIZE = 8 assert (calcsize(OFP_METER_MULTIPART_REQUEST_PACK_STR) == OFP_METER_MULTIPART_REQUEST_SIZE) # struct ofp_meter_stats OFP_METER_STATS_PACK_STR = '!IH6xIQQII' OFP_METER_STATS_SIZE = 40 assert calcsize(OFP_METER_STATS_PACK_STR) == OFP_METER_STATS_SIZE # struct ofp_meter_band_stats OFP_METER_BAND_STATS_PACK_STR = '!QQ' OFP_METER_BAND_STATS_SIZE = 16 assert (calcsize(OFP_METER_BAND_STATS_PACK_STR) == OFP_METER_BAND_STATS_SIZE) # struct ofp_meter_desc OFP_METER_DESC_PACK_STR = '!HHI' OFP_METER_DESC_SIZE = 8 assert calcsize(OFP_METER_DESC_PACK_STR) == OFP_METER_DESC_SIZE # enum ofp_meter_feature_flags OFPMFF_ACTION_SET = 1 << 0 # Support meter action in action set. OFPMFF_ANY_POSITION = 1 << 1 # Support any position in action list. OFPMFF_MULTI_LIST = 1 << 2 # Support multiple actions in action list. # struct ofp_meter_features OFP_METER_FEATURES_PACK_STR = '!IIIBB2xI4x' OFP_METER_FEATURES_SIZE = 24 assert (calcsize(OFP_METER_FEATURES_PACK_STR) == OFP_METER_FEATURES_SIZE) # All ones is used to indicate all queues in a port (for stats retrieval). OFPQ_ALL = 0xffffffff # Min rate > 1000 means not configured. OFPQ_MIN_RATE_UNCFG = 0xffff # Max rate > 1000 means not configured. OFPQ_MAX_RATE_UNCFG = 0xffff # enum ofp_queue_desc_prop_type OFPQDPT_MIN_RATE = 1 # Minimum datarate guaranteed. OFPQDPT_MAX_RATE = 2 # Maximum datarate. OFPQDPT_EXPERIMENTER = 0xffff # Experimenter defined property. # struct ofp_queue_desc_prop_min_rate OFP_QUEUE_DESC_PROP_MIN_RATE_PACK_STR = '!HHH2x' OFP_QUEUE_DESC_PROP_MIN_RATE_SIZE = 8 assert (calcsize(OFP_QUEUE_DESC_PROP_MIN_RATE_PACK_STR) == OFP_QUEUE_DESC_PROP_MIN_RATE_SIZE) # ofp_queue_desc_prop_max_rate OFP_QUEUE_DESC_PROP_MAX_RATE_PACK_STR = '!HHH2x' OFP_QUEUE_DESC_PROP_MAX_RATE_SIZE = 8 assert (calcsize(OFP_QUEUE_DESC_PROP_MAX_RATE_PACK_STR) == OFP_QUEUE_DESC_PROP_MAX_RATE_SIZE) # struct ofp_queue_desc_prop_experimenter OFP_QUEUE_DESC_PROP_EXPERIMENTER_PACK_STR = '!HHII' OFP_QUEUE_DESC_PROP_EXPERIMENTER_SIZE = 12 assert (calcsize(OFP_QUEUE_DESC_PROP_EXPERIMENTER_PACK_STR) == OFP_QUEUE_DESC_PROP_EXPERIMENTER_SIZE) # struct ofp_queue_multipart_request OFP_QUEUE_MULTIPART_REQUEST_PACK_STR = '!II' OFP_QUEUE_MULTIPART_REQUEST_SIZE = 8 assert (calcsize(OFP_QUEUE_MULTIPART_REQUEST_PACK_STR) == OFP_QUEUE_MULTIPART_REQUEST_SIZE) # struct ofp_queue_desc OFP_QUEUE_DESC_PACK_STR = '!IIH6x' OFP_QUEUE_DESC_SIZE = 16 assert calcsize(OFP_QUEUE_DESC_PACK_STR) == OFP_QUEUE_DESC_SIZE # enum ofp_queue_stats_prop_type OFPQSPT_EXPERIMENTER = 0xffff # Experimenter defined property. # struct ofp_queue_stats_prop_experimenter OFP_QUEUE_STATS_PROP_EXPERIMENTER_PACK_STR = '!HHII' OFP_QUEUE_STATS_PROP_EXPERIMENTER_SIZE = 12 assert (calcsize(OFP_QUEUE_STATS_PROP_EXPERIMENTER_PACK_STR) == OFP_QUEUE_STATS_PROP_EXPERIMENTER_SIZE) # struct ofp_queue_stats OFP_QUEUE_STATS_PACK_STR = '!H6xIIQQQII' OFP_QUEUE_STATS_SIZE = 48 assert calcsize(OFP_QUEUE_STATS_PACK_STR) == OFP_QUEUE_STATS_SIZE # struct ofp_flow_monitor_request _OFP_FLOW_MONITOR_REQUEST_0_PACK_STR = 'IIIHBB' OFP_FLOW_MONITOR_REQUEST_0_PACK_STR = ('!' + _OFP_FLOW_MONITOR_REQUEST_0_PACK_STR) OFP_FLOW_MONITOR_REQUEST_0_SIZE = 16 OFP_FLOW_MONITOR_REQUEST_PACK_STR = (OFP_FLOW_MONITOR_REQUEST_0_PACK_STR + _OFP_MATCH_PACK_STR) OFP_FLOW_MONITOR_REQUEST_SIZE = 24 assert (calcsize(OFP_FLOW_MONITOR_REQUEST_PACK_STR) == OFP_FLOW_MONITOR_REQUEST_SIZE) # enum ofp_flow_monitor_command OFPFMC_ADD = 0 # New flow monitor. OFPFMC_MODIFY = 1 # Modify existing flow monitor. OFPFMC_DELETE = 2 # Delete/cancel existing flow monitor. # enum ofp_flow_monitor_flags # When to send updates. OFPFMF_INITIAL = 1 << 0 # Initially matching flows. OFPFMF_ADD = 1 << 1 # New matching flows as they are added. OFPFMF_REMOVED = 1 << 2 # Old matching flows as they are removed. OFPFMF_MODIFY = 1 << 3 # Matching flows as they are changed. # What to include in updates. OFPFMF_INSTRUCTIONS = 1 << 4 # If set, instructions are included. OFPFMF_NO_ABBREV = 1 << 5 # If set, include own changes in full. OFPFMF_ONLY_OWN = 1 << 6 # If set, don't include other controllers. # struct ofp_flow_update_header OFP_FLOW_UPDATE_HEADER_PACK_STR = '!HH' OFP_FLOW_UPDATE_HEADER_SIZE = 4 assert (calcsize(OFP_FLOW_UPDATE_HEADER_PACK_STR) == OFP_FLOW_UPDATE_HEADER_SIZE) # enum ofp_flow_update_event # struct ofp_flow_update_full. OFPFME_INITIAL = 0 # Flow present when flow monitor created. OFPFME_ADDED = 1 # Flow was added. OFPFME_REMOVED = 2 # Flow was removed. OFPFME_MODIFIED = 3 # Flow instructions were changed. # struct ofp_flow_update_abbrev. OFPFME_ABBREV = 4 # Abbreviated reply. # struct ofp_flow_update_header. OFPFME_PAUSED = 5 # Monitoring paused (out of buffer space). OFPFME_RESUMED = 6 # Monitoring resumed. # struct ofp_flow_update_full _OFP_FLOW_UPDATE_FULL_0_PACK_STR = 'HHBBHHH4xQ' OFP_FLOW_UPDATE_FULL_0_PACK_STR = '!' + _OFP_FLOW_UPDATE_FULL_0_PACK_STR OFP_FLOW_UPDATE_FULL_0_SIZE = 24 OFP_FLOW_UPDATE_FULL_PACK_STR = (OFP_FLOW_UPDATE_FULL_0_PACK_STR + _OFP_MATCH_PACK_STR) OFP_FLOW_UPDATE_FULL_SIZE = 32 assert (calcsize(OFP_FLOW_UPDATE_FULL_PACK_STR) == OFP_FLOW_UPDATE_FULL_SIZE) # struct ofp_flow_update_abbrev OFP_FLOW_UPDATE_ABBREV_PACK_STR = '!HHI' OFP_FLOW_UPDATE_ABBREV_SIZE = 8 assert (calcsize(OFP_FLOW_UPDATE_ABBREV_PACK_STR) == OFP_FLOW_UPDATE_ABBREV_SIZE) # struct ofp_flow_update_paused OFP_FLOW_UPDATE_PAUSED_PACK_STR = '!HH4x' OFP_FLOW_UPDATE_PAUSED_SIZE = 8 assert (calcsize(OFP_FLOW_UPDATE_PAUSED_PACK_STR) == OFP_FLOW_UPDATE_PAUSED_SIZE) # enum ofp_controller_status_prop_type OFPCSPT_URI = 0 # Connection URI property. OFPCSPT_EXPERIMENTER = 0xFFFF # Experimenter property. # struct ofp_controller_status_prop_header _OFP_CONTROLLER_STATUS_PROP_HEADER_PACK_STR = 'HH' OFP_CONTROLLER_STATUS_PROP_HEADER_PACK_STR = ( '!' + _OFP_CONTROLLER_STATUS_PROP_HEADER_PACK_STR) OFP_CONTROLLER_STATUS_PROP_HEADER_SIZE = 4 assert (calcsize(OFP_CONTROLLER_STATUS_PROP_HEADER_PACK_STR) == OFP_CONTROLLER_STATUS_PROP_HEADER_SIZE) # struct ofp_controller_status_prop_uri OFP_CONTROLLER_STATUS_PROP_URI_PACK_STR = '!HH' OFP_CONTROLLER_STATUS_PROP_URI_SIZE = 4 assert (calcsize(OFP_CONTROLLER_STATUS_PROP_URI_PACK_STR) == OFP_CONTROLLER_STATUS_PROP_URI_SIZE) # struct ofp_controller_status_prop_experimenter OFP_CONTROLLER_STATUS_PROP_EXPERIMENTER_PACK_STR = '!HHII' OFP_CONTROLLER_STATUS_PROP_EXPERIMENTER_SIZE = 12 assert (calcsize(OFP_CONTROLLER_STATUS_PROP_EXPERIMENTER_PACK_STR) == OFP_CONTROLLER_STATUS_PROP_EXPERIMENTER_SIZE) # enum ofp_controller_status_reason OFPCSR_REQUEST = 0 # Controller requested status. OFPCSR_CHANNEL_STATUS = 1 # Oper status of channel changed. OFPCSR_ROLE = 2 # Controller role changed. OFPCSR_CONTROLLER_ADDED = 3 # New controller added. OFPCSR_CONTROLLER_REMOVED = 4 # Controller removed from config. OFPCSR_SHORT_ID = 5 # Controller ID changed. OFPCSR_EXPERIMENTER = 6 # Experimenter data changed. # struct ofp_controller_status OFP_CONTROLLER_STATUS_PACK_STR = '!HHIBB6x' OFP_CONTROLLER_STATUS_SIZE = 16 assert (calcsize(OFP_CONTROLLER_STATUS_PACK_STR) == OFP_CONTROLLER_STATUS_SIZE) # struct ofp_controller_status_header OFP_CONTROLLER_STATUS_HEADER_PACK_STR = OFP_CONTROLLER_STATUS_PACK_STR OFP_CONTROLLER_STATUS_HEADER_SIZE = OFP_CONTROLLER_STATUS_SIZE + OFP_HEADER_SIZE # enum ofp_control_channel_status OFPCT_STATUS_UP = 0 # Control channel is operational. OFPCT_STATUS_DOWN = 1 # Control channel is not operational. # struct ofp_bundle_features_prop_header OFP_BUNDLE_FEATURES_PROP_HEADER_PACK_STR = '!HH' OFP_BUNDLE_FEATURES_PROP_HEADER_SIZE = 4 assert (calcsize(OFP_BUNDLE_FEATURES_PROP_HEADER_PACK_STR) == OFP_BUNDLE_FEATURES_PROP_HEADER_SIZE) # struct ofp_bundle_features_request OFP_BUNDLE_FEATURES_REQUEST_PACK_STR = '!I4x' OFP_BUNDLE_FEATURES_REQUEST_SIZE = 8 assert (calcsize(OFP_BUNDLE_FEATURES_REQUEST_PACK_STR) == OFP_BUNDLE_FEATURES_REQUEST_SIZE) # enum ofp_bundle_features_prop_type OFPTMPBF_TIME_CAPABILITY = 0x1 # Time feature property. OFPTMPBF_EXPERIMENTER = 0xFFFF # Experimenter property. # struct ofp_time _OFP_TIME_PACK_STR = 'QI4x' OFP_TIME_PACK_STR = '!' + _OFP_TIME_PACK_STR OFP_TIME_SIZE = 16 assert calcsize(OFP_TIME_PACK_STR) == OFP_TIME_SIZE # struct ofp_bundle_features_prop_time OFP_BUNDLE_FEATURES_PROP_TIME_0_PACK_STR = '!HH4x' OFP_BUNDLE_FEATURES_PROP_TIME_0_SIZE = 8 OFP_BUNDLE_FEATURES_PROP_TIME_SIZE = 72 assert (calcsize(OFP_BUNDLE_FEATURES_PROP_TIME_0_PACK_STR) + OFP_TIME_SIZE * 4 == OFP_BUNDLE_FEATURES_PROP_TIME_SIZE) # enum ofp_bundle_feature_flags OFPBF_TIMESTAMP = 1 << 0 # Request includes a timestamp. OFPBF_TIME_SET_SCHED = 1 << 1 # Request includes the sched_max_future and # sched_max_past parameters. # struct ofp_bundle_features OFP_BUNDLE_FEATURES_PACK_STR = '!H6x' OFP_BUNDLE_FEATURES_SIZE = 8 assert (calcsize(OFP_BUNDLE_FEATURES_PACK_STR) == OFP_BUNDLE_FEATURES_SIZE) # struct ofp_experimenter_multipart_header OFP_EXPERIMENTER_MULTIPART_HEADER_PACK_STR = '!II' OFP_EXPERIMENTER_MULTIPART_HEADER_SIZE = 8 assert (calcsize(OFP_EXPERIMENTER_MULTIPART_HEADER_PACK_STR) == OFP_EXPERIMENTER_MULTIPART_HEADER_SIZE) # struct ofp_experimenter_structure OFP_EXPERIMENTER_STRUCTURE_PACK_STR = '!II' OFP_EXPERIMENTER_STRUCTURE_SIZE = 8 assert (calcsize(OFP_EXPERIMENTER_STRUCTURE_PACK_STR) == OFP_EXPERIMENTER_STRUCTURE_SIZE) # struct ofp_error_experimenter_msg OFP_ERROR_EXPERIMENTER_MSG_PACK_STR = '!HHI' OFP_ERROR_EXPERIMENTER_MSG_SIZE = 16 assert (calcsize(OFP_ERROR_EXPERIMENTER_MSG_PACK_STR) + OFP_HEADER_SIZE) == OFP_ERROR_EXPERIMENTER_MSG_SIZE # enum ofp_controller_role OFPCR_ROLE_NOCHANGE = 0 # Don't change current role. OFPCR_ROLE_EQUAL = 1 # Default role, full access. OFPCR_ROLE_MASTER = 2 # Full access, at most one master. OFPCR_ROLE_SLAVE = 3 # Read-only access. # If the switch has not requested an identifier, the short_id should be set to # OFPCID_UNDEFINED. OFPCID_UNDEFINED = 0 # struct ofp_role_request OFP_ROLE_REQUEST_PACK_STR = '!IH2xQ' OFP_ROLE_REQUEST_SIZE = 24 assert (calcsize(OFP_ROLE_REQUEST_PACK_STR) + OFP_HEADER_SIZE == OFP_ROLE_REQUEST_SIZE) # enum ofp_role_prop_type OFPRPT_EXPERIMENTER = 0xFFFF # Experimenter property. # struct ofp_role_prop_header _OFP_ROLE_PROP_HEADER_PACK_STR = 'HH' OFP_ROLE_PROP_HEADER_PACK_STR = '!' + _OFP_ROLE_PROP_HEADER_PACK_STR OFP_ROLE_PROP_HEADER_SIZE = 4 assert (calcsize(OFP_ROLE_PROP_HEADER_PACK_STR) == OFP_ROLE_PROP_HEADER_SIZE) # struct ofp_role_prop_experimenter OFP_ROLE_PROP_EXPERIMENTER_PACK_STR = '!HHII' OFP_ROLE_PROP_EXPERIMENTER_SIZE = 12 assert (calcsize(OFP_ROLE_PROP_EXPERIMENTER_PACK_STR) == OFP_ROLE_PROP_EXPERIMENTER_SIZE) # enum ofp_controller_role_reason OFPCRR_MASTER_REQUEST = 0 # Another controller asked to be master. OFPCRR_CONFIG = 1 # Configuration changed on the switch. OFPCRR_EXPERIMENTER = 2 # Experimenter data changed. # struct ofp_role_status OFP_ROLE_STATUS_PACK_STR = '!IB3xQ' OFP_ROLE_STATUS_SIZE = 24 assert (calcsize(OFP_ROLE_STATUS_PACK_STR) + OFP_HEADER_SIZE == OFP_ROLE_STATUS_SIZE) # enum ofp_async_config_prop_type OFPACPT_PACKET_IN_SLAVE = 0 # Packet-in mask for slave. OFPACPT_PACKET_IN_MASTER = 1 # Packet-in mask for master. OFPACPT_PORT_STATUS_SLAVE = 2 # Port-status mask for slave. OFPACPT_PORT_STATUS_MASTER = 3 # Port-status mask for master. OFPACPT_FLOW_REMOVED_SLAVE = 4 # Flow removed mask for slave. OFPACPT_FLOW_REMOVED_MASTER = 5 # Flow removed mask for master. OFPACPT_ROLE_STATUS_SLAVE = 6 # Role status mask for slave. OFPACPT_ROLE_STATUS_MASTER = 7 # Role status mask for master. OFPACPT_TABLE_STATUS_SLAVE = 8 # Table status mask for slave. OFPACPT_TABLE_STATUS_MASTER = 9 # Table status mask for master. OFPACPT_REQUESTFORWARD_SLAVE = 10 # RequestForward mask for slave. OFPACPT_REQUESTFORWARD_MASTER = 11 # RequestForward mask for master. OFPACPT_FLOW_STATS_SLAVE = 12 # Flow stats mask for slave. OFPACPT_FLOW_STATS_MASTER = 13 # Flow stats mask for master. OFPACPT_CONT_STATUS_SLAVE = 14 # Controller status mask for slave. OFPACPT_CONT_STATUS_MASTER = 15 # Controller status mask for master. OFPACPT_EXPERIMENTER_SLAVE = 0xFFFE # Experimenter for slave. OFPACPT_EXPERIMENTER_MASTER = 0xFFFF # Experimenter for master. # struct ofp_async_config_prop_reasons OFP_ASYNC_CONFIG_PROP_REASONS_PACK_STR = '!HHI' OFP_ASYNC_CONFIG_PROP_REASONS_SIZE = 8 assert (calcsize(OFP_ASYNC_CONFIG_PROP_REASONS_PACK_STR) == OFP_ASYNC_CONFIG_PROP_REASONS_SIZE) # struct ofp_async_config_prop_experimenter OFP_ASYNC_CONFIG_PROP_EXPERIMENTER_PACK_STR = '!HHII' OFP_ASYNC_CONFIG_PROP_EXPERIMENTER_SIZE = 12 assert (calcsize(OFP_ASYNC_CONFIG_PROP_EXPERIMENTER_PACK_STR) == OFP_ASYNC_CONFIG_PROP_EXPERIMENTER_SIZE) # enum ofp_table_reason OFPTR_VACANCY_DOWN = 3 # Vacancy down threshold event. OFPTR_VACANCY_UP = 4 # Vacancy up threshold event. # struct ofp_table_status _OFP_TABLE_STATUS_0_PACK_STR = 'B7x' OFP_TABLE_STATUS_0_PACK_STR = '!' + _OFP_TABLE_STATUS_0_PACK_STR OFP_TABLE_STATUS_0_SIZE = 16 OFP_TABLE_STATUS_PACK_STR = (OFP_TABLE_STATUS_0_PACK_STR + _OFP_TABLE_DESC_PACK_STR) OFP_TABLE_STATUS_SIZE = 24 assert (calcsize(OFP_TABLE_STATUS_PACK_STR) + OFP_HEADER_SIZE == OFP_TABLE_STATUS_SIZE) # enum ofp_requestforward_reason OFPRFR_GROUP_MOD = 0 # Forward group mod requests. OFPRFR_METER_MOD = 1 # Forward meter mod requests. # enum ofp_bundle_prop_type OFPBPT_TIME = 1 # Time property. OFPBPT_EXPERIMENTER = 0xFFFF # Experimenter property. # struct ofp_bundle_prop_experimenter OFP_BUNDLE_PROP_EXPERIMENTER_PACK_STR = '!HHII' OFP_BUNDLE_PROP_EXPERIMENTER_SIZE = 12 assert (calcsize(OFP_BUNDLE_PROP_EXPERIMENTER_PACK_STR) == OFP_BUNDLE_PROP_EXPERIMENTER_SIZE) # struct ofp_bundle_prop_time OFP_BUNDLE_PROP_TIME_PACK_STR0 = '!HH4x' OFP_BUNDLE_PROP_TIME_PACK_STR0_SIZE = 8 assert (calcsize(OFP_BUNDLE_PROP_TIME_PACK_STR0) == OFP_BUNDLE_PROP_TIME_PACK_STR0_SIZE) OFP_BUNDLE_PROP_TIME_PACK_STR = (OFP_BUNDLE_PROP_TIME_PACK_STR0 + _OFP_TIME_PACK_STR) OFP_BUNDLE_PROP_TIME_PACK_STR_SIZE = 24 assert (calcsize(OFP_BUNDLE_PROP_TIME_PACK_STR) == OFP_BUNDLE_PROP_TIME_PACK_STR_SIZE) # enum ofp_bundle_ctrl_type OFPBCT_OPEN_REQUEST = 0 OFPBCT_OPEN_REPLY = 1 OFPBCT_CLOSE_REQUEST = 2 OFPBCT_CLOSE_REPLY = 3 OFPBCT_COMMIT_REQUEST = 4 OFPBCT_COMMIT_REPLY = 5 OFPBCT_DISCARD_REQUEST = 6 OFPBCT_DISCARD_REPLY = 7 # enum ofp_bundle_flags OFPBF_ATOMIC = 1 << 0 # Execute atomically. OFPBF_ORDERED = 1 << 1 # Execute in specified order. OFPBF_TIME = 1 << 2 # Execute in specified time. # struct ofp_bundle_ctrl_msg OFP_BUNDLE_CTRL_MSG_PACK_STR = '!IHH' OFP_BUNDLE_CTRL_MSG_SIZE = 16 assert (calcsize(OFP_BUNDLE_CTRL_MSG_PACK_STR) + OFP_HEADER_SIZE == OFP_BUNDLE_CTRL_MSG_SIZE) # struct ofp_bundle_add_msg _OFP_BUNDLE_ADD_MSG_0_PACK_STR = 'I2xH' OFP_BUNDLE_ADD_MSG_0_PACK_STR = '!' + _OFP_BUNDLE_ADD_MSG_0_PACK_STR OFP_BUNDLE_ADD_MSG_PACK_STR = (OFP_BUNDLE_ADD_MSG_0_PACK_STR + _OFP_HEADER_PACK_STR) OFP_BUNDLE_ADD_MSG_SIZE = 24 assert (calcsize(OFP_BUNDLE_ADD_MSG_PACK_STR) + OFP_HEADER_SIZE == OFP_BUNDLE_ADD_MSG_SIZE) # Note: struct ofp_prop_experimenter is specific to this implementation. # It does not have a corresponding structure in the specification. # This structure defines common structure for ofp_*_prop_experimenter. # struct ofp_prop_experimenter OFP_PROP_EXPERIMENTER_PACK_STR = '!HHII' OFP_PROP_EXPERIMENTER_SIZE = 12 assert (calcsize(OFP_PROP_EXPERIMENTER_PACK_STR) == OFP_PROP_EXPERIMENTER_SIZE) # generate utility methods ofproto_utils.generate(__name__) # define constants OFP_VERSION = 0x06 OFP_TCP_PORT = 6653 OFP_SSL_PORT = 6653 MAX_XID = 0xffffffff ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/ofproto/ofproto_v1_5_parser.py0000664000175000017500000076715700000000000022256 0ustar00zuulzuul00000000000000# Copyright (C) 2012, 2013, 2014 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2012, 2013 Isaku Yamahata # # 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. """ Decoder/Encoder implementations of OpenFlow 1.5. """ import struct import base64 from os_ken.lib import addrconv from os_ken.lib.pack_utils import msg_pack_into from os_ken.lib.packet import packet from os_ken import exception from os_ken import utils from os_ken.ofproto.ofproto_parser import StringifyMixin, MsgBase, MsgInMsgBase from os_ken.ofproto import ether from os_ken.ofproto import nicira_ext from os_ken.ofproto import nx_actions from os_ken.ofproto import ofproto_parser from os_ken.ofproto import ofproto_common from os_ken.ofproto import ofproto_v1_5 as ofproto _MSG_PARSERS = {} def _set_msg_type(msg_type): def _set_cls_msg_type(cls): cls.cls_msg_type = msg_type return cls return _set_cls_msg_type def _register_parser(cls): '''class decorator to register msg parser''' assert cls.cls_msg_type is not None assert cls.cls_msg_type not in _MSG_PARSERS _MSG_PARSERS[cls.cls_msg_type] = cls.parser return cls def _register_exp_type(experimenter, exp_type): assert exp_type not in OFPExperimenter._subtypes def _wrapper(cls): OFPExperimenter._subtypes[(experimenter, exp_type)] = cls return cls return _wrapper @ofproto_parser.register_msg_parser(ofproto.OFP_VERSION) def msg_parser(datapath, version, msg_type, msg_len, xid, buf): parser = _MSG_PARSERS.get(msg_type) return parser(datapath, version, msg_type, msg_len, xid, buf) @_register_parser @_set_msg_type(ofproto.OFPT_HELLO) class OFPHello(MsgBase): """ Hello message When connection is started, the hello message is exchanged between a switch and a controller. This message is handled by the OSKen framework, so the OSKen application do not need to process this typically. ========== ========================================================= Attribute Description ========== ========================================================= elements list of ``OFPHelloElemVersionBitmap`` instance ========== ========================================================= """ def __init__(self, datapath, elements=None): elements = elements if elements else [] super(OFPHello, self).__init__(datapath) self.elements = elements @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPHello, cls).parser(datapath, version, msg_type, msg_len, xid, buf) offset = ofproto.OFP_HELLO_HEADER_SIZE elems = [] while offset < msg.msg_len: type_, length = struct.unpack_from( ofproto.OFP_HELLO_ELEM_HEADER_PACK_STR, msg.buf, offset) # better to register Hello Element classes but currently # Only VerisonBitmap is supported so let's be simple. if type_ == ofproto.OFPHET_VERSIONBITMAP: elem = OFPHelloElemVersionBitmap.parser(msg.buf, offset) elems.append(elem) offset += length msg.elements = elems return msg class OFPHelloElemVersionBitmap(StringifyMixin): """ Version bitmap Hello Element ========== ========================================================= Attribute Description ========== ========================================================= versions list of versions of OpenFlow protocol a device supports ========== ========================================================= """ def __init__(self, versions, type_=None, length=None): super(OFPHelloElemVersionBitmap, self).__init__() self.type = ofproto.OFPHET_VERSIONBITMAP self.length = None self._bitmaps = None self.versions = versions @classmethod def parser(cls, buf, offset): type_, length = struct.unpack_from( ofproto.OFP_HELLO_ELEM_VERSIONBITMAP_HEADER_PACK_STR, buf, offset) assert type_ == ofproto.OFPHET_VERSIONBITMAP bitmaps_len = (length - ofproto.OFP_HELLO_ELEM_VERSIONBITMAP_HEADER_SIZE) offset += ofproto.OFP_HELLO_ELEM_VERSIONBITMAP_HEADER_SIZE bitmaps = [] while bitmaps_len >= 4: bitmap = struct.unpack_from('!I', buf, offset) bitmaps.append(bitmap[0]) offset += 4 bitmaps_len -= 4 versions = [i * 32 + shift for i, bitmap in enumerate(bitmaps) for shift in range(31) if bitmap & (1 << shift)] elem = cls(versions) elem.length = length elem._bitmaps = bitmaps return elem @_register_parser @_set_msg_type(ofproto.OFPT_ECHO_REQUEST) class OFPEchoRequest(MsgBase): """ Echo request message This message is handled by the OSKen framework, so the OSKen application do not need to process this typically. ========== ========================================================= Attribute Description ========== ========================================================= data An arbitrary length data ========== ========================================================= Example:: def send_echo_request(self, datapath, data): ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPEchoRequest(datapath, data) datapath.send_msg(req) @set_ev_cls(ofp_event.EventOFPEchoRequest, [HANDSHAKE_DISPATCHER, CONFIG_DISPATCHER, MAIN_DISPATCHER]) def echo_request_handler(self, ev): self.logger.debug('OFPEchoRequest received: data=%s', utils.hex_array(ev.msg.data)) """ def __init__(self, datapath, data=None): super(OFPEchoRequest, self).__init__(datapath) self.data = data @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPEchoRequest, cls).parser(datapath, version, msg_type, msg_len, xid, buf) msg.data = msg.buf[ofproto.OFP_HEADER_SIZE:] return msg def _serialize_body(self): if self.data is not None: self.buf += self.data @_register_parser @_set_msg_type(ofproto.OFPT_ERROR) class OFPErrorMsg(MsgBase): """ Error message The switch notifies controller of problems by this message. ========== ========================================================= Attribute Description ========== ========================================================= type High level type of error code Details depending on the type data Variable length data depending on the type and code ========== ========================================================= ``type`` attribute corresponds to ``type_`` parameter of __init__. Types and codes are defined in ``os_ken.ofproto.ofproto``. ============================= =========== Type Code ============================= =========== OFPET_HELLO_FAILED OFPHFC_* OFPET_BAD_REQUEST OFPBRC_* OFPET_BAD_ACTION OFPBAC_* OFPET_BAD_INSTRUCTION OFPBIC_* OFPET_BAD_MATCH OFPBMC_* OFPET_FLOW_MOD_FAILED OFPFMFC_* OFPET_GROUP_MOD_FAILED OFPGMFC_* OFPET_PORT_MOD_FAILED OFPPMFC_* OFPET_TABLE_MOD_FAILED OFPTMFC_* OFPET_QUEUE_OP_FAILED OFPQOFC_* OFPET_SWITCH_CONFIG_FAILED OFPSCFC_* OFPET_ROLE_REQUEST_FAILED OFPRRFC_* OFPET_METER_MOD_FAILED OFPMMFC_* OFPET_TABLE_FEATURES_FAILED OFPTFFC_* OFPET_EXPERIMENTER N/A ============================= =========== If ``type == OFPET_EXPERIMENTER``, this message has also the following attributes. ============= ====================================================== Attribute Description ============= ====================================================== exp_type Experimenter defined type experimenter Experimenter ID ============= ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPErrorMsg, [HANDSHAKE_DISPATCHER, CONFIG_DISPATCHER, MAIN_DISPATCHER]) def error_msg_handler(self, ev): msg = ev.msg self.logger.debug('OFPErrorMsg received: type=0x%02x code=0x%02x ' 'message=%s', msg.type, msg.code, utils.hex_array(msg.data)) """ def __init__(self, datapath, type_=None, code=None, data=None, **kwargs): super(OFPErrorMsg, self).__init__(datapath) self.type = type_ self.code = code if isinstance(data, str): data = data.encode('ascii') self.data = data if self.type == ofproto.OFPET_EXPERIMENTER: self.exp_type = kwargs.get('exp_type', None) self.experimenter = kwargs.get('experimenter', None) @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): type_, = struct.unpack_from('!H', bytes(buf), ofproto.OFP_HEADER_SIZE) msg = super(OFPErrorMsg, cls).parser(datapath, version, msg_type, msg_len, xid, buf) if type_ == ofproto.OFPET_EXPERIMENTER: (msg.type, msg.exp_type, msg.experimenter, msg.data) = cls.parse_experimenter_body(buf) else: (msg.type, msg.code, msg.data) = cls.parse_body(buf) return msg @classmethod def parse_body(cls, buf): type_, code = struct.unpack_from( ofproto.OFP_ERROR_MSG_PACK_STR, buf, ofproto.OFP_HEADER_SIZE) data = buf[ofproto.OFP_ERROR_MSG_SIZE:] return type_, code, data @classmethod def parse_experimenter_body(cls, buf): type_, exp_type, experimenter = struct.unpack_from( ofproto.OFP_ERROR_EXPERIMENTER_MSG_PACK_STR, buf, ofproto.OFP_HEADER_SIZE) data = buf[ofproto.OFP_ERROR_EXPERIMENTER_MSG_SIZE:] return type_, exp_type, experimenter, data def _serialize_body(self): assert self.data is not None if self.type == ofproto.OFPET_EXPERIMENTER: msg_pack_into(ofproto.OFP_ERROR_EXPERIMENTER_MSG_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.type, self.exp_type, self.experimenter) self.buf += self.data else: msg_pack_into(ofproto.OFP_ERROR_MSG_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.type, self.code) self.buf += self.data # For the backward compatibility def OFPErrorExperimenterMsg(datapath, type_=None, exp_type=None, experimenter=None, data=None): msg = OFPErrorMsg(datapath, data=data) msg.type = ofproto.OFPET_EXPERIMENTER msg.exp_type = exp_type msg.experimenter = experimenter return msg @_register_parser @_set_msg_type(ofproto.OFPT_ECHO_REPLY) class OFPEchoReply(MsgBase): """ Echo reply message This message is handled by the OSKen framework, so the OSKen application do not need to process this typically. ========== ========================================================= Attribute Description ========== ========================================================= data An arbitrary length data ========== ========================================================= Example:: def send_echo_reply(self, datapath, data): ofp_parser = datapath.ofproto_parser reply = ofp_parser.OFPEchoReply(datapath, data) datapath.send_msg(reply) @set_ev_cls(ofp_event.EventOFPEchoReply, [HANDSHAKE_DISPATCHER, CONFIG_DISPATCHER, MAIN_DISPATCHER]) def echo_reply_handler(self, ev): self.logger.debug('OFPEchoReply received: data=%s', utils.hex_array(ev.msg.data)) """ def __init__(self, datapath, data=None): super(OFPEchoReply, self).__init__(datapath) self.data = data @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPEchoReply, cls).parser(datapath, version, msg_type, msg_len, xid, buf) msg.data = msg.buf[ofproto.OFP_HEADER_SIZE:] return msg def _serialize_body(self): assert self.data is not None self.buf += self.data @_set_msg_type(ofproto.OFPT_FEATURES_REQUEST) class OFPFeaturesRequest(MsgBase): """ Features request message The controller sends a feature request to the switch upon session establishment. This message is handled by the OSKen framework, so the OSKen application do not need to process this typically. Example:: def send_features_request(self, datapath): ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPFeaturesRequest(datapath) datapath.send_msg(req) """ def __init__(self, datapath): super(OFPFeaturesRequest, self).__init__(datapath) @_register_parser @_set_msg_type(ofproto.OFPT_EXPERIMENTER) class OFPExperimenter(MsgBase): """ Experimenter extension message ============= ========================================================= Attribute Description ============= ========================================================= experimenter Experimenter ID exp_type Experimenter defined data Experimenter defined arbitrary additional data ============= ========================================================= """ _subtypes = {} def __init__(self, datapath, experimenter=None, exp_type=None, data=None): super(OFPExperimenter, self).__init__(datapath) self.experimenter = experimenter self.exp_type = exp_type self.data = data @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPExperimenter, cls).parser(datapath, version, msg_type, msg_len, xid, buf) (msg.experimenter, msg.exp_type) = struct.unpack_from( ofproto.OFP_EXPERIMENTER_HEADER_PACK_STR, msg.buf, ofproto.OFP_HEADER_SIZE) msg.data = msg.buf[ofproto.OFP_EXPERIMENTER_HEADER_SIZE:] if (msg.experimenter, msg.exp_type) in cls._subtypes: new_msg = cls._subtypes[ (msg.experimenter, msg.exp_type)].parser_subtype(msg) new_msg.set_headers(msg.version, msg.msg_type, msg.msg_len, msg.xid) new_msg.set_buf(msg.buf) return new_msg return msg def _serialize_body(self): assert self.data is not None msg_pack_into(ofproto.OFP_EXPERIMENTER_HEADER_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.experimenter, self.exp_type) self.buf += self.data @_register_parser @_set_msg_type(ofproto.OFPT_FEATURES_REPLY) class OFPSwitchFeatures(MsgBase): """ Features reply message The switch responds with a features reply message to a features request. This message is handled by the OSKen framework, so the OSKen application do not need to process this typically. Example:: @set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER) def switch_features_handler(self, ev): msg = ev.msg self.logger.debug('OFPSwitchFeatures received: ' 'datapath_id=0x%016x n_buffers=%d ' 'n_tables=%d auxiliary_id=%d ' 'capabilities=0x%08x', msg.datapath_id, msg.n_buffers, msg.n_tables, msg.auxiliary_id, msg.capabilities) """ def __init__(self, datapath, datapath_id=None, n_buffers=None, n_tables=None, auxiliary_id=None, capabilities=None): super(OFPSwitchFeatures, self).__init__(datapath) self.datapath_id = datapath_id self.n_buffers = n_buffers self.n_tables = n_tables self.auxiliary_id = auxiliary_id self.capabilities = capabilities @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPSwitchFeatures, cls).parser(datapath, version, msg_type, msg_len, xid, buf) (msg.datapath_id, msg.n_buffers, msg.n_tables, msg.auxiliary_id, msg.capabilities, msg._reserved) = struct.unpack_from( ofproto.OFP_SWITCH_FEATURES_PACK_STR, msg.buf, ofproto.OFP_HEADER_SIZE) return msg @_set_msg_type(ofproto.OFPT_GET_CONFIG_REQUEST) class OFPGetConfigRequest(MsgBase): """ Get config request message The controller sends a get config request to query configuration parameters in the switch. Example:: def send_get_config_request(self, datapath): ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPGetConfigRequest(datapath) datapath.send_msg(req) """ def __init__(self, datapath): super(OFPGetConfigRequest, self).__init__(datapath) @_register_parser @_set_msg_type(ofproto.OFPT_GET_CONFIG_REPLY) class OFPGetConfigReply(MsgBase): """ Get config reply message The switch responds to a configuration request with a get config reply message. ============= ========================================================= Attribute Description ============= ========================================================= flags Bitmap of the following flags. | OFPC_FRAG_NORMAL | OFPC_FRAG_DROP | OFPC_FRAG_REASM miss_send_len Max bytes of new flow that datapath should send to the controller ============= ========================================================= Example:: @set_ev_cls(ofp_event.EventOFPGetConfigReply, MAIN_DISPATCHER) def get_config_reply_handler(self, ev): msg = ev.msg dp = msg.datapath ofp = dp.ofproto flags = [] if msg.flags & ofp.OFPC_FRAG_NORMAL: flags.append('NORMAL') if msg.flags & ofp.OFPC_FRAG_DROP: flags.append('DROP') if msg.flags & ofp.OFPC_FRAG_REASM: flags.append('REASM') self.logger.debug('OFPGetConfigReply received: ' 'flags=%s miss_send_len=%d', ','.join(flags), msg.miss_send_len) """ def __init__(self, datapath, flags=None, miss_send_len=None): super(OFPGetConfigReply, self).__init__(datapath) self.flags = flags self.miss_send_len = miss_send_len @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPGetConfigReply, cls).parser(datapath, version, msg_type, msg_len, xid, buf) msg.flags, msg.miss_send_len = struct.unpack_from( ofproto.OFP_SWITCH_CONFIG_PACK_STR, msg.buf, ofproto.OFP_HEADER_SIZE) return msg @_set_msg_type(ofproto.OFPT_SET_CONFIG) class OFPSetConfig(MsgBase): """ Set config request message The controller sends a set config request message to set configuraion parameters. ============= ========================================================= Attribute Description ============= ========================================================= flags Bitmap of the following flags. | OFPC_FRAG_NORMAL | OFPC_FRAG_DROP | OFPC_FRAG_REASM miss_send_len Max bytes of new flow that datapath should send to the controller ============= ========================================================= Example:: def send_set_config(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPSetConfig(datapath, ofp.OFPC_FRAG_NORMAL, 256) datapath.send_msg(req) """ def __init__(self, datapath, flags=0, miss_send_len=0): super(OFPSetConfig, self).__init__(datapath) self.flags = flags self.miss_send_len = miss_send_len def _serialize_body(self): assert self.flags is not None assert self.miss_send_len is not None msg_pack_into(ofproto.OFP_SWITCH_CONFIG_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.flags, self.miss_send_len) class OFPMatch(StringifyMixin): """ Flow Match Structure This class is implementation of the flow match structure having compose/query API. You can define the flow match by the keyword arguments. The following arguments are available. ================ =============== ================================== Argument Value Description ================ =============== ================================== in_port Integer 32bit Switch input port in_phy_port Integer 32bit Switch physical input port metadata Integer 64bit Metadata passed between tables eth_dst MAC address Ethernet destination address eth_src MAC address Ethernet source address eth_type Integer 16bit Ethernet frame type vlan_vid Integer 16bit VLAN id vlan_pcp Integer 8bit VLAN priority ip_dscp Integer 8bit IP DSCP (6 bits in ToS field) ip_ecn Integer 8bit IP ECN (2 bits in ToS field) ip_proto Integer 8bit IP protocol ipv4_src IPv4 address IPv4 source address ipv4_dst IPv4 address IPv4 destination address tcp_src Integer 16bit TCP source port tcp_dst Integer 16bit TCP destination port udp_src Integer 16bit UDP source port udp_dst Integer 16bit UDP destination port sctp_src Integer 16bit SCTP source port sctp_dst Integer 16bit SCTP destination port icmpv4_type Integer 8bit ICMP type icmpv4_code Integer 8bit ICMP code arp_op Integer 16bit ARP opcode arp_spa IPv4 address ARP source IPv4 address arp_tpa IPv4 address ARP target IPv4 address arp_sha MAC address ARP source hardware address arp_tha MAC address ARP target hardware address ipv6_src IPv6 address IPv6 source address ipv6_dst IPv6 address IPv6 destination address ipv6_flabel Integer 32bit IPv6 Flow Label icmpv6_type Integer 8bit ICMPv6 type icmpv6_code Integer 8bit ICMPv6 code ipv6_nd_target IPv6 address Target address for ND ipv6_nd_sll MAC address Source link-layer for ND ipv6_nd_tll MAC address Target link-layer for ND mpls_label Integer 32bit MPLS label mpls_tc Integer 8bit MPLS TC mpls_bos Integer 8bit MPLS BoS bit pbb_isid Integer 24bit PBB I-SID tunnel_id Integer 64bit Logical Port Metadata ipv6_exthdr Integer 16bit IPv6 Extension Header pseudo-field pbb_uca Integer 8bit PBB UCA header field tcp_flags Integer 16bit TCP flags actset_output Integer 32bit Output port from action set metadata packet_type Integer 32bit Packet type value ================ =============== ================================== Example:: >>> # compose >>> match = parser.OFPMatch( ... in_port=1, ... eth_type=0x86dd, ... ipv6_src=('2001:db8:bd05:1d2:288a:1fc0:1:10ee', ... 'ffff:ffff:ffff:ffff::'), ... ipv6_dst='2001:db8:bd05:1d2:288a:1fc0:1:10ee') >>> # query >>> if 'ipv6_src' in match: ... print match['ipv6_src'] ... ('2001:db8:bd05:1d2:288a:1fc0:1:10ee', 'ffff:ffff:ffff:ffff::') .. Note:: For the list of the supported Nicira experimenter matches, please refer to :ref:`os_ken.ofproto.nx_match `. .. Note:: For VLAN id match field, special values are defined in OpenFlow Spec. 1) Packets with and without a VLAN tag - Example:: match = parser.OFPMatch() - Packet Matching ====================== ===== non-VLAN-tagged MATCH VLAN-tagged(vlan_id=3) MATCH VLAN-tagged(vlan_id=5) MATCH ====================== ===== 2) Only packets without a VLAN tag - Example:: match = parser.OFPMatch(vlan_vid=0x0000) - Packet Matching ====================== ===== non-VLAN-tagged MATCH VLAN-tagged(vlan_id=3) x VLAN-tagged(vlan_id=5) x ====================== ===== 3) Only packets with a VLAN tag regardless of its value - Example:: match = parser.OFPMatch(vlan_vid=(0x1000, 0x1000)) - Packet Matching ====================== ===== non-VLAN-tagged x VLAN-tagged(vlan_id=3) MATCH VLAN-tagged(vlan_id=5) MATCH ====================== ===== 4) Only packets with VLAN tag and VID equal - Example:: match = parser.OFPMatch(vlan_vid=(0x1000 | 3)) - Packet Matching ====================== ===== non-VLAN-tagged x VLAN-tagged(vlan_id=3) MATCH VLAN-tagged(vlan_id=5) x ====================== ===== """ def __init__(self, type_=None, length=None, _ordered_fields=None, **kwargs): super(OFPMatch, self).__init__() self.type = ofproto.OFPMT_OXM self.length = length if _ordered_fields is not None: assert not kwargs self._fields2 = _ordered_fields else: kwargs = dict(ofproto.oxm_normalize_user(k, v) for (k, v) in kwargs.items()) fields = [ofproto.oxm_from_user(k, v) for (k, v) in kwargs.items()] # assumption: sorting by OXM type values makes fields # meet ordering requirements (eg. eth_type before ipv4_src) fields.sort( key=lambda x: x[0][0] if isinstance(x[0], tuple) else x[0]) self._fields2 = [ofproto.oxm_to_user(n, v, m) for (n, v, m) in fields] @classmethod def parser(cls, buf, offset): """ Returns an object which is generated from a buffer including the expression of the wire protocol of the flow match. """ match = OFPMatch() type_, length = struct.unpack_from('!HH', buf, offset) match.type = type_ match.length = length # ofp_match adjustment offset += 4 length -= 4 fields = [] while length > 0: n, value, mask, field_len = ofproto.oxm_parse(buf, offset) k, uv = ofproto.oxm_to_user(n, value, mask) fields.append((k, uv)) offset += field_len length -= field_len match._fields2 = fields return match def serialize(self, buf, offset): """ Outputs the expression of the wire protocol of the flow match into the buf. Returns the output length. """ fields = [ofproto.oxm_from_user(k, uv) for (k, uv) in self._fields2] hdr_pack_str = '!HH' field_offset = offset + struct.calcsize(hdr_pack_str) for (n, value, mask) in fields: field_offset += ofproto.oxm_serialize(n, value, mask, buf, field_offset) length = field_offset - offset msg_pack_into(hdr_pack_str, buf, offset, ofproto.OFPMT_OXM, length) self.length = length pad_len = utils.round_up(length, 8) - length msg_pack_into("%dx" % pad_len, buf, field_offset) return length + pad_len def __getitem__(self, key): return dict(self._fields2)[key] def __contains__(self, key): return key in dict(self._fields2) def iteritems(self): return iter(dict(self._fields2).items()) def items(self): return self._fields2 def get(self, key, default=None): return dict(self._fields2).get(key, default) def stringify_attrs(self): yield "oxm_fields", dict(self._fields2) def to_jsondict(self): """ Returns a dict expressing the flow match. """ body = {"oxm_fields": [ofproto.oxm_to_jsondict(k, uv) for k, uv in self._fields2], "length": self.length, "type": self.type} return {self.__class__.__name__: body} @classmethod def from_jsondict(cls, dict_): """ Returns an object which is generated from a dict. Exception raises: KeyError -- Unknown match field is defined in dict """ fields = [ofproto.oxm_from_jsondict(f) for f in dict_['oxm_fields']] return OFPMatch(_ordered_fields=fields) class OFPStats(StringifyMixin): """ Flow Stats Structure This class is implementation of the flow stats structure having compose/query API. You can define the flow stats by the keyword arguments. The following arguments are available. ============= ================ ============================================ Argument Value Description ============= ================ ============================================ duration Integer 32bit*2 Time flow entry has been alive. This field is a tuple of two Integer 32bit. The first value is duration_sec and the second is duration_nsec. idle_time Integer 32bit*2 Time flow entry has been idle. flow_count Integer 32bit Number of aggregated flow entries. packet_count Integer 64bit Number of packets matched by a flow entry. byte_count Integer 64bit Number of bytes matched by a flow entry. ============= ================ ============================================ Example:: >>> # compose >>> stats = parser.OFPStats( ... packet_count=100, ... duration=(100, 200) >>> # query >>> if 'duration' in stats: ... print stats['duration'] ... (100, 200) """ def __init__(self, length=None, _ordered_fields=None, **kwargs): super(OFPStats, self).__init__() self.length = length if _ordered_fields is not None: assert not kwargs self.fields = _ordered_fields else: fields = [ofproto.oxs_from_user(k, v) for (k, v) in kwargs.items()] # sort by OXS type values fields.sort( key=lambda x: x[0][0] if isinstance(x[0], tuple) else x[0]) # No mask self.fields = [ofproto.oxs_to_user(n, v, None) for (n, v, _) in fields] @classmethod def parser(cls, buf, offset): """ Returns an object which is generated from a buffer including the expression of the wire protocol of the flow stats. """ stats = OFPStats() reserved, length = struct.unpack_from('!HH', buf, offset) stats.length = length # ofp_stats adjustment offset += 4 length -= 4 fields = [] while length > 0: n, value, _, field_len = ofproto.oxs_parse(buf, offset) k, uv = ofproto.oxs_to_user(n, value, None) # No mask fields.append((k, uv)) offset += field_len length -= field_len stats.fields = fields return stats def serialize(self, buf, offset): """ Outputs the expression of the wire protocol of the flow stats into the buf. Returns the output length. """ fields = [ofproto.oxs_from_user(k, uv) for (k, uv) in self.fields] hdr_pack_str = '!HH' field_offset = offset + struct.calcsize(hdr_pack_str) for (n, value, _) in fields: # No mask field_offset += ofproto.oxs_serialize(n, value, None, buf, field_offset) reserved = 0 length = field_offset - offset msg_pack_into(hdr_pack_str, buf, offset, reserved, length) self.length = length pad_len = utils.round_up(length, 8) - length msg_pack_into("%dx" % pad_len, buf, field_offset) return length + pad_len def __getitem__(self, key): return dict(self.fields)[key] def __contains__(self, key): return key in dict(self.fields) def iteritems(self): return dict(self.fields).items() def items(self): return self.fields def get(self, key, default=None): return dict(self.fields).get(key, default) def stringify_attrs(self): yield "oxs_fields", dict(self.fields) def to_jsondict(self): """ Returns a dict expressing the flow stats. """ body = {"oxs_fields": [ofproto.oxs_to_jsondict(k, uv) for k, uv in self.fields], "length": self.length} return {self.__class__.__name__: body} @classmethod def from_jsondict(cls, dict_): """ Returns an object which is generated from a dict. Exception raises: KeyError -- Unknown stats field is defined in dict """ fields = [ofproto.oxs_from_jsondict(f) for f in dict_['oxs_fields']] return OFPStats(_ordered_fields=fields) class OFPPropUnknown(StringifyMixin): def __init__(self, type_=None, length=None, buf=None): self.buf = buf @classmethod def parser(cls, buf): return cls(buf=buf) class OFPPropBase(StringifyMixin): _PACK_STR = '!HH' # _TYPES = {} must be an attribute of subclass def __init__(self, type_, length=None): self.type = type_ self.length = length @classmethod def register_type(cls, type_): def _register_type(subcls): cls._TYPES[type_] = subcls return subcls return _register_type @classmethod def parse(cls, buf): (type_, length) = struct.unpack_from(cls._PACK_STR, buf, 0) if not length: raise ValueError rest = buf[utils.round_up(length, 8):] try: subcls = cls._TYPES[type_] except KeyError: subcls = OFPPropUnknown prop = subcls.parser(buf) prop.type = type_ prop.length = length return prop, rest @classmethod def get_rest(cls, buf): (type_, length) = struct.unpack_from(cls._PACK_STR, buf, 0) offset = struct.calcsize(cls._PACK_STR) return buf[offset:length] def serialize(self): # Body # serialize_body should be implemented by subclass body = bytearray() body += self.serialize_body() # fixup self.length = len(body) + struct.calcsize(self._PACK_STR) # Header buf = bytearray() msg_pack_into(self._PACK_STR, buf, 0, self.type, self.length) buf += body # Pad pad_len = utils.round_up(self.length, 8) - self.length msg_pack_into("%dx" % pad_len, buf, len(buf)) return buf class OFPPropCommonExperimenter4ByteData(StringifyMixin): _PACK_STR = '!HHII' _EXPERIMENTER_DATA_PACK_STR = '!I' _EXPERIMENTER_DATA_SIZE = 4 def __init__(self, type_=None, length=None, experimenter=None, exp_type=None, data=bytearray()): self.type = type_ self.length = length self.experimenter = experimenter self.exp_type = exp_type self.data = data @classmethod def parser(cls, buf): (type_, length, experimenter, exp_type) = struct.unpack_from( ofproto.OFP_PROP_EXPERIMENTER_PACK_STR, buf, 0) rest = buf[ofproto.OFP_PROP_EXPERIMENTER_SIZE:length] data = [] while rest: (d,) = struct.unpack_from( cls._EXPERIMENTER_DATA_PACK_STR, rest, 0) data.append(d) rest = rest[cls._EXPERIMENTER_DATA_SIZE:] return cls(type_, length, experimenter, exp_type, data) def serialize(self): offset = 0 bin_data = bytearray() for d in self.data: msg_pack_into(self._EXPERIMENTER_DATA_PACK_STR, bin_data, offset, d) offset += self._EXPERIMENTER_DATA_SIZE # fixup self.length = struct.calcsize(self._PACK_STR) self.length += len(bin_data) buf = bytearray() msg_pack_into(self._PACK_STR, buf, 0, self.type, self.length, self.experimenter, self.exp_type) buf += bin_data # Pad pad_len = utils.round_up(self.length, 8) - self.length msg_pack_into("%dx" % pad_len, buf, len(buf)) return buf class OFPPortDescProp(OFPPropBase): _TYPES = {} @OFPPortDescProp.register_type(ofproto.OFPPDPT_ETHERNET) class OFPPortDescPropEthernet(OFPPortDescProp): def __init__(self, type_=None, length=None, curr=None, advertised=None, supported=None, peer=None, curr_speed=None, max_speed=None): self.type = type_ self.length = length self.curr = curr self.advertised = advertised self.supported = supported self.peer = peer self.curr_speed = curr_speed self.max_speed = max_speed @classmethod def parser(cls, buf): ether = cls() (ether.type, ether.length, ether.curr, ether.advertised, ether.supported, ether.peer, ether.curr_speed, ether.max_speed) = struct.unpack_from( ofproto.OFP_PORT_DESC_PROP_ETHERNET_PACK_STR, buf, 0) return ether @OFPPortDescProp.register_type(ofproto.OFPPDPT_OPTICAL) class OFPPortDescPropOptical(OFPPortDescProp): def __init__(self, type_=None, length=None, supported=None, tx_min_freq_lmda=None, tx_max_freq_lmda=None, tx_grid_freq_lmda=None, rx_min_freq_lmda=None, rx_max_freq_lmda=None, rx_grid_freq_lmda=None, tx_pwr_min=None, tx_pwr_max=None): self.type = type_ self.length = length self.supported = supported self.tx_min_freq_lmda = tx_min_freq_lmda self.tx_max_freq_lmda = tx_max_freq_lmda self.tx_grid_freq_lmda = tx_grid_freq_lmda self.rx_min_freq_lmda = rx_min_freq_lmda self.rx_max_freq_lmda = rx_max_freq_lmda self.rx_grid_freq_lmda = rx_grid_freq_lmda self.tx_pwr_min = tx_pwr_min self.tx_pwr_max = tx_pwr_max @classmethod def parser(cls, buf): optical = cls() (optical.type, optical.length, optical.supported, optical.tx_min_freq_lmda, optical.tx_max_freq_lmda, optical.tx_grid_freq_lmda, optical.rx_min_freq_lmda, optical.rx_max_freq_lmda, optical.rx_grid_freq_lmda, optical.tx_pwr_min, optical.tx_pwr_max) = struct.unpack_from( ofproto.OFP_PORT_DESC_PROP_OPTICAL_PACK_STR, buf, 0) return optical @OFPPortDescProp.register_type(ofproto.OFPPDPT_PIPELINE_INPUT) @OFPPortDescProp.register_type(ofproto.OFPPDPT_PIPELINE_OUTPUT) class OFPPortDescPropOxm(OFPPortDescProp): def __init__(self, type_=None, length=None, oxm_ids=None): oxm_ids = oxm_ids if oxm_ids else [] super(OFPPortDescPropOxm, self).__init__(type_, length) self.oxm_ids = oxm_ids @classmethod def parser(cls, buf): rest = cls.get_rest(buf) ids = [] while rest: i, rest = OFPOxmId.parse(rest) ids.append(i) return cls(oxm_ids=ids) def serialize_body(self): bin_ids = bytearray() for i in self.oxm_ids: bin_ids += i.serialize() return bin_ids @OFPPortDescProp.register_type(ofproto.OFPPDPT_RECIRCULATE) class OFPPortDescPropRecirculate(OFPPortDescProp): _PORT_NO_PACK_STR = '!I' def __init__(self, type_=None, length=None, port_nos=None): port_nos = port_nos if port_nos else [] super(OFPPortDescPropRecirculate, self).__init__(type_, length) self.port_nos = port_nos @classmethod def parser(cls, buf): rest = cls.get_rest(buf) nos = [] while rest: (n,) = struct.unpack_from(cls._PORT_NO_PACK_STR, bytes(rest), 0) rest = rest[struct.calcsize(cls._PORT_NO_PACK_STR):] nos.append(n) return cls(port_nos=nos) def serialize_body(self): bin_nos = bytearray() for n in self.port_nos: bin_no = bytearray() msg_pack_into(self._PORT_NO_PACK_STR, bin_no, 0, n) bin_nos += bin_no return bin_nos @OFPPortDescProp.register_type(ofproto.OFPPDPT_EXPERIMENTER) class OFPPortDescPropExperimenter(OFPPropCommonExperimenter4ByteData): pass class OFPTableModProp(OFPPropBase): _TYPES = {} @OFPTableModProp.register_type(ofproto.OFPTMPT_EVICTION) class OFPTableModPropEviction(OFPTableModProp): def __init__(self, type_=None, length=None, flags=None): self.type = type_ self.length = length self.flags = flags @classmethod def parser(cls, buf): eviction = cls() (eviction.type, eviction.length, eviction.flags) = struct.unpack_from( ofproto.OFP_TABLE_MOD_PROP_EVICTION_PACK_STR, buf, 0) return eviction def serialize(self): # fixup self.length = ofproto.OFP_TABLE_MOD_PROP_EVICTION_SIZE buf = bytearray() msg_pack_into(ofproto.OFP_TABLE_MOD_PROP_EVICTION_PACK_STR, buf, 0, self.type, self.length, self.flags) return buf @OFPTableModProp.register_type(ofproto.OFPTMPT_VACANCY) class OFPTableModPropVacancy(OFPTableModProp): def __init__(self, type_=None, length=None, vacancy_down=None, vacancy_up=None, vacancy=None): self.type = type_ self.length = length self.vacancy_down = vacancy_down self.vacancy_up = vacancy_up self.vacancy = vacancy @classmethod def parser(cls, buf): vacancy = cls() (vacancy.type, vacancy.length, vacancy.vacancy_down, vacancy.vacancy_up, vacancy.vacancy) = struct.unpack_from( ofproto.OFP_TABLE_MOD_PROP_VACANCY_PACK_STR, buf, 0) return vacancy def serialize(self): # fixup self.length = ofproto.OFP_TABLE_MOD_PROP_VACANCY_SIZE buf = bytearray() msg_pack_into(ofproto.OFP_TABLE_MOD_PROP_VACANCY_PACK_STR, buf, 0, self.type, self.length, self.vacancy_down, self.vacancy_up, self.vacancy) return buf @OFPTableModProp.register_type(ofproto.OFPTMPT_EXPERIMENTER) class OFPTableModPropExperimenter(OFPPropCommonExperimenter4ByteData): pass class OFPQueueDescProp(OFPPropBase): _TYPES = {} @OFPQueueDescProp.register_type(ofproto.OFPQDPT_MIN_RATE) class OFPQueueDescPropMinRate(OFPQueueDescProp): def __init__(self, type_=None, length=None, rate=None): self.type = type_ self.length = length self.rate = rate @classmethod def parser(cls, buf): minrate = cls() (minrate.type, minrate.length, minrate.rate) = struct.unpack_from( ofproto.OFP_QUEUE_DESC_PROP_MIN_RATE_PACK_STR, buf, 0) return minrate @OFPQueueDescProp.register_type(ofproto.OFPQDPT_MAX_RATE) class OFPQueueDescPropMaxRate(OFPQueueDescProp): def __init__(self, type_=None, length=None, rate=None): self.type = type_ self.length = length self.rate = rate @classmethod def parser(cls, buf): maxrate = cls() (maxrate.type, maxrate.length, maxrate.rate) = struct.unpack_from( ofproto.OFP_QUEUE_DESC_PROP_MAX_RATE_PACK_STR, buf, 0) return maxrate @OFPQueueDescProp.register_type(ofproto.OFPQDPT_EXPERIMENTER) class OFPQueueDescPropExperimenter(OFPPropCommonExperimenter4ByteData): pass class OFPRoleProp(OFPPropBase): _TYPES = {} @OFPRoleProp.register_type(ofproto.OFPRPT_EXPERIMENTER) class OFPRolePropExperimenter(OFPPropCommonExperimenter4ByteData): pass class OFPTime(StringifyMixin): def __init__(self, seconds=None, nanoseconds=None): self.seconds = seconds self.nanoseconds = nanoseconds @classmethod def parser(cls, buf, offset): cls_ = cls() (cls_.seconds, cls_.nanoseconds) = struct.unpack_from( ofproto.OFP_TIME_PACK_STR, buf, offset) return cls_ def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_TIME_PACK_STR, buf, offset, self.seconds, self.nanoseconds) return ofproto.OFP_TIME_SIZE class OFPBundleProp(OFPPropBase): _TYPES = {} @OFPBundleProp.register_type(ofproto.OFPBPT_TIME) class OFPBundlePropTime(OFPBundleProp): def __init__(self, type_=None, length=None, scheduled_time=None): super(OFPBundlePropTime, self).__init__(type_, length) self.scheduled_time = scheduled_time @classmethod def parser(cls, buf): prop = cls() offset = ofproto.OFP_BUNDLE_PROP_TIME_PACK_STR0_SIZE prop.scheduled_time = OFPTime.parser(buf, offset) return prop def serialize(self): # fixup self.length = ofproto.OFP_BUNDLE_PROP_TIME_PACK_STR_SIZE buf = bytearray() msg_pack_into(ofproto.OFP_BUNDLE_PROP_TIME_PACK_STR0, buf, 0, self.type, self.length) offset = ofproto.OFP_BUNDLE_PROP_TIME_PACK_STR0_SIZE self.scheduled_time.serialize(buf, offset) return buf @OFPBundleProp.register_type(ofproto.OFPRPT_EXPERIMENTER) class OFPBundlePropExperimenter(OFPPropCommonExperimenter4ByteData): pass @_register_parser @_set_msg_type(ofproto.OFPT_PACKET_IN) class OFPPacketIn(MsgBase): """ Packet-In message The switch sends the packet that received to the controller by this message. ============= ========================================================= Attribute Description ============= ========================================================= buffer_id ID assigned by datapath total_len Full length of frame reason Reason packet is being sent. | OFPR_TABLE_MISS | OFPR_APPLY_ACTION | OFPR_INVALID_TTL | OFPR_ACTION_SET | OFPR_GROUP | OFPR_PACKET_OUT table_id ID of the table that was looked up cookie Cookie of the flow entry that was looked up match Instance of ``OFPMatch`` data Ethernet frame ============= ========================================================= Example:: @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER) def packet_in_handler(self, ev): msg = ev.msg dp = msg.datapath ofp = dp.ofproto if msg.reason == ofp.TABLE_MISS: reason = 'TABLE MISS' elif msg.reason == ofp.OFPR_APPLY_ACTION: reason = 'APPLY ACTION' elif msg.reason == ofp.OFPR_INVALID_TTL: reason = 'INVALID TTL' elif msg.reason == ofp.OFPR_ACTION_SET: reason = 'ACTION SET' elif msg.reason == ofp.OFPR_GROUP: reason = 'GROUP' elif msg.reason == ofp.OFPR_PACKET_OUT: reason = 'PACKET OUT' else: reason = 'unknown' self.logger.debug('OFPPacketIn received: ' 'buffer_id=%x total_len=%d reason=%s ' 'table_id=%d cookie=%d match=%s data=%s', msg.buffer_id, msg.total_len, reason, msg.table_id, msg.cookie, msg.match, utils.hex_array(msg.data)) """ def __init__(self, datapath, buffer_id=None, total_len=None, reason=None, table_id=None, cookie=None, match=None, data=None): super(OFPPacketIn, self).__init__(datapath) self.buffer_id = buffer_id self.total_len = total_len self.reason = reason self.table_id = table_id self.cookie = cookie self.match = match self.data = data @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPPacketIn, cls).parser(datapath, version, msg_type, msg_len, xid, buf) (msg.buffer_id, msg.total_len, msg.reason, msg.table_id, msg.cookie) = struct.unpack_from( ofproto.OFP_PACKET_IN_PACK_STR, msg.buf, ofproto.OFP_HEADER_SIZE) msg.match = OFPMatch.parser(msg.buf, ofproto.OFP_PACKET_IN_SIZE - ofproto.OFP_MATCH_SIZE) match_len = utils.round_up(msg.match.length, 8) msg.data = msg.buf[(ofproto.OFP_PACKET_IN_SIZE - ofproto.OFP_MATCH_SIZE + match_len + 2):] if msg.total_len < len(msg.data): # discard padding for 8-byte alignment of OFP packet msg.data = msg.data[:msg.total_len] return msg @_register_parser @_set_msg_type(ofproto.OFPT_FLOW_REMOVED) class OFPFlowRemoved(MsgBase): """ Flow removed message When flow entries time out or are deleted, the switch notifies controller with this message. ================ ====================================================== Attribute Description ================ ====================================================== table_id ID of the table reason One of the following values. | OFPRR_IDLE_TIMEOUT | OFPRR_HARD_TIMEOUT | OFPRR_DELETE | OFPRR_GROUP_DELETE | OFPRR_METER_DELETE | OFPRR_EVICTION priority Priority level of flow entry idle_timeout Idle timeout from original flow mod hard_timeout Hard timeout from original flow mod cookie Opaque controller-issued identifier match Instance of ``OFPMatch`` stats Instance of ``OFPStats`` ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPFlowRemoved, MAIN_DISPATCHER) def flow_removed_handler(self, ev): msg = ev.msg dp = msg.datapath ofp = dp.ofproto if msg.reason == ofp.OFPRR_IDLE_TIMEOUT: reason = 'IDLE TIMEOUT' elif msg.reason == ofp.OFPRR_HARD_TIMEOUT: reason = 'HARD TIMEOUT' elif msg.reason == ofp.OFPRR_DELETE: reason = 'DELETE' elif msg.reason == ofp.OFPRR_GROUP_DELETE: reason = 'GROUP DELETE' elif msg.reason == ofp.OFPRR_METER_DELETE: reason = 'METER DELETE' elif msg.reason == ofp.OFPRR_EVICTION: reason = 'EVICTION' else: reason = 'unknown' self.logger.debug('OFPFlowRemoved received: ' 'table_id=%d reason=%s priority=%d ' 'idle_timeout=%d hard_timeout=%d cookie=%d ' 'match=%s stats=%s', msg.table_id, reason, msg.priority, msg.idle_timeout, msg.hard_timeout, msg.cookie, msg.match, msg.stats) """ def __init__(self, datapath, table_id=None, reason=None, priority=None, idle_timeout=None, hard_timeout=None, cookie=None, match=None, stats=None): super(OFPFlowRemoved, self).__init__(datapath) self.table_id = table_id self.reason = reason self.priority = priority self.idle_timeout = idle_timeout self.hard_timeout = hard_timeout self.cookie = cookie self.match = match self.stats = stats @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPFlowRemoved, cls).parser(datapath, version, msg_type, msg_len, xid, buf) (msg.table_id, msg.reason, msg.priority, msg.idle_timeout, msg.hard_timeout, msg.cookie) = struct.unpack_from( ofproto.OFP_FLOW_REMOVED_PACK_STR0, msg.buf, ofproto.OFP_HEADER_SIZE) offset = (ofproto.OFP_FLOW_REMOVED_SIZE - ofproto.OFP_MATCH_SIZE) msg.match = OFPMatch.parser(msg.buf, offset) offset += utils.round_up(msg.match.length, 8) stats_length = msg.msg_len - offset if stats_length > 0: msg.stats = OFPStats.parser(buf, offset) return msg class OFPPort(StringifyMixin): """ Description of a port ========== ========================================================= Attribute Description ========== ========================================================= port_no Port number and it uniquely identifies a port within a switch. length Length of ofp_port (excluding padding). hw_addr MAC address for the port. name Null-terminated string containing a human-readable name for the interface. config Bitmap of port configuration flags. | OFPPC_PORT_DOWN | OFPPC_NO_RECV | OFPPC_NO_FWD | OFPPC_NO_PACKET_IN state Bitmap of port state flags. | OFPPS_LINK_DOWN | OFPPS_BLOCKED | OFPPS_LIVE properties List of ``OFPPortDescProp`` subclass instance ========== ========================================================= """ _TYPE = { 'ascii': [ 'hw_addr', ], 'utf-8': [ # OF spec is unclear about the encoding of name. # we assumes UTF-8, which is used by OVS. 'name', ] } def __init__(self, port_no=None, length=None, hw_addr=None, name=None, config=None, state=None, properties=None): super(OFPPort, self).__init__() self.port_no = port_no self.length = length self.hw_addr = hw_addr self.name = name self.config = config self.state = state self.properties = properties @classmethod def parser(cls, buf, offset): (port_no, length, hw_addr, name, config, state) = struct.unpack_from( ofproto.OFP_PORT_PACK_STR, buf, offset) hw_addr = addrconv.mac.bin_to_text(hw_addr) name = name.rstrip(b'\0') props = [] rest = buf[offset + ofproto.OFP_PORT_SIZE:offset + length] while rest: p, rest = OFPPortDescProp.parse(rest) props.append(p) ofpport = cls(port_no, length, hw_addr, name, config, state, props) return ofpport class OFPTableDesc(StringifyMixin): def __init__(self, length=None, table_id=None, config=None, properties=None): super(OFPTableDesc, self).__init__() self.table_id = table_id self.length = length self.config = config self.properties = properties @classmethod def parser(cls, buf, offset): (length, table_id, config) = struct.unpack_from( ofproto.OFP_TABLE_DESC_PACK_STR, buf, offset) props = [] rest = buf[offset + ofproto.OFP_TABLE_DESC_SIZE:offset + length] while rest: p, rest = OFPTableModProp.parse(rest) props.append(p) ofptabledesc = cls(length, table_id, config, props) return ofptabledesc class OFPQueueDesc(StringifyMixin): def __init__(self, port_no=None, queue_id=None, len_=None, properties=None): super(OFPQueueDesc, self).__init__() self.port_no = port_no self.queue_id = queue_id self.len = len_ self.properties = properties @classmethod def parser(cls, buf, offset): (port_no, queue_id, len_) = struct.unpack_from( ofproto.OFP_QUEUE_DESC_PACK_STR, buf, offset) props = [] rest = buf[offset + ofproto.OFP_QUEUE_DESC_SIZE:offset + len_] while rest: p, rest = OFPQueueDescProp.parse(rest) props.append(p) ofpqueuedesc = cls(port_no, queue_id, len_, props) return ofpqueuedesc def _set_stats_type(stats_type, stats_body_cls): def _set_cls_stats_type(cls): cls.cls_stats_type = stats_type cls.cls_stats_body_cls = stats_body_cls return cls return _set_cls_stats_type @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPMultipartRequest(MsgBase): def __init__(self, datapath, flags): super(OFPMultipartRequest, self).__init__(datapath) self.type = self.__class__.cls_stats_type self.flags = flags def _serialize_stats_body(self): pass def _serialize_body(self): msg_pack_into(ofproto.OFP_MULTIPART_REQUEST_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.type, self.flags) self._serialize_stats_body() @_register_parser @_set_msg_type(ofproto.OFPT_METER_MOD) class OFPMeterMod(MsgBase): """ Meter modification message The controller sends this message to modify the meter. ================ ====================================================== Attribute Description ================ ====================================================== command One of the following values. | OFPMC_ADD | OFPMC_MODIFY | OFPMC_DELETE flags Bitmap of the following flags. | OFPMF_KBPS | OFPMF_PKTPS | OFPMF_BURST | OFPMF_STATS meter_id Meter instance bands list of the following class instance. | OFPMeterBandDrop | OFPMeterBandDscpRemark | OFPMeterBandExperimenter ================ ====================================================== """ def __init__(self, datapath, command=ofproto.OFPMC_ADD, flags=ofproto.OFPMF_KBPS, meter_id=1, bands=None): bands = bands if bands else [] super(OFPMeterMod, self).__init__(datapath) self.command = command self.flags = flags self.meter_id = meter_id self.bands = bands @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPMeterMod, cls).parser( datapath, version, msg_type, msg_len, xid, buf) (msg.command, msg.flags, msg.meter_id) = struct.unpack_from( ofproto.OFP_METER_MOD_PACK_STR, buf, ofproto.OFP_HEADER_SIZE) offset = ofproto.OFP_METER_MOD_SIZE msg.bands = [] while offset < msg.msg_len: band = OFPMeterBandHeader.parser(buf, offset) msg.bands.append(band) offset += band.len return msg def _serialize_body(self): msg_pack_into(ofproto.OFP_METER_MOD_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.command, self.flags, self.meter_id) offset = ofproto.OFP_METER_MOD_SIZE for b in self.bands: b.serialize(self.buf, offset) offset += b.len @_set_msg_type(ofproto.OFPT_TABLE_MOD) class OFPTableMod(MsgBase): """ Flow table configuration message The controller sends this message to configure table state. ================ ====================================================== Attribute Description ================ ====================================================== table_id ID of the table (OFPTT_ALL indicates all tables) config Bitmap of configuration flags. | OFPTC_EVICTION | OFPTC_VACANCY_EVENTS properties List of ``OFPTableModProp`` subclass instance ================ ====================================================== Example:: def send_table_mod(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPTableMod(datapath, 1, 3) flags = ofp.OFPTC_VACANCY_EVENTS properties = [ofp_parser.OFPTableModPropEviction(flags)] req = ofp_parser.OFPTableMod(datapath, 1, 3, properties) datapath.send_msg(req) """ def __init__(self, datapath, table_id, config, properties): super(OFPTableMod, self).__init__(datapath) self.table_id = table_id self.config = config self.properties = properties def _serialize_body(self): props_buf = bytearray() for p in self.properties: props_buf += p.serialize() msg_pack_into(ofproto.OFP_TABLE_MOD_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.table_id, self.config) self.buf += props_buf @_register_parser @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPMultipartReply(MsgBase): _STATS_MSG_TYPES = {} @staticmethod def register_stats_type(body_single_struct=False): def _register_stats_type(cls): assert cls.cls_stats_type is not None assert cls.cls_stats_type not in OFPMultipartReply._STATS_MSG_TYPES assert cls.cls_stats_body_cls is not None cls.cls_body_single_struct = body_single_struct OFPMultipartReply._STATS_MSG_TYPES[cls.cls_stats_type] = cls return cls return _register_stats_type def __init__(self, datapath, body=None, flags=None): super(OFPMultipartReply, self).__init__(datapath) self.body = body self.flags = flags @classmethod def parser_stats_body(cls, buf, msg_len, offset): body_cls = cls.cls_stats_body_cls body = [] while offset < msg_len: entry = body_cls.parser(buf, offset) body.append(entry) offset += entry.length if cls.cls_body_single_struct: return body[0] return body @classmethod def parser_stats(cls, datapath, version, msg_type, msg_len, xid, buf): msg = MsgBase.parser.__func__( cls, datapath, version, msg_type, msg_len, xid, buf) msg.body = msg.parser_stats_body(msg.buf, msg.msg_len, ofproto.OFP_MULTIPART_REPLY_SIZE) return msg @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): type_, flags = struct.unpack_from( ofproto.OFP_MULTIPART_REPLY_PACK_STR, bytes(buf), ofproto.OFP_HEADER_SIZE) stats_type_cls = cls._STATS_MSG_TYPES.get(type_) msg = super(OFPMultipartReply, stats_type_cls).parser( datapath, version, msg_type, msg_len, xid, buf) msg.type = type_ msg.flags = flags offset = ofproto.OFP_MULTIPART_REPLY_SIZE body = [] while offset < msg_len: b = stats_type_cls.cls_stats_body_cls.parser(msg.buf, offset) offset_step = b.length if hasattr(b, 'length') else b.len if offset_step < 1: raise exception.OFPMalformedMessage() body.append(b) offset += offset_step if stats_type_cls.cls_body_single_struct: msg.body = body[0] else: msg.body = body return msg class OFPDescStats(ofproto_parser.namedtuple('OFPDescStats', ( 'mfr_desc', 'hw_desc', 'sw_desc', 'serial_num', 'dp_desc'))): _TYPE = { 'ascii': [ 'mfr_desc', 'hw_desc', 'sw_desc', 'serial_num', 'dp_desc', ] } @classmethod def parser(cls, buf, offset): desc = struct.unpack_from(ofproto.OFP_DESC_PACK_STR, buf, offset) desc = list(desc) desc = [x.rstrip(b'\0') for x in desc] stats = cls(*desc) stats.length = ofproto.OFP_DESC_SIZE return stats @_set_stats_type(ofproto.OFPMP_DESC, OFPDescStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPDescStatsRequest(OFPMultipartRequest): """ Description statistics request message The controller uses this message to query description of the switch. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or ``OFPMPF_REQ_MORE`` ================ ====================================================== Example:: def send_desc_stats_request(self, datapath): ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPDescStatsRequest(datapath, 0) datapath.send_msg(req) """ def __init__(self, datapath, flags=0, type_=None): super(OFPDescStatsRequest, self).__init__(datapath, flags) @OFPMultipartReply.register_stats_type(body_single_struct=True) @_set_stats_type(ofproto.OFPMP_DESC, OFPDescStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPDescStatsReply(OFPMultipartReply): """ Description statistics reply message The switch responds with this message to a description statistics request. ================ ====================================================== Attribute Description ================ ====================================================== body Instance of ``OFPDescStats`` ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPDescStatsReply, MAIN_DISPATCHER) def desc_stats_reply_handler(self, ev): body = ev.msg.body self.logger.debug('DescStats: mfr_desc=%s hw_desc=%s sw_desc=%s ' 'serial_num=%s dp_desc=%s', body.mfr_desc, body.hw_desc, body.sw_desc, body.serial_num, body.dp_desc) """ def __init__(self, datapath, type_=None, **kwargs): super(OFPDescStatsReply, self).__init__(datapath, **kwargs) class OFPTableFeaturesStats(StringifyMixin): _TYPE = { 'utf-8': [ # OF spec is unclear about the encoding of name. # we assumes UTF-8. 'name', ] } def __init__(self, table_id=None, command=None, features=None, name=None, metadata_match=None, metadata_write=None, capabilities=None, max_entries=None, properties=None, length=None): super(OFPTableFeaturesStats, self).__init__() self.length = length self.table_id = table_id self.command = command self.features = features self.name = name self.metadata_match = metadata_match self.metadata_write = metadata_write self.capabilities = capabilities self.max_entries = max_entries self.properties = properties @classmethod def parser(cls, buf, offset): tbl = cls() (tbl.length, tbl.table_id, tbl.command, tbl.features, name, tbl.metadata_match, tbl.metadata_write, tbl.capabilities, tbl.max_entries ) = struct.unpack_from(ofproto.OFP_TABLE_FEATURES_PACK_STR, buf, offset) tbl.name = name.rstrip(b'\0') props = [] rest = buf[offset + ofproto.OFP_TABLE_FEATURES_SIZE: offset + tbl.length] while rest: p, rest = OFPTableFeatureProp.parse(rest) props.append(p) tbl.properties = props return tbl def serialize(self): # fixup bin_props = bytearray() for p in self.properties: bin_props += p.serialize() self.length = ofproto.OFP_TABLE_FEATURES_SIZE + len(bin_props) buf = bytearray() msg_pack_into(ofproto.OFP_TABLE_FEATURES_PACK_STR, buf, 0, self.length, self.table_id, self.command, self.features, self.name, self.metadata_match, self.metadata_write, self.capabilities, self.max_entries) return buf + bin_props class OFPTableFeatureProp(OFPPropBase): _TYPES = {} class OFPInstructionId(StringifyMixin): _PACK_STR = '!HH' # type, len def __init__(self, type_, len_=None): self.type = type_ self.len = len_ # XXX experimenter @classmethod def parse(cls, buf): (type_, len_,) = struct.unpack_from(cls._PACK_STR, bytes(buf), 0) rest = buf[len_:] return cls(type_=type_, len_=len_), rest def serialize(self): # fixup self.len = struct.calcsize(self._PACK_STR) buf = bytearray() msg_pack_into(self._PACK_STR, buf, 0, self.type, self.len) return buf @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_INSTRUCTIONS) @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_INSTRUCTIONS_MISS) class OFPTableFeaturePropInstructions(OFPTableFeatureProp): def __init__(self, type_=None, length=None, instruction_ids=None): instruction_ids = instruction_ids if instruction_ids else [] super(OFPTableFeaturePropInstructions, self).__init__(type_, length) self.instruction_ids = instruction_ids @classmethod def parser(cls, buf): rest = cls.get_rest(buf) ids = [] while rest: i, rest = OFPInstructionId.parse(rest) ids.append(i) return cls(instruction_ids=ids) def serialize_body(self): bin_ids = bytearray() for i in self.instruction_ids: bin_ids += i.serialize() return bin_ids # Implementation note: While OpenFlow 1.3.2 shares the same ofp_action_header # for flow_mod and table_features, we have separate classes. We named this # class to match with OpenFlow 1.4's name. (ofp_action_id) class OFPActionId(StringifyMixin): _PACK_STR = '!HH' # type, len def __init__(self, type_, len_=None): self.type = type_ self.len = len_ # XXX experimenter @classmethod def parse(cls, buf): (type_, len_,) = struct.unpack_from(cls._PACK_STR, bytes(buf), 0) rest = buf[len_:] return cls(type_=type_, len_=len_), rest def serialize(self): # fixup self.len = struct.calcsize(self._PACK_STR) buf = bytearray() msg_pack_into(self._PACK_STR, buf, 0, self.type, self.len) return buf @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_WRITE_ACTIONS) @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_WRITE_ACTIONS_MISS) @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_APPLY_ACTIONS) @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_APPLY_ACTIONS_MISS) class OFPTableFeaturePropActions(OFPTableFeatureProp): def __init__(self, type_=None, length=None, action_ids=None): action_ids = action_ids if action_ids else [] super(OFPTableFeaturePropActions, self).__init__(type_, length) self.action_ids = action_ids @classmethod def parser(cls, buf): rest = cls.get_rest(buf) ids = [] while rest: i, rest = OFPActionId.parse(rest) ids.append(i) return cls(action_ids=ids) def serialize_body(self): bin_ids = bytearray() for i in self.action_ids: bin_ids += i.serialize() return bin_ids @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_NEXT_TABLES) @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_NEXT_TABLES_MISS) @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_TABLE_SYNC_FROM) class OFPTableFeaturePropNextTables(OFPTableFeatureProp): _TABLE_ID_PACK_STR = '!B' def __init__(self, type_=None, length=None, table_ids=None): table_ids = table_ids if table_ids else [] super(OFPTableFeaturePropNextTables, self).__init__(type_, length) self.table_ids = table_ids @classmethod def parser(cls, buf): rest = cls.get_rest(buf) ids = [] while rest: (i,) = struct.unpack_from(cls._TABLE_ID_PACK_STR, bytes(rest), 0) rest = rest[struct.calcsize(cls._TABLE_ID_PACK_STR):] ids.append(i) return cls(table_ids=ids) def serialize_body(self): bin_ids = bytearray() for i in self.table_ids: bin_id = bytearray() msg_pack_into(self._TABLE_ID_PACK_STR, bin_id, 0, i) bin_ids += bin_id return bin_ids # Implementation note: OFPOxmId is specific to this implementation. # It does not have a corresponding structure in the specification. # (the specification uses plain uint32_t for non-experimenter OXMs # and uint64_t for experimenter OXMs.) # # i have taken a look at some of software switch implementations # but they all look broken or incomplete. according to the spec, # oxm_hasmask should be 1 if a switch supports masking for the type. # the right value for oxm_length is not clear from the spec. # update: OpenFlow 1.3.3 "clarified" that oxm_length here is the payload # length. it's still unclear if it should be doubled for hasmask or not, # though. # ofsoftswitch13 # oxm_hasmask always 0 # oxm_length same as ofp_match etc (as without mask) # linc/of_protocol # oxm_hasmask always 0 # oxm_length always 0 # ovs: # seems in flux as of writing this [20141003] # updtate: OVS checks the oxm_length strictly which contained in # the OFPAT_COPY_FIELD action when using OpenFlow 1.5, so here composes the # payload length as the oxm_length (if has mask, it will be doubled, still # unclear though). class OFPOxmId(StringifyMixin): _PACK_STR = '!I' # oxm header _EXPERIMENTER_ID_PACK_STR = '!I' _TYPE = { 'ascii': [ 'type', ], } def __init__(self, type_, hasmask=False, length=None): self.type = type_ self.hasmask = hasmask self.length = length @classmethod def parse(cls, buf): (oxm,) = struct.unpack_from(cls._PACK_STR, bytes(buf), 0) # oxm (32 bit) == class (16) | field (7) | hasmask (1) | length (8) # in case of experimenter OXMs, another 32 bit value # (experimenter id) follows. (type_, _v) = ofproto.oxm_to_user(oxm >> (1 + 8), None, None) rest = buf[struct.calcsize(cls._PACK_STR):] hasmask = ofproto.oxm_tlv_header_extract_hasmask(oxm) length = oxm & 0xff # XXX see the comment on OFPOxmId class_ = oxm >> (7 + 1 + 8) if class_ == ofproto.OFPXMC_EXPERIMENTER: (exp_id,) = struct.unpack_from(cls._EXPERIMENTER_ID_PACK_STR, bytes(rest), 0) rest = rest[struct.calcsize(cls._EXPERIMENTER_ID_PACK_STR):] subcls = OFPExperimenterOxmId return subcls(type_=type_, exp_id=exp_id, hasmask=hasmask, length=length), rest else: return cls(type_=type_, hasmask=hasmask, length=length), rest def serialize(self): n, t = ofproto.oxm_get_field_info_by_name(self.type) if not self.length: # XXX see the comment on OFPOxmId self.length = t.size * 2 if self.hasmask else t.size oxm = (n << (1 + 8)) | (self.hasmask << 8) | self.length buf = bytearray() msg_pack_into(self._PACK_STR, buf, 0, oxm) assert n >> 7 != ofproto.OFPXMC_EXPERIMENTER return buf class OFPExperimenterOxmId(OFPOxmId): def __init__(self, type_, exp_id, hasmask=False, length=None): super(OFPExperimenterOxmId, self).__init__(type_=type_, hasmask=hasmask, length=length) self.exp_id = exp_id def serialize(self): buf = super(OFPExperimenterOxmId, self).serialize() msg_pack_into(self._EXPERIMENTER_ID_PACK_STR, buf, struct.calcsize(self._PACK_STR), self.exp_id) @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_MATCH) @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_WILDCARDS) @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_WRITE_SETFIELD) @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_WRITE_SETFIELD_MISS) @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_APPLY_SETFIELD) @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_APPLY_SETFIELD_MISS) @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_WRITE_COPYFIELD) @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_WRITE_COPYFIELD_MISS) @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_APPLY_COPYFIELD) @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_APPLY_COPYFIELD_MISS) class OFPTableFeaturePropOxm(OFPTableFeatureProp): def __init__(self, type_=None, length=None, oxm_ids=None): oxm_ids = oxm_ids if oxm_ids else [] super(OFPTableFeaturePropOxm, self).__init__(type_, length) self.oxm_ids = oxm_ids @classmethod def parser(cls, buf): rest = cls.get_rest(buf) ids = [] while rest: i, rest = OFPOxmId.parse(rest) ids.append(i) return cls(oxm_ids=ids) def serialize_body(self): bin_ids = bytearray() for i in self.oxm_ids: bin_ids += i.serialize() return bin_ids @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_PACKET_TYPES) class OFPTableFeaturePropOxmValues(OFPTableFeatureProp): def __init__(self, type_=None, length=None, _ordered_values=None, **kwargs): super(OFPTableFeaturePropOxmValues, self).__init__(type_, length) if _ordered_values is not None: assert not kwargs self.oxm_values = _ordered_values else: kwargs = dict(ofproto.oxm_normalize_user(k, v) for (k, v) in kwargs.items()) values = [ofproto.oxm_from_user(k, v) for (k, v) in kwargs.items()] # assumption: sorting by OXM type values makes fields # meet ordering requirements (eg. eth_type before ipv4_src) values.sort( key=lambda x: x[0][0] if isinstance(x[0], tuple) else x[0]) self.oxm_values = [ofproto.oxm_to_user(n, v, m) for (n, v, m) in values] @classmethod def parser(cls, buf): rest = cls.get_rest(buf) values = [] while rest: n, value, mask, field_len = ofproto.oxm_parse(rest, 0) k, uv = ofproto.oxm_to_user(n, value, mask) values.append((k, uv)) rest = rest[field_len:] return cls(_ordered_values=values) def serialize_body(self): values = [ofproto.oxm_from_user(k, uv) for (k, uv) in self.oxm_values] offset = 0 buf = bytearray() for (n, value, mask) in values: offset += ofproto.oxm_serialize(n, value, mask, buf, offset) return buf def __getitem__(self, key): return dict(self.oxm_values)[key] def __contains__(self, key): return key in dict(self.oxm_values) def iteritems(self): return iter(dict(self.oxm_values).items()) def items(self): return self.oxm_values def get(self, key, default=None): return dict(self.oxm_values).get(key, default) def stringify_attrs(self): yield "oxm_values", dict(self.oxm_values) def to_jsondict(self): """ Returns a dict expressing the OXM values. """ body = {"oxm_values": [ofproto.oxm_to_jsondict(k, uv) for k, uv in self.oxm_values], "length": self.length, "type": self.type} return {self.__class__.__name__: body} @classmethod def from_jsondict(cls, dict_): """ Returns an object which is generated from a dict. Exception raises: KeyError -- Unknown OXM value is defined in dict """ type_ = dict_['type'] values = [ofproto.oxm_from_jsondict(f) for f in dict_['oxm_values']] return cls(type_=type_, _ordered_values=values) @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_EXPERIMENTER) @OFPTableFeatureProp.register_type(ofproto.OFPTFPT_EXPERIMENTER_MISS) class OFPTableFeaturePropExperimenter(OFPPropCommonExperimenter4ByteData): pass @_set_stats_type(ofproto.OFPMP_TABLE_FEATURES, OFPTableFeaturesStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPTableFeaturesStatsRequest(OFPMultipartRequest): """ Table features statistics request message The controller uses this message to query table features. ================ ====================================================== Attribute Description ================ ====================================================== body List of ``OFPTableFeaturesStats`` instances. The default is []. ================ ====================================================== """ def __init__(self, datapath, flags=0, body=None, type_=None): body = body if body else [] super(OFPTableFeaturesStatsRequest, self).__init__(datapath, flags) self.body = body def _serialize_stats_body(self): bin_body = bytearray() for p in self.body: bin_body += p.serialize() self.buf += bin_body @OFPMultipartReply.register_stats_type() @_set_stats_type(ofproto.OFPMP_TABLE_FEATURES, OFPTableFeaturesStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPTableFeaturesStatsReply(OFPMultipartReply): """ Table features statistics reply message The switch responds with this message to a table features statistics request. ================ ====================================================== Attribute Description ================ ====================================================== body List of ``OFPTableFeaturesStats`` instance ================ ====================================================== """ def __init__(self, datapath, type_=None, **kwargs): super(OFPTableFeaturesStatsReply, self).__init__(datapath, **kwargs) @_set_stats_type(ofproto.OFPMP_PORT_DESC, OFPPort) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPPortDescStatsRequest(OFPMultipartRequest): """ Port description request message The controller uses this message to query description of one or all the ports. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or ``OFPMPF_REQ_MORE`` port_no Port number to read (OFPP_ANY to all ports) ================ ====================================================== Example:: def send_port_desc_stats_request(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPPortDescStatsRequest(datapath, 0, ofp.OFPP_ANY) datapath.send_msg(req) """ def __init__(self, datapath, flags=0, port_no=ofproto.OFPP_ANY, type_=None): super(OFPPortDescStatsRequest, self).__init__(datapath, flags) self.port_no = port_no def _serialize_stats_body(self): msg_pack_into(ofproto.OFP_PORT_MULTIPART_REQUEST_PACK_STR, self.buf, ofproto.OFP_MULTIPART_REQUEST_SIZE, self.port_no) @OFPMultipartReply.register_stats_type() @_set_stats_type(ofproto.OFPMP_PORT_DESC, OFPPort) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPPortDescStatsReply(OFPMultipartReply): """ Port description reply message The switch responds with this message to a port description request. ================ ====================================================== Attribute Description ================ ====================================================== body List of ``OFPPort`` instance ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPPortDescStatsReply, MAIN_DISPATCHER) def port_desc_stats_reply_handler(self, ev): ports = [] for p in ev.msg.body: ports.append('port_no=%d hw_addr=%s name=%s config=0x%08x ' 'state=0x%08x properties=%s' % (p.port_no, p.hw_addr, p.name, p.config, p.state, repr(p.properties))) self.logger.debug('OFPPortDescStatsReply received: %s', ports) """ def __init__(self, datapath, type_=None, **kwargs): super(OFPPortDescStatsReply, self).__init__(datapath, **kwargs) @_set_stats_type(ofproto.OFPMP_TABLE_DESC, OFPTableDesc) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPTableDescStatsRequest(OFPMultipartRequest): """ Table description request message The controller uses this message to query description of all the tables. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or ``OFPMPF_REQ_MORE`` ================ ====================================================== Example:: def send_table_desc_stats_request(self, datapath): ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPTableDescStatsRequest(datapath, 0) datapath.send_msg(req) """ def __init__(self, datapath, flags=0, type_=None): super(OFPTableDescStatsRequest, self).__init__(datapath, flags) @OFPMultipartReply.register_stats_type() @_set_stats_type(ofproto.OFPMP_TABLE_DESC, OFPTableDesc) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPTableDescStatsReply(OFPMultipartReply): """ Table description reply message The switch responds with this message to a table description request. ================ ====================================================== Attribute Description ================ ====================================================== body List of ``OFPTableDesc`` instance ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPTableDescStatsReply, MAIN_DISPATCHER) def table_desc_stats_reply_handler(self, ev): tables = [] for p in ev.msg.body: tables.append('table_id=%d config=0x%08x properties=%s' % (p.table_id, p.config, repr(p.properties))) self.logger.debug('OFPTableDescStatsReply received: %s', tables) """ def __init__(self, datapath, type_=None, **kwargs): super(OFPTableDescStatsReply, self).__init__(datapath, **kwargs) @_set_stats_type(ofproto.OFPMP_QUEUE_DESC, OFPQueueDesc) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPQueueDescStatsRequest(OFPMultipartRequest): """ Queue description request message The controller uses this message to query description of all the queues. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or ``OFPMPF_REQ_MORE`` port_no Port number to read (OFPP_ANY for all ports) queue_id ID of queue to read (OFPQ_ALL for all queues) ================ ====================================================== Example:: def send_queue_desc_stats_request(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPQueueDescStatsRequest(datapath, 0, ofp.OFPP_ANY, ofp.OFPQ_ALL) datapath.send_msg(req) """ def __init__(self, datapath, flags=0, port_no=ofproto.OFPP_ANY, queue_id=ofproto.OFPQ_ALL, type_=None): super(OFPQueueDescStatsRequest, self).__init__(datapath, flags) self.port_no = port_no self.queue_id = queue_id def _serialize_stats_body(self): msg_pack_into(ofproto.OFP_QUEUE_MULTIPART_REQUEST_PACK_STR, self.buf, ofproto.OFP_MULTIPART_REQUEST_SIZE, self.port_no, self.queue_id) @OFPMultipartReply.register_stats_type() @_set_stats_type(ofproto.OFPMP_QUEUE_DESC, OFPQueueDesc) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPQueueDescStatsReply(OFPMultipartReply): """ Queue description reply message The switch responds with this message to a queue description request. ================ ====================================================== Attribute Description ================ ====================================================== body List of ``OFPQueueDesc`` instance ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPQueueDescStatsReply, MAIN_DISPATCHER) def queue_desc_stats_reply_handler(self, ev): queues = [] for q in ev.msg.body: queues.append('port_no=%d queue_id=0x%08x properties=%s' % (q.port_no, q.queue_id, repr(q.properties))) self.logger.debug('OFPQueueDescStatsReply received: %s', queues) """ def __init__(self, datapath, type_=None, **kwargs): super(OFPQueueDescStatsReply, self).__init__(datapath, **kwargs) class OFPQueueStatsProp(OFPPropBase): _TYPES = {} @OFPQueueStatsProp.register_type(ofproto.OFPQSPT_EXPERIMENTER) class OFPQueueStatsPropExperimenter(OFPPropCommonExperimenter4ByteData): pass class OFPQueueStats(StringifyMixin): def __init__(self, length=None, port_no=None, queue_id=None, tx_bytes=None, tx_packets=None, tx_errors=None, duration_sec=None, duration_nsec=None, properties=None): super(OFPQueueStats, self).__init__() self.length = length self.port_no = port_no self.queue_id = queue_id self.tx_bytes = tx_bytes self.tx_packets = tx_packets self.tx_errors = tx_errors self.duration_sec = duration_sec self.duration_nsec = duration_nsec self.properties = properties @classmethod def parser(cls, buf, offset): (length, port_no, queue_id, tx_bytes, tx_packets, tx_errors, duration_sec, duration_nsec) = struct.unpack_from( ofproto.OFP_QUEUE_STATS_PACK_STR, buf, offset) props = [] rest = buf[offset + ofproto.OFP_QUEUE_STATS_SIZE:offset + length] while rest: p, rest = OFPQueueStatsProp.parse(rest) props.append(p) stats = cls(length, port_no, queue_id, tx_bytes, tx_packets, tx_errors, duration_sec, duration_nsec, props) return stats @_set_stats_type(ofproto.OFPMP_QUEUE_STATS, OFPQueueStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPQueueStatsRequest(OFPMultipartRequest): """ Queue statistics request message The controller uses this message to query queue statictics. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or ``OFPMPF_REQ_MORE`` port_no Port number to read queue_id ID of queue to read ================ ====================================================== Example:: def send_queue_stats_request(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPQueueStatsRequest(datapath, 0, ofp.OFPP_ANY, ofp.OFPQ_ALL) datapath.send_msg(req) """ def __init__(self, datapath, flags=0, port_no=ofproto.OFPP_ANY, queue_id=ofproto.OFPQ_ALL, type_=None): super(OFPQueueStatsRequest, self).__init__(datapath, flags) self.port_no = port_no self.queue_id = queue_id def _serialize_stats_body(self): msg_pack_into(ofproto.OFP_QUEUE_MULTIPART_REQUEST_PACK_STR, self.buf, ofproto.OFP_MULTIPART_REQUEST_SIZE, self.port_no, self.queue_id) @OFPMultipartReply.register_stats_type() @_set_stats_type(ofproto.OFPMP_QUEUE_STATS, OFPQueueStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPQueueStatsReply(OFPMultipartReply): """ Queue statistics reply message The switch responds with this message to an aggregate flow statistics request. ================ ====================================================== Attribute Description ================ ====================================================== body List of ``OFPQueueStats`` instance ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPQueueStatsReply, MAIN_DISPATCHER) def queue_stats_reply_handler(self, ev): queues = [] for stat in ev.msg.body: queues.append('port_no=%d queue_id=%d ' 'tx_bytes=%d tx_packets=%d tx_errors=%d ' 'duration_sec=%d duration_nsec=%d' 'properties=%s' % (stat.port_no, stat.queue_id, stat.tx_bytes, stat.tx_packets, stat.tx_errors, stat.duration_sec, stat.duration_nsec, repr(stat.properties))) self.logger.debug('QueueStats: %s', queues) """ def __init__(self, datapath, type_=None, **kwargs): super(OFPQueueStatsReply, self).__init__(datapath, **kwargs) class OFPBucketCounter(StringifyMixin): def __init__(self, packet_count, byte_count): super(OFPBucketCounter, self).__init__() self.packet_count = packet_count self.byte_count = byte_count @classmethod def parser(cls, buf, offset): packet_count, byte_count = struct.unpack_from( ofproto.OFP_BUCKET_COUNTER_PACK_STR, buf, offset) return cls(packet_count, byte_count) class OFPGroupStats(StringifyMixin): def __init__(self, length=None, group_id=None, ref_count=None, packet_count=None, byte_count=None, duration_sec=None, duration_nsec=None, bucket_stats=None): super(OFPGroupStats, self).__init__() self.length = length self.group_id = group_id self.ref_count = ref_count self.packet_count = packet_count self.byte_count = byte_count self.duration_sec = duration_sec self.duration_nsec = duration_nsec self.bucket_stats = bucket_stats @classmethod def parser(cls, buf, offset): group = struct.unpack_from(ofproto.OFP_GROUP_STATS_PACK_STR, buf, offset) group_stats = cls(*group) group_stats.bucket_stats = [] total_len = group_stats.length + offset offset += ofproto.OFP_GROUP_STATS_SIZE while total_len > offset: b = OFPBucketCounter.parser(buf, offset) group_stats.bucket_stats.append(b) offset += ofproto.OFP_BUCKET_COUNTER_SIZE return group_stats @_set_stats_type(ofproto.OFPMP_GROUP_STATS, OFPGroupStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPGroupStatsRequest(OFPMultipartRequest): """ Group statistics request message The controller uses this message to query statistics of one or more groups. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or ``OFPMPF_REQ_MORE`` group_id ID of group to read (OFPG_ALL to all groups) ================ ====================================================== Example:: def send_group_stats_request(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPGroupStatsRequest(datapath, 0, ofp.OFPG_ALL) datapath.send_msg(req) """ def __init__(self, datapath, flags=0, group_id=ofproto.OFPG_ALL, type_=None): super(OFPGroupStatsRequest, self).__init__(datapath, flags) self.group_id = group_id def _serialize_stats_body(self): msg_pack_into(ofproto.OFP_GROUP_MULTIPART_REQUEST_PACK_STR, self.buf, ofproto.OFP_MULTIPART_REQUEST_SIZE, self.group_id) @OFPMultipartReply.register_stats_type() @_set_stats_type(ofproto.OFPMP_GROUP_STATS, OFPGroupStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPGroupStatsReply(OFPMultipartReply): """ Group statistics reply message The switch responds with this message to a group statistics request. ================ ====================================================== Attribute Description ================ ====================================================== body List of ``OFPGroupStats`` instance ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPGroupStatsReply, MAIN_DISPATCHER) def group_stats_reply_handler(self, ev): groups = [] for stat in ev.msg.body: groups.append('length=%d group_id=%d ' 'ref_count=%d packet_count=%d byte_count=%d ' 'duration_sec=%d duration_nsec=%d' % (stat.length, stat.group_id, stat.ref_count, stat.packet_count, stat.byte_count, stat.duration_sec, stat.duration_nsec)) self.logger.debug('GroupStats: %s', groups) """ def __init__(self, datapath, type_=None, **kwargs): super(OFPGroupStatsReply, self).__init__(datapath, **kwargs) class OFPGroupDescStats(StringifyMixin): def __init__(self, type_=None, group_id=None, buckets=None, properties=None, length=None, bucket_array_len=None): buckets = buckets if buckets else [] properties = properties if properties else [] super(OFPGroupDescStats, self).__init__() self.length = length self.type = type_ self.group_id = group_id self.buckets = buckets self.properties = properties @classmethod def parser(cls, buf, offset): stats = cls() (stats.length, stats.type, stats.group_id, stats.bucket_array_len) = struct.unpack_from( ofproto.OFP_GROUP_DESC_STATS_PACK_STR, buf, offset) offset += ofproto.OFP_GROUP_DESC_STATS_SIZE bucket_buf = buf[offset:offset + stats.bucket_array_len] stats.buckets = [] while bucket_buf: bucket = OFPBucket.parser(bucket_buf, 0) stats.buckets.append(bucket) bucket_buf = bucket_buf[bucket.len:] offset += stats.bucket_array_len rest = buf[offset:offset + stats.length] while rest: p, rest = OFPGroupProp.parse(rest) stats.properties.append(p) return stats @_set_stats_type(ofproto.OFPMP_GROUP_DESC, OFPGroupDescStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPGroupDescStatsRequest(OFPMultipartRequest): """ Group description request message The controller uses this message to list the set of groups on a switch. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or ``OFPMPF_REQ_MORE`` group_id ID of group to read (OFPG_ALL to all groups) ================ ====================================================== Example:: def send_group_desc_stats_request(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPGroupDescStatsRequest(datapath, 0, ofp.OFPG_ALL) datapath.send_msg(req) """ def __init__(self, datapath, flags=0, group_id=ofproto.OFPG_ALL, type_=None): super(OFPGroupDescStatsRequest, self).__init__(datapath, flags) self.group_id = group_id def _serialize_stats_body(self): msg_pack_into(ofproto.OFP_GROUP_MULTIPART_REQUEST_PACK_STR, self.buf, ofproto.OFP_MULTIPART_REQUEST_SIZE, self.group_id) @OFPMultipartReply.register_stats_type() @_set_stats_type(ofproto.OFPMP_GROUP_DESC, OFPGroupDescStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPGroupDescStatsReply(OFPMultipartReply): """ Group description reply message The switch responds with this message to a group description request. ================ ====================================================== Attribute Description ================ ====================================================== body List of ``OFPGroupDescStats`` instance ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPGroupDescStatsReply, MAIN_DISPATCHER) def group_desc_stats_reply_handler(self, ev): descs = [] for stat in ev.msg.body: descs.append('length=%d type=%d group_id=%d ' 'buckets=%s properties=%s' % (stat.length, stat.type, stat.group_id, stat.bucket, repr(stat.properties))) self.logger.debug('GroupDescStats: %s', descs) """ def __init__(self, datapath, type_=None, **kwargs): super(OFPGroupDescStatsReply, self).__init__(datapath, **kwargs) class OFPGroupFeaturesStats(ofproto_parser.namedtuple('OFPGroupFeaturesStats', ('types', 'capabilities', 'max_groups', 'actions'))): @classmethod def parser(cls, buf, offset): group_features = struct.unpack_from( ofproto.OFP_GROUP_FEATURES_PACK_STR, buf, offset) types = group_features[0] capabilities = group_features[1] max_groups = list(group_features[2:6]) actions = list(group_features[6:10]) stats = cls(types, capabilities, max_groups, actions) stats.length = ofproto.OFP_GROUP_FEATURES_SIZE return stats @_set_stats_type(ofproto.OFPMP_GROUP_FEATURES, OFPGroupFeaturesStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPGroupFeaturesStatsRequest(OFPMultipartRequest): """ Group features request message The controller uses this message to list the capabilities of groups on a switch. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or ``OFPMPF_REQ_MORE`` ================ ====================================================== Example:: def send_group_features_stats_request(self, datapath): ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPGroupFeaturesStatsRequest(datapath, 0) datapath.send_msg(req) """ def __init__(self, datapath, flags=0, type_=None): super(OFPGroupFeaturesStatsRequest, self).__init__(datapath, flags) @OFPMultipartReply.register_stats_type(body_single_struct=True) @_set_stats_type(ofproto.OFPMP_GROUP_FEATURES, OFPGroupFeaturesStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPGroupFeaturesStatsReply(OFPMultipartReply): """ Group features reply message The switch responds with this message to a group features request. ================ ====================================================== Attribute Description ================ ====================================================== body Instance of ``OFPGroupFeaturesStats`` ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPGroupFeaturesStatsReply, MAIN_DISPATCHER) def group_features_stats_reply_handler(self, ev): body = ev.msg.body self.logger.debug('GroupFeaturesStats: types=%d ' 'capabilities=0x%08x max_groups=%s ' 'actions=%s', body.types, body.capabilities, body.max_groups, body.actions) """ def __init__(self, datapath, type_=None, **kwargs): super(OFPGroupFeaturesStatsReply, self).__init__(datapath, **kwargs) class OFPMeterBandStats(StringifyMixin): def __init__(self, packet_band_count, byte_band_count): super(OFPMeterBandStats, self).__init__() self.packet_band_count = packet_band_count self.byte_band_count = byte_band_count @classmethod def parser(cls, buf, offset): band_stats = struct.unpack_from( ofproto.OFP_METER_BAND_STATS_PACK_STR, buf, offset) return cls(*band_stats) class OFPMeterStats(StringifyMixin): def __init__(self, meter_id=None, ref_count=None, packet_in_count=None, byte_in_count=None, duration_sec=None, duration_nsec=None, band_stats=None, len_=None): super(OFPMeterStats, self).__init__() self.meter_id = meter_id self.len = 0 self.ref_count = ref_count self.packet_in_count = packet_in_count self.byte_in_count = byte_in_count self.duration_sec = duration_sec self.duration_nsec = duration_nsec self.band_stats = band_stats @classmethod def parser(cls, buf, offset): meter_stats = cls() (meter_stats.meter_id, meter_stats.len, meter_stats.ref_count, meter_stats.packet_in_count, meter_stats.byte_in_count, meter_stats.duration_sec, meter_stats.duration_nsec) = struct.unpack_from( ofproto.OFP_METER_STATS_PACK_STR, buf, offset) offset += ofproto.OFP_METER_STATS_SIZE meter_stats.band_stats = [] length = ofproto.OFP_METER_STATS_SIZE while length < meter_stats.len: band_stats = OFPMeterBandStats.parser(buf, offset) meter_stats.band_stats.append(band_stats) offset += ofproto.OFP_METER_BAND_STATS_SIZE length += ofproto.OFP_METER_BAND_STATS_SIZE return meter_stats @_set_stats_type(ofproto.OFPMP_METER_STATS, OFPMeterStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPMeterStatsRequest(OFPMultipartRequest): """ Meter statistics request message The controller uses this message to query statistics for one or more meters. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or ``OFPMPF_REQ_MORE`` meter_id ID of meter to read (OFPM_ALL to all meters) ================ ====================================================== Example:: def send_meter_stats_request(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPMeterStatsRequest(datapath, 0, ofp.OFPM_ALL) datapath.send_msg(req) """ def __init__(self, datapath, flags=0, meter_id=ofproto.OFPM_ALL, type_=None): super(OFPMeterStatsRequest, self).__init__(datapath, flags) self.meter_id = meter_id def _serialize_stats_body(self): msg_pack_into(ofproto.OFP_METER_MULTIPART_REQUEST_PACK_STR, self.buf, ofproto.OFP_MULTIPART_REQUEST_SIZE, self.meter_id) @OFPMultipartReply.register_stats_type() @_set_stats_type(ofproto.OFPMP_METER_STATS, OFPMeterStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPMeterStatsReply(OFPMultipartReply): """ Meter statistics reply message The switch responds with this message to a meter statistics request. ================ ====================================================== Attribute Description ================ ====================================================== body List of ``OFPMeterStats`` instance ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPMeterStatsReply, MAIN_DISPATCHER) def meter_stats_reply_handler(self, ev): meters = [] for stat in ev.msg.body: meters.append('meter_id=0x%08x len=%d ref_count=%d ' 'packet_in_count=%d byte_in_count=%d ' 'duration_sec=%d duration_nsec=%d ' 'band_stats=%s' % (stat.meter_id, stat.len, stat.ref_count, stat.packet_in_count, stat.byte_in_count, stat.duration_sec, stat.duration_nsec, stat.band_stats)) self.logger.debug('MeterStats: %s', meters) """ def __init__(self, datapath, type_=None, **kwargs): super(OFPMeterStatsReply, self).__init__(datapath, **kwargs) class OFPMeterBand(StringifyMixin): def __init__(self, type_, len_): super(OFPMeterBand, self).__init__() self.type = type_ self.len = len_ class OFPMeterBandHeader(OFPMeterBand): _METER_BAND = {} @staticmethod def register_meter_band_type(type_, len_): def _register_meter_band_type(cls): OFPMeterBandHeader._METER_BAND[type_] = cls cls.cls_meter_band_type = type_ cls.cls_meter_band_len = len_ return cls return _register_meter_band_type def __init__(self): cls = self.__class__ super(OFPMeterBandHeader, self).__init__(cls.cls_meter_band_type, cls.cls_meter_band_len) @classmethod def parser(cls, buf, offset): type_, len_, _rate, _burst_size = struct.unpack_from( ofproto.OFP_METER_BAND_HEADER_PACK_STR, buf, offset) cls_ = cls._METER_BAND[type_] assert cls_.cls_meter_band_len == len_ return cls_.parser(buf, offset) @OFPMeterBandHeader.register_meter_band_type( ofproto.OFPMBT_DROP, ofproto.OFP_METER_BAND_DROP_SIZE) class OFPMeterBandDrop(OFPMeterBandHeader): def __init__(self, rate=0, burst_size=0, type_=None, len_=None): super(OFPMeterBandDrop, self).__init__() self.rate = rate self.burst_size = burst_size def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_METER_BAND_DROP_PACK_STR, buf, offset, self.type, self.len, self.rate, self.burst_size) @classmethod def parser(cls, buf, offset): type_, len_, rate, burst_size = struct.unpack_from( ofproto.OFP_METER_BAND_DROP_PACK_STR, buf, offset) assert cls.cls_meter_band_type == type_ assert cls.cls_meter_band_len == len_ return cls(rate, burst_size) @OFPMeterBandHeader.register_meter_band_type( ofproto.OFPMBT_DSCP_REMARK, ofproto.OFP_METER_BAND_DSCP_REMARK_SIZE) class OFPMeterBandDscpRemark(OFPMeterBandHeader): def __init__(self, rate=0, burst_size=0, prec_level=0, type_=None, len_=None): super(OFPMeterBandDscpRemark, self).__init__() self.rate = rate self.burst_size = burst_size self.prec_level = prec_level def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_METER_BAND_DSCP_REMARK_PACK_STR, buf, offset, self.type, self.len, self.rate, self.burst_size, self.prec_level) @classmethod def parser(cls, buf, offset): type_, len_, rate, burst_size, prec_level = struct.unpack_from( ofproto.OFP_METER_BAND_DSCP_REMARK_PACK_STR, buf, offset) assert cls.cls_meter_band_type == type_ assert cls.cls_meter_band_len == len_ return cls(rate, burst_size, prec_level) @OFPMeterBandHeader.register_meter_band_type( ofproto.OFPMBT_EXPERIMENTER, ofproto.OFP_METER_BAND_EXPERIMENTER_SIZE) class OFPMeterBandExperimenter(OFPMeterBandHeader): def __init__(self, rate=0, burst_size=0, experimenter=None, type_=None, len_=None): super(OFPMeterBandExperimenter, self).__init__() self.rate = rate self.burst_size = burst_size self.experimenter = experimenter def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_METER_BAND_EXPERIMENTER_PACK_STR, buf, offset, self.type, self.len, self.rate, self.burst_size, self.experimenter) @classmethod def parser(cls, buf, offset): type_, len_, rate, burst_size, experimenter = struct.unpack_from( ofproto.OFP_METER_BAND_EXPERIMENTER_PACK_STR, buf, offset) assert cls.cls_meter_band_type == type_ assert cls.cls_meter_band_len == len_ return cls(rate, burst_size, experimenter) class OFPMeterDescStats(StringifyMixin): def __init__(self, flags=None, meter_id=None, bands=None, length=None): super(OFPMeterDescStats, self).__init__() self.length = None self.flags = flags self.meter_id = meter_id self.bands = bands @classmethod def parser(cls, buf, offset): meter_config = cls() (meter_config.length, meter_config.flags, meter_config.meter_id) = struct.unpack_from( ofproto.OFP_METER_DESC_PACK_STR, buf, offset) offset += ofproto.OFP_METER_DESC_SIZE meter_config.bands = [] length = ofproto.OFP_METER_DESC_SIZE while length < meter_config.length: band = OFPMeterBandHeader.parser(buf, offset) meter_config.bands.append(band) offset += band.len length += band.len return meter_config @_set_stats_type(ofproto.OFPMP_METER_DESC, OFPMeterDescStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPMeterDescStatsRequest(OFPMultipartRequest): """ Meter description statistics request message The controller uses this message to query configuration for one or more meters. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or ``OFPMPF_REQ_MORE`` meter_id ID of meter to read (OFPM_ALL to all meters) ================ ====================================================== Example:: def send_meter_desc_stats_request(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPMeterDescStatsRequest(datapath, 0, ofp.OFPM_ALL) datapath.send_msg(req) """ def __init__(self, datapath, flags=0, meter_id=ofproto.OFPM_ALL, type_=None): super(OFPMeterDescStatsRequest, self).__init__(datapath, flags) self.meter_id = meter_id def _serialize_stats_body(self): msg_pack_into(ofproto.OFP_METER_MULTIPART_REQUEST_PACK_STR, self.buf, ofproto.OFP_MULTIPART_REQUEST_SIZE, self.meter_id) @OFPMultipartReply.register_stats_type() @_set_stats_type(ofproto.OFPMP_METER_DESC, OFPMeterDescStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPMeterDescStatsReply(OFPMultipartReply): """ Meter description statistics reply message The switch responds with this message to a meter description statistics request. ================ ====================================================== Attribute Description ================ ====================================================== body List of ``OFPMeterDescStats`` instance ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPMeterDescStatsReply, MAIN_DISPATCHER) def meter_desc_stats_reply_handler(self, ev): configs = [] for stat in ev.msg.body: configs.append('length=%d flags=0x%04x meter_id=0x%08x ' 'bands=%s' % (stat.length, stat.flags, stat.meter_id, stat.bands)) self.logger.debug('MeterDescStats: %s', configs) """ def __init__(self, datapath, type_=None, **kwargs): super(OFPMeterDescStatsReply, self).__init__(datapath, **kwargs) class OFPMeterFeaturesStats(ofproto_parser.namedtuple('OFPMeterFeaturesStats', ('max_meter', 'band_types', 'capabilities', 'max_bands', 'max_color', 'features'))): @classmethod def parser(cls, buf, offset): meter_features = struct.unpack_from( ofproto.OFP_METER_FEATURES_PACK_STR, buf, offset) stats = cls(*meter_features) stats.length = ofproto.OFP_METER_FEATURES_SIZE return stats @_set_stats_type(ofproto.OFPMP_METER_FEATURES, OFPMeterFeaturesStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPMeterFeaturesStatsRequest(OFPMultipartRequest): """ Meter features statistics request message The controller uses this message to query the set of features of the metering subsystem. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or ``OFPMPF_REQ_MORE`` ================ ====================================================== Example:: def send_meter_features_stats_request(self, datapath): ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPMeterFeaturesStatsRequest(datapath, 0) datapath.send_msg(req) """ def __init__(self, datapath, flags=0, type_=None): super(OFPMeterFeaturesStatsRequest, self).__init__(datapath, flags) @OFPMultipartReply.register_stats_type() @_set_stats_type(ofproto.OFPMP_METER_FEATURES, OFPMeterFeaturesStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPMeterFeaturesStatsReply(OFPMultipartReply): """ Meter features statistics reply message The switch responds with this message to a meter features statistics request. ================ ====================================================== Attribute Description ================ ====================================================== body List of ``OFPMeterFeaturesStats`` instance ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPMeterFeaturesStatsReply, MAIN_DISPATCHER) def meter_features_stats_reply_handler(self, ev): features = [] for stat in ev.msg.body: features.append('max_meter=%d band_types=0x%08x ' 'capabilities=0x%08x max_bands=%d ' 'max_color=%d' % (stat.max_meter, stat.band_types, stat.capabilities, stat.max_bands, stat.max_color)) self.logger.debug('MeterFeaturesStats: %s', features) """ def __init__(self, datapath, type_=None, **kwargs): super(OFPMeterFeaturesStatsReply, self).__init__(datapath, **kwargs) class OFPFlowUpdate(StringifyMixin): def __init__(self, length, event): super(OFPFlowUpdate, self).__init__() self.length = length self.event = event class OFPFlowUpdateHeader(OFPFlowUpdate): _EVENT = {} @staticmethod def register_flow_update_event(event, length): def _register_flow_update_event(cls): OFPFlowUpdateHeader._EVENT[event] = cls cls.cls_flow_update_event = event cls.cls_flow_update_length = length return cls return _register_flow_update_event def __init__(self, length=None, event=None): cls = self.__class__ super(OFPFlowUpdateHeader, self).__init__(length, cls.cls_flow_update_event) self.length = length @classmethod def parser(cls, buf, offset): length, event = struct.unpack_from( ofproto.OFP_FLOW_UPDATE_HEADER_PACK_STR, buf, offset) cls_ = cls._EVENT[event] return cls_.parser(buf, offset) @OFPFlowUpdateHeader.register_flow_update_event( ofproto.OFPFME_INITIAL, ofproto.OFP_FLOW_UPDATE_FULL_SIZE) @OFPFlowUpdateHeader.register_flow_update_event( ofproto.OFPFME_ADDED, ofproto.OFP_FLOW_UPDATE_FULL_SIZE) @OFPFlowUpdateHeader.register_flow_update_event( ofproto.OFPFME_REMOVED, ofproto.OFP_FLOW_UPDATE_FULL_SIZE) @OFPFlowUpdateHeader.register_flow_update_event( ofproto.OFPFME_MODIFIED, ofproto.OFP_FLOW_UPDATE_FULL_SIZE) class OFPFlowUpdateFull(OFPFlowUpdateHeader): def __init__(self, length=None, event=None, table_id=None, reason=None, idle_timeout=None, hard_timeout=None, priority=None, cookie=None, match=None, instructions=None): instructions = instructions if instructions else [] super(OFPFlowUpdateFull, self).__init__(length, event) self.table_id = table_id self.reason = reason self.idle_timeout = idle_timeout self.hard_timeout = hard_timeout self.priority = priority self.cookie = cookie self.match = match assert (event != ofproto.OFPFME_REMOVED or len(instructions) == 0) for i in instructions: assert isinstance(i, OFPInstruction) self.instructions = instructions @classmethod def parser(cls, buf, offset): (length, event, table_id, reason, idle_timeout, hard_timeout, priority, cookie) = struct.unpack_from(ofproto.OFP_FLOW_UPDATE_FULL_0_PACK_STR, buf, offset) offset += ofproto.OFP_FLOW_UPDATE_FULL_0_SIZE assert cls.cls_flow_update_length <= length assert cls.cls_flow_update_event == event match = OFPMatch.parser(buf, offset) match_length = utils.round_up(match.length, 8) offset += match_length inst_length = (length - ofproto.OFP_FLOW_UPDATE_FULL_0_SIZE - match_length) instructions = [] while inst_length > 0: inst = OFPInstruction.parser(buf, offset) instructions.append(inst) offset += inst.len inst_length -= inst.len return cls(length, event, table_id, reason, idle_timeout, hard_timeout, priority, cookie, match, instructions) @OFPFlowUpdateHeader.register_flow_update_event( ofproto.OFPFME_ABBREV, ofproto.OFP_FLOW_UPDATE_ABBREV_SIZE) class OFPFlowUpdateAbbrev(OFPFlowUpdateHeader): def __init__(self, length=None, event=None, xid=None): super(OFPFlowUpdateAbbrev, self).__init__(length, event) self.xid = xid @classmethod def parser(cls, buf, offset): length, event, xid = struct.unpack_from( ofproto.OFP_FLOW_UPDATE_ABBREV_PACK_STR, buf, offset) assert cls.cls_flow_update_length == length assert cls.cls_flow_update_event == event return cls(length, event, xid) @OFPFlowUpdateHeader.register_flow_update_event( ofproto.OFPFME_PAUSED, ofproto.OFP_FLOW_UPDATE_PAUSED_SIZE) @OFPFlowUpdateHeader.register_flow_update_event( ofproto.OFPFME_RESUMED, ofproto.OFP_FLOW_UPDATE_PAUSED_SIZE) class OFPFlowUpdatePaused(OFPFlowUpdateHeader): @classmethod def parser(cls, buf, offset): length, event = struct.unpack_from( ofproto.OFP_FLOW_UPDATE_PAUSED_PACK_STR, buf, offset) assert cls.cls_flow_update_length == length assert cls.cls_flow_update_event == event return cls(length, event) class OFPFlowMonitorRequestBase(OFPMultipartRequest): def __init__(self, datapath, flags, monitor_id, out_port, out_group, monitor_flags, table_id, command, match): super(OFPFlowMonitorRequestBase, self).__init__(datapath, flags) self.monitor_id = monitor_id self.out_port = out_port self.out_group = out_group self.monitor_flags = monitor_flags self.table_id = table_id self.command = command self.match = match def _serialize_stats_body(self): offset = ofproto.OFP_MULTIPART_REQUEST_SIZE msg_pack_into(ofproto.OFP_FLOW_MONITOR_REQUEST_0_PACK_STR, self.buf, offset, self.monitor_id, self.out_port, self.out_group, self.monitor_flags, self.table_id, self.command) offset += ofproto.OFP_FLOW_MONITOR_REQUEST_0_SIZE self.match.serialize(self.buf, offset) @_set_stats_type(ofproto.OFPMP_FLOW_MONITOR, OFPFlowUpdateHeader) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPFlowMonitorRequest(OFPFlowMonitorRequestBase): """ Flow monitor request message The controller uses this message to query flow monitors. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or ``OFPMPF_REQ_MORE`` monitor_id Controller-assigned ID for this monitor out_port Require matching entries to include this as an output port out_group Require matching entries to include this as an output group monitor_flags Bitmap of the following flags. | OFPFMF_INITIAL | OFPFMF_ADD | OFPFMF_REMOVED | OFPFMF_MODIFY | OFPFMF_INSTRUCTIONS | OFPFMF_NO_ABBREV | OFPFMF_ONLY_OWN table_id ID of table to monitor command One of the following values. | OFPFMC_ADD | OFPFMC_MODIFY | OFPFMC_DELETE match Instance of ``OFPMatch`` ================ ====================================================== Example:: def send_flow_monitor_request(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser monitor_flags = [ofp.OFPFMF_INITIAL, ofp.OFPFMF_ONLY_OWN] match = ofp_parser.OFPMatch(in_port=1) req = ofp_parser.OFPFlowMonitorRequest(datapath, 0, 10000, ofp.OFPP_ANY, ofp.OFPG_ANY, monitor_flags, ofp.OFPTT_ALL, ofp.OFPFMC_ADD, match) datapath.send_msg(req) """ def __init__(self, datapath, flags=0, monitor_id=0, out_port=ofproto.OFPP_ANY, out_group=ofproto.OFPG_ANY, monitor_flags=0, table_id=ofproto.OFPTT_ALL, command=ofproto.OFPFMC_ADD, match=None, type_=None): if match is None: match = OFPMatch() super(OFPFlowMonitorRequest, self).__init__(datapath, flags, monitor_id, out_port, out_group, monitor_flags, table_id, command, match) @OFPMultipartReply.register_stats_type() @_set_stats_type(ofproto.OFPMP_FLOW_MONITOR, OFPFlowUpdateHeader) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPFlowMonitorReply(OFPMultipartReply): """ Flow monitor reply message The switch responds with this message to a flow monitor request. ================ ====================================================== Attribute Description ================ ====================================================== body List of list of the following class instance. | OFPFlowMonitorFull | OFPFlowMonitorAbbrev | OFPFlowMonitorPaused ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPFlowMonitorReply, MAIN_DISPATCHER) def flow_monitor_reply_handler(self, ev): msg = ev.msg dp = msg.datapath ofp = dp.ofproto flow_updates = [] for update in msg.body: update_str = 'length=%d event=%d' % (update.length, update.event) if (update.event == ofp.OFPFME_INITIAL or update.event == ofp.OFPFME_ADDED or update.event == ofp.OFPFME_REMOVED or update.event == ofp.OFPFME_MODIFIED): update_str += 'table_id=%d reason=%d idle_timeout=%d ' 'hard_timeout=%d priority=%d cookie=%d ' 'match=%d instructions=%s' % (update.table_id, update.reason, update.idle_timeout, update.hard_timeout, update.priority, update.cookie, update.match, update.instructions) elif update.event == ofp.OFPFME_ABBREV: update_str += 'xid=%d' % (update.xid) flow_updates.append(update_str) self.logger.debug('FlowUpdates: %s', flow_updates) """ def __init__(self, datapath, type_=None, **kwargs): super(OFPFlowMonitorReply, self).__init__(datapath, **kwargs) class OFPBundleFeaturesProp(OFPPropBase): _TYPES = {} @OFPBundleFeaturesProp.register_type(ofproto.OFPTMPBF_TIME_CAPABILITY) class OFPBundleFeaturesPropTime(OFPBundleFeaturesProp): def __init__(self, type_=None, length=None, sched_accuracy=None, sched_max_future=None, sched_max_past=None, timestamp=None): super(OFPBundleFeaturesPropTime, self).__init__(type_, length) self.sched_accuracy = sched_accuracy self.sched_max_future = sched_max_future self.sched_max_past = sched_max_past self.timestamp = timestamp @classmethod def parser(cls, buf): prop = cls() (prop.type, prop.length) = struct.unpack_from( ofproto.OFP_BUNDLE_FEATURES_PROP_TIME_0_PACK_STR, buf) offset = ofproto.OFP_BUNDLE_FEATURES_PROP_TIME_0_SIZE for f in ['sched_accuracy', 'sched_max_future', 'sched_max_past', 'timestamp']: t = OFPTime.parser(buf, offset) setattr(prop, f, t) offset += ofproto.OFP_TIME_SIZE return prop def serialize(self): # fixup self.length = ofproto.OFP_BUNDLE_FEATURES_PROP_TIME_SIZE buf = bytearray() msg_pack_into(ofproto.OFP_BUNDLE_FEATURES_PROP_TIME_0_PACK_STR, buf, 0, self.type, self.length) offset = ofproto.OFP_BUNDLE_FEATURES_PROP_TIME_0_SIZE for f in [self.sched_accuracy, self.sched_max_future, self.sched_max_past, self.timestamp]: f.serialize(buf, offset) offset += ofproto.OFP_TIME_SIZE return buf @OFPBundleFeaturesProp.register_type(ofproto.OFPTMPBF_EXPERIMENTER) class OFPBundleFeaturesPropExperimenter(OFPPropCommonExperimenter4ByteData): pass class OFPBundleFeaturesStats(ofproto_parser.namedtuple( 'OFPBundleFeaturesStats', ('capabilities', 'properties'))): @classmethod def parser(cls, buf, offset): (capabilities, ) = struct.unpack_from( ofproto.OFP_BUNDLE_FEATURES_PACK_STR, buf, offset) properties = [] length = ofproto.OFP_BUNDLE_FEATURES_SIZE rest = buf[offset + length:] while rest: p, rest = OFPBundleFeaturesProp.parse(rest) properties.append(p) length += p.length bndl = cls(capabilities, properties) # Note: length field is not defined in the specification and # is specific to this implementation. bndl.length = length return bndl @_set_stats_type(ofproto.OFPMP_BUNDLE_FEATURES, OFPBundleFeaturesStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPBundleFeaturesStatsRequest(OFPMultipartRequest): """ Bundle features request message The controller uses this message to query a switch about its bundle capabilities, including whether it supports atomic bundles, ordered bundles, and scheduled bundles. ====================== ==================================================== Attribute Description ====================== ==================================================== flags Zero or ``OFPMPF_REQ_MORE`` feature_request_flags Bitmap of the following flags. | OFPBF_TIMESTAMP | OFPBF_TIME_SET_SCHED properties List of ``OFPBundleFeaturesProp`` subclass instance ====================== ==================================================== Example:: def send_bundle_features_stats_request(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPBundleFeaturesStatsRequest(datapath, 0) datapath.send_msg(req) """ def __init__(self, datapath, flags=0, feature_request_flags=0, properties=None, type_=None): properties = properties if properties else [] super(OFPBundleFeaturesStatsRequest, self).__init__(datapath, flags) self.feature_request_flags = feature_request_flags self.properties = properties def _serialize_stats_body(self): bin_props = bytearray() for p in self.properties: bin_props += p.serialize() msg_pack_into(ofproto.OFP_BUNDLE_FEATURES_REQUEST_PACK_STR, self.buf, ofproto.OFP_MULTIPART_REQUEST_SIZE, self.feature_request_flags) self.buf += bin_props @OFPMultipartReply.register_stats_type(body_single_struct=True) @_set_stats_type(ofproto.OFPMP_BUNDLE_FEATURES, OFPBundleFeaturesStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPBundleFeaturesStatsReply(OFPMultipartReply): """ Bundle features reply message The switch responds with this message to a bundle features request. ================ ====================================================== Attribute Description ================ ====================================================== body Instance of ``OFPBundleFeaturesStats`` ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPBundleFeaturesStatsReply, MAIN_DISPATCHER) def bundle_features_stats_reply_handler(self, ev): body = ev.msg.body self.logger.debug('OFPBundleFeaturesStats: capabilities=%0x%08x ' 'properties=%s', body.capabilities, repr(body.properties)) """ def __init__(self, datapath, type_=None, **kwargs): super(OFPBundleFeaturesStatsReply, self).__init__(datapath, **kwargs) class OFPExperimenterMultipart(ofproto_parser.namedtuple( 'OFPExperimenterMultipart', ('experimenter', 'exp_type', 'data'))): """ The body of OFPExperimenterStatsReply multipart messages. ================ ====================================================== Attribute Description ================ ====================================================== experimenter Experimenter ID exp_type Experimenter defined data Experimenter defined additional data ================ ====================================================== """ @classmethod def parser(cls, buf, offset): args = struct.unpack_from( ofproto.OFP_EXPERIMENTER_MULTIPART_HEADER_PACK_STR, buf, offset) args = list(args) args.append(buf[offset + ofproto.OFP_EXPERIMENTER_MULTIPART_HEADER_SIZE:]) stats = cls(*args) stats.length = ofproto.OFP_METER_FEATURES_SIZE return stats def serialize(self): buf = bytearray() msg_pack_into(ofproto.OFP_EXPERIMENTER_MULTIPART_HEADER_PACK_STR, buf, 0, self.experimenter, self.exp_type) return buf + self.data class OFPExperimenterStatsRequestBase(OFPMultipartRequest): def __init__(self, datapath, flags, experimenter, exp_type, type_=None): super(OFPExperimenterStatsRequestBase, self).__init__(datapath, flags) self.experimenter = experimenter self.exp_type = exp_type @_set_stats_type(ofproto.OFPMP_EXPERIMENTER, OFPExperimenterMultipart) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPExperimenterStatsRequest(OFPExperimenterStatsRequestBase): """ Experimenter multipart request message ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or ``OFPMPF_REQ_MORE`` experimenter Experimenter ID exp_type Experimenter defined data Experimenter defined additional data ================ ====================================================== """ def __init__(self, datapath, flags, experimenter, exp_type, data, type_=None): super(OFPExperimenterStatsRequest, self).__init__(datapath, flags, experimenter, exp_type, type_) self.data = data def _serialize_stats_body(self): body = OFPExperimenterMultipart(experimenter=self.experimenter, exp_type=self.exp_type, data=self.data) self.buf += body.serialize() @OFPMultipartReply.register_stats_type(body_single_struct=True) @_set_stats_type(ofproto.OFPMP_EXPERIMENTER, OFPExperimenterMultipart) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPExperimenterStatsReply(OFPMultipartReply): """ Experimenter multipart reply message ================ ====================================================== Attribute Description ================ ====================================================== body An ``OFPExperimenterMultipart`` instance ================ ====================================================== """ def __init__(self, datapath, type_=None, **kwargs): super(OFPExperimenterStatsReply, self).__init__(datapath, **kwargs) class OFPFlowDesc(StringifyMixin): def __init__(self, table_id=None, priority=None, idle_timeout=None, hard_timeout=None, flags=None, importance=None, cookie=None, match=None, stats=None, instructions=None, length=None): super(OFPFlowDesc, self).__init__() self.length = length self.table_id = table_id self.priority = priority self.idle_timeout = idle_timeout self.hard_timeout = hard_timeout self.flags = flags self.importance = importance self.cookie = cookie self.match = match self.stats = stats self.instructions = instructions @classmethod def parser(cls, buf, offset): flow_desc = cls() (flow_desc.length, flow_desc.table_id, flow_desc.priority, flow_desc.idle_timeout, flow_desc.hard_timeout, flow_desc.flags, flow_desc.importance, flow_desc.cookie) = struct.unpack_from( ofproto.OFP_FLOW_DESC_0_PACK_STR, buf, offset) offset += ofproto.OFP_FLOW_DESC_0_SIZE flow_desc.match = OFPMatch.parser(buf, offset) match_length = utils.round_up(flow_desc.match.length, 8) offset += match_length flow_desc.stats = OFPStats.parser(buf, offset) stats_length = utils.round_up(flow_desc.stats.length, 8) offset += stats_length instructions = [] inst_length = (flow_desc.length - (ofproto.OFP_FLOW_DESC_0_SIZE + match_length + stats_length)) while inst_length > 0: inst = OFPInstruction.parser(buf, offset) instructions.append(inst) offset += inst.len inst_length -= inst.len flow_desc.instructions = instructions return flow_desc class OFPFlowStats(StringifyMixin): def __init__(self, table_id=None, reason=None, priority=None, match=None, stats=None, length=None): super(OFPFlowStats, self).__init__() self.table_id = table_id self.reason = reason self.priority = priority self.match = match self.stats = stats self.length = length @classmethod def parser(cls, buf, offset): flow_stats = cls() (flow_stats.length, flow_stats.table_id, flow_stats.reason, flow_stats.priority) = struct.unpack_from( ofproto.OFP_FLOW_STATS_0_PACK_STR, buf, offset) offset += ofproto.OFP_FLOW_STATS_0_SIZE flow_stats.match = OFPMatch.parser(buf, offset) match_length = utils.round_up(flow_stats.match.length, 8) offset += match_length stats_length = (flow_stats.length - (ofproto.OFP_FLOW_STATS_0_SIZE + match_length)) if stats_length > 0: flow_stats.stats = OFPStats.parser(buf, offset) return flow_stats class OFPFlowStatsRequestBase(OFPMultipartRequest): def __init__(self, datapath, flags, table_id, out_port, out_group, cookie, cookie_mask, match): super(OFPFlowStatsRequestBase, self).__init__(datapath, flags) self.table_id = table_id self.out_port = out_port self.out_group = out_group self.cookie = cookie self.cookie_mask = cookie_mask self.match = match def _serialize_stats_body(self): offset = ofproto.OFP_MULTIPART_REQUEST_SIZE msg_pack_into(ofproto.OFP_FLOW_STATS_REQUEST_0_PACK_STR, self.buf, offset, self.table_id, self.out_port, self.out_group, self.cookie, self.cookie_mask) offset += ofproto.OFP_FLOW_STATS_REQUEST_0_SIZE self.match.serialize(self.buf, offset) @_set_stats_type(ofproto.OFPMP_FLOW_DESC, OFPFlowDesc) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPFlowDescStatsRequest(OFPFlowStatsRequestBase): """ Individual flow descriptions request message The controller uses this message to query individual flow descriptions. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or ``OFPMPF_REQ_MORE`` table_id ID of table to read out_port Require matching entries to include this as an output port out_group Require matching entries to include this as an output group cookie Require matching entries to contain this cookie value cookie_mask Mask used to restrict the cookie bits that must match match Instance of ``OFPMatch`` ================ ====================================================== Example:: def send_flow_desc_request(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser cookie = cookie_mask = 0 match = ofp_parser.OFPMatch(in_port=1) req = ofp_parser.OFPFlowDescStatsRequest(datapath, 0, ofp.OFPTT_ALL, ofp.OFPP_ANY, ofp.OFPG_ANY, cookie, cookie_mask, match) datapath.send_msg(req) """ def __init__(self, datapath, flags=0, table_id=ofproto.OFPTT_ALL, out_port=ofproto.OFPP_ANY, out_group=ofproto.OFPG_ANY, cookie=0, cookie_mask=0, match=None, type_=None): if match is None: match = OFPMatch() super(OFPFlowDescStatsRequest, self).__init__( datapath, flags, table_id, out_port, out_group, cookie, cookie_mask, match) @OFPMultipartReply.register_stats_type() @_set_stats_type(ofproto.OFPMP_FLOW_DESC, OFPFlowDesc) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPFlowDescStatsReply(OFPMultipartReply): """ Individual flow descriptions reply message The switch responds with this message to an individual flow descriptions request. ================ ====================================================== Attribute Description ================ ====================================================== body List of ``OFPFlowDesc`` instance ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPFlowDescStatsReply, MAIN_DISPATCHER) def flow_desc_reply_handler(self, ev): flows = [] for stat in ev.msg.body: flows.append('table_id=%s priority=%d ' 'idle_timeout=%d hard_timeout=%d flags=0x%04x ' 'importance=%d cookie=%d match=%s ' 'stats=%s instructions=%s' % (stat.table_id, stat.priority, stat.idle_timeout, stat.hard_timeout, stat.flags, stat.importance, stat.cookie, stat.match, stat.stats, stat.instructions)) self.logger.debug('FlowDesc: %s', flows) """ def __init__(self, datapath, type_=None, **kwargs): super(OFPFlowDescStatsReply, self).__init__(datapath, **kwargs) @_set_stats_type(ofproto.OFPMP_FLOW_STATS, OFPFlowStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPFlowStatsRequest(OFPFlowStatsRequestBase): """ Individual flow statistics request message The controller uses this message to query individual flow statistics. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or ``OFPMPF_REQ_MORE`` table_id ID of table to read out_port Require matching entries to include this as an output port out_group Require matching entries to include this as an output group cookie Require matching entries to contain this cookie value cookie_mask Mask used to restrict the cookie bits that must match match Instance of ``OFPMatch`` ================ ====================================================== Example:: def send_flow_stats_request(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser cookie = cookie_mask = 0 match = ofp_parser.OFPMatch(in_port=1) req = ofp_parser.OFPFlowStatsRequest(datapath, 0, ofp.OFPTT_ALL, ofp.OFPP_ANY, ofp.OFPG_ANY, cookie, cookie_mask, match) datapath.send_msg(req) """ def __init__(self, datapath, flags=0, table_id=ofproto.OFPTT_ALL, out_port=ofproto.OFPP_ANY, out_group=ofproto.OFPG_ANY, cookie=0, cookie_mask=0, match=None, type_=None): if match is None: match = OFPMatch() super(OFPFlowStatsRequest, self).__init__(datapath, flags, table_id, out_port, out_group, cookie, cookie_mask, match) @OFPMultipartReply.register_stats_type() @_set_stats_type(ofproto.OFPMP_FLOW_STATS, OFPFlowStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPFlowStatsReply(OFPMultipartReply): """ Individual flow statistics reply message The switch responds with this message to an individual flow statistics request. ================ ====================================================== Attribute Description ================ ====================================================== body List of ``OFPFlowStats`` instance ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPFlowStatsReply, MAIN_DISPATCHER) def flow_stats_reply_handler(self, ev): flows = [] for stat in ev.msg.body: flows.append('table_id=%s reason=%d priority=%d ' 'match=%s stats=%s' % (stat.table_id, stat.reason, stat.priority, stat.match, stat.stats)) self.logger.debug('FlowStats: %s', flows) """ def __init__(self, datapath, type_=None, **kwargs): super(OFPFlowStatsReply, self).__init__(datapath, **kwargs) class OFPAggregateStats(StringifyMixin): def __init__(self, stats=None, length=None): super(OFPAggregateStats, self).__init__() self.stats = stats # Note: length field is specific to this implementation. # It does not have a corresponding field in the specification. self.length = length @classmethod def parser(cls, buf, offset): stats = OFPStats.parser(buf, offset) agg = cls(stats) agg.length = utils.round_up(stats.length, 8) return agg @_set_stats_type(ofproto.OFPMP_AGGREGATE_STATS, OFPAggregateStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPAggregateStatsRequest(OFPFlowStatsRequestBase): """ Aggregate flow statistics request message The controller uses this message to query aggregate flow statictics. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or ``OFPMPF_REQ_MORE`` table_id ID of table to read out_port Require matching entries to include this as an output port out_group Require matching entries to include this as an output group cookie Require matching entries to contain this cookie value cookie_mask Mask used to restrict the cookie bits that must match match Instance of ``OFPMatch`` ================ ====================================================== Example:: def send_aggregate_stats_request(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser cookie = cookie_mask = 0 match = ofp_parser.OFPMatch(in_port=1) req = ofp_parser.OFPAggregateStatsRequest(datapath, 0, ofp.OFPTT_ALL, ofp.OFPP_ANY, ofp.OFPG_ANY, cookie, cookie_mask, match) datapath.send_msg(req) """ def __init__(self, datapath, flags, table_id, out_port, out_group, cookie, cookie_mask, match, type_=None): super(OFPAggregateStatsRequest, self).__init__(datapath, flags, table_id, out_port, out_group, cookie, cookie_mask, match) @OFPMultipartReply.register_stats_type(body_single_struct=True) @_set_stats_type(ofproto.OFPMP_AGGREGATE_STATS, OFPAggregateStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPAggregateStatsReply(OFPMultipartReply): """ Aggregate flow statistics reply message The switch responds with this message to an aggregate flow statistics request. ================ ====================================================== Attribute Description ================ ====================================================== body Instance of ``OFPAggregateStats`` ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPAggregateStatsReply, MAIN_DISPATCHER) def aggregate_stats_reply_handler(self, ev): body = ev.msg.body self.logger.debug('AggregateStats: stats=%s', body.stats) """ def __init__(self, datapath, type_=None, **kwargs): super(OFPAggregateStatsReply, self).__init__(datapath, **kwargs) class OFPTableStats(ofproto_parser.namedtuple('OFPTableStats', ( 'table_id', 'active_count', 'lookup_count', 'matched_count'))): @classmethod def parser(cls, buf, offset): tbl = struct.unpack_from(ofproto.OFP_TABLE_STATS_PACK_STR, buf, offset) stats = cls(*tbl) stats.length = ofproto.OFP_TABLE_STATS_SIZE return stats @_set_stats_type(ofproto.OFPMP_TABLE_STATS, OFPTableStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPTableStatsRequest(OFPMultipartRequest): """ Table statistics request message The controller uses this message to query flow table statictics. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or ``OFPMPF_REQ_MORE`` ================ ====================================================== Example:: def send_table_stats_request(self, datapath): ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPTableStatsRequest(datapath, 0) datapath.send_msg(req) """ def __init__(self, datapath, flags, type_=None): super(OFPTableStatsRequest, self).__init__(datapath, flags) @OFPMultipartReply.register_stats_type() @_set_stats_type(ofproto.OFPMP_TABLE_STATS, OFPTableStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPTableStatsReply(OFPMultipartReply): """ Table statistics reply message The switch responds with this message to a table statistics request. ================ ====================================================== Attribute Description ================ ====================================================== body List of ``OFPTableStats`` instance ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPTableStatsReply, MAIN_DISPATCHER) def table_stats_reply_handler(self, ev): tables = [] for stat in ev.msg.body: tables.append('table_id=%d active_count=%d lookup_count=%d ' ' matched_count=%d' % (stat.table_id, stat.active_count, stat.lookup_count, stat.matched_count)) self.logger.debug('TableStats: %s', tables) """ def __init__(self, datapath, type_=None, **kwargs): super(OFPTableStatsReply, self).__init__(datapath, **kwargs) class OFPPortStatsProp(OFPPropBase): _TYPES = {} @OFPPortStatsProp.register_type(ofproto.OFPPSPT_ETHERNET) class OFPPortStatsPropEthernet(OFPPortStatsProp): def __init__(self, type_=None, length=None, rx_frame_err=None, rx_over_err=None, rx_crc_err=None, collisions=None): self.type = type_ self.length = length self.rx_frame_err = rx_frame_err self.rx_over_err = rx_over_err self.rx_crc_err = rx_crc_err self.collisions = collisions @classmethod def parser(cls, buf): ether = cls() (ether.type, ether.length, ether.rx_frame_err, ether.rx_over_err, ether.rx_crc_err, ether.collisions) = struct.unpack_from( ofproto.OFP_PORT_STATS_PROP_ETHERNET_PACK_STR, buf, 0) return ether @OFPPortStatsProp.register_type(ofproto.OFPPSPT_OPTICAL) class OFPPortStatsPropOptical(OFPPortStatsProp): def __init__(self, type_=None, length=None, flags=None, tx_freq_lmda=None, tx_offset=None, tx_grid_span=None, rx_freq_lmda=None, rx_offset=None, rx_grid_span=None, tx_pwr=None, rx_pwr=None, bias_current=None, temperature=None): self.type = type_ self.length = length self.flags = flags self.tx_freq_lmda = tx_freq_lmda self.tx_offset = tx_offset self.tx_grid_span = tx_grid_span self.rx_freq_lmda = rx_freq_lmda self.rx_offset = rx_offset self.rx_grid_span = rx_grid_span self.tx_pwr = tx_pwr self.rx_pwr = rx_pwr self.bias_current = bias_current self.temperature = temperature @classmethod def parser(cls, buf): optical = cls() (optical.type, optical.length, optical.flags, optical.tx_freq_lmda, optical.tx_offset, optical.tx_grid_span, optical.rx_freq_lmda, optical.rx_offset, optical.rx_grid_span, optical.tx_pwr, optical.rx_pwr, optical.bias_current, optical.temperature) = struct.unpack_from( ofproto.OFP_PORT_STATS_PROP_OPTICAL_PACK_STR, buf, 0) return optical @OFPPortStatsProp.register_type(ofproto.OFPPSPT_EXPERIMENTER) class OFPPortStatsPropExperimenter(OFPPropCommonExperimenter4ByteData): pass class OFPPortStats(StringifyMixin): def __init__(self, length=None, port_no=None, duration_sec=None, duration_nsec=None, rx_packets=None, tx_packets=None, rx_bytes=None, tx_bytes=None, rx_dropped=None, tx_dropped=None, rx_errors=None, tx_errors=None, properties=None): super(OFPPortStats, self).__init__() self.length = length self.port_no = port_no self.duration_sec = duration_sec self.duration_nsec = duration_nsec self.rx_packets = rx_packets self.tx_packets = tx_packets self.rx_bytes = rx_bytes self.tx_bytes = tx_bytes self.rx_dropped = rx_dropped self.tx_dropped = tx_dropped self.rx_errors = rx_errors self.tx_errors = tx_errors self.properties = properties @classmethod def parser(cls, buf, offset): (length, port_no, duration_sec, duration_nsec, rx_packets, tx_packets, rx_bytes, tx_bytes, rx_dropped, tx_dropped, rx_errors, tx_errors) = struct.unpack_from( ofproto.OFP_PORT_STATS_PACK_STR, buf, offset) props = [] rest = buf[offset + ofproto.OFP_PORT_STATS_SIZE:offset + length] while rest: p, rest = OFPPortStatsProp.parse(rest) props.append(p) stats = cls(length, port_no, duration_sec, duration_nsec, rx_packets, tx_packets, rx_bytes, tx_bytes, rx_dropped, tx_dropped, rx_errors, tx_errors, props) return stats @_set_stats_type(ofproto.OFPMP_PORT_STATS, OFPPortStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPPortStatsRequest(OFPMultipartRequest): """ Port statistics request message The controller uses this message to query information about ports statistics. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or ``OFPMPF_REQ_MORE`` port_no Port number to read (OFPP_ANY to all ports) ================ ====================================================== Example:: def send_port_stats_request(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPPortStatsRequest(datapath, 0, ofp.OFPP_ANY) datapath.send_msg(req) """ def __init__(self, datapath, flags, port_no, type_=None): super(OFPPortStatsRequest, self).__init__(datapath, flags) self.port_no = port_no def _serialize_stats_body(self): msg_pack_into(ofproto.OFP_PORT_MULTIPART_REQUEST_PACK_STR, self.buf, ofproto.OFP_MULTIPART_REQUEST_SIZE, self.port_no) @OFPMultipartReply.register_stats_type() @_set_stats_type(ofproto.OFPMP_PORT_STATS, OFPPortStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPPortStatsReply(OFPMultipartReply): """ Port statistics reply message The switch responds with this message to a port statistics request. ================ ====================================================== Attribute Description ================ ====================================================== body List of ``OFPPortStats`` instance ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPPortStatsReply, MAIN_DISPATCHER) def port_stats_reply_handler(self, ev): ports = [] for stat in ev.msg.body: ports.append(stat.length, stat.port_no, stat.duration_sec, stat.duration_nsec, stat.rx_packets, stat.tx_packets, stat.rx_bytes, stat.tx_bytes, stat.rx_dropped, stat.tx_dropped, stat.rx_errors, stat.tx_errors, repr(stat.properties)) self.logger.debug('PortStats: %s', ports) """ def __init__(self, datapath, type_=None, **kwargs): super(OFPPortStatsReply, self).__init__(datapath, **kwargs) @_set_msg_type(ofproto.OFPT_BARRIER_REQUEST) class OFPBarrierRequest(MsgBase): """ Barrier request message The controller sends this message to ensure message dependencies have been met or receive notifications for completed operations. Example:: def send_barrier_request(self, datapath): ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPBarrierRequest(datapath) datapath.send_msg(req) """ def __init__(self, datapath): super(OFPBarrierRequest, self).__init__(datapath) @_register_parser @_set_msg_type(ofproto.OFPT_BARRIER_REPLY) class OFPBarrierReply(MsgBase): """ Barrier reply message The switch responds with this message to a barrier request. Example:: @set_ev_cls(ofp_event.EventOFPBarrierReply, MAIN_DISPATCHER) def barrier_reply_handler(self, ev): self.logger.debug('OFPBarrierReply received') """ def __init__(self, datapath): super(OFPBarrierReply, self).__init__(datapath) @_register_parser @_set_msg_type(ofproto.OFPT_PORT_STATUS) class OFPPortStatus(MsgBase): """ Port status message The switch notifies controller of change of ports. ================ ====================================================== Attribute Description ================ ====================================================== reason One of the following values. | OFPPR_ADD | OFPPR_DELETE | OFPPR_MODIFY desc instance of ``OFPPort`` ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPPortStatus, MAIN_DISPATCHER) def port_status_handler(self, ev): msg = ev.msg dp = msg.datapath ofp = dp.ofproto if msg.reason == ofp.OFPPR_ADD: reason = 'ADD' elif msg.reason == ofp.OFPPR_DELETE: reason = 'DELETE' elif msg.reason == ofp.OFPPR_MODIFY: reason = 'MODIFY' else: reason = 'unknown' self.logger.debug('OFPPortStatus received: reason=%s desc=%s', reason, msg.desc) """ def __init__(self, datapath, reason=None, desc=None): super(OFPPortStatus, self).__init__(datapath) self.reason = reason self.desc = desc @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPPortStatus, cls).parser(datapath, version, msg_type, msg_len, xid, buf) msg.reason = struct.unpack_from( ofproto.OFP_PORT_STATUS_PACK_STR, msg.buf, ofproto.OFP_HEADER_SIZE)[0] msg.desc = OFPPort.parser(msg.buf, ofproto.OFP_PORT_STATUS_DESC_OFFSET) return msg @_register_parser @_set_msg_type(ofproto.OFPT_ROLE_STATUS) class OFPRoleStatus(MsgBase): """ Role status message The switch notifies controller of change of role. ================ ====================================================== Attribute Description ================ ====================================================== role One of the following values. | OFPCR_ROLE_NOCHANGE | OFPCR_ROLE_EQUAL | OFPCR_ROLE_MASTER reason One of the following values. | OFPCRR_MASTER_REQUEST | OFPCRR_CONFIG | OFPCRR_EXPERIMENTER generation_id Master Election Generation ID properties List of ``OFPRoleProp`` subclass instance ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPRoleStatus, MAIN_DISPATCHER) def role_status_handler(self, ev): msg = ev.msg dp = msg.datapath ofp = dp.ofproto if msg.role == ofp.OFPCR_ROLE_NOCHANGE: role = 'ROLE NOCHANGE' elif msg.role == ofp.OFPCR_ROLE_EQUAL: role = 'ROLE EQUAL' elif msg.role == ofp.OFPCR_ROLE_MASTER: role = 'ROLE MASTER' else: role = 'unknown' if msg.reason == ofp.OFPCRR_MASTER_REQUEST: reason = 'MASTER REQUEST' elif msg.reason == ofp.OFPCRR_CONFIG: reason = 'CONFIG' elif msg.reason == ofp.OFPCRR_EXPERIMENTER: reason = 'EXPERIMENTER' else: reason = 'unknown' self.logger.debug('OFPRoleStatus received: role=%s reason=%s ' 'generation_id=%d properties=%s', role, reason, msg.generation_id, repr(msg.properties)) """ def __init__(self, datapath, role=None, reason=None, generation_id=None, properties=None): super(OFPRoleStatus, self).__init__(datapath) self.role = role self.reason = reason self.generation_id = generation_id self.properties = properties @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPRoleStatus, cls).parser(datapath, version, msg_type, msg_len, xid, buf) (msg.role, msg.reason, msg.generation_id) = struct.unpack_from( ofproto.OFP_ROLE_STATUS_PACK_STR, msg.buf, ofproto.OFP_HEADER_SIZE) msg.properties = [] rest = msg.buf[ofproto.OFP_ROLE_STATUS_SIZE:] while rest: p, rest = OFPRoleProp.parse(rest) msg.properties.append(p) return msg @_register_parser @_set_msg_type(ofproto.OFPT_TABLE_STATUS) class OFPTableStatus(MsgBase): """ Table status message The switch notifies controller of change of table status. ================ ====================================================== Attribute Description ================ ====================================================== reason One of the following values. | OFPTR_VACANCY_DOWN | OFPTR_VACANCY_UP table ``OFPTableDesc`` instance ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPTableStatus, MAIN_DISPATCHER) def table(self, ev): msg = ev.msg dp = msg.datapath ofp = dp.ofproto if msg.reason == ofp.OFPTR_VACANCY_DOWN: reason = 'VACANCY_DOWN' elif msg.reason == ofp.OFPTR_VACANCY_UP: reason = 'VACANCY_UP' else: reason = 'unknown' self.logger.debug('OFPTableStatus received: reason=%s ' 'table_id=%d config=0x%08x properties=%s', reason, msg.table.table_id, msg.table.config, repr(msg.table.properties)) """ def __init__(self, datapath, reason=None, table=None): super(OFPTableStatus, self).__init__(datapath) self.reason = reason self.table = table @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPTableStatus, cls).parser(datapath, version, msg_type, msg_len, xid, buf) (msg.reason,) = struct.unpack_from(ofproto.OFP_TABLE_STATUS_0_PACK_STR, msg.buf, ofproto.OFP_HEADER_SIZE) msg.table = OFPTableDesc.parser(msg.buf, ofproto.OFP_TABLE_STATUS_0_SIZE) return msg @_register_parser @_set_msg_type(ofproto.OFPT_REQUESTFORWARD) class OFPRequestForward(MsgInMsgBase): """ Forwarded request message The swtich forwards request messages from one controller to other controllers. ================ ====================================================== Attribute Description ================ ====================================================== request ``OFPGroupMod`` or ``OFPMeterMod`` instance ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPRequestForward, MAIN_DISPATCHER) def request_forward_handler(self, ev): msg = ev.msg dp = msg.datapath ofp = dp.ofproto if msg.request.msg_type == ofp.OFPT_GROUP_MOD: self.logger.debug( 'OFPRequestForward received: request=OFPGroupMod(' 'command=%d, type=%d, group_id=%d, command_bucket_id=%d, ' 'buckets=%s, properties=%s)', msg.request.command, msg.request.type, msg.request.group_id, msg.request.command_bucket_id, msg.request.buckets, repr(msg.request.properties)) elif msg.request.msg_type == ofp.OFPT_METER_MOD: self.logger.debug( 'OFPRequestForward received: request=OFPMeterMod(' 'command=%d, flags=%d, meter_id=%d, bands=%s)', msg.request.command, msg.request.flags, msg.request.meter_id, msg.request.bands) else: self.logger.debug( 'OFPRequestForward received: request=Unknown') """ def __init__(self, datapath, request=None): super(OFPRequestForward, self).__init__(datapath) self.request = request @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPRequestForward, cls).parser( datapath, version, msg_type, msg_len, xid, buf) req_buf = buf[ofproto.OFP_HEADER_SIZE:] (_ver, _type, _len, _xid) = ofproto_parser.header(req_buf) msg.request = ofproto_parser.msg( datapath, _ver, _type, _len, _xid, req_buf) return msg def _serialize_body(self): assert isinstance(self.request, (OFPGroupMod, OFPMeterMod)) self.request.serialize() self.buf += self.request.buf class OFPControllerStatusProp(OFPPropBase): _TYPES = {} @OFPControllerStatusProp.register_type(ofproto.OFPCSPT_URI) class OFPControllerStatusPropUri(OFPControllerStatusProp): _TYPE = { 'ascii': [ 'uri', ] } def __init__(self, type_=None, length=None, uri=None): super(OFPControllerStatusPropUri, self).__init__(type_, length) self.uri = uri @classmethod def parser(cls, buf): rest = cls.get_rest(buf) pack_str = '!%ds' % len(rest) (uri, ) = struct.unpack_from(pack_str, rest, 0) return cls(uri=uri) @OFPControllerStatusProp.register_type(ofproto.OFPCSPT_EXPERIMENTER) class OFPControllerStatusPropExperimenter(OFPPropCommonExperimenter4ByteData): pass class OFPControllerStatusStats(StringifyMixin): """ Controller status structure ============== ========================================================= Attribute Description ============== ========================================================= length Length of this entry. short_id ID number which identifies the controller. role Bitmap of controller's role flags. | OFPCR_ROLE_NOCHANGE | OFPCR_ROLE_EQUAL | OFPCR_ROLE_MASTER | OFPCR_ROLE_SLAVE reason Bitmap of controller status reason flags. | OFPCSR_REQUEST | OFPCSR_CHANNEL_STATUS | OFPCSR_ROLE | OFPCSR_CONTROLLER_ADDED | OFPCSR_CONTROLLER_REMOVED | OFPCSR_SHORT_ID | OFPCSR_EXPERIMENTER channel_status Bitmap of control channel status flags. | OFPCT_STATUS_UP | OFPCT_STATUS_DOWN properties List of ``OFPControllerStatusProp`` subclass instance ============== ========================================================= """ def __init__(self, short_id=None, role=None, reason=None, channel_status=None, properties=None, length=None): super(OFPControllerStatusStats, self).__init__() self.length = length self.short_id = short_id self.role = role self.reason = reason self.channel_status = channel_status self.properties = properties @classmethod def parser(cls, buf, offset): status = cls() (status.length, status.short_id, status.role, status.reason, status.channel_status) = struct.unpack_from( ofproto.OFP_CONTROLLER_STATUS_PACK_STR, buf, offset) offset += ofproto.OFP_CONTROLLER_STATUS_SIZE status.properties = [] rest = buf[offset:offset + status.length] while rest: p, rest = OFPControllerStatusProp.parse(rest) status.properties.append(p) return status @_set_stats_type(ofproto.OFPMP_CONTROLLER_STATUS, OFPControllerStatusStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REQUEST) class OFPControllerStatusStatsRequest(OFPMultipartRequest): """ Controller status multipart request message The controller uses this message to request the status, the roles and the control channels of other controllers configured on the switch. ================ ====================================================== Attribute Description ================ ====================================================== flags Zero or ``OFPMPF_REQ_MORE`` ================ ====================================================== Example:: def send_controller_status_multipart_request(self, datapath): ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPPortDescStatsRequest(datapath, 0) datapath.send_msg(req) """ def __init__(self, datapath, flags=0, type_=None): super(OFPControllerStatusStatsRequest, self).__init__(datapath, flags) @OFPMultipartReply.register_stats_type() @_set_stats_type(ofproto.OFPMP_CONTROLLER_STATUS, OFPControllerStatusStats) @_set_msg_type(ofproto.OFPT_MULTIPART_REPLY) class OFPControllerStatusStatsReply(OFPMultipartReply): """ Controller status multipart reply message The switch responds with this message to a controller status multipart request. ================ ====================================================== Attribute Description ================ ====================================================== body List of ``OFPControllerStatus`` instance ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPControllerStatusStatsReply, MAIN_DISPATCHER) def controller_status_multipart_reply_handler(self, ev): status = [] for s in ev.msg.body: status.append('short_id=%d role=%d reason=%d ' 'channel_status=%d properties=%s' % (s.short_id, s.role, s.reason, s.channel_status, repr(s.properties))) self.logger.debug('OFPControllerStatusStatsReply received: %s', status) """ def __init__(self, datapath, type_=None, **kwargs): super(OFPControllerStatusStatsReply, self).__init__(datapath, **kwargs) @_register_parser @_set_msg_type(ofproto.OFPT_CONTROLLER_STATUS) class OFPControllerStatus(MsgBase): """ Controller status message The switch informs the controller about the status of the control channel it maintains with each controller. ================ ====================================================== Attribute Description ================ ====================================================== status ``OFPControllerStatusStats`` instance ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPControllerStatus, MAIN_DISPATCHER) def table(self, ev): msg = ev.msg dp = msg.datapath ofp = dp.ofproto status = msg.status if status.role == ofp.OFPCR_ROLE_NOCHANGE: role = 'NOCHANGE' elif status.role == ofp.OFPCR_ROLE_EQUAL: role = 'EQUAL' elif status.role == ofp.OFPCR_ROLE_MASTER: role = 'MASTER' elif status.role == ofp.OFPCR_ROLE_SLAVE: role = 'SLAVE' else: role = 'unknown' if status.reason == ofp.OFPCSR_REQUEST: reason = 'REQUEST' elif status.reason == ofp.OFPCSR_CHANNEL_STATUS: reason = 'CHANNEL_STATUS' elif status.reason == ofp.OFPCSR_ROLE: reason = 'ROLE' elif status.reason == ofp.OFPCSR_CONTROLLER_ADDED: reason = 'CONTROLLER_ADDED' elif status.reason == ofp.OFPCSR_CONTROLLER_REMOVED: reason = 'CONTROLLER_REMOVED' elif status.reason == ofp.OFPCSR_SHORT_ID: reason = 'SHORT_ID' elif status.reason == ofp.OFPCSR_EXPERIMENTER: reason = 'EXPERIMENTER' else: reason = 'unknown' if status.channel_status == OFPCT_STATUS_UP: channel_status = 'UP' if status.channel_status == OFPCT_STATUS_DOWN: channel_status = 'DOWN' else: channel_status = 'unknown' self.logger.debug('OFPControllerStatus received: short_id=%d' 'role=%s reason=%s channel_status=%s ' 'properties=%s', status.short_id, role, reason, channel_status, repr(status.properties)) """ def __init__(self, datapath, status=None): super(OFPControllerStatus, self).__init__(datapath) self.status = status @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPControllerStatus, cls).parser(datapath, version, msg_type, msg_len, xid, buf) msg.status = OFPControllerStatusStats.parser(msg.buf, ofproto.OFP_HEADER_SIZE) return msg @_set_msg_type(ofproto.OFPT_PACKET_OUT) class OFPPacketOut(MsgBase): """ Packet-Out message The controller uses this message to send a packet out throught the switch. ================ ====================================================== Attribute Description ================ ====================================================== buffer_id ID assigned by datapath (OFP_NO_BUFFER if none) match Instance of ``OFPMatch`` (``in_port`` is mandatory in the match field) actions list of OpenFlow action class data Packet data of a binary type value or an instances of packet.Packet. ================ ====================================================== Example:: def send_packet_out(self, datapath, buffer_id, in_port): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser match = OFPMatch(in_port=in_port) actions = [ofp_parser.OFPActionOutput(ofp.OFPP_FLOOD, 0)] req = ofp_parser.OFPPacketOut(datapath, buffer_id, match, actions) datapath.send_msg(req) """ def __init__(self, datapath, buffer_id=None, match=None, actions=None, data=None, actions_len=None): super(OFPPacketOut, self).__init__(datapath) if buffer_id is None: self.buffer_id = ofproto.OFP_NO_BUFFER else: self.buffer_id = buffer_id self.actions_len = 0 assert 'in_port' in match self.match = match self.actions = actions self.data = data def _serialize_body(self): # adjustment offset = ofproto.OFP_PACKET_OUT_0_SIZE match_len = self.match.serialize(self.buf, offset) offset += match_len self.actions_len = 0 for a in self.actions: a.serialize(self.buf, offset) offset += a.len self.actions_len += a.len if self.buffer_id == ofproto.OFP_NO_BUFFER: assert self.data is not None if isinstance(self.data, packet.Packet): self.data.serialize() self.buf += self.data.data else: self.buf += self.data else: assert self.data is None msg_pack_into(ofproto.OFP_PACKET_OUT_0_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.buffer_id, self.actions_len) @classmethod def from_jsondict(cls, dict_, decode_string=base64.b64decode, **additional_args): if isinstance(dict_['data'], dict): data = dict_.pop('data') ins = super(OFPPacketOut, cls).from_jsondict(dict_, decode_string, **additional_args) ins.data = packet.Packet.from_jsondict(data['Packet']) dict_['data'] = data else: ins = super(OFPPacketOut, cls).from_jsondict(dict_, decode_string, **additional_args) return ins @_register_parser @_set_msg_type(ofproto.OFPT_FLOW_MOD) class OFPFlowMod(MsgBase): """ Modify Flow entry message The controller sends this message to modify the flow table. ================ ====================================================== Attribute Description ================ ====================================================== cookie Opaque controller-issued identifier cookie_mask Mask used to restrict the cookie bits that must match when the command is ``OPFFC_MODIFY*`` or ``OFPFC_DELETE*`` table_id ID of the table to put the flow in command One of the following values. | OFPFC_ADD | OFPFC_MODIFY | OFPFC_MODIFY_STRICT | OFPFC_DELETE | OFPFC_DELETE_STRICT idle_timeout Idle time before discarding (seconds) hard_timeout Max time before discarding (seconds) priority Priority level of flow entry buffer_id Buffered packet to apply to (or OFP_NO_BUFFER) out_port For ``OFPFC_DELETE*`` commands, require matching entries to include this as an output port out_group For ``OFPFC_DELETE*`` commands, require matching entries to include this as an output group flags Bitmap of the following flags. | OFPFF_SEND_FLOW_REM | OFPFF_CHECK_OVERLAP | OFPFF_RESET_COUNTS | OFPFF_NO_PKT_COUNTS | OFPFF_NO_BYT_COUNTS importance Eviction precedence match Instance of ``OFPMatch`` instructions list of ``OFPInstruction*`` instance ================ ====================================================== Example:: def send_flow_mod(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser cookie = cookie_mask = 0 table_id = 0 idle_timeout = hard_timeout = 0 priority = 32768 buffer_id = ofp.OFP_NO_BUFFER importance = 0 match = ofp_parser.OFPMatch(in_port=1, eth_dst='ff:ff:ff:ff:ff:ff') actions = [ofp_parser.OFPActionOutput(ofp.OFPP_NORMAL, 0)] inst = [ofp_parser.OFPInstructionActions(ofp.OFPIT_APPLY_ACTIONS, actions)] req = ofp_parser.OFPFlowMod(datapath, cookie, cookie_mask, table_id, ofp.OFPFC_ADD, idle_timeout, hard_timeout, priority, buffer_id, ofp.OFPP_ANY, ofp.OFPG_ANY, ofp.OFPFF_SEND_FLOW_REM, importance, match, inst) datapath.send_msg(req) """ def __init__(self, datapath, cookie=0, cookie_mask=0, table_id=0, command=ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=0, priority=ofproto.OFP_DEFAULT_PRIORITY, buffer_id=ofproto.OFP_NO_BUFFER, out_port=0, out_group=0, flags=0, importance=0, match=None, instructions=None): instructions = instructions if instructions else [] super(OFPFlowMod, self).__init__(datapath) self.cookie = cookie self.cookie_mask = cookie_mask self.table_id = table_id self.command = command self.idle_timeout = idle_timeout self.hard_timeout = hard_timeout self.priority = priority self.buffer_id = buffer_id self.out_port = out_port self.out_group = out_group self.flags = flags self.importance = importance if match is None: match = OFPMatch() assert isinstance(match, OFPMatch) self.match = match for i in instructions: assert isinstance(i, OFPInstruction) self.instructions = instructions def _serialize_body(self): msg_pack_into(ofproto.OFP_FLOW_MOD_PACK_STR0, self.buf, ofproto.OFP_HEADER_SIZE, self.cookie, self.cookie_mask, self.table_id, self.command, self.idle_timeout, self.hard_timeout, self.priority, self.buffer_id, self.out_port, self.out_group, self.flags, self.importance) offset = (ofproto.OFP_FLOW_MOD_SIZE - ofproto.OFP_MATCH_SIZE) match_len = self.match.serialize(self.buf, offset) offset += match_len for inst in self.instructions: inst.serialize(self.buf, offset) offset += inst.len @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPFlowMod, cls).parser( datapath, version, msg_type, msg_len, xid, buf) (msg.cookie, msg.cookie_mask, msg.table_id, msg.command, msg.idle_timeout, msg.hard_timeout, msg.priority, msg.buffer_id, msg.out_port, msg.out_group, msg.flags, msg.importance) = struct.unpack_from( ofproto.OFP_FLOW_MOD_PACK_STR0, msg.buf, ofproto.OFP_HEADER_SIZE) offset = ofproto.OFP_FLOW_MOD_SIZE - ofproto.OFP_HEADER_SIZE msg.match = OFPMatch.parser(buf, offset) offset += utils.round_up(msg.match.length, 8) instructions = [] while offset < msg_len: i = OFPInstruction.parser(buf, offset) instructions.append(i) offset += i.len msg.instructions = instructions return msg class OFPInstruction(StringifyMixin): _INSTRUCTION_TYPES = {} @staticmethod def register_instruction_type(types): def _register_instruction_type(cls): for type_ in types: OFPInstruction._INSTRUCTION_TYPES[type_] = cls return cls return _register_instruction_type @classmethod def parser(cls, buf, offset): (type_, len_) = struct.unpack_from('!HH', buf, offset) cls_ = cls._INSTRUCTION_TYPES.get(type_) return cls_.parser(buf, offset) @OFPInstruction.register_instruction_type([ofproto.OFPIT_GOTO_TABLE]) class OFPInstructionGotoTable(OFPInstruction): """ Goto table instruction This instruction indicates the next table in the processing pipeline. ================ ====================================================== Attribute Description ================ ====================================================== table_id Next table ================ ====================================================== """ def __init__(self, table_id, type_=None, len_=None): super(OFPInstructionGotoTable, self).__init__() self.type = ofproto.OFPIT_GOTO_TABLE self.len = ofproto.OFP_INSTRUCTION_GOTO_TABLE_SIZE self.table_id = table_id @classmethod def parser(cls, buf, offset): (type_, len_, table_id) = struct.unpack_from( ofproto.OFP_INSTRUCTION_GOTO_TABLE_PACK_STR, buf, offset) return cls(table_id) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_INSTRUCTION_GOTO_TABLE_PACK_STR, buf, offset, self.type, self.len, self.table_id) @OFPInstruction.register_instruction_type([ofproto.OFPIT_WRITE_METADATA]) class OFPInstructionWriteMetadata(OFPInstruction): """ Write metadata instruction This instruction writes the masked metadata value into the metadata field. ================ ====================================================== Attribute Description ================ ====================================================== metadata Metadata value to write metadata_mask Metadata write bitmask ================ ====================================================== """ def __init__(self, metadata, metadata_mask, type_=None, len_=None): super(OFPInstructionWriteMetadata, self).__init__() self.type = ofproto.OFPIT_WRITE_METADATA self.len = ofproto.OFP_INSTRUCTION_WRITE_METADATA_SIZE self.metadata = metadata self.metadata_mask = metadata_mask @classmethod def parser(cls, buf, offset): (type_, len_, metadata, metadata_mask) = struct.unpack_from( ofproto.OFP_INSTRUCTION_WRITE_METADATA_PACK_STR, buf, offset) return cls(metadata, metadata_mask) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_INSTRUCTION_WRITE_METADATA_PACK_STR, buf, offset, self.type, self.len, self.metadata, self.metadata_mask) @OFPInstruction.register_instruction_type([ofproto.OFPIT_WRITE_ACTIONS, ofproto.OFPIT_APPLY_ACTIONS, ofproto.OFPIT_CLEAR_ACTIONS]) class OFPInstructionActions(OFPInstruction): """ Actions instruction This instruction writes/applies/clears the actions. ================ ====================================================== Attribute Description ================ ====================================================== type One of following values. | OFPIT_WRITE_ACTIONS | OFPIT_APPLY_ACTIONS | OFPIT_CLEAR_ACTIONS actions list of OpenFlow action class ================ ====================================================== ``type`` attribute corresponds to ``type_`` parameter of __init__. """ def __init__(self, type_, actions=None, len_=None): super(OFPInstructionActions, self).__init__() self.type = type_ for a in actions: assert isinstance(a, OFPAction) self.actions = actions @classmethod def parser(cls, buf, offset): (type_, len_) = struct.unpack_from( ofproto.OFP_INSTRUCTION_ACTIONS_PACK_STR, buf, offset) offset += ofproto.OFP_INSTRUCTION_ACTIONS_SIZE actions = [] actions_len = len_ - ofproto.OFP_INSTRUCTION_ACTIONS_SIZE while actions_len > 0: a = OFPAction.parser(buf, offset) actions.append(a) actions_len -= a.len offset += a.len inst = cls(type_, actions) inst.len = len_ return inst def serialize(self, buf, offset): action_offset = offset + ofproto.OFP_INSTRUCTION_ACTIONS_SIZE if self.actions: for a in self.actions: a.serialize(buf, action_offset) action_offset += a.len self.len = action_offset - offset pad_len = utils.round_up(self.len, 8) - self.len msg_pack_into("%dx" % pad_len, buf, action_offset) self.len += pad_len msg_pack_into(ofproto.OFP_INSTRUCTION_ACTIONS_PACK_STR, buf, offset, self.type, self.len) @OFPInstruction.register_instruction_type([ofproto.OFPIT_STAT_TRIGGER]) class OFPInstructionStatTrigger(OFPInstruction): """ Statistics triggers instruction This instruction defines a set of statistics thresholds using OXS. ================ ====================================================== Attribute Description ================ ====================================================== flags Bitmap of the following flags. | OFPSTF_PERIODIC | OFPSTF_ONLY_FIRST thresholds Instance of ``OFPStats`` ================ ====================================================== """ def __init__(self, flags, thresholds, type_=None, len_=None): super(OFPInstructionStatTrigger, self).__init__() self.type = ofproto.OFPIT_STAT_TRIGGER self.len = len_ self.flags = flags self.thresholds = thresholds @classmethod def parser(cls, buf, offset): (type_, len_, flags) = struct.unpack_from( ofproto.OFP_INSTRUCTION_STAT_TRIGGER_PACK_STR0, buf, offset) # adjustment offset += 8 thresholds = OFPStats.parser(buf, offset) inst = cls(flags, thresholds) inst.len = len_ return inst def serialize(self, buf, offset): stats_len = self.thresholds.serialize(buf, offset + 8) self.len = 8 + stats_len msg_pack_into(ofproto.OFP_INSTRUCTION_STAT_TRIGGER_PACK_STR0, buf, offset, self.type, self.len, self.flags) class OFPActionHeader(StringifyMixin): def __init__(self, type_, len_): self.type = type_ self.len = len_ def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_HEADER_PACK_STR, buf, offset, self.type, self.len) class OFPAction(OFPActionHeader): _ACTION_TYPES = {} @staticmethod def register_action_type(type_, len_): def _register_action_type(cls): cls.cls_action_type = type_ cls.cls_action_len = len_ OFPAction._ACTION_TYPES[cls.cls_action_type] = cls return cls return _register_action_type def __init__(self): cls = self.__class__ super(OFPAction, self).__init__(cls.cls_action_type, cls.cls_action_len) @classmethod def parser(cls, buf, offset): type_, len_ = struct.unpack_from( ofproto.OFP_ACTION_HEADER_PACK_STR, buf, offset) cls_ = cls._ACTION_TYPES.get(type_) assert cls_ is not None return cls_.parser(buf, offset) @OFPAction.register_action_type(ofproto.OFPAT_OUTPUT, ofproto.OFP_ACTION_OUTPUT_SIZE) class OFPActionOutput(OFPAction): """ Output action This action indicates output a packet to the switch port. ================ ====================================================== Attribute Description ================ ====================================================== port Output port max_len Max length to send to controller ================ ====================================================== """ def __init__(self, port, max_len=ofproto.OFPCML_MAX, type_=None, len_=None): super(OFPActionOutput, self).__init__() self.port = port self.max_len = max_len @classmethod def parser(cls, buf, offset): type_, len_, port, max_len = struct.unpack_from( ofproto.OFP_ACTION_OUTPUT_PACK_STR, buf, offset) return cls(port, max_len) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_OUTPUT_PACK_STR, buf, offset, self.type, self.len, self.port, self.max_len) @OFPAction.register_action_type(ofproto.OFPAT_GROUP, ofproto.OFP_ACTION_GROUP_SIZE) class OFPActionGroup(OFPAction): """ Group action This action indicates the group used to process the packet. ================ ====================================================== Attribute Description ================ ====================================================== group_id Group identifier ================ ====================================================== """ def __init__(self, group_id=0, type_=None, len_=None): super(OFPActionGroup, self).__init__() self.group_id = group_id @classmethod def parser(cls, buf, offset): (type_, len_, group_id) = struct.unpack_from( ofproto.OFP_ACTION_GROUP_PACK_STR, buf, offset) return cls(group_id) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_GROUP_PACK_STR, buf, offset, self.type, self.len, self.group_id) @OFPAction.register_action_type(ofproto.OFPAT_SET_QUEUE, ofproto.OFP_ACTION_SET_QUEUE_SIZE) class OFPActionSetQueue(OFPAction): """ Set queue action This action sets the queue id that will be used to map a flow to an already-configured queue on a port. ================ ====================================================== Attribute Description ================ ====================================================== queue_id Queue ID for the packets ================ ====================================================== """ def __init__(self, queue_id, type_=None, len_=None): super(OFPActionSetQueue, self).__init__() self.queue_id = queue_id @classmethod def parser(cls, buf, offset): (type_, len_, queue_id) = struct.unpack_from( ofproto.OFP_ACTION_SET_QUEUE_PACK_STR, buf, offset) return cls(queue_id) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_SET_QUEUE_PACK_STR, buf, offset, self.type, self.len, self.queue_id) @OFPAction.register_action_type(ofproto.OFPAT_SET_MPLS_TTL, ofproto.OFP_ACTION_MPLS_TTL_SIZE) class OFPActionSetMplsTtl(OFPAction): """ Set MPLS TTL action This action sets the MPLS TTL. ================ ====================================================== Attribute Description ================ ====================================================== mpls_ttl MPLS TTL ================ ====================================================== """ def __init__(self, mpls_ttl, type_=None, len_=None): super(OFPActionSetMplsTtl, self).__init__() self.mpls_ttl = mpls_ttl @classmethod def parser(cls, buf, offset): (type_, len_, mpls_ttl) = struct.unpack_from( ofproto.OFP_ACTION_MPLS_TTL_PACK_STR, buf, offset) return cls(mpls_ttl) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_MPLS_TTL_PACK_STR, buf, offset, self.type, self.len, self.mpls_ttl) @OFPAction.register_action_type(ofproto.OFPAT_DEC_MPLS_TTL, ofproto.OFP_ACTION_HEADER_SIZE) class OFPActionDecMplsTtl(OFPAction): """ Decrement MPLS TTL action This action decrements the MPLS TTL. """ def __init__(self, type_=None, len_=None): super(OFPActionDecMplsTtl, self).__init__() @classmethod def parser(cls, buf, offset): (type_, len_) = struct.unpack_from( ofproto.OFP_ACTION_HEADER_PACK_STR, buf, offset) return cls() @OFPAction.register_action_type(ofproto.OFPAT_SET_NW_TTL, ofproto.OFP_ACTION_NW_TTL_SIZE) class OFPActionSetNwTtl(OFPAction): """ Set IP TTL action This action sets the IP TTL. ================ ====================================================== Attribute Description ================ ====================================================== nw_ttl IP TTL ================ ====================================================== """ def __init__(self, nw_ttl, type_=None, len_=None): super(OFPActionSetNwTtl, self).__init__() self.nw_ttl = nw_ttl @classmethod def parser(cls, buf, offset): (type_, len_, nw_ttl) = struct.unpack_from( ofproto.OFP_ACTION_NW_TTL_PACK_STR, buf, offset) return cls(nw_ttl) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_NW_TTL_PACK_STR, buf, offset, self.type, self.len, self.nw_ttl) @OFPAction.register_action_type(ofproto.OFPAT_DEC_NW_TTL, ofproto.OFP_ACTION_HEADER_SIZE) class OFPActionDecNwTtl(OFPAction): """ Decrement IP TTL action This action decrements the IP TTL. """ def __init__(self, type_=None, len_=None): super(OFPActionDecNwTtl, self).__init__() @classmethod def parser(cls, buf, offset): (type_, len_) = struct.unpack_from( ofproto.OFP_ACTION_HEADER_PACK_STR, buf, offset) return cls() @OFPAction.register_action_type(ofproto.OFPAT_COPY_TTL_OUT, ofproto.OFP_ACTION_HEADER_SIZE) class OFPActionCopyTtlOut(OFPAction): """ Copy TTL Out action This action copies the TTL from the next-to-outermost header with TTL to the outermost header with TTL. """ def __init__(self, type_=None, len_=None): super(OFPActionCopyTtlOut, self).__init__() @classmethod def parser(cls, buf, offset): (type_, len_) = struct.unpack_from( ofproto.OFP_ACTION_HEADER_PACK_STR, buf, offset) return cls() @OFPAction.register_action_type(ofproto.OFPAT_COPY_TTL_IN, ofproto.OFP_ACTION_HEADER_SIZE) class OFPActionCopyTtlIn(OFPAction): """ Copy TTL In action This action copies the TTL from the outermost header with TTL to the next-to-outermost header with TTL. """ def __init__(self, type_=None, len_=None): super(OFPActionCopyTtlIn, self).__init__() @classmethod def parser(cls, buf, offset): (type_, len_) = struct.unpack_from( ofproto.OFP_ACTION_HEADER_PACK_STR, buf, offset) return cls() @OFPAction.register_action_type(ofproto.OFPAT_PUSH_VLAN, ofproto.OFP_ACTION_PUSH_SIZE) class OFPActionPushVlan(OFPAction): """ Push VLAN action This action pushes a new VLAN tag to the packet. ================ ====================================================== Attribute Description ================ ====================================================== ethertype Ether type. The default is 802.1Q. (0x8100) ================ ====================================================== """ def __init__(self, ethertype=ether.ETH_TYPE_8021Q, type_=None, len_=None): super(OFPActionPushVlan, self).__init__() self.ethertype = ethertype @classmethod def parser(cls, buf, offset): (type_, len_, ethertype) = struct.unpack_from( ofproto.OFP_ACTION_PUSH_PACK_STR, buf, offset) return cls(ethertype) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_PUSH_PACK_STR, buf, offset, self.type, self.len, self.ethertype) @OFPAction.register_action_type(ofproto.OFPAT_PUSH_MPLS, ofproto.OFP_ACTION_PUSH_SIZE) class OFPActionPushMpls(OFPAction): """ Push MPLS action This action pushes a new MPLS header to the packet. ================ ====================================================== Attribute Description ================ ====================================================== ethertype Ether type ================ ====================================================== """ def __init__(self, ethertype=ether.ETH_TYPE_MPLS, type_=None, len_=None): super(OFPActionPushMpls, self).__init__() self.ethertype = ethertype @classmethod def parser(cls, buf, offset): (type_, len_, ethertype) = struct.unpack_from( ofproto.OFP_ACTION_PUSH_PACK_STR, buf, offset) return cls(ethertype) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_PUSH_PACK_STR, buf, offset, self.type, self.len, self.ethertype) @OFPAction.register_action_type(ofproto.OFPAT_POP_VLAN, ofproto.OFP_ACTION_HEADER_SIZE) class OFPActionPopVlan(OFPAction): """ Pop VLAN action This action pops the outermost VLAN tag from the packet. """ def __init__(self, type_=None, len_=None): super(OFPActionPopVlan, self).__init__() @classmethod def parser(cls, buf, offset): (type_, len_) = struct.unpack_from( ofproto.OFP_ACTION_HEADER_PACK_STR, buf, offset) return cls() @OFPAction.register_action_type(ofproto.OFPAT_POP_MPLS, ofproto.OFP_ACTION_POP_MPLS_SIZE) class OFPActionPopMpls(OFPAction): """ Pop MPLS action This action pops the MPLS header from the packet. """ def __init__(self, ethertype=ether.ETH_TYPE_IP, type_=None, len_=None): super(OFPActionPopMpls, self).__init__() self.ethertype = ethertype @classmethod def parser(cls, buf, offset): (type_, len_, ethertype) = struct.unpack_from( ofproto.OFP_ACTION_POP_MPLS_PACK_STR, buf, offset) return cls(ethertype) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_POP_MPLS_PACK_STR, buf, offset, self.type, self.len, self.ethertype) @OFPAction.register_action_type(ofproto.OFPAT_SET_FIELD, ofproto.OFP_ACTION_SET_FIELD_SIZE) class OFPActionSetField(OFPAction): """ Set field action This action modifies a header field in the packet. The set of keywords available for this is same as OFPMatch which including with/without mask. Example:: set_field = OFPActionSetField(eth_src="00:00:00:00:00:00") set_field = OFPActionSetField(ipv4_src=("192.168.100.0", "255.255.255.0")) """ def __init__(self, field=None, **kwargs): super(OFPActionSetField, self).__init__() assert len(kwargs) == 1 key = list(kwargs.keys())[0] value = kwargs[key] assert isinstance(key, (str, str)) self.key = key self.value = value @classmethod def parser(cls, buf, offset): (type_, len_) = struct.unpack_from( ofproto.OFP_ACTION_SET_FIELD_PACK_STR, buf, offset) (n, value, mask, _len) = ofproto.oxm_parse(buf, offset + 4) k, uv = ofproto.oxm_to_user(n, value, mask) action = cls(**{k: uv}) action.len = len_ return action def serialize(self, buf, offset): n, value, mask = ofproto.oxm_from_user(self.key, self.value) len_ = ofproto.oxm_serialize(n, value, mask, buf, offset + 4) self.len = utils.round_up(4 + len_, 8) msg_pack_into('!HH', buf, offset, self.type, self.len) pad_len = self.len - (4 + len_) msg_pack_into("%dx" % pad_len, buf, offset + 4 + len_) def to_jsondict(self): return { self.__class__.__name__: { 'field': ofproto.oxm_to_jsondict(self.key, self.value), "len": self.len, "type": self.type } } @classmethod def from_jsondict(cls, dict_): k, v = ofproto.oxm_from_jsondict(dict_['field']) return OFPActionSetField(**{k: v}) def stringify_attrs(self): yield (self.key, self.value) @OFPAction.register_action_type(ofproto.OFPAT_PUSH_PBB, ofproto.OFP_ACTION_PUSH_SIZE) class OFPActionPushPbb(OFPAction): """ Push PBB action This action pushes a new PBB header to the packet. ================ ====================================================== Attribute Description ================ ====================================================== ethertype Ether type ================ ====================================================== """ def __init__(self, ethertype, type_=None, len_=None): super(OFPActionPushPbb, self).__init__() self.ethertype = ethertype @classmethod def parser(cls, buf, offset): (type_, len_, ethertype) = struct.unpack_from( ofproto.OFP_ACTION_PUSH_PACK_STR, buf, offset) return cls(ethertype) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_PUSH_PACK_STR, buf, offset, self.type, self.len, self.ethertype) @OFPAction.register_action_type(ofproto.OFPAT_POP_PBB, ofproto.OFP_ACTION_HEADER_SIZE) class OFPActionPopPbb(OFPAction): """ Pop PBB action This action pops the outermost PBB service instance header from the packet. """ def __init__(self, type_=None, len_=None): super(OFPActionPopPbb, self).__init__() @classmethod def parser(cls, buf, offset): (type_, len_) = struct.unpack_from( ofproto.OFP_ACTION_HEADER_PACK_STR, buf, offset) return cls() @OFPAction.register_action_type(ofproto.OFPAT_COPY_FIELD, ofproto.OFP_ACTION_COPY_FIELD_SIZE) class OFPActionCopyField(OFPAction): """ Copy Field action This action copy value between header and register. ================ ====================================================== Attribute Description ================ ====================================================== n_bits Number of bits to copy. src_offset Starting bit offset in source. dst_offset Starting bit offset in destination. oxm_ids List of ``OFPOxmId`` instances. The first element of this list, src_oxm_id, identifies the field where the value is copied from. The second element of this list, dst_oxm_id, identifies the field where the value is copied to. The default is []. ================ ====================================================== """ def __init__(self, n_bits=0, src_offset=0, dst_offset=0, oxm_ids=None, type_=None, len_=None): oxm_ids = oxm_ids if oxm_ids else [] super(OFPActionCopyField, self).__init__() self.n_bits = n_bits self.src_offset = src_offset self.dst_offset = dst_offset assert len(oxm_ids) == 2 self.oxm_ids = [] for i in oxm_ids: if isinstance(i, OFPOxmId): i.hasmask = False # fixup self.oxm_ids.append(i) elif isinstance(i, str): self.oxm_ids.append(OFPOxmId(i, hasmask=False)) else: raise ValueError('invalid value for oxm_ids: %s' % oxm_ids) @classmethod def parser(cls, buf, offset): (type_, len_, n_bits, src_offset, dst_offset) = struct.unpack_from( ofproto.OFP_ACTION_COPY_FIELD_PACK_STR, buf, offset) offset += ofproto.OFP_ACTION_COPY_FIELD_SIZE rest = buf[offset:offset + len_] oxm_ids = [] while rest: i, rest = OFPOxmId.parse(rest) oxm_ids.append(i) return cls(n_bits, src_offset, dst_offset, oxm_ids, type_, len_) def serialize(self, buf, offset): oxm_ids_buf = b'' for i in self.oxm_ids: oxm_ids_buf += i.serialize() action_len = ofproto.OFP_ACTION_COPY_FIELD_SIZE + len(oxm_ids_buf) self.len = utils.round_up(action_len, 8) pad_len = self.len - action_len msg_pack_into(ofproto.OFP_ACTION_COPY_FIELD_PACK_STR, buf, offset, self.type, self.len, self.n_bits, self.src_offset, self.dst_offset) buf += oxm_ids_buf + b'\x00' * pad_len @OFPAction.register_action_type(ofproto.OFPAT_METER, ofproto.OFP_ACTION_METER_SIZE) class OFPActionMeter(OFPAction): """ Meter action This action applies meter (rate limiter) ================ ====================================================== Attribute Description ================ ====================================================== meter_id Meter instance ================ ====================================================== """ def __init__(self, meter_id, type_=None, len_=None): super(OFPActionMeter, self).__init__() self.meter_id = meter_id @classmethod def parser(cls, buf, offset): type_, len_, meter_id = struct.unpack_from( ofproto.OFP_ACTION_METER_PACK_STR, buf, offset) return cls(meter_id) def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_METER_PACK_STR, buf, offset, self.type, self.len, self.meter_id) @OFPAction.register_action_type( ofproto.OFPAT_EXPERIMENTER, ofproto.OFP_ACTION_EXPERIMENTER_HEADER_SIZE) class OFPActionExperimenter(OFPAction): """ Experimenter action This action is an extensible action for the experimenter. ================ ====================================================== Attribute Description ================ ====================================================== experimenter Experimenter ID ================ ====================================================== .. Note:: For the list of the supported Nicira experimenter actions, please refer to :ref:`os_ken.ofproto.nx_actions `. """ def __init__(self, experimenter): super(OFPActionExperimenter, self).__init__() self.type = ofproto.OFPAT_EXPERIMENTER self.experimenter = experimenter self.len = None @classmethod def parser(cls, buf, offset): (type_, len_, experimenter) = struct.unpack_from( ofproto.OFP_ACTION_EXPERIMENTER_HEADER_PACK_STR, buf, offset) data = buf[(offset + ofproto.OFP_ACTION_EXPERIMENTER_HEADER_SIZE ): offset + len_] if experimenter == ofproto_common.NX_EXPERIMENTER_ID: obj = NXAction.parse(data) else: obj = OFPActionExperimenterUnknown(experimenter, data) obj.len = len_ return obj def serialize(self, buf, offset): msg_pack_into(ofproto.OFP_ACTION_EXPERIMENTER_HEADER_PACK_STR, buf, offset, self.type, self.len, self.experimenter) class OFPActionExperimenterUnknown(OFPActionExperimenter): def __init__(self, experimenter, data=None, type_=None, len_=None): super(OFPActionExperimenterUnknown, self).__init__(experimenter=experimenter) self.data = data def serialize(self, buf, offset): # fixup data = self.data if data is None: data = bytearray() self.len = (utils.round_up(len(data), 8) + ofproto.OFP_ACTION_EXPERIMENTER_HEADER_SIZE) super(OFPActionExperimenterUnknown, self).serialize(buf, offset) msg_pack_into('!%ds' % len(self.data), buf, offset + ofproto.OFP_ACTION_EXPERIMENTER_HEADER_SIZE, self.data) class OFPGroupProp(OFPPropBase): _TYPES = {} @OFPGroupProp.register_type(ofproto.OFPGPT_EXPERIMENTER) class OFPGroupPropExperimenter(OFPPropCommonExperimenter4ByteData): pass @_register_parser @_set_msg_type(ofproto.OFPT_GROUP_MOD) class OFPGroupMod(MsgBase): """ Modify group entry message The controller sends this message to modify the group table. ================== ====================================================== Attribute Description ================== ====================================================== command One of the following values. | OFPGC_ADD | OFPGC_MODIFY | OFPGC_DELETE | OFPGC_INSERT_BUCKET | OFPGC_REMOVE_BUCKET type One of the following values. | OFPGT_ALL | OFPGT_SELECT | OFPGT_INDIRECT | OFPGT_FF group_id Group identifier. command_bucket_id Bucket Id used as part of OFPGC_INSERT_BUCKET and OFPGC_REMOVE_BUCKET commands execution. buckets List of ``OFPBucket`` instance properties List of ``OFPGroupProp`` instance ================== ====================================================== ``type`` attribute corresponds to ``type_`` parameter of __init__. Example:: def send_group_mod(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser port = 1 max_len = 2000 actions = [ofp_parser.OFPActionOutput(port, max_len)] weight = 100 watch_port = 0 watch_group = 0 buckets = [ofp_parser.OFPBucket(weight, watch_port, watch_group, actions)] group_id = 1 command_bucket_id=1 req = ofp_parser.OFPGroupMod(datapath, ofp.OFPGC_ADD, ofp.OFPGT_SELECT, group_id, command_bucket_id, buckets) datapath.send_msg(req) """ def __init__(self, datapath, command=ofproto.OFPGC_ADD, type_=ofproto.OFPGT_ALL, group_id=0, command_bucket_id=ofproto.OFPG_BUCKET_ALL, buckets=None, properties=None, bucket_array_len=None): buckets = buckets if buckets else [] properties = properties if properties else [] super(OFPGroupMod, self).__init__(datapath) self.command = command self.type = type_ self.group_id = group_id self.command_bucket_id = command_bucket_id self.buckets = buckets self.properties = properties @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPGroupMod, cls).parser( datapath, version, msg_type, msg_len, xid, buf) (msg.command, msg.type, msg.group_id, msg.bucket_array_len, msg.command_bucket_id) = struct.unpack_from( ofproto.OFP_GROUP_MOD_PACK_STR, buf, ofproto.OFP_HEADER_SIZE) offset = ofproto.OFP_GROUP_MOD_SIZE bucket_buf = buf[offset:offset + msg.bucket_array_len] msg.buckets = [] while bucket_buf: bucket = OFPBucket.parser(bucket_buf, 0) msg.buckets.append(bucket) bucket_buf = bucket_buf[bucket.len:] offset += msg.bucket_array_len rest = buf[offset:offset + msg.msg_len] while rest: p, rest = OFPGroupProp.parse(rest) msg.properties.append(p) return msg def _serialize_body(self): offset = ofproto.OFP_GROUP_MOD_SIZE self.bucket_array_len = 0 for b in self.buckets: b.serialize(self.buf, offset) offset += b.len self.bucket_array_len += b.len msg_pack_into(ofproto.OFP_GROUP_MOD_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.command, self.type, self.group_id, self.bucket_array_len, self.command_bucket_id) bin_props = bytearray() for p in self.properties: bin_props += p.serialize() self.buf += bin_props class OFPPortModProp(OFPPropBase): _TYPES = {} class OFPPortModPropEthernet(OFPPortModProp): def __init__(self, type_=None, length=None, advertise=None): self.type = type_ self.advertise = advertise def serialize(self): # fixup self.length = struct.calcsize( ofproto.OFP_PORT_MOD_PROP_ETHERNET_PACK_STR) buf = bytearray() msg_pack_into(ofproto.OFP_PORT_MOD_PROP_ETHERNET_PACK_STR, buf, 0, self.type, self.length, self.advertise) return buf class OFPPortModPropOptical(OFPPortModProp): def __init__(self, type_=None, length=None, configure=None, freq_lmda=None, fl_offset=None, grid_span=None, tx_pwr=None): self.type = type_ self.length = length self.configure = configure self.freq_lmda = freq_lmda self.fl_offset = fl_offset self.grid_span = grid_span self.tx_pwr = tx_pwr def serialize(self): # fixup self.length = struct.calcsize( ofproto.OFP_PORT_MOD_PROP_OPTICAL_PACK_STR) buf = bytearray() msg_pack_into(ofproto.OFP_PORT_MOD_PROP_OPTICAL_PACK_STR, buf, 0, self.type, self.length, self.configure, self.freq_lmda, self.fl_offset, self.grid_span, self.tx_pwr) return buf class OFPPortModPropExperimenter(OFPPropCommonExperimenter4ByteData): pass @_set_msg_type(ofproto.OFPT_PORT_MOD) class OFPPortMod(MsgBase): """ Port modification message The controller sneds this message to modify the behavior of the port. ================ ====================================================== Attribute Description ================ ====================================================== port_no Port number to modify hw_addr The hardware address that must be the same as hw_addr of ``OFPPort`` of ``OFPSwitchFeatures`` config Bitmap of configuration flags. | OFPPC_PORT_DOWN | OFPPC_NO_RECV | OFPPC_NO_FWD | OFPPC_NO_PACKET_IN mask Bitmap of configuration flags above to be changed properties List of ``OFPPortModProp`` subclass instance ================ ====================================================== Example:: def send_port_mod(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser port_no = 3 hw_addr = 'fa:c8:e8:76:1d:7e' config = 0 mask = (ofp.OFPPC_PORT_DOWN | ofp.OFPPC_NO_RECV | ofp.OFPPC_NO_FWD | ofp.OFPPC_NO_PACKET_IN) advertise = (ofp.OFPPF_10MB_HD | ofp.OFPPF_100MB_FD | ofp.OFPPF_1GB_FD | ofp.OFPPF_COPPER | ofp.OFPPF_AUTONEG | ofp.OFPPF_PAUSE | ofp.OFPPF_PAUSE_ASYM) properties = [ofp_parser.OFPPortModPropEthernet(advertise)] req = ofp_parser.OFPPortMod(datapath, port_no, hw_addr, config, mask, properties) datapath.send_msg(req) """ _TYPE = { 'ascii': [ 'hw_addr', ] } def __init__(self, datapath, port_no=0, hw_addr='00:00:00:00:00:00', config=0, mask=0, properties=None): super(OFPPortMod, self).__init__(datapath) self.port_no = port_no self.hw_addr = hw_addr self.config = config self.mask = mask self.properties = properties or [] def _serialize_body(self): bin_props = bytearray() for p in self.properties: bin_props += p.serialize() msg_pack_into(ofproto.OFP_PORT_MOD_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.port_no, addrconv.mac.text_to_bin(self.hw_addr), self.config, self.mask) self.buf += bin_props class OFPGroupBucketProp(OFPPropBase): _TYPES = {} @OFPGroupBucketProp.register_type(ofproto.OFPGBPT_WEIGHT) class OFPGroupBucketPropWeight(OFPGroupBucketProp): def __init__(self, type_=None, length=None, weight=None): super(OFPGroupBucketPropWeight, self).__init__(type_, length) self.weight = weight @classmethod def parser(cls, buf): prop = cls() (prop.type, prop.length, prop.weight) = struct.unpack_from( ofproto.OFP_GROUP_BUCKET_PROP_WEIGHT_PACK_STR, buf, 0) return prop def serialize(self): # fixup self.length = ofproto.OFP_GROUP_BUCKET_PROP_WEIGHT_SIZE buf = bytearray() msg_pack_into(ofproto.OFP_GROUP_BUCKET_PROP_WEIGHT_PACK_STR, buf, 0, self.type, self.length, self.weight) return buf @OFPGroupBucketProp.register_type(ofproto.OFPGBPT_WATCH_PORT) @OFPGroupBucketProp.register_type(ofproto.OFPGBPT_WATCH_GROUP) class OFPGroupBucketPropWatch(OFPGroupBucketProp): def __init__(self, type_=None, length=None, watch=None): super(OFPGroupBucketPropWatch, self).__init__(type_, length) self.watch = watch @classmethod def parser(cls, buf): prop = cls() (prop.type, prop.length, prop.watch) = struct.unpack_from( ofproto.OFP_GROUP_BUCKET_PROP_WATCH_PACK_STR, buf, 0) return prop def serialize(self): # fixup self.length = ofproto.OFP_GROUP_BUCKET_PROP_WATCH_SIZE buf = bytearray() msg_pack_into(ofproto.OFP_GROUP_BUCKET_PROP_WATCH_PACK_STR, buf, 0, self.type, self.length, self.watch) return buf @OFPGroupBucketProp.register_type(ofproto.OFPGBPT_EXPERIMENTER) class OFPGroupBucketPropExperimenter(OFPPropCommonExperimenter4ByteData): pass class OFPBucket(StringifyMixin): def __init__(self, bucket_id=0, actions=None, properties=None, len_=None, action_array_len=None): actions = actions if actions else [] properties = properties if properties else [] super(OFPBucket, self).__init__() self.bucket_id = bucket_id self.actions = actions self.properties = properties @classmethod def parser(cls, buf, offset): msg = cls() (msg.len, msg.action_array_len, msg.bucket_id) = struct.unpack_from( ofproto.OFP_BUCKET_PACK_STR, buf, offset) offset += ofproto.OFP_BUCKET_SIZE action_buf = buf[offset:offset + msg.action_array_len] msg.actions = [] while action_buf: action = OFPAction.parser(action_buf, 0) msg.actions.append(action) action_buf = action_buf[action.len:] offset += msg.action_array_len rest = buf[offset:offset + msg.len] msg.properties = [] while rest: p, rest = OFPGroupBucketProp.parse(rest) msg.properties.append(p) return msg def serialize(self, buf, offset): action_offset = offset + ofproto.OFP_BUCKET_SIZE self.action_array_len = 0 for a in self.actions: a.serialize(buf, action_offset) action_offset += a.len self.action_array_len += a.len bin_props = bytearray() for p in self.properties: bin_props += p.serialize() props_len = len(bin_props) self.len = utils.round_up(ofproto.OFP_BUCKET_SIZE + self.action_array_len + props_len, 8) msg_pack_into(ofproto.OFP_BUCKET_PACK_STR, buf, offset, self.len, self.action_array_len, self.bucket_id) buf += bin_props @_set_msg_type(ofproto.OFPT_ROLE_REQUEST) class OFPRoleRequest(MsgBase): """ Role request message The controller uses this message to change its role. ================ ====================================================== Attribute Description ================ ====================================================== role One of the following values. | OFPCR_ROLE_NOCHANGE | OFPCR_ROLE_EQUAL | OFPCR_ROLE_MASTER | OFPCR_ROLE_SLAVE short_id ID number for the controller. The default is OFPCID_UNDEFINED. generation_id Master Election Generation ID ================ ====================================================== Example:: def send_role_request(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPRoleRequest(datapath, ofp.OFPCR_ROLE_EQUAL, ofp.OFPCID_UNDEFINED, 0) datapath.send_msg(req) """ def __init__(self, datapath, role=None, short_id=None, generation_id=None): super(OFPRoleRequest, self).__init__(datapath) self.role = role self.short_id = short_id self.generation_id = generation_id def _serialize_body(self): assert self.role is not None assert self.generation_id is not None if self.short_id is None: self.short_id = ofproto.OFPCID_UNDEFINED msg_pack_into(ofproto.OFP_ROLE_REQUEST_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.role, self.short_id, self.generation_id) @_register_parser @_set_msg_type(ofproto.OFPT_ROLE_REPLY) class OFPRoleReply(MsgBase): """ Role reply message The switch responds with this message to a role request. ================ ====================================================== Attribute Description ================ ====================================================== role One of the following values. | OFPCR_ROLE_NOCHANGE | OFPCR_ROLE_EQUAL | OFPCR_ROLE_MASTER | OFPCR_ROLE_SLAVE short_id ID number for the controller. The default is OFPCID_UNDEFINED. generation_id Master Election Generation ID ================ ====================================================== Example:: @set_ev_cls(ofp_event.EventOFPRoleReply, MAIN_DISPATCHER) def role_reply_handler(self, ev): msg = ev.msg dp = msg.datapath ofp = dp.ofproto if msg.role == ofp.OFPCR_ROLE_NOCHANGE: role = 'NOCHANGE' elif msg.role == ofp.OFPCR_ROLE_EQUAL: role = 'EQUAL' elif msg.role == ofp.OFPCR_ROLE_MASTER: role = 'MASTER' elif msg.role == ofp.OFPCR_ROLE_SLAVE: role = 'SLAVE' else: role = 'unknown' self.logger.debug('OFPRoleReply received: ' 'role=%s short_id=%d, generation_id=%d', role, msg.short_id, msg.generation_id) """ def __init__(self, datapath, role=None, short_id=None, generation_id=None): super(OFPRoleReply, self).__init__(datapath) self.role = role self.short_id = short_id self.generation_id = generation_id @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPRoleReply, cls).parser(datapath, version, msg_type, msg_len, xid, buf) (msg.role, msg.short_id, msg.generation_id) = struct.unpack_from( ofproto.OFP_ROLE_REQUEST_PACK_STR, msg.buf, ofproto.OFP_HEADER_SIZE) return msg class OFPAsyncConfigProp(OFPPropBase): _TYPES = {} @OFPAsyncConfigProp.register_type(ofproto.OFPACPT_PACKET_IN_SLAVE) @OFPAsyncConfigProp.register_type(ofproto.OFPACPT_PACKET_IN_MASTER) @OFPAsyncConfigProp.register_type(ofproto.OFPACPT_PORT_STATUS_SLAVE) @OFPAsyncConfigProp.register_type(ofproto.OFPACPT_PORT_STATUS_MASTER) @OFPAsyncConfigProp.register_type(ofproto.OFPACPT_FLOW_REMOVED_SLAVE) @OFPAsyncConfigProp.register_type(ofproto.OFPACPT_FLOW_REMOVED_MASTER) @OFPAsyncConfigProp.register_type(ofproto.OFPACPT_ROLE_STATUS_SLAVE) @OFPAsyncConfigProp.register_type(ofproto.OFPACPT_ROLE_STATUS_MASTER) @OFPAsyncConfigProp.register_type(ofproto.OFPACPT_TABLE_STATUS_SLAVE) @OFPAsyncConfigProp.register_type(ofproto.OFPACPT_TABLE_STATUS_MASTER) @OFPAsyncConfigProp.register_type(ofproto.OFPACPT_REQUESTFORWARD_SLAVE) @OFPAsyncConfigProp.register_type(ofproto.OFPACPT_REQUESTFORWARD_MASTER) class OFPAsyncConfigPropReasons(OFPAsyncConfigProp): def __init__(self, type_=None, length=None, mask=None): self.type = type_ self.length = length self.mask = mask @classmethod def parser(cls, buf): reasons = cls() (reasons.type, reasons.length, reasons.mask) = struct.unpack_from( ofproto.OFP_ASYNC_CONFIG_PROP_REASONS_PACK_STR, buf, 0) return reasons def serialize(self): # fixup self.length = ofproto.OFP_ASYNC_CONFIG_PROP_REASONS_SIZE buf = bytearray() msg_pack_into(ofproto.OFP_ASYNC_CONFIG_PROP_REASONS_PACK_STR, buf, 0, self.type, self.length, self.mask) return buf @OFPAsyncConfigProp.register_type(ofproto.OFPACPT_EXPERIMENTER_SLAVE) @OFPAsyncConfigProp.register_type(ofproto.OFPACPT_EXPERIMENTER_MASTER) class OFPAsyncConfigPropExperimenter(OFPPropCommonExperimenter4ByteData): pass @_set_msg_type(ofproto.OFPT_GET_ASYNC_REQUEST) class OFPGetAsyncRequest(MsgBase): """ Get asynchronous configuration request message The controller uses this message to query the asynchronous message. Example:: def send_get_async_request(self, datapath): ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPGetAsyncRequest(datapath) datapath.send_msg(req) """ def __init__(self, datapath): super(OFPGetAsyncRequest, self).__init__(datapath) @_register_parser @_set_msg_type(ofproto.OFPT_GET_ASYNC_REPLY) class OFPGetAsyncReply(MsgBase): """ Get asynchronous configuration reply message The switch responds with this message to a get asynchronous configuration request. ================== ==================================================== Attribute Description ================== ==================================================== properties List of ``OFPAsyncConfigProp`` subclass instances ================== ==================================================== Example:: @set_ev_cls(ofp_event.EventOFPGetAsyncReply, MAIN_DISPATCHER) def get_async_reply_handler(self, ev): msg = ev.msg self.logger.debug('OFPGetAsyncReply received: ' 'properties=%s', repr(msg.properties)) """ def __init__(self, datapath, properties=None): super(OFPGetAsyncReply, self).__init__(datapath) self.properties = properties @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPGetAsyncReply, cls).parser(datapath, version, msg_type, msg_len, xid, buf) msg.properties = [] rest = msg.buf[ofproto.OFP_HEADER_SIZE:] while rest: p, rest = OFPAsyncConfigProp.parse(rest) msg.properties.append(p) return msg @_set_msg_type(ofproto.OFPT_SET_ASYNC) class OFPSetAsync(MsgBase): """ Set asynchronous configuration message The controller sends this message to set the asynchronous messages that it wants to receive on a given OpneFlow channel. ================== ==================================================== Attribute Description ================== ==================================================== properties List of ``OFPAsyncConfigProp`` subclass instances ================== ==================================================== Example:: def send_set_async(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser properties = [ ofp_parser.OFPAsyncConfigPropReasons( ofp.OFPACPT_PACKET_IN_SLAVE, 8, (1 << ofp.OFPR_APPLY_ACTION | 1 << ofp.OFPR_INVALID_TTL))] req = ofp_parser.OFPSetAsync(datapath, properties) datapath.send_msg(req) """ def __init__(self, datapath, properties=None): super(OFPSetAsync, self).__init__(datapath) self.properties = properties def _serialize_body(self): bin_props = bytearray() for p in self.properties: bin_props += p.serialize() self.buf += bin_props @_register_parser @_set_msg_type(ofproto.OFPT_BUNDLE_CONTROL) class OFPBundleCtrlMsg(MsgBase): """ Bundle control message The controller uses this message to create, destroy and commit bundles ================ ====================================================== Attribute Description ================ ====================================================== bundle_id Id of the bundle type One of the following values. | OFPBCT_OPEN_REQUEST | OFPBCT_OPEN_REPLY | OFPBCT_CLOSE_REQUEST | OFPBCT_CLOSE_REPLY | OFPBCT_COMMIT_REQUEST | OFPBCT_COMMIT_REPLY | OFPBCT_DISCARD_REQUEST | OFPBCT_DISCARD_REPLY flags Bitmap of the following flags. | OFPBF_ATOMIC | OFPBF_ORDERED properties List of ``OFPBundleProp`` subclass instance ================ ====================================================== Example:: def send_bundle_control(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser req = ofp_parser.OFPBundleCtrlMsg(datapath, 7, ofp.OFPBCT_OPEN_REQUEST, ofp.OFPBF_ATOMIC, []) datapath.send_msg(req) """ def __init__(self, datapath, bundle_id=None, type_=None, flags=None, properties=None): super(OFPBundleCtrlMsg, self).__init__(datapath) self.bundle_id = bundle_id self.type = type_ self.flags = flags self.properties = properties def _serialize_body(self): bin_props = bytearray() for p in self.properties: bin_props += p.serialize() msg_pack_into(ofproto.OFP_BUNDLE_CTRL_MSG_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.bundle_id, self.type, self.flags) self.buf += bin_props @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPBundleCtrlMsg, cls).parser(datapath, version, msg_type, msg_len, xid, buf) (bundle_id, type_, flags) = struct.unpack_from( ofproto.OFP_BUNDLE_CTRL_MSG_PACK_STR, buf, ofproto.OFP_HEADER_SIZE) msg.bundle_id = bundle_id msg.type = type_ msg.flags = flags msg.properties = [] rest = msg.buf[ofproto.OFP_BUNDLE_CTRL_MSG_SIZE:] while rest: p, rest = OFPBundleProp.parse(rest) msg.properties.append(p) return msg @_set_msg_type(ofproto.OFPT_BUNDLE_ADD_MESSAGE) class OFPBundleAddMsg(MsgInMsgBase): """ Bundle add message The controller uses this message to add a message to a bundle ================ ====================================================== Attribute Description ================ ====================================================== bundle_id Id of the bundle flags Bitmap of the following flags. | OFPBF_ATOMIC | OFPBF_ORDERED message ``MsgBase`` subclass instance properties List of ``OFPBundleProp`` subclass instance ================ ====================================================== Example:: def send_bundle_add_message(self, datapath): ofp = datapath.ofproto ofp_parser = datapath.ofproto_parser msg = ofp_parser.OFPRoleRequest(datapath, ofp.OFPCR_ROLE_EQUAL, 0) req = ofp_parser.OFPBundleAddMsg(datapath, 7, ofp.OFPBF_ATOMIC, msg, []) datapath.send_msg(req) """ def __init__(self, datapath, bundle_id, flags, message, properties): super(OFPBundleAddMsg, self).__init__(datapath) self.bundle_id = bundle_id self.flags = flags self.message = message self.properties = properties def _serialize_body(self): # The xid of the inner message must be the same as # that of the outer message (OF1.4.0 7.3.9.2) if self.message.xid != self.xid: self.message.set_xid(self.xid) # Message self.message.serialize() tail_buf = self.message.buf # Pad if len(self.properties) > 0: message_len = len(tail_buf) pad_len = utils.round_up(message_len, 8) - message_len msg_pack_into("%dx" % pad_len, tail_buf, message_len) # Properties for p in self.properties: tail_buf += p.serialize() # Head msg_pack_into(ofproto.OFP_BUNDLE_ADD_MSG_0_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.bundle_id, self.flags) # Finish self.buf += tail_buf @_register_exp_type(ofproto_common.NX_EXPERIMENTER_ID, nicira_ext.NXT_SET_PACKET_IN_FORMAT) class NXTSetPacketInFormatMsg(OFPExperimenter): def __init__(self, datapath, packet_in_format): super(NXTSetPacketInFormatMsg, self).__init__( datapath, ofproto_common.NX_EXPERIMENTER_ID, nicira_ext.NXT_SET_PACKET_IN_FORMAT) self.packet_in_format = packet_in_format def _serialize_body(self): msg_pack_into(ofproto.OFP_EXPERIMENTER_HEADER_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.experimenter, self.exp_type) msg_pack_into(nicira_ext.NX_SET_PACKET_IN_FORMAT_PACK_STR, self.buf, ofproto.OFP_EXPERIMENTER_HEADER_SIZE, self.packet_in_format) @classmethod def parser_subtype(cls, super_msg): packet_in_format = struct.unpack_from( nicira_ext.NX_SET_PACKET_IN_FORMAT_PACK_STR, super_msg.data)[0] msg = cls(super_msg.datapath, packet_in_format) msg.properties = [] return msg @_register_exp_type(ofproto_common.NX_EXPERIMENTER_ID, nicira_ext.NXT_PACKET_IN2) class NXTPacketIn2(OFPExperimenter): def __init__(self, datapath, properties=None): super(NXTPacketIn2, self).__init__( datapath, ofproto_common.NX_EXPERIMENTER_ID, nicira_ext.NXT_PACKET_IN2) self.properties = properties or [] self.data = None self.total_len = None self.buffer_id = None self.table_id = None self.cookie = None self.reason = None self.metadata = None self.userdata = None self.continuation = None def _serialize_body(self): bin_props = bytearray() for p in self.properties: bin_props += p.serialize() msg_pack_into(ofproto.OFP_EXPERIMENTER_HEADER_PACK_STR, self.buf, ofproto.OFP_HEADER_SIZE, self.experimenter, self.exp_type) self.buf += bin_props @classmethod def parser_subtype(cls, super_msg): msg = cls(super_msg.datapath) rest = super_msg.data while rest: p, rest = NXTPacketIn2Prop.parse(rest) msg.properties.append(p) msg._parse_property(p) return msg def _parse_property(self, p): if p.type == nicira_ext.NXPINT_PACKET: self.data = p.data # Note: here total_len is length of packet but not msg self.total_len = p.length elif p.type == nicira_ext.NXPINT_FULL_LEN: self.total_len = struct.unpack_from('!I', p.data)[0] elif p.type == nicira_ext.NXPINT_BUFFER_ID: self.buffer_id = struct.unpack_from('!I', p.data)[0] elif p.type == nicira_ext.NXPINT_TABLE_ID: self.table_id = struct.unpack_from('B', p.data)[0] elif p.type == nicira_ext.NXPINT_COOKIE: self.cookie = struct.unpack_from('!Q', p.data)[0] elif p.type == nicira_ext.NXPINT_REASON: self.reason = struct.unpack_from('!B', p.data)[0] elif p.type == nicira_ext.NXPINT_METADATA: self.metadata = p.data elif p.type == nicira_ext.NXPINT_USERDATA: self.userdata = p.data elif p.type == nicira_ext.NXPINT_CONTINUATION: self.continuation = p.data class NXTPacketIn2Prop(OFPPropBase): _TYPES = {} _PROP_TYPE = None def __init__(self, type_=None, length=None, data=None): super(NXTPacketIn2Prop, self).__init__(type_, length) self.data = data @classmethod def parse(cls, buf): (type_, length) = struct.unpack_from(cls._PACK_STR, buf, 0) if not length: raise ValueError rest = buf[utils.round_up(length, 8):] try: subcls = cls._TYPES[type_] except KeyError: subcls = OFPPropUnknown prop = subcls.sub_parser(buf, type, length) prop.type = type_ prop.length = length return prop, rest def serialize_body(self): return self.data @classmethod def sub_parser(cls, buf, type, length): p = cls(type, length - 4, buf[4:length]) return p @NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_PACKET) class NXTPacketIn2PropPacket(NXTPacketIn2Prop): _PROP_TYPE = nicira_ext.NXPINT_PACKET @NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_FULL_LEN) class NXTPacketIn2PropFullLen(NXTPacketIn2Prop): _PROP_TYPE = nicira_ext.NXPINT_FULL_LEN @NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_BUFFER_ID) class NXTPacketIn2PropBufferId(NXTPacketIn2Prop): _PROP_TYPE = nicira_ext.NXPINT_BUFFER_ID @NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_TABLE_ID) class NXTPacketIn2PropTableId(NXTPacketIn2Prop): _PROP_TYPE = nicira_ext.NXPINT_TABLE_ID @NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_COOKIE) class NXTPacketIn2PropCookie(NXTPacketIn2Prop): _PROP_TYPE = nicira_ext.NXPINT_COOKIE @NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_REASON) class NXTPacketIn2PropReason(NXTPacketIn2Prop): _PROP_TYPE = nicira_ext.NXPINT_REASON @NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_METADATA) class NXTPacketIn2PropMetadata(NXTPacketIn2Prop): _PROP_TYPE = nicira_ext.NXPINT_METADATA @NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_USERDATA) class NXTPacketIn2PropUserData(NXTPacketIn2Prop): _PROP_TYPE = nicira_ext.NXPINT_USERDATA @NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_CONTINUATION) class NXTPacketIn2PropContinuation(NXTPacketIn2Prop): _PROP_TYPE = nicira_ext.NXPINT_CONTINUATION nx_actions.generate( 'os_ken.ofproto.ofproto_v1_5', 'os_ken.ofproto.ofproto_v1_5_parser' ) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/ofproto/oxm_fields.py0000664000175000017500000001663000000000000020470 0ustar00zuulzuul00000000000000# Copyright (C) 2013-2015 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013-2015 YAMAMOTO Takashi # # 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. # there are two representations of value and mask this module deal with. # # "user" # (value, mask) or value. the latter means no mask. # value and mask are strings. # # "internal" # value and mask are on-wire bytes. # mask is None if no mask. # There are two types of OXM/NXM headers. # # 32-bit OXM/NXM header # +-------------------------------+-------------+-+---------------+ # | class | field |m| length | # +-------------------------------+-------------+-+---------------+ # # 64-bit experimenter OXM header # +-------------------------------+-------------+-+---------------+ # | class (OFPXMC_EXPERIMENTER) | field |m| length | # +-------------------------------+-------------+-+---------------+ # | experimenter ID | # +---------------------------------------------------------------+ # NOTE: OpenFlow Spec 1.5 mandates that Experimenter OXMs encode # the experimenter type in the oxm_field field of the OXM header # (EXT-380). # NOTE: EXT-256 had a variation of experimenter OXM header. # It has been rectified since then. Currently this implementation # supports only the old version. # # ONF EXT-256 (old, exp_type = 2560) # +-------------------------------+-------------+-+---------------+ # | class (OFPXMC_EXPERIMENTER) | ????? |m| length | # +-------------------------------+-------------+-+---------------+ # | experimenter ID (ONF_EXPERIMENTER_ID) | # +-------------------------------+---------------+---------------+ # | exp_type (PBB_UCA=2560) | pbb_uca | # +-------------------------------+---------------+ # # ONF EXT-256 (new, oxm_field = 41) # +-------------------------------+-------------+-+---------------+ # | class (OFPXMC_EXPERIMENTER) | PBB_UCA=41 |m| length | # +-------------------------------+-------------+-+---------------+ # | experimenter ID (ONF_EXPERIMENTER_ID) | # +-------------------------------+---------------+---------------+ # | reserved, should be zero | pbb_uca | # +-------------------------------+---------------+ from os_ken.ofproto.oxx_fields import ( _get_field_info_by_name, _from_user, _from_user_header, _to_user, _to_user_header, _field_desc, _normalize_user, _parse, _parse_header, _serialize, _serialize_header) from os_ken.ofproto import ofproto_common OFPXMC_NXM_0 = 0 # Nicira Extended Match (NXM_OF_) OFPXMC_NXM_1 = 1 # Nicira Extended Match (NXM_NX_) OFPXMC_OPENFLOW_BASIC = 0x8000 OFPXMC_PACKET_REGS = 0x8001 OFPXMC_EXPERIMENTER = 0xffff class _OxmClass(object): def __init__(self, name, num, type_): self.name = name self.oxm_field = num self.oxm_type = num | (self._class << 7) # TODO(yamamoto): Clean this up later. # Probably when we drop EXT-256 style experimenter OXMs. self.num = self.oxm_type self.type = type_ class OpenFlowBasic(_OxmClass): _class = OFPXMC_OPENFLOW_BASIC class PacketRegs(_OxmClass): _class = OFPXMC_PACKET_REGS class _Experimenter(_OxmClass): _class = OFPXMC_EXPERIMENTER def __init__(self, name, num, type_): super(_Experimenter, self).__init__(name, num, type_) self.num = (self.experimenter_id, self.oxm_type) self.exp_type = self.oxm_field class ONFExperimenter(_Experimenter): experimenter_id = ofproto_common.ONF_EXPERIMENTER_ID class OldONFExperimenter(_Experimenter): # This class is for the old version of EXT-256 experimenter_id = ofproto_common.ONF_EXPERIMENTER_ID def __init__(self, name, num, type_): super(OldONFExperimenter, self).__init__(name, 0, type_) self.num = (self.experimenter_id, num) self.exp_type = 2560 class NiciraExperimenter(_Experimenter): experimenter_id = ofproto_common.NX_EXPERIMENTER_ID class NiciraNshExperimenter(_Experimenter): experimenter_id = ofproto_common.NX_NSH_EXPERIMENTER_ID class NiciraExtended0(_OxmClass): """Nicira Extended Match (NXM_0) NXM header format is same as 32-bit (non-experimenter) OXMs. """ _class = OFPXMC_NXM_0 class NiciraExtended1(_OxmClass): """Nicira Extended Match (NXM_1) NXM header format is same as 32-bit (non-experimenter) OXMs. """ _class = OFPXMC_NXM_1 def generate(modname): import sys import functools mod = sys.modules[modname] def add_attr(k, v): setattr(mod, k, v) for i in mod.oxm_types: if isinstance(i.num, tuple): continue if i._class != OFPXMC_OPENFLOW_BASIC: continue uk = i.name.upper() ofpxmt = i.oxm_field td = i.type add_attr('OFPXMT_OFB_' + uk, ofpxmt) add_attr('OXM_OF_' + uk, mod.oxm_tlv_header(ofpxmt, td.size)) add_attr('OXM_OF_' + uk + '_W', mod.oxm_tlv_header_w(ofpxmt, td.size)) # 'oxx' indicates the OpenFlow Extensible class type. # eg.) 'oxm' indicates that this class is OXM class. oxx = 'oxm' name_to_field = dict((f.name, f) for f in mod.oxm_types) num_to_field = dict((f.num, f) for f in mod.oxm_types) # create functions by using oxx_fields module. add_attr('oxm_get_field_info_by_name', functools.partial(_get_field_info_by_name, oxx, name_to_field)) add_attr('oxm_from_user', functools.partial(_from_user, oxx, name_to_field)) add_attr('oxm_from_user_header', functools.partial(_from_user_header, oxx, name_to_field)) add_attr('oxm_to_user', functools.partial(_to_user, oxx, num_to_field)) add_attr('oxm_to_user_header', functools.partial(_to_user_header, oxx, num_to_field)) add_attr('_oxm_field_desc', # oxx is not required functools.partial(_field_desc, num_to_field)) add_attr('oxm_normalize_user', functools.partial(_normalize_user, oxx, mod)) add_attr('oxm_parse', # oxx is not required functools.partial(_parse, mod)) add_attr('oxm_parse_header', # oxx is not required functools.partial(_parse_header, mod)) add_attr('oxm_serialize', functools.partial(_serialize, oxx, mod)) add_attr('oxm_serialize_header', functools.partial(_serialize_header, oxx, mod)) add_attr('oxm_to_jsondict', _to_jsondict) add_attr('oxm_from_jsondict', _from_jsondict) def _to_jsondict(k, uv): if isinstance(uv, tuple): (value, mask) = uv else: value = uv mask = None return {"OXMTlv": {"field": k, "value": value, "mask": mask}} def _from_jsondict(j): tlv = j['OXMTlv'] field = tlv['field'] value = tlv['value'] mask = tlv.get('mask') if mask is None: uv = value else: uv = (value, mask) return (field, uv) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/ofproto/oxs_fields.py0000664000175000017500000001334200000000000020473 0ustar00zuulzuul00000000000000# Copyright (C) 2015 Nippon Telegraph and Telephone 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. # there are two representations of value which this module deal with. # # "user" # the readable value which are strings. # # "internal" # the on-wire bytes value. # There are two types of OXS headers. # # 32-bit OXS header # 31 16 15 9 8 7 0 # +-------------------------------+-------------+-+---------------+ # | class | field |r| length | # +-------------------------------+-------------+-+---------------+ # # 64-bit experimenter OXS header # 31 16 15 9 8 7 0 # +-------------------------------+-------------+-+---------------+ # | class (OFPXSC_EXPERIMENTER) | field |r| length | # +-------------------------------+-------------+-+---------------+ # | experimenter ID | # +---------------------------------------------------------------+ # # Description of OXS header fields # +----------------------+-------+--------------------------------------------+ # | Name | Width | Usage | # +----------+-----------+-------+--------------------------------------------+ # | oxs_type | oxs_class | 16 | Stat class: member class or reserved class | # | +-----------+-------+--------------------------------------------+ # | | oxs_field | 7 | Stat field within the class | # +----------+-----------+-------+--------------------------------------------+ # | reserved | 1 | Reserved for future use | # +----------------------+-------+--------------------------------------------+ # | length | 8 | Length of OXS payload | # +----------------------+-------+--------------------------------------------+ # Assumption: The followings can be applied for OXSs too. # OpenFlow Spec 1.5 mandates that Experimenter OXMs encode the experimenter # type in the oxm_field field of the OXM header (EXT-380). from os_ken.ofproto.oxx_fields import ( _from_user, _from_user_header, _to_user, _to_user_header, _field_desc, _parse, _parse_header, _serialize, _serialize_header) OFPXSC_OPENFLOW_BASIC = 0x8002 OFPXSC_EXPERIMENTER = 0xFFFF OFPXSC_HEADER_PACK_STR = '!I' OFPXSC_EXP_HEADER_PACK_STR = '!I' class _OxsClass(object): # _class = OFPXSC_* must be an attribute of subclass. def __init__(self, name, num, type_): self.name = name self.oxs_field = num self.oxs_type = num | (self._class << 7) # 'num' has not corresponding field in the specification. # This is specific to this implementation and used to retrieve # _OxsClass subclass from 'num_to_field' dictionary. self.num = self.oxs_type self.type = type_ class OpenFlowBasic(_OxsClass): _class = OFPXSC_OPENFLOW_BASIC class _Experimenter(_OxsClass): _class = OFPXSC_EXPERIMENTER # experimenter_id must be an attribute of subclass. def __init__(self, name, num, type_): super(_Experimenter, self).__init__(name, num, type_) self.num = (self.experimenter_id, self.oxs_type) self.exp_type = self.oxs_field def generate(modname): import sys import functools mod = sys.modules[modname] def add_attr(k, v): setattr(mod, k, v) for i in mod.oxs_types: if isinstance(i.num, tuple): continue if i._class != OFPXSC_OPENFLOW_BASIC: continue uk = i.name.upper() ofpxst = i.oxs_field td = i.type add_attr('OFPXST_OFB_' + uk, ofpxst) add_attr('OXS_OF_' + uk, mod.oxs_tlv_header(ofpxst, td.size)) # 'oxx' indicates the OpenFlow Extensible class type. # eg.) 'oxs' indicates that this class is OXS class. oxx = 'oxs' name_to_field = dict((f.name, f) for f in mod.oxs_types) num_to_field = dict((f.num, f) for f in mod.oxs_types) # create functions by using oxx_fields module. add_attr('oxs_from_user', functools.partial(_from_user, oxx, name_to_field)) add_attr('oxs_from_user_header', functools.partial(_from_user_header, oxx, name_to_field)) add_attr('oxs_to_user', functools.partial(_to_user, oxx, num_to_field)) add_attr('oxs_to_user_header', functools.partial(_to_user_header, oxx, num_to_field)) add_attr('_oxs_field_desc', # oxx is not required functools.partial(_field_desc, num_to_field)) add_attr('oxs_parse', # oxx is not required functools.partial(_parse, mod)) add_attr('oxs_parse_header', # oxx is not required functools.partial(_parse_header, mod)) add_attr('oxs_serialize', functools.partial(_serialize, oxx, mod)) add_attr('oxs_serialize_header', functools.partial(_serialize_header, oxx, mod)) add_attr('oxs_to_jsondict', _to_jsondict) add_attr('oxs_from_jsondict', _from_jsondict) def _to_jsondict(k, uv): return {"OXSTlv": {"field": k, "value": uv}} def _from_jsondict(j): tlv = j['OXSTlv'] field = tlv['field'] value = tlv['value'] return (field, value) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/ofproto/oxx_fields.py0000664000175000017500000002120100000000000020471 0ustar00zuulzuul00000000000000# Copyright (C) 2015 Nippon Telegraph and Telephone 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. # there are two representations of value and mask this module deal with. # # "user" # (value, mask) or value. the latter means no mask. # value and mask are strings. # # "internal" # value and mask are on-wire bytes. # mask is None if no mask. import struct from os_ken.ofproto import ofproto_common from os_ken.lib.pack_utils import msg_pack_into from os_ken.lib import type_desc # 'OFPXXC_EXPERIMENTER' has not corresponding field in the specification. # This is transparently value for Experimenter class ID for OXM/OXS. OFPXXC_EXPERIMENTER = 0xffff def _get_field_info_by_name(oxx, name_to_field, name): try: f = name_to_field[name] t = f.type num = f.num except KeyError: t = type_desc.UnknownType if name.startswith('field_'): num = int(name.split('_')[1]) else: raise KeyError('unknown %s field: %s' % (oxx.upper(), name)) return num, t def _from_user_header(oxx, name_to_field, name): (num, t) = _get_field_info_by_name(oxx, name_to_field, name) return num def _from_user(oxx, name_to_field, name, user_value): (num, t) = _get_field_info_by_name(oxx, name_to_field, name) # the 'list' case below is a bit hack; json.dumps silently maps # python tuples into json lists. if oxx == 'oxm' and isinstance(user_value, (tuple, list)): (value, mask) = user_value else: value = user_value mask = None if value is not None: value = t.from_user(value) if mask is not None: mask = t.from_user(mask) elif isinstance(value, tuple): # This hack is to accomodate CIDR notations with IPv[46]Addr. value, mask = value return num, value, mask def _get_field_info_by_number(oxx, num_to_field, n): try: f = num_to_field[n] t = f.type name = f.name except KeyError: t = type_desc.UnknownType if isinstance(n, int): name = 'field_%d' % (n,) else: raise KeyError('unknown %s field number: %s' % (oxx.upper(), n)) return name, t def _to_user_header(oxx, num_to_field, n): (name, t) = _get_field_info_by_number(oxx, num_to_field, n) return name def _to_user(oxx, num_to_field, n, v, m): (name, t) = _get_field_info_by_number(oxx, num_to_field, n) if v is not None: if isinstance(v, (tuple, list)): v_len = len(v) * len(v[0]) else: v_len = len(v) if hasattr(t, 'size') and t.size != v_len: raise Exception( 'Unexpected %s payload length %d for %s (expected %d)' % (oxx.upper(), v_len, name, t.size)) value = t.to_user(v) else: value = None if m is None: user_value = value else: user_value = (value, t.to_user(m)) return name, user_value def _field_desc(num_to_field, n): return num_to_field[n] def _normalize_user(oxx, mod, k, uv): try: from_user = getattr(mod, oxx + '_from_user') (n, v, m) = from_user(k, uv) except: return (k, uv) # apply mask if m is not None: v = b''.join(struct.Struct(">B").pack(int(x) & int(y)) for (x, y) in zip(v, m)) try: to_user = getattr(mod, oxx + '_to_user') (k2, uv2) = to_user(n, v, m) except: return (k, uv) assert k2 == k return (k2, uv2) def _parse_header_impl(mod, buf, offset): hdr_pack_str = '!I' (header, ) = struct.unpack_from(hdr_pack_str, buf, offset) hdr_len = struct.calcsize(hdr_pack_str) oxx_type = header >> 9 # class|field oxm_hasmask = mod.oxm_tlv_header_extract_hasmask(header) oxx_class = oxx_type >> 7 oxx_length = header & 0xff if oxx_class == OFPXXC_EXPERIMENTER: # Experimenter OXMs/OXSs have 64-bit header. # (vs 32-bit for other OXMs/OXSs) exp_hdr_pack_str = '!I' # experimenter_id (exp_id, ) = struct.unpack_from(exp_hdr_pack_str, buf, offset + hdr_len) exp_hdr_len = struct.calcsize(exp_hdr_pack_str) assert exp_hdr_len == 4 oxx_field = oxx_type & 0x7f if exp_id == ofproto_common.ONF_EXPERIMENTER_ID and oxx_field == 0: # XXX # This block implements EXT-256 style experimenter OXM. onf_exp_type_pack_str = '!H' (exp_type, ) = struct.unpack_from(onf_exp_type_pack_str, buf, offset + hdr_len + exp_hdr_len) exp_hdr_len += struct.calcsize(onf_exp_type_pack_str) assert exp_hdr_len == 4 + 2 num = (exp_id, exp_type) else: num = (exp_id, oxx_type) else: num = oxx_type exp_hdr_len = 0 value_len = oxx_length - exp_hdr_len if oxm_hasmask: value_len //= 2 assert value_len > 0 field_len = hdr_len + oxx_length total_hdr_len = hdr_len + exp_hdr_len return num, total_hdr_len, oxm_hasmask, value_len, field_len def _parse_header(mod, buf, offset): (oxx_type_num, total_hdr_len, hasmask, value_len, field_len) = _parse_header_impl(mod, buf, offset) return oxx_type_num, field_len - value_len def _parse(mod, buf, offset): (oxx_type_num, total_hdr_len, hasmask, value_len, field_len) = _parse_header_impl(mod, buf, offset) # Note: OXM/OXS payload length (oxx_len) includes Experimenter ID # (exp_hdr_len) for experimenter OXMs/OXSs. value_offset = offset + total_hdr_len value_pack_str = '!%ds' % value_len assert struct.calcsize(value_pack_str) == value_len (value, ) = struct.unpack_from(value_pack_str, buf, value_offset) if hasmask: (mask, ) = struct.unpack_from(value_pack_str, buf, value_offset + value_len) else: mask = None return oxx_type_num, value, mask, field_len def _make_exp_hdr(oxx, mod, n): exp_hdr = bytearray() try: get_desc = getattr(mod, '_' + oxx + '_field_desc') desc = get_desc(n) except KeyError: return n, exp_hdr if desc._class == OFPXXC_EXPERIMENTER: (exp_id, exp_type) = n assert desc.experimenter_id == exp_id oxx_type = getattr(desc, oxx + '_type') if desc.exp_type == 2560: # XXX # This block implements EXT-256 style experimenter OXM. exp_hdr_pack_str = '!IH' # experimenter_id, exp_type msg_pack_into(exp_hdr_pack_str, exp_hdr, 0, desc.experimenter_id, desc.exp_type) else: assert oxx_type == exp_type | (OFPXXC_EXPERIMENTER << 7) exp_hdr_pack_str = '!I' # experimenter_id msg_pack_into(exp_hdr_pack_str, exp_hdr, 0, desc.experimenter_id) assert len(exp_hdr) == struct.calcsize(exp_hdr_pack_str) n = oxx_type assert (n >> 7) == OFPXXC_EXPERIMENTER return n, exp_hdr def _serialize_header(oxx, mod, n, buf, offset): try: get_desc = getattr(mod, '_' + oxx + '_field_desc') desc = get_desc(n) value_len = desc.type.size except KeyError: value_len = 0 n, exp_hdr = _make_exp_hdr(oxx, mod, n) exp_hdr_len = len(exp_hdr) pack_str = "!I%ds" % (exp_hdr_len,) msg_pack_into(pack_str, buf, offset, (n << 9) | (0 << 8) | (exp_hdr_len + value_len), bytes(exp_hdr)) return struct.calcsize(pack_str) def _serialize(oxx, mod, n, value, mask, buf, offset): n, exp_hdr = _make_exp_hdr(oxx, mod, n) exp_hdr_len = len(exp_hdr) value_len = len(value) if mask: assert value_len == len(mask) pack_str = "!I%ds%ds%ds" % (exp_hdr_len, value_len, len(mask)) msg_pack_into(pack_str, buf, offset, (n << 9) | (1 << 8) | (exp_hdr_len + value_len * 2), bytes(exp_hdr), value, mask) else: pack_str = "!I%ds%ds" % (exp_hdr_len, value_len,) msg_pack_into(pack_str, buf, offset, (n << 9) | (0 << 8) | (exp_hdr_len + value_len), bytes(exp_hdr), value) return struct.calcsize(pack_str) ././@PaxHeader0000000000000000000000000000003300000000000011451 xustar000000000000000027 mtime=1724334546.098105 os-ken-2.10.0/os_ken/services/0000775000175000017500000000000000000000000016112 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/__init__.py0000664000175000017500000000124600000000000020226 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013 YAMAMOTO Takashi # # 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. ././@PaxHeader0000000000000000000000000000003300000000000011451 xustar000000000000000027 mtime=1724334546.098105 os-ken-2.10.0/os_ken/services/protocols/0000775000175000017500000000000000000000000020136 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/__init__.py0000664000175000017500000000125200000000000022247 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013 Isaku Yamahata # # 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. ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.1021051 os-ken-2.10.0/os_ken/services/protocols/bgp/0000775000175000017500000000000000000000000020706 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/__init__.py0000664000175000017500000000000000000000000023005 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.1061053 os-ken-2.10.0/os_ken/services/protocols/bgp/api/0000775000175000017500000000000000000000000021457 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/api/__init__.py0000664000175000017500000000000000000000000023556 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/api/all.py0000664000175000017500000000017500000000000022604 0ustar00zuulzuul00000000000000# flake8: noqa from . import core from . import operator from . import prefix from . import rtconf from . import import_map ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/api/base.py0000664000175000017500000001644300000000000022753 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone 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. """ Public API for BGPSpeaker. This API can be used by various services like RPC, CLI, IoC, etc. """ import logging import traceback from os_ken.services.protocols.bgp.base import add_bgp_error_metadata from os_ken.services.protocols.bgp.base import API_ERROR_CODE from os_ken.services.protocols.bgp.base import BGPSException from os_ken.services.protocols.bgp.core_manager import CORE_MANAGER from os_ken.services.protocols.bgp.rtconf.base import get_validator from os_ken.services.protocols.bgp.rtconf.base import MissingRequiredConf from os_ken.services.protocols.bgp.rtconf.base import RuntimeConfigError LOG = logging.getLogger('bgpspeaker.api.base') # Various constants used in API calls ROUTE_DISTINGUISHER = 'route_dist' PREFIX = 'prefix' NEXT_HOP = 'next_hop' VPN_LABEL = 'label' API_SYM = 'name' ORIGIN_RD = 'origin_rd' ROUTE_FAMILY = 'route_family' EVPN_ROUTE_TYPE = 'route_type' EVPN_ESI = 'esi' EVPN_ETHERNET_TAG_ID = 'ethernet_tag_id' REDUNDANCY_MODE = 'redundancy_mode' MAC_ADDR = 'mac_addr' IP_ADDR = 'ip_addr' IP_PREFIX = 'ip_prefix' GW_IP_ADDR = 'gw_ip_addr' MPLS_LABELS = 'mpls_labels' TUNNEL_TYPE = 'tunnel_type' EVPN_VNI = 'vni' PMSI_TUNNEL_TYPE = 'pmsi_tunnel_type' TUNNEL_ENDPOINT_IP = 'tunnel_endpoint_ip' MAC_MOBILITY = 'mac_mobility' FLOWSPEC_FAMILY = 'flowspec_family' FLOWSPEC_RULES = 'rules' FLOWSPEC_ACTIONS = 'actions' # API call registry _CALL_REGISTRY = {} @add_bgp_error_metadata(code=API_ERROR_CODE, sub_code=1, def_desc='Unknown API error.') class ApiException(BGPSException): pass @add_bgp_error_metadata(code=API_ERROR_CODE, sub_code=2, def_desc='API symbol or method is not known.') class MethodNotFound(ApiException): pass @add_bgp_error_metadata(code=API_ERROR_CODE, sub_code=3, def_desc='Error related to BGPS core not starting.') class CoreNotStarted(ApiException): pass def register(**kwargs): """Decorator for registering API function. Does not do any check or validation. """ def decorator(func): _CALL_REGISTRY[kwargs.get(API_SYM, func.__name__)] = func return func return decorator class RegisterWithArgChecks(object): """Decorator for registering API functions. Does some argument checking and validation of required arguments. """ def __init__(self, name, req_args=None, opt_args=None): self._name = name if not req_args: req_args = [] self._req_args = req_args if not opt_args: opt_args = [] self._opt_args = opt_args self._all_args = (set(self._req_args) | set(self._opt_args)) def __call__(self, func): """Wraps given function and registers it as API. Returns original function. """ def wrapped_fun(**kwargs): """Wraps a function to do validation before calling actual func. Wraps a function to take key-value args. only. Checks if: 1) all required argument of wrapped function are provided 2) no extra/un-known arguments are passed 3) checks if validator for required arguments is available 4) validates required arguments 5) if validator for optional arguments is registered, validates optional arguments. Raises exception if no validator can be found for required args. """ # Check if we are missing arguments. if not kwargs and len(self._req_args) > 0: raise MissingRequiredConf(desc='Missing all required ' 'attributes.') # Check if we have unknown arguments. given_args = set(kwargs.keys()) unknown_attrs = given_args - set(self._all_args) if unknown_attrs: raise RuntimeConfigError(desc=('Unknown attributes %r' % unknown_attrs)) # Check if required arguments are missing missing_req_args = set(self._req_args) - given_args if missing_req_args: conf_name = ', '.join(missing_req_args) raise MissingRequiredConf(conf_name=conf_name) # # Prepare to call wrapped function. # # Collect required arguments in the order asked and validate it. req_values = [] for req_arg in self._req_args: req_value = kwargs.get(req_arg) # Validate required value. validator = get_validator(req_arg) if not validator: raise ValueError('No validator registered for function=%s' ' and arg=%s' % (func, req_arg)) validator(req_value) req_values.append(req_value) # Collect optional arguments. opt_items = {} for opt_arg, opt_value in kwargs.items(): if opt_arg in self._opt_args: # Validate optional value. # Note: If no validator registered for optional value, # skips validation. validator = get_validator(opt_arg) if validator: validator(opt_value) opt_items[opt_arg] = opt_value # Call actual function return func(*req_values, **opt_items) # Register wrapped function _CALL_REGISTRY[self._name] = wrapped_fun return func def is_call_registered(call_name): return call_name in _CALL_REGISTRY def get_call(call_name): return _CALL_REGISTRY.get(call_name) def call(symbol, **kwargs): """Calls/executes BGPS public API identified by given symbol and passes given kwargs as param. """ if 'password' in kwargs: log_str = str( dict(kwargs.items() - {'password': kwargs['password']}.items())) else: log_str = str(kwargs) LOG.info( "API method %s called with args: %s", symbol, log_str) # TODO(PH, JK) improve the way api function modules are loaded from . import all # noqa if not is_call_registered(symbol): message = 'Did not find any method registered by symbol %s' % symbol raise MethodNotFound(message) if not symbol.startswith('core') and not CORE_MANAGER.started: raise CoreNotStarted(desc='CoreManager is not active.') call = get_call(symbol) try: return call(**kwargs) except BGPSException as r: LOG.error(traceback.format_exc()) raise r except Exception as e: LOG.error(traceback.format_exc()) raise ApiException(desc=str(e)) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/api/core.py0000664000175000017500000000634100000000000022765 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone 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. """ Defines APIs related to Core/CoreManager. """ from os_ken.lib import hub from os_ken.services.protocols.bgp.api.base import register from os_ken.services.protocols.bgp.core_manager import CORE_MANAGER from os_ken.services.protocols.bgp.rtconf.base import RuntimeConfigError from os_ken.services.protocols.bgp.rtconf.common import CommonConf NEIGHBOR_RESET_WAIT_TIME = 3 @register(name='core.start') def start(**kwargs): """Starts new context using provided configuration. Raises RuntimeConfigError if a context is already active. """ if CORE_MANAGER.started: raise RuntimeConfigError('Current context has to be stopped to start ' 'a new context.') try: waiter = kwargs.pop('waiter') except KeyError: waiter = hub.Event() common_config = CommonConf(**kwargs) hub.spawn(CORE_MANAGER.start, *[], **{'common_conf': common_config, 'waiter': waiter}) return True @register(name='core.stop') def stop(**kwargs): """Stops current context is one is active. Raises RuntimeConfigError if runtime is not active or initialized yet. """ if not CORE_MANAGER.started: raise RuntimeConfigError('No runtime is active. Call start to create ' 'a runtime') CORE_MANAGER.stop() return True @register(name='core.reset_neighbor') def reset_neighbor(ip_address): neighs_conf = CORE_MANAGER.neighbors_conf neigh_conf = neighs_conf.get_neighbor_conf(ip_address) # Check if we have neighbor with given IP. if not neigh_conf: raise RuntimeConfigError('No neighbor configuration found for given' ' IP: %s' % ip_address) # If neighbor is enabled, we disable it. if neigh_conf.enabled: # Disable neighbor to close existing session. neigh_conf.enabled = False # Enable neighbor after NEIGHBOR_RESET_WAIT_TIME # this API works asynchronously # it's recommended to check it really reset neighbor later def up(): neigh_conf.enabled = True hub.spawn_after(NEIGHBOR_RESET_WAIT_TIME, up) else: raise RuntimeConfigError('Neighbor %s is not enabled, hence cannot' ' reset.' % ip_address) return True # ============================================================================= # Common configuration related APIs # ============================================================================= @register(name='comm_conf.get') def get_common_conf(): comm_conf = CORE_MANAGER.common_conf return comm_conf.settings ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/api/import_map.py0000664000175000017500000000523000000000000024200 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone 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. """ Import-map configuration. """ import logging from os_ken.services.protocols.bgp.api.base import register from os_ken.services.protocols.bgp.core_manager import CORE_MANAGER from os_ken.services.protocols.bgp.core_managers.import_map_manager\ import ImportMapAlreadyExistsError from os_ken.services.protocols.bgp.rtconf.base import RuntimeConfigError LOG = logging.getLogger('bgpspeaker.api.import_map') @register(name='importmap.create') def create_importmap(type, action, name, value, route_family=None): if action != 'drop': raise RuntimeConfigError( 'Unknown action. For now we only support "drop" action.' ) if type not in ('prefix_match', 'rt_match'): raise RuntimeConfigError( 'Unknown type. We support only "prefix_match" and "rt_match".' ) if type == 'prefix_match': return _create_prefix_match_importmap(name, value, route_family) elif type == 'rt_match': return _create_rt_match_importmap(name, value) def _create_prefix_match_importmap(name, value, route_family): core_service = CORE_MANAGER.get_core_service() importmap_manager = core_service.importmap_manager try: if route_family == 'ipv4': importmap_manager.create_vpnv4_nlri_import_map(name, value) elif route_family == 'ipv6': importmap_manager.create_vpnv6_nlri_import_map(name, value) else: raise RuntimeConfigError( 'Unknown address family %s. it should be ipv4 or ipv6' % route_family ) except ImportMapAlreadyExistsError: raise RuntimeConfigError( 'Map with this name already exists' ) return True def _create_rt_match_importmap(name, value): core_service = CORE_MANAGER.get_core_service() importmap_manager = core_service.importmap_manager try: importmap_manager.create_rt_import_map(name, value) except ImportMapAlreadyExistsError: raise RuntimeConfigError( 'Map with this name already exists' ) return True ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/api/operator.py0000664000175000017500000000462300000000000023671 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone 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. """ Api for operator. Mainly commands to build CLI and operator interface around them. """ import logging from os_ken.services.protocols.bgp.api.base import ApiException from os_ken.services.protocols.bgp.api.base import register from os_ken.services.protocols.bgp.api.rpc_log_handler import RpcLogHandler from os_ken.services.protocols.bgp.operator.command import Command from os_ken.services.protocols.bgp.operator.command import STATUS_ERROR from os_ken.services.protocols.bgp.operator.commands.clear import ClearCmd from os_ken.services.protocols.bgp.operator.commands.set import SetCmd from os_ken.services.protocols.bgp.operator.commands.show import ShowCmd from os_ken.services.protocols.bgp.operator.internal_api import InternalApi LOG = logging.getLogger('bgpspeaker.api.rtconf') DEFAULT_LOG_FORMAT = '%(asctime)s %(levelname)s %(message)s' def _init_log_handler(): log_handler = RpcLogHandler() log_handler.setLevel(logging.ERROR) log_handler.formatter = logging.Formatter(DEFAULT_LOG_FORMAT) return log_handler INTERNAL_API = InternalApi(_init_log_handler()) class RootCmd(Command): subcommands = { 'show': ShowCmd, 'set': SetCmd, 'clear': ClearCmd} def operator_run(cmd, **kwargs): params = kwargs.get('params', []) fmt = kwargs.get('format', 'json') root = RootCmd(api=INTERNAL_API, resp_formatter_name=fmt) ret, _ = root([cmd] + params) if ret.status == STATUS_ERROR: raise ApiException(str(ret.value)) return ret.value @register(name="operator.show") def operator_show(**kwargs): return operator_run('show', **kwargs) @register(name="operator.set") def operator_set(**kwargs): return operator_run('set', **kwargs) @register(name="operator.clear") def operator_clear(**kwargs): return operator_run('clear', **kwargs) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/api/prefix.py0000664000175000017500000004267300000000000023342 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone 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. """ Prefix related APIs. """ import logging from os_ken.lib.packet.bgp import EvpnEsi from os_ken.lib.packet.bgp import EvpnNLRI from os_ken.lib.packet.bgp import EvpnEthernetAutoDiscoveryNLRI from os_ken.lib.packet.bgp import EvpnMacIPAdvertisementNLRI from os_ken.lib.packet.bgp import EvpnInclusiveMulticastEthernetTagNLRI from os_ken.lib.packet.bgp import EvpnEthernetSegmentNLRI from os_ken.lib.packet.bgp import EvpnIpPrefixNLRI from os_ken.lib.packet.bgp import BGPPathAttributePmsiTunnel from os_ken.lib.packet.bgp import FlowSpecIPv4NLRI from os_ken.lib.packet.bgp import FlowSpecIPv6NLRI from os_ken.lib.packet.bgp import FlowSpecVPNv4NLRI from os_ken.lib.packet.bgp import FlowSpecVPNv6NLRI from os_ken.lib.packet.bgp import FlowSpecL2VPNNLRI from os_ken.lib.packet.bgp import BGPFlowSpecTrafficRateCommunity from os_ken.lib.packet.bgp import BGPFlowSpecTrafficActionCommunity from os_ken.lib.packet.bgp import BGPFlowSpecRedirectCommunity from os_ken.lib.packet.bgp import BGPFlowSpecTrafficMarkingCommunity from os_ken.lib.packet.bgp import BGPFlowSpecVlanActionCommunity from os_ken.lib.packet.bgp import BGPFlowSpecTPIDActionCommunity from os_ken.services.protocols.bgp.api.base import EVPN_ROUTE_TYPE from os_ken.services.protocols.bgp.api.base import EVPN_ESI from os_ken.services.protocols.bgp.api.base import EVPN_ETHERNET_TAG_ID from os_ken.services.protocols.bgp.api.base import REDUNDANCY_MODE from os_ken.services.protocols.bgp.api.base import MAC_ADDR from os_ken.services.protocols.bgp.api.base import IP_ADDR from os_ken.services.protocols.bgp.api.base import IP_PREFIX from os_ken.services.protocols.bgp.api.base import GW_IP_ADDR from os_ken.services.protocols.bgp.api.base import MPLS_LABELS from os_ken.services.protocols.bgp.api.base import NEXT_HOP from os_ken.services.protocols.bgp.api.base import PREFIX from os_ken.services.protocols.bgp.api.base import RegisterWithArgChecks from os_ken.services.protocols.bgp.api.base import ROUTE_DISTINGUISHER from os_ken.services.protocols.bgp.api.base import VPN_LABEL from os_ken.services.protocols.bgp.api.base import EVPN_VNI from os_ken.services.protocols.bgp.api.base import TUNNEL_TYPE from os_ken.services.protocols.bgp.api.base import PMSI_TUNNEL_TYPE from os_ken.services.protocols.bgp.api.base import MAC_MOBILITY from os_ken.services.protocols.bgp.api.base import TUNNEL_ENDPOINT_IP from os_ken.services.protocols.bgp.api.base import FLOWSPEC_FAMILY from os_ken.services.protocols.bgp.api.base import FLOWSPEC_RULES from os_ken.services.protocols.bgp.api.base import FLOWSPEC_ACTIONS from os_ken.services.protocols.bgp.base import add_bgp_error_metadata from os_ken.services.protocols.bgp.base import PREFIX_ERROR_CODE from os_ken.services.protocols.bgp.base import validate from os_ken.services.protocols.bgp.core import BgpCoreError from os_ken.services.protocols.bgp.core_manager import CORE_MANAGER from os_ken.services.protocols.bgp.rtconf.base import ConfigValueError from os_ken.services.protocols.bgp.rtconf.base import RuntimeConfigError from os_ken.services.protocols.bgp.rtconf.vrfs import VRF_RF from os_ken.services.protocols.bgp.rtconf.vrfs import VRF_RF_IPV4 from os_ken.services.protocols.bgp.rtconf.vrfs import VRF_RF_L2_EVPN from os_ken.services.protocols.bgp.utils import validation LOG = logging.getLogger('bgpspeaker.api.prefix') # Maximum value of the Ethernet Tag ID EVPN_MAX_ET = EvpnNLRI.MAX_ET # ESI Types ESI_TYPE_ARBITRARY = EvpnEsi.ARBITRARY ESI_TYPE_LACP = EvpnEsi.LACP ESI_TYPE_L2_BRIDGE = EvpnEsi.L2_BRIDGE ESI_TYPE_MAC_BASED = EvpnEsi.MAC_BASED ESI_TYPE_ROUTER_ID = EvpnEsi.ROUTER_ID ESI_TYPE_AS_BASED = EvpnEsi.AS_BASED SUPPORTED_ESI_TYPES = [ ESI_TYPE_ARBITRARY, ESI_TYPE_LACP, ESI_TYPE_L2_BRIDGE, ESI_TYPE_MAC_BASED, ESI_TYPE_ROUTER_ID, ESI_TYPE_AS_BASED, ] # Constants used in API calls for EVPN EVPN_ETH_AUTO_DISCOVERY = EvpnEthernetAutoDiscoveryNLRI.ROUTE_TYPE_NAME EVPN_MAC_IP_ADV_ROUTE = EvpnMacIPAdvertisementNLRI.ROUTE_TYPE_NAME EVPN_MULTICAST_ETAG_ROUTE = ( EvpnInclusiveMulticastEthernetTagNLRI.ROUTE_TYPE_NAME) EVPN_ETH_SEGMENT = EvpnEthernetSegmentNLRI.ROUTE_TYPE_NAME EVPN_IP_PREFIX_ROUTE = EvpnIpPrefixNLRI.ROUTE_TYPE_NAME SUPPORTED_EVPN_ROUTE_TYPES = [ EVPN_ETH_AUTO_DISCOVERY, EVPN_MAC_IP_ADV_ROUTE, EVPN_MULTICAST_ETAG_ROUTE, EVPN_ETH_SEGMENT, EVPN_IP_PREFIX_ROUTE, ] # Constants used in API calls for Flow Specification FLOWSPEC_FAMILY_IPV4 = FlowSpecIPv4NLRI.FLOWSPEC_FAMILY FLOWSPEC_FAMILY_IPV6 = FlowSpecIPv6NLRI.FLOWSPEC_FAMILY FLOWSPEC_FAMILY_VPNV4 = FlowSpecVPNv4NLRI.FLOWSPEC_FAMILY FLOWSPEC_FAMILY_VPNV6 = FlowSpecVPNv6NLRI.FLOWSPEC_FAMILY FLOWSPEC_FAMILY_L2VPN = FlowSpecL2VPNNLRI.FLOWSPEC_FAMILY SUPPORTED_FLOWSPEC_FAMILIES = ( FLOWSPEC_FAMILY_IPV4, FLOWSPEC_FAMILY_IPV6, FLOWSPEC_FAMILY_VPNV4, FLOWSPEC_FAMILY_VPNV6, FLOWSPEC_FAMILY_L2VPN, ) # Constants for the Traffic Filtering Actions of Flow Specification # Constants for the Traffic Filtering Actions of Flow Specification. FLOWSPEC_ACTION_TRAFFIC_RATE = BGPFlowSpecTrafficRateCommunity.ACTION_NAME FLOWSPEC_ACTION_TRAFFIC_ACTION = BGPFlowSpecTrafficActionCommunity.ACTION_NAME FLOWSPEC_ACTION_REDIRECT = BGPFlowSpecRedirectCommunity.ACTION_NAME FLOWSPEC_ACTION_TRAFFIC_MARKING = BGPFlowSpecTrafficMarkingCommunity.ACTION_NAME FLOWSPEC_ACTION_VLAN = BGPFlowSpecVlanActionCommunity.ACTION_NAME FLOWSPEC_ACTION_TPID = BGPFlowSpecTPIDActionCommunity.ACTION_NAME SUPPORTTED_FLOWSPEC_ACTIONS = ( FLOWSPEC_ACTION_TRAFFIC_RATE, FLOWSPEC_ACTION_TRAFFIC_ACTION, FLOWSPEC_ACTION_REDIRECT, FLOWSPEC_ACTION_TRAFFIC_MARKING, FLOWSPEC_ACTION_VLAN, FLOWSPEC_ACTION_TPID, ) # Constants for ESI Label extended community REDUNDANCY_MODE_ALL_ACTIVE = 'all_active' REDUNDANCY_MODE_SINGLE_ACTIVE = 'single_active' SUPPORTED_REDUNDANCY_MODES = [ REDUNDANCY_MODE_ALL_ACTIVE, REDUNDANCY_MODE_SINGLE_ACTIVE, ] # Constants for BGP Tunnel Encapsulation Attribute TUNNEL_TYPE_VXLAN = 'vxlan' TUNNEL_TYPE_NVGRE = 'nvgre' TUNNEL_TYPE_MPLS = 'mpls' TUNNEL_TYPE_MPLS_IN_GRE = 'mpls_in_gre' TUNNEL_TYPE_VXLAN_GRE = 'vxlan_gre' SUPPORTED_TUNNEL_TYPES = [ TUNNEL_TYPE_VXLAN, TUNNEL_TYPE_NVGRE, TUNNEL_TYPE_MPLS, TUNNEL_TYPE_MPLS_IN_GRE, TUNNEL_TYPE_VXLAN_GRE, ] # Constants for PMSI Tunnel Attribute PMSI_TYPE_NO_TUNNEL_INFO = ( BGPPathAttributePmsiTunnel.TYPE_NO_TUNNEL_INFORMATION_PRESENT ) PMSI_TYPE_INGRESS_REP = ( BGPPathAttributePmsiTunnel.TYPE_INGRESS_REPLICATION ) SUPPORTED_PMSI_TUNNEL_TYPES = [ PMSI_TYPE_NO_TUNNEL_INFO, PMSI_TYPE_INGRESS_REP, ] @add_bgp_error_metadata(code=PREFIX_ERROR_CODE, sub_code=1, def_desc='Unknown error related to operation on ' 'prefixes') class PrefixError(RuntimeConfigError): pass @validate(name=PREFIX) def is_valid_prefix(prefix): if not (validation.is_valid_ipv4_prefix(prefix) or validation.is_valid_ipv6_prefix(prefix)): raise ConfigValueError(conf_name=PREFIX, conf_value=prefix) @validate(name=NEXT_HOP) def is_valid_next_hop(next_hop): if not (validation.is_valid_ipv4(next_hop) or validation.is_valid_ipv6(next_hop)): raise ConfigValueError(conf_name=NEXT_HOP, conf_value=next_hop) @validate(name=EVPN_ROUTE_TYPE) def is_valid_evpn_route_type(route_type): if route_type not in SUPPORTED_EVPN_ROUTE_TYPES: raise ConfigValueError(conf_name=EVPN_ROUTE_TYPE, conf_value=route_type) @validate(name=EVPN_ESI) def is_valid_esi(esi): if not validation.is_valid_esi(esi): raise ConfigValueError(conf_name=EVPN_ESI, conf_value=esi) @validate(name=EVPN_ETHERNET_TAG_ID) def is_valid_ethernet_tag_id(ethernet_tag_id): if not validation.is_valid_ethernet_tag_id(ethernet_tag_id): raise ConfigValueError(conf_name=EVPN_ETHERNET_TAG_ID, conf_value=ethernet_tag_id) @validate(name=REDUNDANCY_MODE) def is_valid_redundancy_mode(redundancy_mode): if redundancy_mode not in SUPPORTED_REDUNDANCY_MODES: raise ConfigValueError(conf_name=REDUNDANCY_MODE, conf_value=redundancy_mode) @validate(name=MAC_ADDR) def is_valid_mac_addr(addr): if not validation.is_valid_mac(addr): raise ConfigValueError(conf_name=MAC_ADDR, conf_value=addr) @validate(name=IP_ADDR) def is_valid_ip_addr(addr): # Note: Allows empty IP Address (means length=0). # e.g.) L2VPN MAC advertisement of Cisco NX-OS if not (addr is None or validation.is_valid_ipv4(addr) or validation.is_valid_ipv6(addr)): raise ConfigValueError(conf_name=IP_ADDR, conf_value=addr) @validate(name=IP_PREFIX) def is_valid_ip_prefix(prefix): if not (validation.is_valid_ipv4_prefix(prefix) or validation.is_valid_ipv6_prefix(prefix)): raise ConfigValueError(conf_name=IP_PREFIX, conf_value=prefix) @validate(name=GW_IP_ADDR) def is_valid_gw_ip_addr(addr): if not (validation.is_valid_ipv4(addr) or validation.is_valid_ipv6(addr)): raise ConfigValueError(conf_name=GW_IP_ADDR, conf_value=addr) @validate(name=MPLS_LABELS) def is_valid_mpls_labels(labels): if not validation.is_valid_mpls_labels(labels): raise ConfigValueError(conf_name=MPLS_LABELS, conf_value=labels) @validate(name=EVPN_VNI) def is_valid_vni(vni): if not validation.is_valid_vni(vni): raise ConfigValueError(conf_name=EVPN_VNI, conf_value=vni) @validate(name=TUNNEL_TYPE) def is_valid_tunnel_type(tunnel_type): if tunnel_type not in SUPPORTED_TUNNEL_TYPES: raise ConfigValueError(conf_name=TUNNEL_TYPE, conf_value=tunnel_type) @validate(name=PMSI_TUNNEL_TYPE) def is_valid_pmsi_tunnel_type(pmsi_tunnel_type): if pmsi_tunnel_type not in SUPPORTED_PMSI_TUNNEL_TYPES: raise ConfigValueError(conf_name=PMSI_TUNNEL_TYPE, conf_value=pmsi_tunnel_type) @validate(name=FLOWSPEC_FAMILY) def is_valid_flowspec_family(flowspec_family): if flowspec_family not in SUPPORTED_FLOWSPEC_FAMILIES: raise ConfigValueError(conf_name=FLOWSPEC_FAMILY, conf_value=flowspec_family) @validate(name=FLOWSPEC_RULES) def is_valid_flowspec_rules(rules): if not isinstance(rules, dict): raise ConfigValueError(conf_name=FLOWSPEC_RULES, conf_value=rules) @validate(name=FLOWSPEC_ACTIONS) def is_valid_flowspec_actions(actions): for k in actions: if k not in SUPPORTTED_FLOWSPEC_ACTIONS: raise ConfigValueError(conf_name=FLOWSPEC_ACTIONS, conf_value=actions) @RegisterWithArgChecks(name='prefix.add_local', req_args=[ROUTE_DISTINGUISHER, PREFIX, NEXT_HOP], opt_args=[VRF_RF]) def add_local(route_dist, prefix, next_hop, route_family=VRF_RF_IPV4): """Adds *prefix* from VRF identified by *route_dist* and sets the source as network controller. """ try: # Create new path and insert into appropriate VRF table. tm = CORE_MANAGER.get_core_service().table_manager label = tm.update_vrf_table(route_dist, prefix, next_hop, route_family) # Currently we only allocate one label per local_prefix, # so we share first label from the list. if label: label = label[0] # Send success response with new label. return [{ROUTE_DISTINGUISHER: route_dist, PREFIX: prefix, VRF_RF: route_family, VPN_LABEL: label}] except BgpCoreError as e: raise PrefixError(desc=e) @RegisterWithArgChecks(name='prefix.delete_local', req_args=[ROUTE_DISTINGUISHER, PREFIX], opt_args=[VRF_RF]) def delete_local(route_dist, prefix, route_family=VRF_RF_IPV4): """Deletes/withdraws *prefix* from VRF identified by *route_dist* and source as network controller. """ try: tm = CORE_MANAGER.get_core_service().table_manager tm.update_vrf_table(route_dist, prefix, route_family=route_family, is_withdraw=True) # Send success response. return [{ROUTE_DISTINGUISHER: route_dist, PREFIX: prefix, VRF_RF: route_family}] except BgpCoreError as e: raise PrefixError(desc=e) # ============================================================================= # BGP EVPN Routes related APIs # ============================================================================= @RegisterWithArgChecks(name='evpn_prefix.add_local', req_args=[EVPN_ROUTE_TYPE, ROUTE_DISTINGUISHER, NEXT_HOP], opt_args=[EVPN_ESI, EVPN_ETHERNET_TAG_ID, REDUNDANCY_MODE, MAC_ADDR, IP_ADDR, IP_PREFIX, GW_IP_ADDR, EVPN_VNI, TUNNEL_TYPE, PMSI_TUNNEL_TYPE, TUNNEL_ENDPOINT_IP, MAC_MOBILITY]) def add_evpn_local(route_type, route_dist, next_hop, **kwargs): """Adds EVPN route from VRF identified by *route_dist*. """ if(route_type in [EVPN_ETH_AUTO_DISCOVERY, EVPN_ETH_SEGMENT] and kwargs['esi'] == 0): raise ConfigValueError(conf_name=EVPN_ESI, conf_value=kwargs['esi']) try: # Create new path and insert into appropriate VRF table. tm = CORE_MANAGER.get_core_service().table_manager label = tm.update_vrf_table(route_dist, next_hop=next_hop, route_family=VRF_RF_L2_EVPN, route_type=route_type, **kwargs) # Currently we only allocate one label per local route, # so we share first label from the list. if label: label = label[0] # Send success response with new label. return [{EVPN_ROUTE_TYPE: route_type, ROUTE_DISTINGUISHER: route_dist, VRF_RF: VRF_RF_L2_EVPN, VPN_LABEL: label}.update(kwargs)] except BgpCoreError as e: raise PrefixError(desc=e) @RegisterWithArgChecks(name='evpn_prefix.delete_local', req_args=[EVPN_ROUTE_TYPE, ROUTE_DISTINGUISHER], opt_args=[EVPN_ESI, EVPN_ETHERNET_TAG_ID, MAC_ADDR, IP_ADDR, IP_PREFIX, EVPN_VNI]) def delete_evpn_local(route_type, route_dist, **kwargs): """Deletes/withdraws EVPN route from VRF identified by *route_dist*. """ try: tm = CORE_MANAGER.get_core_service().table_manager tm.update_vrf_table(route_dist, route_family=VRF_RF_L2_EVPN, route_type=route_type, is_withdraw=True, **kwargs) # Send success response. return [{EVPN_ROUTE_TYPE: route_type, ROUTE_DISTINGUISHER: route_dist, VRF_RF: VRF_RF_L2_EVPN}.update(kwargs)] except BgpCoreError as e: raise PrefixError(desc=e) # ============================================================================= # BGP Flow Specification Routes related APIs # ============================================================================= @RegisterWithArgChecks( name='flowspec.add_local', req_args=[FLOWSPEC_FAMILY, ROUTE_DISTINGUISHER, FLOWSPEC_RULES], opt_args=[FLOWSPEC_ACTIONS]) def add_flowspec_local(flowspec_family, route_dist, rules, **kwargs): """Adds Flow Specification route from VRF identified by *route_dist*. """ try: # Create new path and insert into appropriate VRF table. tm = CORE_MANAGER.get_core_service().table_manager tm.update_flowspec_vrf_table( flowspec_family=flowspec_family, route_dist=route_dist, rules=rules, **kwargs) # Send success response. return [{FLOWSPEC_FAMILY: flowspec_family, ROUTE_DISTINGUISHER: route_dist, FLOWSPEC_RULES: rules}.update(kwargs)] except BgpCoreError as e: raise PrefixError(desc=e) @RegisterWithArgChecks( name='flowspec.del_local', req_args=[FLOWSPEC_FAMILY, ROUTE_DISTINGUISHER, FLOWSPEC_RULES]) def del_flowspec_local(flowspec_family, route_dist, rules): """Deletes/withdraws Flow Specification route from VRF identified by *route_dist*. """ try: tm = CORE_MANAGER.get_core_service().table_manager tm.update_flowspec_vrf_table( flowspec_family=flowspec_family, route_dist=route_dist, rules=rules, is_withdraw=True) # Send success response. return [{FLOWSPEC_FAMILY: flowspec_family, ROUTE_DISTINGUISHER: route_dist, FLOWSPEC_RULES: rules}] except BgpCoreError as e: raise PrefixError(desc=e) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/api/rpc_log_handler.py0000664000175000017500000000222000000000000025147 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone 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. """ Defined log handler to be used to log to RPC connection. """ import logging from os_ken.services.protocols.bgp.net_ctrl import NET_CONTROLLER from os_ken.services.protocols.bgp.net_ctrl import NOTIFICATION_LOG class RpcLogHandler(logging.Handler): """Outputs log records to `NET_CONTROLLER`.""" def emit(self, record): msg = self.format(record) NET_CONTROLLER.send_rpc_notification( NOTIFICATION_LOG, { 'level': record.levelname, 'msg': msg } ) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/api/rtconf.py0000664000175000017500000002622700000000000023335 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone 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. """ Runtime configuration manager. """ import logging from os_ken.services.protocols.bgp.api.base import register from os_ken.services.protocols.bgp.api.base import RegisterWithArgChecks from os_ken.services.protocols.bgp.api.base import FLOWSPEC_FAMILY from os_ken.services.protocols.bgp.api.base import FLOWSPEC_RULES from os_ken.services.protocols.bgp.api.base import FLOWSPEC_ACTIONS from os_ken.services.protocols.bgp.core_manager import CORE_MANAGER from os_ken.services.protocols.bgp.rtconf.base import ConfWithId from os_ken.services.protocols.bgp.rtconf.base import RuntimeConfigError from os_ken.services.protocols.bgp.rtconf import neighbors from os_ken.services.protocols.bgp.rtconf.neighbors import NeighborConf from os_ken.services.protocols.bgp.rtconf.vrfs import ROUTE_DISTINGUISHER from os_ken.services.protocols.bgp.rtconf.vrfs import VRF_RF from os_ken.services.protocols.bgp.rtconf.vrfs import VRF_RF_IPV4 from os_ken.services.protocols.bgp.rtconf.vrfs import VrfConf from os_ken.services.protocols.bgp import constants as const LOG = logging.getLogger('bgpspeaker.api.rtconf') # ============================================================================= # Neighbor configuration related APIs # ============================================================================= def _get_neighbor_conf(neigh_ip_address): """Returns neighbor configuration for given neighbor ip address. Raises exception if no neighbor with `neigh_ip_address` exists. """ neigh_conf = \ CORE_MANAGER.neighbors_conf.get_neighbor_conf(neigh_ip_address) if not neigh_conf: raise RuntimeConfigError(desc='No Neighbor configuration with IP' ' address %s' % neigh_ip_address) assert isinstance(neigh_conf, NeighborConf) return neigh_conf @register(name='neighbor.create') def create_neighbor(**kwargs): neigh_conf = NeighborConf(**kwargs) CORE_MANAGER.neighbors_conf.add_neighbor_conf(neigh_conf) return True @RegisterWithArgChecks(name='neighbor.update_enabled', req_args=[neighbors.IP_ADDRESS, neighbors.ENABLED]) def update_neighbor_enabled(neigh_ip_address, enabled): neigh_conf = _get_neighbor_conf(neigh_ip_address) neigh_conf.enabled = enabled return True @RegisterWithArgChecks(name='neighbor.update', req_args=[neighbors.IP_ADDRESS, neighbors.CHANGES]) def update_neighbor(neigh_ip_address, changes): rets = [] for k, v in changes.items(): if k == neighbors.MULTI_EXIT_DISC: rets.append(_update_med(neigh_ip_address, v)) if k == neighbors.ENABLED: rets.append(update_neighbor_enabled(neigh_ip_address, v)) if k == neighbors.CONNECT_MODE: rets.append(_update_connect_mode(neigh_ip_address, v)) return all(rets) def _update_med(neigh_ip_address, value): neigh_conf = _get_neighbor_conf(neigh_ip_address) neigh_conf.multi_exit_disc = value LOG.info('MED value for neigh: %s updated to %s', neigh_conf, value) return True def _update_connect_mode(neigh_ip_address, value): neigh_conf = _get_neighbor_conf(neigh_ip_address) neigh_conf.connect_mode = value return True @RegisterWithArgChecks(name='neighbor.delete', req_args=[neighbors.IP_ADDRESS]) def delete_neighbor(neigh_ip_address): neigh_conf = _get_neighbor_conf(neigh_ip_address) if neigh_conf: neigh_conf.enabled = False CORE_MANAGER.neighbors_conf.remove_neighbor_conf(neigh_ip_address) return True return False @RegisterWithArgChecks(name='neighbor.get', req_args=[neighbors.IP_ADDRESS]) def get_neighbor_conf(neigh_ip_address): """Returns a neighbor configuration for given ip address if exists.""" neigh_conf = _get_neighbor_conf(neigh_ip_address) return neigh_conf.settings @register(name='neighbors.get') def get_neighbors_conf(): return CORE_MANAGER.neighbors_conf.settings @RegisterWithArgChecks(name='neighbor.in_filter.get', req_args=[neighbors.IP_ADDRESS]) def get_neighbor_in_filter(neigh_ip_address): """Returns a neighbor in_filter for given ip address if exists.""" core = CORE_MANAGER.get_core_service() peer = core.peer_manager.get_by_addr(neigh_ip_address) return peer.in_filters @RegisterWithArgChecks(name='neighbor.in_filter.set', req_args=[neighbors.IP_ADDRESS, neighbors.IN_FILTER]) def set_neighbor_in_filter(neigh_ip_address, filters): """Returns a neighbor in_filter for given ip address if exists.""" core = CORE_MANAGER.get_core_service() peer = core.peer_manager.get_by_addr(neigh_ip_address) peer.in_filters = filters return True @RegisterWithArgChecks(name='neighbor.out_filter.get', req_args=[neighbors.IP_ADDRESS]) def get_neighbor_out_filter(neigh_ip_address): """Returns a neighbor out_filter for given ip address if exists.""" core = CORE_MANAGER.get_core_service() ret = core.peer_manager.get_by_addr(neigh_ip_address).out_filters return ret @RegisterWithArgChecks(name='neighbor.out_filter.set', req_args=[neighbors.IP_ADDRESS, neighbors.OUT_FILTER]) def set_neighbor_out_filter(neigh_ip_address, filters): """Sets the out_filter of a neighbor.""" core = CORE_MANAGER.get_core_service() peer = core.peer_manager.get_by_addr(neigh_ip_address) peer.out_filters = filters return True @RegisterWithArgChecks(name='neighbor.attribute_map.set', req_args=[neighbors.IP_ADDRESS, neighbors.ATTRIBUTE_MAP], opt_args=[ROUTE_DISTINGUISHER, VRF_RF]) def set_neighbor_attribute_map(neigh_ip_address, at_maps, route_dist=None, route_family=VRF_RF_IPV4): """set attribute_maps to the neighbor.""" core = CORE_MANAGER.get_core_service() peer = core.peer_manager.get_by_addr(neigh_ip_address) at_maps_key = const.ATTR_MAPS_LABEL_DEFAULT at_maps_dict = {} if route_dist is not None: vrf_conf =\ CORE_MANAGER.vrfs_conf.get_vrf_conf(route_dist, route_family) if vrf_conf: at_maps_key = ':'.join([route_dist, route_family]) else: raise RuntimeConfigError(desc='No VrfConf with rd %s' % route_dist) at_maps_dict[const.ATTR_MAPS_LABEL_KEY] = at_maps_key at_maps_dict[const.ATTR_MAPS_VALUE] = at_maps peer.attribute_maps = at_maps_dict return True @RegisterWithArgChecks(name='neighbor.attribute_map.get', req_args=[neighbors.IP_ADDRESS], opt_args=[ROUTE_DISTINGUISHER, VRF_RF]) def get_neighbor_attribute_map(neigh_ip_address, route_dist=None, route_family=VRF_RF_IPV4): """Returns a neighbor attribute_map for given ip address if exists.""" core = CORE_MANAGER.get_core_service() peer = core.peer_manager.get_by_addr(neigh_ip_address) at_maps_key = const.ATTR_MAPS_LABEL_DEFAULT if route_dist is not None: at_maps_key = ':'.join([route_dist, route_family]) at_maps = peer.attribute_maps.get(at_maps_key) if at_maps: return at_maps.get(const.ATTR_MAPS_ORG_KEY) else: return [] # ============================================================================= # VRF configuration related APIs # ============================================================================= @register(name='vrf.create') def create_vrf(**kwargs): vrf_conf = VrfConf(**kwargs) CORE_MANAGER.vrfs_conf.add_vrf_conf(vrf_conf) return True @register(name='vrf.update') def update_vrf(**kwargs): route_dist = kwargs.get(ROUTE_DISTINGUISHER) vrf_id = kwargs.get(ConfWithId.ID) vrf_rf = kwargs.get(VRF_RF) vrf_conf = CORE_MANAGER.vrfs_conf.get_vrf_conf( route_dist, vrf_rf, vrf_id=vrf_id ) # If we do not have a VrfConf with given id, we create one. if not vrf_conf: create_vrf(**kwargs) else: vrf_conf.update(**kwargs) return True @RegisterWithArgChecks(name='vrf.delete', req_args=[ROUTE_DISTINGUISHER]) def delete_vrf(route_dist): vrf_conf = CORE_MANAGER.vrfs_conf.remove_vrf_conf(route_dist) if vrf_conf: return True return False @RegisterWithArgChecks( name='vrf.get', req_args=[ROUTE_DISTINGUISHER], opt_args=[VRF_RF]) def get_vrf(route_dist, route_family=VRF_RF_IPV4): vrf_conf = CORE_MANAGER.vrfs_conf.get_vrf_conf( route_dist, vrf_rf=route_family ) if not vrf_conf: raise RuntimeConfigError(desc='No VrfConf with vpn id %s' % route_dist) return vrf_conf.settings @register(name='vrfs.get') def get_vrfs_conf(): vrfs_conf = CORE_MANAGER.vrfs_conf return vrfs_conf.settings # ============================================================================= # network configuration related APIs # ============================================================================= @register(name='network.add') def add_network(prefix, next_hop=None): tm = CORE_MANAGER.get_core_service().table_manager tm.update_global_table(prefix, next_hop) return True @register(name='network.del') def del_network(prefix): tm = CORE_MANAGER.get_core_service().table_manager tm.update_global_table(prefix, is_withdraw=True) return True # ============================================================================= # BMP configuration related APIs # ============================================================================= @register(name='bmp.start') def bmp_start(host, port): core = CORE_MANAGER.get_core_service() return core.start_bmp(host, port) @register(name='bmp.stop') def bmp_stop(host, port): core = CORE_MANAGER.get_core_service() return core.stop_bmp(host, port) # ============================================================================= # BGP Flow Specification Routes related APIs # ============================================================================= @RegisterWithArgChecks( name='flowspec.add', req_args=[FLOWSPEC_FAMILY, FLOWSPEC_RULES], opt_args=[FLOWSPEC_ACTIONS]) def add_flowspec(flowspec_family, rules, **kwargs): tm = CORE_MANAGER.get_core_service().table_manager tm.update_flowspec_global_table(flowspec_family, rules, **kwargs) return True @RegisterWithArgChecks( name='flowspec.del', req_args=[FLOWSPEC_FAMILY, FLOWSPEC_RULES]) def del_flowspec(flowspec_family, rules): tm = CORE_MANAGER.get_core_service().table_manager tm.update_flowspec_global_table(flowspec_family, rules, is_withdraw=True) return True ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/application.py0000664000175000017500000003450600000000000023573 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone 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 provides a convenient application for using OSKen BGPSpeaker and for writing your BGP application. It reads a configuration file which includes settings for neighbors, routes and some others. Please refer to ``os_ken/services/protocols/bgp/bgp_sample_conf.py`` for the sample configuration. Usage Example:: $ osken-manager os_ken/services/protocols/bgp/application.py \\ --bgp-app-config-file os_ken/services/protocols/bgp/bgp_sample_conf.py SSH Console =========== You can also use the SSH console and see the RIB and do some operations from this console. The SSH port and username/password can be configured by the configuration file. You can check the help by hitting '?' key in this interface. Example:: $ ssh localhost -p 4990 Hello, this is OSKen BGP speaker (version 4.19). bgpd> # Hit '?' key clear - allows to reset BGP connections help - show this help quit - exit this session set - set runtime settings show - shows runtime state information bgpd> bgpd> show rib all Status codes: * valid, > best Origin codes: i - IGP, e - EGP, ? - incomplete Network Labels Next Hop Reason Metric LocPrf Path *> 10.10.1.0/24 None 0.0.0.0 Only Path i bgpd> Integration with Other Applications =================================== ``os_ken.services.protocols.bgp.application.OSKenBGPSpeaker`` will notifies the following events to other OSKen applications. - ``EventBestPathChanged`` - ``EventAdjRibInChanged`` - ``EventPeerDown`` - ``EventPeerUp`` To catch these events, specify ``@set_ev_cls()`` decorator to the event handlers in the OSKen applications. Example Application:: # my_bgp_app.py from os_ken.base import app_manager from os_ken.controller.handler import set_ev_cls from os_ken.services.protocols.bgp import application as bgp_application class MyBGPApp(app_manager.OSKenApp): _CONTEXTS = { 'os_kenbgpspeaker': bgp_application.OSKenBGPSpeaker, } def __init__(self, *args, **kwargs): super(MyBGPApp, self).__init__(*args, **kwargs) # Stores "os_ken.services.protocols.bgp.application.OSKenBGPSpeaker" # instance in order to call the APIs of # "os_ken.services.protocols.bgp.bgpspeaker.BGPSpeaker" via # "self.app.speaker". # Please note at this time, "BGPSpeaker" is NOT instantiated yet. self.app = kwargs['os_kenbgpspeaker'] @set_ev_cls(bgp_application.EventBestPathChanged) def _best_patch_changed_handler(self, ev): self.logger.info( 'Best path changed: is_withdraw=%s, path=%s', ev.is_withdraw, ev.path) Usage Example:: $ osken-manager my_bgp_app.py \\ --bgp-app-config-file os_ken/services/protocols/bgp/bgp_sample_conf.py .. note:: For the APIs for ``os_ken.services.protocols.bgp.bgpspeaker.BGPSpeaker``, please refer to :doc:`../library_bgp_speaker_ref`. API Reference ============= """ import logging import os from os_ken import cfg from os_ken.lib import hub from os_ken.utils import load_source from os_ken.base.app_manager import OSKenApp from os_ken.controller.event import EventBase from os_ken.services.protocols.bgp.base import add_bgp_error_metadata from os_ken.services.protocols.bgp.base import BGPSException from os_ken.services.protocols.bgp.base import BIN_ERROR from os_ken.services.protocols.bgp.bgpspeaker import BGPSpeaker from os_ken.services.protocols.bgp.net_ctrl import NET_CONTROLLER from os_ken.services.protocols.bgp.net_ctrl import NC_RPC_BIND_IP from os_ken.services.protocols.bgp.net_ctrl import NC_RPC_BIND_PORT from os_ken.services.protocols.bgp.rtconf.base import RuntimeConfigError from os_ken.services.protocols.bgp.rtconf.common import LOCAL_AS from os_ken.services.protocols.bgp.rtconf.common import ROUTER_ID from os_ken.services.protocols.bgp.utils.validation import is_valid_ipv4 from os_ken.services.protocols.bgp.utils.validation import is_valid_ipv6 LOG = logging.getLogger('bgpspeaker.application') CONF = cfg.CONF['bgp-app'] @add_bgp_error_metadata(code=BIN_ERROR, sub_code=1, def_desc='Unknown bootstrap exception.') class ApplicationException(BGPSException): """ Specific Base exception related to `BSPSpeaker`. """ pass def validate_rpc_host(ip): """ Validates the given ip for use as RPC server address. """ if not is_valid_ipv4(ip) and not is_valid_ipv6(ip): raise ApplicationException( desc='Invalid RPC ip address: %s' % ip) return ip def load_config(config_file): """ Validates the given file for use as the settings file for BGPSpeaker and loads the configuration from the given file as a module instance. """ if not config_file or not os.path.isfile(config_file): raise ApplicationException( desc='Invalid configuration file: %s' % config_file) # Loads the configuration from the given file, if available. try: return load_source('bgpspeaker.application.settings', config_file) except Exception as e: raise ApplicationException(desc=str(e)) class EventBestPathChanged(EventBase): """ Event called when any best remote path is changed due to UPDATE messages or remote peer's down. This event is the wrapper for ``best_path_change_handler`` of ``bgpspeaker.BGPSpeaker``. ``path`` attribute contains an instance of ``info_base.base.Path`` subclasses. If ``is_withdraw`` attribute is ``True``, ``path`` attribute has the information of the withdraw route. """ def __init__(self, path, is_withdraw): super(EventBestPathChanged, self).__init__() self.path = path self.is_withdraw = is_withdraw class EventAdjRibInChanged(EventBase): """ Event called when any adj-RIB-in path is changed due to UPDATE messages or remote peer's down. This event is the wrapper for ``adj_rib_in_change_handler`` of ``bgpspeaker.BGPSpeaker``. ``path`` attribute contains an instance of ``info_base.base.Path`` subclasses. If ``is_withdraw`` attribute is ``True``, ``path`` attribute has the information of the withdraw route. ``peer_ip`` is the peer's IP address who sent this path. ``peer_as`` is the peer's AS number who sent this path. """ def __init__(self, path, is_withdraw, peer_ip, peer_as): super(EventAdjRibInChanged, self).__init__() self.path = path self.is_withdraw = is_withdraw self.peer_ip = peer_ip self.peer_as = peer_as class EventPeerDown(EventBase): """ Event called when the session to the remote peer goes down. This event is the wrapper for ``peer_down_handler`` of ``bgpspeaker.BGPSpeaker``. ``remote_ip`` attribute is the IP address of the remote peer. ``remote_as`` attribute is the AS number of the remote peer. """ def __init__(self, remote_ip, remote_as): super(EventPeerDown, self).__init__() self.remote_ip = remote_ip self.remote_as = remote_as class EventPeerUp(EventBase): """ Event called when the session to the remote peer goes up. This event is the wrapper for ``peer_up_handler`` of ``bgpspeaker.BGPSpeaker``. ``remote_ip`` attribute is the IP address of the remote peer. ``remote_as`` attribute is the AS number of the remote peer. """ def __init__(self, remote_ip, remote_as): super(EventPeerUp, self).__init__() self.remote_ip = remote_ip self.remote_as = remote_as class OSKenBGPSpeaker(OSKenApp): """ Base application for implementing BGP applications. """ _EVENTS = [ EventBestPathChanged, EventAdjRibInChanged, EventPeerDown, EventPeerUp, ] def __init__(self, *args, **kwargs): super(OSKenBGPSpeaker, self).__init__(*args, **kwargs) self.config_file = CONF.config_file # BGPSpeaker instance (not instantiated yet) self.speaker = None def start(self): super(OSKenBGPSpeaker, self).start() # If configuration file was provided and loaded successfully, we start # BGPSpeaker using the given settings. # If no configuration file is provided or if any minimum required # setting is missing, BGPSpeaker will not be started. if self.config_file: LOG.debug('Loading config file %s...', self.config_file) settings = load_config(self.config_file) # Configure logging settings, if available. if hasattr(settings, 'LOGGING'): # Not implemented yet. LOG.debug('Loading LOGGING settings... (NOT implemented yet)') # from logging.config import dictConfig # logging_settings = dictConfig(settings.LOGGING) # Configure BGP settings, if available. if hasattr(settings, 'BGP'): LOG.debug('Loading BGP settings...') self._start_speaker(settings.BGP) # Configure SSH settings, if available. if hasattr(settings, 'SSH'): LOG.debug('Loading SSH settings...') # Note: paramiko used in bgp.operator.ssh is the optional # requirements, imports bgp.operator.ssh here. from os_ken.services.protocols.bgp.operator import ssh hub.spawn(ssh.SSH_CLI_CONTROLLER.start, **settings.SSH) # Start RPC server with the given RPC settings. rpc_settings = { NC_RPC_BIND_PORT: CONF.rpc_port, NC_RPC_BIND_IP: validate_rpc_host(CONF.rpc_host), } return hub.spawn(NET_CONTROLLER.start, **rpc_settings) def _start_speaker(self, settings): """ Starts BGPSpeaker using the given settings. """ # Check required settings. _required_settings = ( LOCAL_AS, ROUTER_ID, ) for required in _required_settings: if required not in settings: raise ApplicationException( desc='Required BGP configuration missing: %s' % required) # Set event notify handlers if no corresponding handler specified. settings.setdefault( 'best_path_change_handler', self._notify_best_path_changed_event) settings.setdefault( 'adj_rib_in_change_handler', self._notify_adj_rib_in_changed_event) settings.setdefault( 'peer_down_handler', self._notify_peer_down_event) settings.setdefault( 'peer_up_handler', self._notify_peer_up_event) # Pop settings other than creating BGPSpeaker instance. neighbors_settings = settings.pop('neighbors', []) vrfs_settings = settings.pop('vrfs', []) routes_settings = settings.pop('routes', []) # Create BGPSpeaker instance. LOG.debug('Starting BGPSpeaker...') settings.setdefault('as_number', settings.pop(LOCAL_AS)) self.speaker = BGPSpeaker(**settings) # Add neighbors. LOG.debug('Adding neighbors...') self._add_neighbors(neighbors_settings) # Add VRFs. LOG.debug('Adding VRFs...') self._add_vrfs(vrfs_settings) # Add routes LOG.debug('Adding routes...') self._add_routes(routes_settings) def _notify_best_path_changed_event(self, ev): ev = EventBestPathChanged(ev.path, ev.is_withdraw) self.send_event_to_observers(ev) def _notify_adj_rib_in_changed_event(self, ev, peer_ip, peer_as): ev = EventAdjRibInChanged(ev.path, ev.is_withdraw, peer_ip, peer_as) self.send_event_to_observers(ev) def _notify_peer_down_event(self, remote_ip, remote_as): ev = EventPeerDown(remote_ip, remote_as) self.send_event_to_observers(ev) def _notify_peer_up_event(self, remote_ip, remote_as): ev = EventPeerUp(remote_ip, remote_as) self.send_event_to_observers(ev) def _add_neighbors(self, settings): """ Add BGP neighbors from the given settings. All valid neighbors are loaded. Miss-configured neighbors are ignored and errors are logged. """ for neighbor_settings in settings: LOG.debug('Adding neighbor settings: %s', neighbor_settings) try: self.speaker.neighbor_add(**neighbor_settings) except RuntimeConfigError as e: LOG.exception(e) def _add_vrfs(self, settings): """ Add BGP VRFs from the given settings. All valid VRFs are loaded. Miss-configured VRFs are ignored and errors are logged. """ for vrf_settings in settings: LOG.debug('Adding VRF settings: %s', vrf_settings) try: self.speaker.vrf_add(**vrf_settings) except RuntimeConfigError as e: LOG.exception(e) def _add_routes(self, settings): """ Add BGP routes from given settings. All valid routes are loaded. Miss-configured routes are ignored and errors are logged. """ for route_settings in settings: if 'prefix' in route_settings: prefix_add = self.speaker.prefix_add elif 'route_type' in route_settings: prefix_add = self.speaker.evpn_prefix_add elif 'flowspec_family' in route_settings: prefix_add = self.speaker.flowspec_prefix_add else: LOG.debug('Skip invalid route settings: %s', route_settings) continue LOG.debug('Adding route settings: %s', route_settings) try: prefix_add(**route_settings) except RuntimeConfigError as e: LOG.exception(e) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/base.py0000664000175000017500000004530400000000000022200 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone 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. """ Defines some base class related to managing green threads. """ import abc from collections import OrderedDict import logging import socket import time import traceback import weakref import netaddr from os_ken.lib import hub from os_ken.lib import sockopt from os_ken.lib import ip from os_ken.lib.hub import Timeout from os_ken.lib.packet.bgp import RF_IPv4_UC from os_ken.lib.packet.bgp import RF_IPv6_UC from os_ken.lib.packet.bgp import RF_IPv4_VPN from os_ken.lib.packet.bgp import RF_IPv6_VPN from os_ken.lib.packet.bgp import RF_L2_EVPN from os_ken.lib.packet.bgp import RF_IPv4_FLOWSPEC from os_ken.lib.packet.bgp import RF_IPv6_FLOWSPEC from os_ken.lib.packet.bgp import RF_VPNv4_FLOWSPEC from os_ken.lib.packet.bgp import RF_VPNv6_FLOWSPEC from os_ken.lib.packet.bgp import RF_L2VPN_FLOWSPEC from os_ken.lib.packet.bgp import RF_RTC_UC from os_ken.services.protocols.bgp.utils.circlist import CircularListType from os_ken.services.protocols.bgp.utils.evtlet import LoopingCall # Logger instance for this module. LOG = logging.getLogger('bgpspeaker.base') # Pointer to active/available OrderedDict. OrderedDict = OrderedDict # Currently supported address families. SUPPORTED_GLOBAL_RF = { RF_IPv4_UC, RF_IPv6_UC, RF_IPv4_VPN, RF_RTC_UC, RF_IPv6_VPN, RF_L2_EVPN, RF_IPv4_FLOWSPEC, RF_IPv6_FLOWSPEC, RF_VPNv4_FLOWSPEC, RF_VPNv6_FLOWSPEC, RF_L2VPN_FLOWSPEC, } # Various error codes ACTIVITY_ERROR_CODE = 100 RUNTIME_CONF_ERROR_CODE = 200 BIN_ERROR = 300 NET_CTRL_ERROR_CODE = 400 API_ERROR_CODE = 500 PREFIX_ERROR_CODE = 600 BGP_PROCESSOR_ERROR_CODE = 700 CORE_ERROR_CODE = 800 # Registry of custom exceptions # Key: code:sub-code # Value: exception class _EXCEPTION_REGISTRY = {} class BGPSException(Exception): """Base exception class for all BGPS related exceptions. """ CODE = 1 SUB_CODE = 1 DEF_DESC = 'Unknown exception.' def __init__(self, desc=None): super(BGPSException, self).__init__() if not desc: desc = self.__class__.DEF_DESC kls = self.__class__ self.message = '%d.%d - %s' % (kls.CODE, kls.SUB_CODE, desc) def __repr__(self): kls = self.__class__ return '<%s(desc=%s)>' % (kls, self.message) def __str__(self, *args, **kwargs): return self.message def add_bgp_error_metadata(code, sub_code, def_desc='unknown'): """Decorator for all exceptions that want to set exception class meta-data. """ # Check registry if we already have an exception with same code/sub-code if _EXCEPTION_REGISTRY.get((code, sub_code)) is not None: raise ValueError('BGPSException with code %d and sub-code %d ' 'already defined.' % (code, sub_code)) def decorator(subclass): """Sets class constants for exception code and sub-code. If given class is sub-class of BGPSException we sets class constants. """ if issubclass(subclass, BGPSException): _EXCEPTION_REGISTRY[(code, sub_code)] = subclass subclass.CODE = code subclass.SUB_CODE = sub_code subclass.DEF_DESC = def_desc return subclass return decorator @add_bgp_error_metadata(code=ACTIVITY_ERROR_CODE, sub_code=1, def_desc='Unknown activity exception.') class ActivityException(BGPSException): """Base class for exceptions related to Activity. """ pass class Activity(object, metaclass=abc.ABCMeta): """Base class for a thread of execution that provides some custom settings. Activity is also a container of other activities or threads that it has started. Inside a Activity you should always use one of the spawn method to start another activity or greenthread. Activity is also holds pointers to sockets that it or its child activities of threads have create. """ def __init__(self, name=None): self._name = name if self._name is None: self._name = 'UnknownActivity: ' + str(time.time()) self._child_thread_map = weakref.WeakValueDictionary() self._child_activity_map = weakref.WeakValueDictionary() self._asso_socket_map = weakref.WeakValueDictionary() self._timers = weakref.WeakValueDictionary() self._started = False @property def name(self): return self._name @property def started(self): return self._started def _validate_activity(self, activity): """Checks the validity of the given activity before it can be started. """ if not self._started: raise ActivityException(desc='Tried to spawn a child activity' ' before Activity was started.') if activity.started: raise ActivityException(desc='Tried to start an Activity that was ' 'already started.') def _spawn_activity(self, activity, *args, **kwargs): """Starts *activity* in a new thread and passes *args* and *kwargs*. Maintains pointer to this activity and stops *activity* when this activity is stopped. """ self._validate_activity(activity) # Spawn a new greenthread for given activity greenthread = hub.spawn(activity.start, *args, **kwargs) self._child_thread_map[activity.name] = greenthread self._child_activity_map[activity.name] = activity return greenthread def _spawn_activity_after(self, seconds, activity, *args, **kwargs): self._validate_activity(activity) # Schedule to spawn a new greenthread after requested delay greenthread = hub.spawn_after(seconds, activity.start, *args, **kwargs) self._child_thread_map[activity.name] = greenthread self._child_activity_map[activity.name] = activity return greenthread def _validate_callable(self, callable_): if callable_ is None: raise ActivityException(desc='Callable cannot be None') if not hasattr(callable_, '__call__'): raise ActivityException(desc='Currently only supports instances' ' that have __call__ as callable which' ' is missing in given arg.') if not self._started: raise ActivityException(desc='Tried to spawn a child thread ' 'before this Activity was started.') def _spawn(self, name, callable_, *args, **kwargs): self._validate_callable(callable_) greenthread = hub.spawn(callable_, *args, **kwargs) self._child_thread_map[name] = greenthread return greenthread def _spawn_after(self, name, seconds, callable_, *args, **kwargs): self._validate_callable(callable_) greenthread = hub.spawn_after(seconds, callable_, *args, **kwargs) self._child_thread_map[name] = greenthread return greenthread def _create_timer(self, name, func, *arg, **kwarg): timer = LoopingCall(func, *arg, **kwarg) self._timers[name] = timer return timer @abc.abstractmethod def _run(self, *args, **kwargs): """Main activity of this class. Can launch other activity/callables here. Sub-classes should override this method. """ raise NotImplementedError() def start(self, *args, **kwargs): """Starts the main activity of this class. Calls *_run* and calls *stop* when *_run* is finished. This method should be run in a new greenthread as it may not return immediately. """ if self.started: raise ActivityException(desc='Activity already started') self._started = True try: self._run(*args, **kwargs) except BGPSException: LOG.error(traceback.format_exc()) finally: if self.started: # could have been stopped somewhere else self.stop() def pause(self, seconds=0): """Relinquishes hub for given number of seconds. In other words is puts to sleep to give other greenthread a chance to run. """ hub.sleep(seconds) def _stop_child_activities(self, name=None): """Stop all child activities spawn by this activity. """ # Makes a list copy of items() to avoid dictionary size changed # during iteration for child_name, child in list(self._child_activity_map.items()): if name is not None and name != child_name: continue LOG.debug('%s: Stopping child activity %s ', self.name, child_name) if child.started: child.stop() self._child_activity_map.pop(child_name, None) def _stop_child_threads(self, name=None): """Stops all threads spawn by this activity. """ for thread_name, thread in list(self._child_thread_map.items()): if name is None or thread_name == name: LOG.debug('%s: Stopping child thread %s', self.name, thread_name) thread.kill() self._child_thread_map.pop(thread_name, None) def _close_asso_sockets(self): """Closes all the sockets linked to this activity. """ for sock_name, sock in list(self._asso_socket_map.items()): LOG.debug('%s: Closing socket %s - %s', self.name, sock_name, sock) sock.close() def _stop_timers(self): for timer_name, timer in list(self._timers.items()): LOG.debug('%s: Stopping timer %s', self.name, timer_name) timer.stop() def stop(self): """Stops all child threads and activities and closes associated sockets. Re-initializes this activity to be able to start again. If the activity is not started (is already stopped), it will silently return. """ if not self.started: return LOG.debug('Stopping activity %s.', self.name) self._stop_timers() self._stop_child_activities() self._stop_child_threads() self._close_asso_sockets() # Setup activity for start again. self._started = False self._asso_socket_map = weakref.WeakValueDictionary() self._child_activity_map = weakref.WeakValueDictionary() self._child_thread_map = weakref.WeakValueDictionary() self._timers = weakref.WeakValueDictionary() LOG.debug('Stopping activity %s finished.', self.name) def _canonicalize_ip(self, ip): addr = netaddr.IPAddress(ip) if addr.is_ipv4_mapped(): ip = str(addr.ipv4()) return ip def get_remotename(self, sock): addr, port = sock.getpeername()[:2] return self._canonicalize_ip(addr), str(port) def get_localname(self, sock): addr, port = sock.getsockname()[:2] return self._canonicalize_ip(addr), str(port) def _create_listen_socket(self, family, loc_addr): s = socket.socket(family) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.bind(loc_addr) s.listen(1) return s def _listen_socket_loop(self, s, conn_handle): while True: sock, client_address = s.accept() client_address, port = self.get_remotename(sock) LOG.debug('Connect request received from client for port' ' %s:%s', client_address, port) client_name = self.name + '_client@' + client_address self._asso_socket_map[client_name] = sock self._spawn(client_name, conn_handle, sock) def _listen_tcp(self, loc_addr, conn_handle): """Creates a TCP server socket which listens on `port` number. For each connection `server_factory` starts a new protocol. """ info = socket.getaddrinfo(loc_addr[0], loc_addr[1], socket.AF_UNSPEC, socket.SOCK_STREAM, 0, socket.AI_PASSIVE) listen_sockets = {} for res in info: af, socktype, proto, _, sa = res sock = None try: sock = socket.socket(af, socktype, proto) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) if af == socket.AF_INET6: sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 1) sock.bind(sa) sock.listen(50) listen_sockets[sa] = sock except socket.error as e: LOG.error('Error creating socket: %s', e) if sock: sock.close() count = 0 server = None for sa in listen_sockets: name = self.name + '_server@' + str(sa[0]) self._asso_socket_map[name] = listen_sockets[sa] if count == 0: import eventlet server = eventlet.spawn(self._listen_socket_loop, listen_sockets[sa], conn_handle) self._child_thread_map[name] = server count += 1 else: server = self._spawn(name, self._listen_socket_loop, listen_sockets[sa], conn_handle) return server, listen_sockets def _connect_tcp(self, peer_addr, conn_handler, time_out=None, bind_address=None, password=None): """Creates a TCP connection to given peer address. Tries to create a socket for `timeout` number of seconds. If successful, uses the socket instance to start `client_factory`. The socket is bound to `bind_address` if specified. """ LOG.debug('Connect TCP called for %s:%s', peer_addr[0], peer_addr[1]) if ip.valid_ipv4(peer_addr[0]): family = socket.AF_INET else: family = socket.AF_INET6 with Timeout(time_out, socket.error): sock = socket.socket(family) if bind_address: sock.bind(bind_address) if password: sockopt.set_tcp_md5sig(sock, peer_addr[0], password) sock.connect(peer_addr) # socket.error exception is raised in case of timeout and # the following code is executed only when the connection # is established. # Connection name for pro-active connection is made up of # local end address + remote end address local = self.get_localname(sock)[0] remote = self.get_remotename(sock)[0] conn_name = ('L: ' + local + ', R: ' + remote) self._asso_socket_map[conn_name] = sock # If connection is established, we call connection handler # in a new thread. self._spawn(conn_name, conn_handler, sock) return sock # # Sink # class Sink(object): """An entity to which we send out messages (eg. BGP routes).""" # # OutgoingMsgList # # A circular list type in which objects are linked to each # other using the 'next_sink_out_route' and 'prev_sink_out_route' # attributes. # OutgoingMsgList = CircularListType(next_attr_name='next_sink_out_route', prev_attr_name='prev_sink_out_route') # Next available index that can identify an instance uniquely. idx = 0 @staticmethod def next_index(): """Increments the sink index and returns the value.""" Sink.idx += 1 return Sink.idx def __init__(self): # A small integer that represents this sink. self.index = Sink.next_index() # Create an event for signal enqueuing. from .utils.evtlet import EventletIOFactory self.outgoing_msg_event = EventletIOFactory.create_custom_event() self.messages_queued = 0 # List of msgs. that are to be sent to this peer. Each item # in the list is an instance of OutgoingRoute. self.outgoing_msg_list = Sink.OutgoingMsgList() def clear_outgoing_msg_list(self): self.outgoing_msg_list = Sink.OutgoingMsgList() def enque_outgoing_msg(self, msg): self.outgoing_msg_list.append(msg) self.outgoing_msg_event.set() self.messages_queued += 1 def enque_first_outgoing_msg(self, msg): self.outgoing_msg_list.prepend(msg) self.outgoing_msg_event.set() def __iter__(self): return self def next(self): """Pops and returns the first outgoing message from the list. If message list currently has no messages, the calling thread will be put to sleep until we have at-least one message in the list that can be popped and returned. """ # We pick the first outgoing available and send it. outgoing_msg = self.outgoing_msg_list.pop_first() # If we do not have any outgoing msg., we wait. if outgoing_msg is None: self.outgoing_msg_event.clear() self.outgoing_msg_event.wait() outgoing_msg = self.outgoing_msg_list.pop_first() return outgoing_msg # For Python 3 compatibility __next__ = next # # Source # class Source(object): """An entity that gives us BGP routes. A BGP peer, for example.""" def __init__(self, version_num): # Number that is currently being used to stamp information # received from this source. We will bump this number up when # the information that is now expected from the source belongs # to a different logical batch. This mechanism can be used to # identify stale information. self.version_num = version_num class FlexinetPeer(Source, Sink): def __init__(self): # Initialize source and sink Source.__init__(self, 1) Sink.__init__(self) # Registry of validators for configuration/settings. _VALIDATORS = {} def validate(**kwargs): """Defines a decorator to register a validator with a name for look-up. If name is not provided we use function name as name of the validator. """ def decorator(func): _VALIDATORS[kwargs.pop('name', func.__name__)] = func return func return decorator def get_validator(name): """Returns a validator registered for given name. """ return _VALIDATORS.get(name) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/bgp_sample_conf.py0000664000175000017500000003750600000000000024411 0ustar00zuulzuul00000000000000 import os from os_ken.services.protocols.bgp.bgpspeaker import RF_VPN_V4 from os_ken.services.protocols.bgp.bgpspeaker import RF_VPN_V6 from os_ken.services.protocols.bgp.bgpspeaker import RF_L2_EVPN from os_ken.services.protocols.bgp.bgpspeaker import RF_VPNV4_FLOWSPEC from os_ken.services.protocols.bgp.bgpspeaker import RF_VPNV6_FLOWSPEC from os_ken.services.protocols.bgp.bgpspeaker import RF_L2VPN_FLOWSPEC from os_ken.services.protocols.bgp.bgpspeaker import EVPN_MAX_ET from os_ken.services.protocols.bgp.bgpspeaker import ESI_TYPE_LACP from os_ken.services.protocols.bgp.bgpspeaker import ESI_TYPE_MAC_BASED from os_ken.services.protocols.bgp.bgpspeaker import EVPN_ETH_AUTO_DISCOVERY from os_ken.services.protocols.bgp.bgpspeaker import EVPN_MAC_IP_ADV_ROUTE from os_ken.services.protocols.bgp.bgpspeaker import TUNNEL_TYPE_VXLAN from os_ken.services.protocols.bgp.bgpspeaker import EVPN_MULTICAST_ETAG_ROUTE from os_ken.services.protocols.bgp.bgpspeaker import EVPN_ETH_SEGMENT from os_ken.services.protocols.bgp.bgpspeaker import EVPN_IP_PREFIX_ROUTE from os_ken.services.protocols.bgp.bgpspeaker import FLOWSPEC_FAMILY_IPV4 from os_ken.services.protocols.bgp.bgpspeaker import FLOWSPEC_FAMILY_IPV6 from os_ken.services.protocols.bgp.bgpspeaker import FLOWSPEC_FAMILY_VPNV4 from os_ken.services.protocols.bgp.bgpspeaker import FLOWSPEC_FAMILY_VPNV6 from os_ken.services.protocols.bgp.bgpspeaker import FLOWSPEC_FAMILY_L2VPN from os_ken.services.protocols.bgp.bgpspeaker import FLOWSPEC_TA_SAMPLE from os_ken.services.protocols.bgp.bgpspeaker import FLOWSPEC_TA_TERMINAL from os_ken.services.protocols.bgp.bgpspeaker import FLOWSPEC_VLAN_POP from os_ken.services.protocols.bgp.bgpspeaker import FLOWSPEC_VLAN_PUSH from os_ken.services.protocols.bgp.bgpspeaker import FLOWSPEC_VLAN_SWAP from os_ken.services.protocols.bgp.bgpspeaker import FLOWSPEC_VLAN_RW_INNER from os_ken.services.protocols.bgp.bgpspeaker import FLOWSPEC_VLAN_RW_OUTER from os_ken.services.protocols.bgp.bgpspeaker import FLOWSPEC_TPID_TI from os_ken.services.protocols.bgp.bgpspeaker import FLOWSPEC_TPID_TO from os_ken.services.protocols.bgp.bgpspeaker import REDUNDANCY_MODE_SINGLE_ACTIVE # ============================================================================= # BGP configuration. # ============================================================================= BGP = { # AS number for this BGP instance. 'local_as': 65001, # BGP Router ID. 'router_id': '172.17.0.1', # Default local preference 'local_pref': 100, # List of TCP listen host addresses. 'bgp_server_hosts': ['0.0.0.0', '::'], # List of BGP neighbors. # The parameters for each neighbor are the same as the arguments of # BGPSpeaker.neighbor_add() method. 'neighbors': [ { 'address': '172.17.0.2', 'remote_as': 65002, 'enable_ipv4': True, 'enable_ipv6': True, 'enable_vpnv4': True, 'enable_vpnv6': True, }, { 'address': '172.17.0.3', 'remote_as': 65001, 'enable_evpn': True, }, { 'address': '172.17.0.4', 'remote_as': 65001, 'enable_ipv4fs': True, 'enable_ipv6fs': True, 'enable_vpnv4fs': True, 'enable_vpnv6fs': True, 'enable_l2vpnfs': True, }, ], # List of BGP VRF tables. # The parameters for each VRF table are the same as the arguments of # BGPSpeaker.vrf_add() method. 'vrfs': [ # Example of VRF for IPv4 { 'route_dist': '65001:100', 'import_rts': ['65001:100'], 'export_rts': ['65001:100'], 'route_family': RF_VPN_V4, }, # Example of VRF for IPv6 { 'route_dist': '65001:150', 'import_rts': ['65001:150'], 'export_rts': ['65001:150'], 'route_family': RF_VPN_V6, }, # Example of VRF for EVPN { 'route_dist': '65001:200', 'import_rts': ['65001:200'], 'export_rts': ['65001:200'], 'route_family': RF_L2_EVPN, }, # Example of VRF for IPv4 FlowSpec { 'route_dist': '65001:250', 'import_rts': ['65001:250'], 'export_rts': ['65001:250'], 'route_family': RF_VPNV4_FLOWSPEC, }, # Example of VRF for IPv6 FlowSpec { 'route_dist': '65001:300', 'import_rts': ['65001:300'], 'export_rts': ['65001:300'], 'route_family': RF_VPNV6_FLOWSPEC, }, # Example of VRF for L2VPN FlowSpec { 'route_dist': '65001:350', 'import_rts': ['65001:350'], 'export_rts': ['65001:350'], 'route_family': RF_L2VPN_FLOWSPEC, }, ], # List of BGP routes. # The parameters for each route are the same as the arguments of # the following methods: # - BGPSpeaker.prefix_add() # - BGPSpeaker.evpn_prefix_add() # - BGPSpeaker.flowspec_prefix_add() 'routes': [ # Example of IPv4 prefix { 'prefix': '10.10.1.0/24', }, # Example of VPNv4 prefix { 'prefix': '10.20.1.0/24', 'next_hop': '172.17.0.1', 'route_dist': '65001:100', }, # Example of IPv6 prefix { 'prefix': '2001:db8:1::/64', }, # Example of VPNv6 prefix { 'prefix': '2001:db8:2::/64', 'next_hop': '172.17.0.1', 'route_dist': '65001:150', }, # Example of EVPN prefix { 'route_type': EVPN_ETH_AUTO_DISCOVERY, 'route_dist': '65001:200', 'esi': { 'type': ESI_TYPE_LACP, 'mac_addr': 'aa:bb:cc:dd:ee:ff', 'port_key': 100, }, 'ethernet_tag_id': EVPN_MAX_ET, 'redundancy_mode': REDUNDANCY_MODE_SINGLE_ACTIVE, }, { 'route_type': EVPN_MAC_IP_ADV_ROUTE, 'route_dist': '65001:200', 'esi': 0, 'ethernet_tag_id': 0, 'tunnel_type': TUNNEL_TYPE_VXLAN, 'vni': 200, 'mac_addr': 'aa:bb:cc:dd:ee:ff', 'ip_addr': '10.30.1.1', 'next_hop': '172.17.0.1', }, { 'route_type': EVPN_MULTICAST_ETAG_ROUTE, 'route_dist': '65001:200', 'esi': 0, 'ethernet_tag_id': 0, 'ip_addr': '10.40.1.1', }, { 'route_type': EVPN_ETH_SEGMENT, 'route_dist': '65001:200', 'esi': { 'type': ESI_TYPE_MAC_BASED, 'mac_addr': 'aa:bb:cc:dd:ee:ff', 'local_disc': 100, }, 'ip_addr': '172.17.0.1', }, { 'route_type': EVPN_IP_PREFIX_ROUTE, 'route_dist': '65001:200', 'esi': 0, 'ethernet_tag_id': 0, 'ip_prefix': '10.50.1.0/24', 'gw_ip_addr': '172.16.0.1', }, # Example of Flow Specification IPv4 prefix { 'flowspec_family': FLOWSPEC_FAMILY_IPV4, 'rules': { 'dst_prefix': '10.60.1.0/24', 'src_prefix': '172.17.0.0/24', 'ip_proto': 6, 'port': '80 | 8000', 'dst_port': '>9000 & <9050', 'src_port': '>=8500 & <=9000', 'icmp_type': 0, 'icmp_code': 6, 'tcp_flags': 'SYN+ACK & !=URGENT', 'packet_len': 1000, 'dscp': '22 | 24', 'fragment': 'LF | ==FF', }, 'actions': { 'traffic_rate': { 'as_number': 0, 'rate_info': 100.0, }, 'traffic_action': { 'action': FLOWSPEC_TA_SAMPLE | FLOWSPEC_TA_TERMINAL, }, 'redirect': { 'as_number': 10, 'local_administrator': 100, }, 'traffic_marking': { 'dscp': 24, } }, }, # Example of Flow Specification VPNv4 prefix { 'flowspec_family': FLOWSPEC_FAMILY_VPNV4, 'route_dist': '65001:250', 'rules': { 'dst_prefix': '10.70.1.0/24', 'src_prefix': '172.18.0.0/24', 'ip_proto': 6, 'port': '80 | 8000', 'dst_port': '>9000 & <9050', 'src_port': '>=8500 & <=9000', 'icmp_type': 0, 'icmp_code': 6, 'tcp_flags': 'SYN+ACK & !=URGENT', 'packet_len': 1000, 'dscp': '22 | 24', 'fragment': 'LF | ==FF', }, 'actions': { 'traffic_rate': { 'as_number': 0, 'rate_info': 100.0, }, 'traffic_action': { 'action': FLOWSPEC_TA_SAMPLE | FLOWSPEC_TA_TERMINAL, }, 'redirect': { 'as_number': 10, 'local_administrator': 100, }, 'traffic_marking': { 'dscp': 24, } }, }, # Example of Flow Specification IPv6 prefix { 'flowspec_family': FLOWSPEC_FAMILY_IPV6, 'rules': { 'dst_prefix': '2001::1/128/32', 'src_prefix': '3001::2/128', 'next_header': 6, 'port': '80 | 8000', 'dst_port': '>9000 & <9050', 'src_port': '>=8500 & <=9000', 'icmp_type': 0, 'icmp_code': 6, 'tcp_flags': 'SYN+ACK & !=URGENT', 'packet_len': 1000, 'dscp': '22 | 24', 'fragment': 'LF | ==FF', 'flow_label': 100, }, 'actions': { 'traffic_rate': { 'as_number': 0, 'rate_info': 100.0, }, 'traffic_action': { 'action': FLOWSPEC_TA_SAMPLE | FLOWSPEC_TA_TERMINAL, }, 'redirect': { 'as_number': 10, 'local_administrator': 100, }, 'traffic_marking': { 'dscp': 24, } }, }, # Example of Flow Specification VPNv6 prefix { 'flowspec_family': FLOWSPEC_FAMILY_VPNV6, 'route_dist': '65001:300', 'rules': { 'dst_prefix': '2001::1/128/32', 'src_prefix': '3001::2/128', 'next_header': 6, 'port': '80 | 8000', 'dst_port': '>9000 & <9050', 'src_port': '>=8500 & <=9000', 'icmp_type': 0, 'icmp_code': 6, 'tcp_flags': 'SYN+ACK & !=URGENT', 'packet_len': 1000, 'dscp': '22 | 24', 'fragment': 'LF | ==FF', 'flow_label': 100, }, 'actions': { 'traffic_rate': { 'as_number': 0, 'rate_info': 100.0, }, 'traffic_action': { 'action': FLOWSPEC_TA_SAMPLE | FLOWSPEC_TA_TERMINAL, }, 'redirect': { 'as_number': 10, 'local_administrator': 100, }, 'traffic_marking': { 'dscp': 24, } }, }, # Example of Flow Specification L2VPN prefix { 'flowspec_family': FLOWSPEC_FAMILY_L2VPN, 'route_dist': '65001:350', 'rules': { 'ether_type': 0x0800, 'src_mac': '12:34:56:78:90:AB', 'dst_mac': 'BE:EF:C0:FF:EE:DD', 'llc_dsap': 0x42, 'llc_ssap': 0x42, 'llc_control': 100, 'snap': 0x12345, 'vlan_id': '>4000', 'vlan_cos': '>=3', 'inner_vlan_id': '<3000', 'inner_vlan_cos': '<=5', }, 'actions': { 'traffic_rate': { 'as_number': 0, 'rate_info': 100.0, }, 'traffic_action': { 'action': FLOWSPEC_TA_SAMPLE | FLOWSPEC_TA_TERMINAL, }, 'redirect': { 'as_number': 10, 'local_administrator': 100, }, 'traffic_marking': { 'dscp': 24, }, 'vlan_action': { 'actions_1': FLOWSPEC_VLAN_POP | FLOWSPEC_VLAN_PUSH, 'vlan_1': 3000, 'cos_1': 3, 'actions_2': FLOWSPEC_VLAN_SWAP, 'vlan_2': 4000, 'cos_2': 2, }, 'tpid_action': { 'actions': FLOWSPEC_TPID_TI | FLOWSPEC_TPID_TO, 'tpid_1': 200, 'tpid_2': 300, } }, } ], } # ============================================================================= # SSH server configuration. # ============================================================================= SSH = { 'ssh_port': 4990, 'ssh_host': 'localhost', # 'ssh_host_key': '/etc/ssh_host_rsa_key', # 'ssh_username': 'os_ken', # 'ssh_password': 'os_ken', } # ============================================================================= # Logging configuration. # ============================================================================= LOGGING = { # We use python logging package for logging. 'version': 1, 'disable_existing_loggers': False, 'formatters': { 'verbose': { 'format': '%(levelname)s %(asctime)s %(module)s ' + '[%(process)d %(thread)d] %(message)s' }, 'simple': { 'format': '%(levelname)s %(asctime)s %(module)s %(lineno)s ' + '%(message)s' }, 'stats': { 'format': '%(message)s' }, }, 'handlers': { # Outputs log to console. 'console': { 'level': 'DEBUG', 'class': 'logging.StreamHandler', 'formatter': 'simple' }, 'console_stats': { 'level': 'DEBUG', 'class': 'logging.StreamHandler', 'formatter': 'stats' }, # Rotates log file when its size reaches 10MB. 'log_file': { 'level': 'ERROR', 'class': 'logging.handlers.RotatingFileHandler', 'filename': os.path.join('.', 'bgpspeaker.log'), 'maxBytes': '10000000', 'formatter': 'verbose' }, 'stats_file': { 'level': 'DEBUG', 'class': 'logging.handlers.RotatingFileHandler', 'filename': os.path.join('.', 'statistics_bgps.log'), 'maxBytes': '10000000', 'formatter': 'stats' }, }, # Fine-grained control of logging per instance. 'loggers': { 'bgpspeaker': { 'handlers': ['console', 'log_file'], 'level': 'DEBUG', 'propagate': False, }, 'stats': { 'handlers': ['stats_file', 'console_stats'], 'level': 'INFO', 'propagate': False, 'formatter': 'stats', }, }, # Root loggers. 'root': { 'handlers': ['console', 'log_file'], 'level': 'DEBUG', 'propagate': True, }, } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/bgpspeaker.py0000664000175000017500000015205100000000000023407 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone 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 offers a class to enable your code to speak BGP protocol. """ import netaddr from os_ken.lib import hub from os_ken.lib import ip from os_ken.lib.packet.bgp import ( BGPFlowSpecTrafficActionCommunity, BGPFlowSpecVlanActionCommunity, BGPFlowSpecTPIDActionCommunity, ) from os_ken.services.protocols.bgp.core_manager import CORE_MANAGER from os_ken.services.protocols.bgp.signals.emit import BgpSignalBus from os_ken.services.protocols.bgp.api.base import call from os_ken.services.protocols.bgp.api.base import PREFIX from os_ken.services.protocols.bgp.api.base import EVPN_ROUTE_TYPE from os_ken.services.protocols.bgp.api.base import EVPN_ESI from os_ken.services.protocols.bgp.api.base import EVPN_ETHERNET_TAG_ID from os_ken.services.protocols.bgp.api.base import REDUNDANCY_MODE from os_ken.services.protocols.bgp.api.base import IP_ADDR from os_ken.services.protocols.bgp.api.base import MAC_ADDR from os_ken.services.protocols.bgp.api.base import NEXT_HOP from os_ken.services.protocols.bgp.api.base import IP_PREFIX from os_ken.services.protocols.bgp.api.base import GW_IP_ADDR from os_ken.services.protocols.bgp.api.base import ROUTE_DISTINGUISHER from os_ken.services.protocols.bgp.api.base import ROUTE_FAMILY from os_ken.services.protocols.bgp.api.base import EVPN_VNI from os_ken.services.protocols.bgp.api.base import TUNNEL_TYPE from os_ken.services.protocols.bgp.api.base import PMSI_TUNNEL_TYPE from os_ken.services.protocols.bgp.api.base import MAC_MOBILITY from os_ken.services.protocols.bgp.api.base import TUNNEL_ENDPOINT_IP from os_ken.services.protocols.bgp.api.prefix import EVPN_MAX_ET from os_ken.services.protocols.bgp.api.prefix import ESI_TYPE_LACP from os_ken.services.protocols.bgp.api.prefix import ESI_TYPE_L2_BRIDGE from os_ken.services.protocols.bgp.api.prefix import ESI_TYPE_MAC_BASED from os_ken.services.protocols.bgp.api.prefix import EVPN_ETH_AUTO_DISCOVERY from os_ken.services.protocols.bgp.api.prefix import EVPN_MAC_IP_ADV_ROUTE from os_ken.services.protocols.bgp.api.prefix import EVPN_MULTICAST_ETAG_ROUTE from os_ken.services.protocols.bgp.api.prefix import EVPN_ETH_SEGMENT from os_ken.services.protocols.bgp.api.prefix import EVPN_IP_PREFIX_ROUTE from os_ken.services.protocols.bgp.api.prefix import REDUNDANCY_MODE_ALL_ACTIVE from os_ken.services.protocols.bgp.api.prefix import REDUNDANCY_MODE_SINGLE_ACTIVE from os_ken.services.protocols.bgp.api.prefix import TUNNEL_TYPE_VXLAN from os_ken.services.protocols.bgp.api.prefix import TUNNEL_TYPE_NVGRE from os_ken.services.protocols.bgp.api.prefix import ( PMSI_TYPE_NO_TUNNEL_INFO, PMSI_TYPE_INGRESS_REP) from os_ken.services.protocols.bgp.api.prefix import ( FLOWSPEC_FAMILY, FLOWSPEC_FAMILY_IPV4, FLOWSPEC_FAMILY_VPNV4, FLOWSPEC_FAMILY_IPV6, FLOWSPEC_FAMILY_VPNV6, FLOWSPEC_FAMILY_L2VPN, FLOWSPEC_RULES, FLOWSPEC_ACTIONS) from os_ken.services.protocols.bgp.model import ReceivedRoute from os_ken.services.protocols.bgp.rtconf.common import LOCAL_AS from os_ken.services.protocols.bgp.rtconf.common import ROUTER_ID from os_ken.services.protocols.bgp.rtconf.common import CLUSTER_ID from os_ken.services.protocols.bgp.rtconf.common import BGP_SERVER_HOSTS from os_ken.services.protocols.bgp.rtconf.common import BGP_SERVER_PORT from os_ken.services.protocols.bgp.rtconf.common import DEFAULT_BGP_SERVER_HOSTS from os_ken.services.protocols.bgp.rtconf.common import DEFAULT_BGP_SERVER_PORT from os_ken.services.protocols.bgp.rtconf.common import ( DEFAULT_REFRESH_MAX_EOR_TIME, DEFAULT_REFRESH_STALEPATH_TIME) from os_ken.services.protocols.bgp.rtconf.common import DEFAULT_LABEL_RANGE from os_ken.services.protocols.bgp.rtconf.common import REFRESH_MAX_EOR_TIME from os_ken.services.protocols.bgp.rtconf.common import REFRESH_STALEPATH_TIME from os_ken.services.protocols.bgp.rtconf.common import LABEL_RANGE from os_ken.services.protocols.bgp.rtconf.common import ALLOW_LOCAL_AS_IN_COUNT from os_ken.services.protocols.bgp.rtconf.common import LOCAL_PREF from os_ken.services.protocols.bgp.rtconf.common import DEFAULT_LOCAL_PREF from os_ken.services.protocols.bgp.rtconf import neighbors from os_ken.services.protocols.bgp.rtconf import vrfs from os_ken.services.protocols.bgp.rtconf.base import CAP_MBGP_IPV4 from os_ken.services.protocols.bgp.rtconf.base import CAP_MBGP_IPV6 from os_ken.services.protocols.bgp.rtconf.base import CAP_MBGP_VPNV4 from os_ken.services.protocols.bgp.rtconf.base import CAP_MBGP_VPNV6 from os_ken.services.protocols.bgp.rtconf.base import CAP_MBGP_EVPN from os_ken.services.protocols.bgp.rtconf.base import CAP_MBGP_IPV4FS from os_ken.services.protocols.bgp.rtconf.base import CAP_MBGP_IPV6FS from os_ken.services.protocols.bgp.rtconf.base import CAP_MBGP_VPNV4FS from os_ken.services.protocols.bgp.rtconf.base import CAP_MBGP_VPNV6FS from os_ken.services.protocols.bgp.rtconf.base import CAP_MBGP_L2VPNFS from os_ken.services.protocols.bgp.rtconf.base import CAP_ENHANCED_REFRESH from os_ken.services.protocols.bgp.rtconf.base import CAP_FOUR_OCTET_AS_NUMBER from os_ken.services.protocols.bgp.rtconf.base import MULTI_EXIT_DISC from os_ken.services.protocols.bgp.rtconf.base import SITE_OF_ORIGINS from os_ken.services.protocols.bgp.rtconf.neighbors import ( DEFAULT_CAP_MBGP_IPV4, DEFAULT_CAP_MBGP_IPV6, DEFAULT_CAP_MBGP_VPNV4, DEFAULT_CAP_MBGP_VPNV6, DEFAULT_CAP_MBGP_EVPN, DEFAULT_CAP_MBGP_IPV4FS, DEFAULT_CAP_MBGP_IPV6FS, DEFAULT_CAP_MBGP_VPNV4FS, DEFAULT_CAP_MBGP_VPNV6FS, DEFAULT_CAP_MBGP_L2VPNFS, DEFAULT_CAP_ENHANCED_REFRESH, DEFAULT_CAP_FOUR_OCTET_AS_NUMBER, DEFAULT_CONNECT_MODE, REMOTE_PORT, DEFAULT_BGP_PORT, PEER_NEXT_HOP, PASSWORD, DEFAULT_IS_ROUTE_SERVER_CLIENT, IS_ROUTE_SERVER_CLIENT, DEFAULT_IS_ROUTE_REFLECTOR_CLIENT, IS_ROUTE_REFLECTOR_CLIENT, DEFAULT_IS_NEXT_HOP_SELF, IS_NEXT_HOP_SELF, CONNECT_MODE, LOCAL_ADDRESS, LOCAL_PORT, ) from os_ken.services.protocols.bgp.rtconf.vrfs import SUPPORTED_VRF_RF from os_ken.services.protocols.bgp.info_base.base import Filter from os_ken.services.protocols.bgp.info_base.ipv4 import Ipv4Path from os_ken.services.protocols.bgp.info_base.ipv6 import Ipv6Path from os_ken.services.protocols.bgp.info_base.vpnv4 import Vpnv4Path from os_ken.services.protocols.bgp.info_base.vpnv6 import Vpnv6Path from os_ken.services.protocols.bgp.info_base.evpn import EvpnPath NEIGHBOR_CONF_MED = MULTI_EXIT_DISC # for backward compatibility RF_VPN_V4 = vrfs.VRF_RF_IPV4 RF_VPN_V6 = vrfs.VRF_RF_IPV6 RF_L2_EVPN = vrfs.VRF_RF_L2_EVPN RF_VPNV4_FLOWSPEC = vrfs.VRF_RF_IPV4_FLOWSPEC RF_VPNV6_FLOWSPEC = vrfs.VRF_RF_IPV6_FLOWSPEC RF_L2VPN_FLOWSPEC = vrfs.VRF_RF_L2VPN_FLOWSPEC # Constants for the Traffic Filtering Actions of Flow Specification. FLOWSPEC_TA_SAMPLE = BGPFlowSpecTrafficActionCommunity.SAMPLE FLOWSPEC_TA_TERMINAL = BGPFlowSpecTrafficActionCommunity.TERMINAL # Constants for the VLAN Actions of Flow Specification. FLOWSPEC_VLAN_POP = BGPFlowSpecVlanActionCommunity.POP FLOWSPEC_VLAN_PUSH = BGPFlowSpecVlanActionCommunity.PUSH FLOWSPEC_VLAN_SWAP = BGPFlowSpecVlanActionCommunity.SWAP FLOWSPEC_VLAN_RW_INNER = BGPFlowSpecVlanActionCommunity.REWRITE_INNER FLOWSPEC_VLAN_RW_OUTER = BGPFlowSpecVlanActionCommunity.REWRITE_OUTER # Constants for the TPID Actions of Flow Specification. FLOWSPEC_TPID_TI = BGPFlowSpecTPIDActionCommunity.TI FLOWSPEC_TPID_TO = BGPFlowSpecTPIDActionCommunity.TO class EventPrefix(object): """ Used to pass an update on any best remote path to best_path_change_handler. ================ ====================================================== Attribute Description ================ ====================================================== remote_as The AS number of a peer that caused this change route_dist None in the case of IPv4 or IPv6 family prefix A prefix was changed nexthop The nexthop of the changed prefix label MPLS label for VPNv4, VPNv6 or EVPN prefix path An instance of ``info_base.base.Path`` subclass is_withdraw True if this prefix has gone otherwise False ================ ====================================================== """ def __init__(self, path, is_withdraw): self.path = path self.is_withdraw = is_withdraw @property def remote_as(self): return self.path.source.remote_as @property def route_dist(self): if (isinstance(self.path, Vpnv4Path) or isinstance(self.path, Vpnv6Path) or isinstance(self.path, EvpnPath)): return self.path.nlri.route_dist else: return None @property def prefix(self): if isinstance(self.path, Ipv4Path) or isinstance(self.path, Ipv6Path): return self.path.nlri.addr + '/' + str(self.path.nlri.length) elif (isinstance(self.path, Vpnv4Path) or isinstance(self.path, Vpnv6Path) or isinstance(self.path, EvpnPath)): return self.path.nlri.prefix else: return None @property def nexthop(self): return self.path.nexthop @property def label(self): if (isinstance(self.path, Vpnv4Path) or isinstance(self.path, Vpnv6Path) or isinstance(self.path, EvpnPath)): return getattr(self.path.nlri, 'label_list', None) else: return None class BGPSpeaker(object): """Class to provide the APIs of OSKen BGP Speaker. ``as_number`` specifies an Autonomous Number. It must be an integer between 1 and 65535. ``router_id`` specifies BGP router identifier. It must be the string representation of an IPv4 address (e.g. 10.0.0.1). ``bgp_server_host`` specifies a list of TCP listen host addresses. ``bgp_server_port`` specifies TCP listen port number. 179 is used if not specified. ``refresh_stalepath_time`` causes the BGP speaker to remove stale routes from the BGP table after the timer expires, even if the speaker does not receive a Router-Refresh End-of-RIB message. This feature is disabled (not implemented yet). ``refresh_max_eor_time`` causes the BGP speaker to generate a Route-Refresh End-of-RIB message if it was not able to generate one due to route flapping. This feature is disabled (not implemented yet). ``best_path_change_handler``, if specified, is called when any best remote path is changed due to an update message or remote peer down. The handler is supposed to take one argument, the instance of an EventPrefix class instance. ``adj_rib_in_change_handler``, if specified, is called when any adj-RIB-in path is changed due to an update message or remote peer down. The given handler should take three argument, the instance of an EventPrefix class instance, str type peer's IP address and int type peer's AS number. ``peer_down_handler``, if specified, is called when BGP peering session goes down. ``peer_up_handler``, if specified, is called when BGP peering session goes up. ``ssh_console`` specifies whether or not SSH CLI need to be started. ``ssh_port`` specifies the port number for SSH CLI server. The default is bgp.operator.ssh.DEFAULT_SSH_PORT. ``ssh_host`` specifies the IP address for SSH CLI server. The default is bgp.operator.ssh.DEFAULT_SSH_HOST. ``ssh_host_key`` specifies the path to the host key added to the keys list used by SSH CLI server. The default is bgp.operator.ssh.DEFAULT_SSH_HOST_KEY. ``label_range`` specifies the range of MPLS labels generated automatically. ``allow_local_as_in_count`` maximum number of local AS number occurrences in AS_PATH. This option is useful for e.g. auto RD/RT configurations in leaf/spine architecture with shared AS numbers. The default is 0 and means "local AS number is not allowed in AS_PATH". To allow local AS, 3 is recommended (Cisco's default). ``cluster_id`` specifies the cluster identifier for Route Reflector. It must be the string representation of an IPv4 address. If omitted, "router_id" is used for this field. ``local_pref`` specifies the default local preference. It must be an integer. """ def __init__(self, as_number, router_id, bgp_server_hosts=DEFAULT_BGP_SERVER_HOSTS, bgp_server_port=DEFAULT_BGP_SERVER_PORT, refresh_stalepath_time=DEFAULT_REFRESH_STALEPATH_TIME, refresh_max_eor_time=DEFAULT_REFRESH_MAX_EOR_TIME, best_path_change_handler=None, adj_rib_in_change_handler=None, peer_down_handler=None, peer_up_handler=None, ssh_console=False, ssh_port=None, ssh_host=None, ssh_host_key=None, label_range=DEFAULT_LABEL_RANGE, allow_local_as_in_count=0, cluster_id=None, local_pref=DEFAULT_LOCAL_PREF): super(BGPSpeaker, self).__init__() settings = { LOCAL_AS: as_number, ROUTER_ID: router_id, BGP_SERVER_HOSTS: bgp_server_hosts, BGP_SERVER_PORT: bgp_server_port, REFRESH_STALEPATH_TIME: refresh_stalepath_time, REFRESH_MAX_EOR_TIME: refresh_max_eor_time, LABEL_RANGE: label_range, ALLOW_LOCAL_AS_IN_COUNT: allow_local_as_in_count, CLUSTER_ID: cluster_id, LOCAL_PREF: local_pref, } self._core_start(settings) self._init_signal_listeners() self._best_path_change_handler = best_path_change_handler self._adj_rib_in_change_handler = adj_rib_in_change_handler self._peer_down_handler = peer_down_handler self._peer_up_handler = peer_up_handler if ssh_console: # Note: paramiko used in bgp.operator.ssh is the optional # requirements, imports bgp.operator.ssh here. from os_ken.services.protocols.bgp.operator import ssh ssh_settings = { ssh.SSH_PORT: ssh_port or ssh.DEFAULT_SSH_PORT, ssh.SSH_HOST: ssh_host or ssh.DEFAULT_SSH_HOST, ssh.SSH_HOST_KEY: ssh_host_key or ssh.DEFAULT_SSH_HOST_KEY, } hub.spawn(ssh.SSH_CLI_CONTROLLER.start, **ssh_settings) def _notify_peer_down(self, peer): remote_ip = peer.ip_address remote_as = peer.remote_as if self._peer_down_handler: self._peer_down_handler(remote_ip, remote_as) def _notify_peer_up(self, peer): remote_ip = peer.protocol.recv_open_msg.bgp_identifier remote_as = peer.protocol.recv_open_msg.my_as if self._peer_up_handler: self._peer_up_handler(remote_ip, remote_as) def _notify_best_path_changed(self, path, is_withdraw): if (not path.source or not isinstance(path, (Ipv4Path, Ipv6Path, Vpnv4Path, Vpnv6Path, EvpnPath))): return ev = EventPrefix(path, is_withdraw) if self._best_path_change_handler: self._best_path_change_handler(ev) def _notify_adj_rib_in_changed(self, peer, route): if not isinstance(route, ReceivedRoute): return if self._adj_rib_in_change_handler: self._adj_rib_in_change_handler( EventPrefix(route.path, route.path.is_withdraw), peer.ip_address, peer.remote_as) def _init_signal_listeners(self): CORE_MANAGER.get_core_service()._signal_bus.register_listener( BgpSignalBus.BGP_BEST_PATH_CHANGED, lambda _, info: self._notify_best_path_changed(info['path'], info['is_withdraw']) ) CORE_MANAGER.get_core_service()._signal_bus.register_listener( BgpSignalBus.BGP_ADJ_RIB_IN_CHANGED, lambda _, info: self._notify_adj_rib_in_changed(info['peer'], info['received_route']) ) CORE_MANAGER.get_core_service()._signal_bus.register_listener( BgpSignalBus.BGP_ADJ_DOWN, lambda _, info: self._notify_peer_down(info['peer']) ) CORE_MANAGER.get_core_service()._signal_bus.register_listener( BgpSignalBus.BGP_ADJ_UP, lambda _, info: self._notify_peer_up(info['peer']) ) def _core_start(self, settings): waiter = hub.Event() call('core.start', waiter=waiter, **settings) waiter.wait() def _serve_forever(self): pass def shutdown(self): """ Shutdown BGP speaker """ call('core.stop') def neighbor_add(self, address, remote_as, remote_port=DEFAULT_BGP_PORT, enable_ipv4=DEFAULT_CAP_MBGP_IPV4, enable_ipv6=DEFAULT_CAP_MBGP_IPV6, enable_vpnv4=DEFAULT_CAP_MBGP_VPNV4, enable_vpnv6=DEFAULT_CAP_MBGP_VPNV6, enable_evpn=DEFAULT_CAP_MBGP_EVPN, enable_ipv4fs=DEFAULT_CAP_MBGP_IPV4FS, enable_ipv6fs=DEFAULT_CAP_MBGP_IPV6FS, enable_vpnv4fs=DEFAULT_CAP_MBGP_VPNV4FS, enable_vpnv6fs=DEFAULT_CAP_MBGP_VPNV6FS, enable_l2vpnfs=DEFAULT_CAP_MBGP_L2VPNFS, enable_enhanced_refresh=DEFAULT_CAP_ENHANCED_REFRESH, enable_four_octet_as_number=DEFAULT_CAP_FOUR_OCTET_AS_NUMBER, next_hop=None, password=None, multi_exit_disc=None, site_of_origins=None, is_route_server_client=DEFAULT_IS_ROUTE_SERVER_CLIENT, is_route_reflector_client=DEFAULT_IS_ROUTE_REFLECTOR_CLIENT, is_next_hop_self=DEFAULT_IS_NEXT_HOP_SELF, local_address=None, local_port=None, local_as=None, connect_mode=DEFAULT_CONNECT_MODE): """ This method registers a new neighbor. The BGP speaker tries to establish a bgp session with the peer (accepts a connection from the peer and also tries to connect to it). ``address`` specifies the IP address of the peer. It must be the string representation of an IP address. Only IPv4 is supported now. ``remote_as`` specifies the AS number of the peer. It must be an integer between 1 and 65535. ``remote_port`` specifies the TCP port number of the peer. ``enable_ipv4`` enables IPv4 address family for this neighbor. ``enable_ipv6`` enables IPv6 address family for this neighbor. ``enable_vpnv4`` enables VPNv4 address family for this neighbor. ``enable_vpnv6`` enables VPNv6 address family for this neighbor. ``enable_evpn`` enables Ethernet VPN address family for this neighbor. ``enable_ipv4fs`` enables IPv4 Flow Specification address family for this neighbor. ``enable_ipv6fs`` enables IPv6 Flow Specification address family for this neighbor. ``enable_vpnv4fs`` enables VPNv4 Flow Specification address family for this neighbor. ``enable_vpnv6fs`` enables VPNv6 Flow Specification address family for this neighbor. ``enable_l2vpnfs`` enables L2VPN Flow Specification address family for this neighbor. ``enable_enhanced_refresh`` enables Enhanced Route Refresh for this neighbor. ``enable_four_octet_as_number`` enables Four-Octet AS Number capability for this neighbor. ``next_hop`` specifies the next hop IP address. If not specified, host's ip address to access to a peer is used. ``password`` is used for the MD5 authentication if it's specified. By default, the MD5 authentication is disabled. ``multi_exit_disc`` specifies multi exit discriminator (MED) value as an int type value. If omitted, MED is not sent to the neighbor. ``site_of_origins`` specifies site_of_origin values. This parameter must be a list of string. ``is_route_server_client`` specifies whether this neighbor is a router server's client or not. ``is_route_reflector_client`` specifies whether this neighbor is a router reflector's client or not. ``is_next_hop_self`` specifies whether the BGP speaker announces its own ip address to iBGP neighbor or not as path's next_hop address. ``local_address`` specifies Loopback interface address for iBGP peering. ``local_port`` specifies source TCP port for iBGP peering. ``local_as`` specifies local AS number per-peer. If omitted, the AS number of BGPSpeaker instance is used. ``connect_mode`` specifies how to connect to this neighbor. This parameter must be one of the following. - CONNECT_MODE_ACTIVE = 'active' - CONNECT_MODE_PASSIVE = 'passive' - CONNECT_MODE_BOTH (default) = 'both' """ bgp_neighbor = { neighbors.IP_ADDRESS: address, neighbors.REMOTE_AS: remote_as, REMOTE_PORT: remote_port, PEER_NEXT_HOP: next_hop, PASSWORD: password, IS_ROUTE_SERVER_CLIENT: is_route_server_client, IS_ROUTE_REFLECTOR_CLIENT: is_route_reflector_client, IS_NEXT_HOP_SELF: is_next_hop_self, CONNECT_MODE: connect_mode, CAP_ENHANCED_REFRESH: enable_enhanced_refresh, CAP_FOUR_OCTET_AS_NUMBER: enable_four_octet_as_number, CAP_MBGP_IPV4: enable_ipv4, CAP_MBGP_IPV6: enable_ipv6, CAP_MBGP_VPNV4: enable_vpnv4, CAP_MBGP_VPNV6: enable_vpnv6, CAP_MBGP_EVPN: enable_evpn, CAP_MBGP_IPV4FS: enable_ipv4fs, CAP_MBGP_IPV6FS: enable_ipv6fs, CAP_MBGP_VPNV4FS: enable_vpnv4fs, CAP_MBGP_VPNV6FS: enable_vpnv6fs, CAP_MBGP_L2VPNFS: enable_l2vpnfs, } if multi_exit_disc: bgp_neighbor[MULTI_EXIT_DISC] = multi_exit_disc if site_of_origins: bgp_neighbor[SITE_OF_ORIGINS] = site_of_origins if local_address: bgp_neighbor[LOCAL_ADDRESS] = local_address if local_port: bgp_neighbor[LOCAL_PORT] = local_port if local_as: bgp_neighbor[LOCAL_AS] = local_as call('neighbor.create', **bgp_neighbor) def neighbor_del(self, address): """ This method unregister the registered neighbor. If a session with the peer exists, the session will be closed. ``address`` specifies the IP address of the peer. It must be the string representation of an IP address. """ bgp_neighbor = { neighbors.IP_ADDRESS: address, } call('neighbor.delete', **bgp_neighbor) def neighbor_reset(self, address): """ This method reset the registered neighbor. ``address`` specifies the IP address of the peer. It must be the string representation of an IP address. """ bgp_neighbor = { neighbors.IP_ADDRESS: address, } call('core.reset_neighbor', **bgp_neighbor) def neighbor_update(self, address, conf_type, conf_value): """ This method changes the neighbor configuration. ``address`` specifies the IP address of the peer. ``conf_type`` specifies configuration type which you want to change. Currently os_ken.services.protocols.bgp.bgpspeaker.MULTI_EXIT_DISC can be specified. ``conf_value`` specifies value for the configuration type. """ assert conf_type == MULTI_EXIT_DISC or conf_type == CONNECT_MODE func_name = 'neighbor.update' attribute_param = {} if conf_type == MULTI_EXIT_DISC: attribute_param = {neighbors.MULTI_EXIT_DISC: conf_value} elif conf_type == CONNECT_MODE: attribute_param = {neighbors.CONNECT_MODE: conf_value} param = {neighbors.IP_ADDRESS: address, neighbors.CHANGES: attribute_param} call(func_name, **param) def neighbor_state_get(self, address=None, format='json'): """ This method returns the state of peer(s) in a json format. ``address`` specifies the address of a peer. If not given, the state of all the peers return. ``format`` specifies the format of the response. This parameter must be one of the following. - 'json' (default) - 'cli' """ show = { 'params': ['neighbor', 'summary'], 'format': format, } if address: show['params'].append(address) return call('operator.show', **show) def prefix_add(self, prefix, next_hop=None, route_dist=None): """ This method adds a new prefix to be advertised. ``prefix`` must be the string representation of an IP network (e.g., 10.1.1.0/24). ``next_hop`` specifies the next hop address for this prefix. This parameter is necessary for only VPNv4 and VPNv6 address families. ``route_dist`` specifies a route distinguisher value. This parameter is necessary for only VPNv4 and VPNv6 address families. """ func_name = 'network.add' networks = { PREFIX: prefix, } if next_hop: networks[NEXT_HOP] = next_hop if route_dist: func_name = 'prefix.add_local' networks[ROUTE_DISTINGUISHER] = route_dist rf, p = self._check_rf_and_normalize(prefix) networks[ROUTE_FAMILY] = rf networks[PREFIX] = p if rf == vrfs.VRF_RF_IPV6 and ip.valid_ipv4(next_hop): # convert the next_hop to IPv4-Mapped IPv6 Address networks[NEXT_HOP] = \ str(netaddr.IPAddress(next_hop).ipv6()) return call(func_name, **networks) def prefix_del(self, prefix, route_dist=None): """ This method deletes a advertised prefix. ``prefix`` must be the string representation of an IP network. ``route_dist`` specifies a route distinguisher value. """ func_name = 'network.del' networks = { PREFIX: prefix, } if route_dist: func_name = 'prefix.delete_local' networks[ROUTE_DISTINGUISHER] = route_dist rf, p = self._check_rf_and_normalize(prefix) networks[ROUTE_FAMILY] = rf networks[PREFIX] = p call(func_name, **networks) def evpn_prefix_add(self, route_type, route_dist, esi=0, ethernet_tag_id=None, mac_addr=None, ip_addr=None, ip_prefix=None, gw_ip_addr=None, vni=None, next_hop=None, tunnel_type=None, pmsi_tunnel_type=None, redundancy_mode=None, tunnel_endpoint_ip=None, mac_mobility=None): """ This method adds a new EVPN route to be advertised. ``route_type`` specifies one of the EVPN route type name. This parameter must be one of the following. - EVPN_ETH_AUTO_DISCOVERY = 'eth_ad' - EVPN_MAC_IP_ADV_ROUTE = 'mac_ip_adv' - EVPN_MULTICAST_ETAG_ROUTE = 'multicast_etag' - EVPN_ETH_SEGMENT = 'eth_seg' - EVPN_IP_PREFIX_ROUTE = 'ip_prefix' ``route_dist`` specifies a route distinguisher value. ``esi`` is an value to specify the Ethernet Segment Identifier. 0 is the default and denotes a single-homed site. If you want to advertise esi other than 0, it must be set as dictionary type. If esi is dictionary type, 'type' key must be set and specifies ESI type. For the supported ESI type, see :py:mod:`os_ken.lib.packet.bgp.EvpnEsi`. The remaining arguments are the same as that for the corresponding class. ``ethernet_tag_id`` specifies the Ethernet Tag ID. ``mac_addr`` specifies a MAC address to advertise. ``ip_addr`` specifies an IPv4 or IPv6 address to advertise. ``ip_prefix`` specifies an IPv4 or IPv6 prefix to advertise. ``gw_ip_addr`` specifies an IPv4 or IPv6 address of gateway to advertise. ``vni`` specifies an Virtual Network Identifier for VXLAN or Virtual Subnet Identifier for NVGRE. If tunnel_type is not TUNNEL_TYPE_VXLAN or TUNNEL_TYPE_NVGRE, this field is ignored. ``next_hop`` specifies the next hop address for this prefix. ``tunnel_type`` specifies the data plane encapsulation type to advertise. By the default, this attribute is not advertised. The supported encapsulation types are following. - TUNNEL_TYPE_VXLAN = 'vxlan' - TUNNEL_TYPE_NVGRE = 'nvgre ``pmsi_tunnel_type`` specifies the type of the PMSI tunnel attribute used to encode the multicast tunnel identifier. This attribute is advertised only if route_type is EVPN_MULTICAST_ETAG_ROUTE and not advertised by the default. This attribute can also carry vni if tunnel_type is specified. The supported PMSI tunnel types are following. - PMSI_TYPE_NO_TUNNEL_INFO = 0 - PMSI_TYPE_INGRESS_REP = 6 ``redundancy_mode`` specifies a redundancy mode type. This attribute is advertised only if route_type is EVPN_ETH_AUTO_DISCOVERY and not advertised by the default. The supported redundancy mode types are following. - REDUNDANCY_MODE_ALL_ACTIVE = 'all_active' - REDUNDANCY_MODE_SINGLE_ACTIVE = 'single_active' ``tunnel_endpoint_ip`` specifies a VTEP IP address other than the local router ID. This attribute is advertised only if route_type is EVPN_MULTICAST_ETAG_ROUTE, and defaults to the local router ID. ``mac_mobility`` specifies an optional integer sequence number to use in a MAC Mobility extended community field. The special value '-1' can be used to set the STATIC flag with a 0-value sequence number. """ func_name = 'evpn_prefix.add_local' # Check the default values if not next_hop: next_hop = '0.0.0.0' # Set required arguments kwargs = {EVPN_ROUTE_TYPE: route_type, ROUTE_DISTINGUISHER: route_dist, NEXT_HOP: next_hop} # Set optional arguments if tunnel_type in [TUNNEL_TYPE_VXLAN, TUNNEL_TYPE_NVGRE]: kwargs[TUNNEL_TYPE] = tunnel_type elif tunnel_type is not None: raise ValueError('Unsupported tunnel type: %s' % tunnel_type) # Set route type specific arguments if route_type == EVPN_ETH_AUTO_DISCOVERY: kwargs.update({ EVPN_ESI: esi, EVPN_ETHERNET_TAG_ID: ethernet_tag_id, }) if vni is not None: kwargs[EVPN_VNI] = vni # Set Redundancy Mode Attribute arguments if redundancy_mode in [ REDUNDANCY_MODE_ALL_ACTIVE, REDUNDANCY_MODE_SINGLE_ACTIVE]: kwargs[REDUNDANCY_MODE] = redundancy_mode elif redundancy_mode is not None: raise ValueError('Unsupported Redundancy Mode: %s' % redundancy_mode) elif route_type == EVPN_MAC_IP_ADV_ROUTE: kwargs.update({ EVPN_ESI: esi, EVPN_ETHERNET_TAG_ID: ethernet_tag_id, MAC_ADDR: mac_addr, IP_ADDR: ip_addr, }) # Set tunnel type specific arguments if tunnel_type in [TUNNEL_TYPE_VXLAN, TUNNEL_TYPE_NVGRE]: kwargs[EVPN_VNI] = vni # Pass on mac_mobility, must be integer value if mac_mobility is not None: kwargs[MAC_MOBILITY] = int(mac_mobility) elif route_type == EVPN_MULTICAST_ETAG_ROUTE: kwargs.update({ EVPN_ETHERNET_TAG_ID: ethernet_tag_id, IP_ADDR: ip_addr, }) # Set tunnel type specific arguments if tunnel_type in [TUNNEL_TYPE_VXLAN, TUNNEL_TYPE_NVGRE]: kwargs[EVPN_VNI] = vni # Set PMSI Tunnel Attribute arguments if pmsi_tunnel_type in [ PMSI_TYPE_NO_TUNNEL_INFO, PMSI_TYPE_INGRESS_REP]: kwargs[PMSI_TUNNEL_TYPE] = pmsi_tunnel_type elif pmsi_tunnel_type is not None: raise ValueError('Unsupported PMSI tunnel type: %s' % pmsi_tunnel_type) # Set non-default tunnel endpoint IP, if provided if tunnel_endpoint_ip is not None: kwargs[TUNNEL_ENDPOINT_IP] = tunnel_endpoint_ip elif route_type == EVPN_ETH_SEGMENT: kwargs.update({ EVPN_ESI: esi, IP_ADDR: ip_addr, }) elif route_type == EVPN_IP_PREFIX_ROUTE: kwargs.update({ EVPN_ESI: esi, EVPN_ETHERNET_TAG_ID: ethernet_tag_id, IP_PREFIX: ip_prefix, GW_IP_ADDR: gw_ip_addr, }) # Set tunnel type specific arguments if tunnel_type in [TUNNEL_TYPE_VXLAN, TUNNEL_TYPE_NVGRE]: kwargs[EVPN_VNI] = vni # Add mac_mobility if mac_mobility is not None: kwargs[MAC_MOBILITY] = int(mac_mobility) else: raise ValueError('Unsupported EVPN route type: %s' % route_type) call(func_name, **kwargs) def evpn_prefix_del(self, route_type, route_dist, esi=0, ethernet_tag_id=None, mac_addr=None, ip_addr=None, ip_prefix=None): """ This method deletes an advertised EVPN route. ``route_type`` specifies one of the EVPN route type name. ``route_dist`` specifies a route distinguisher value. ``esi`` is an value to specify the Ethernet Segment Identifier. ``ethernet_tag_id`` specifies the Ethernet Tag ID. ``mac_addr`` specifies a MAC address to advertise. ``ip_addr`` specifies an IPv4 or IPv6 address to advertise. ``ip_prefix`` specifies an IPv4 or IPv6 prefix to advertise. """ func_name = 'evpn_prefix.delete_local' # Set required arguments kwargs = {EVPN_ROUTE_TYPE: route_type, ROUTE_DISTINGUISHER: route_dist} # Set route type specific arguments if route_type == EVPN_ETH_AUTO_DISCOVERY: kwargs.update({ EVPN_ESI: esi, EVPN_ETHERNET_TAG_ID: ethernet_tag_id, }) elif route_type == EVPN_MAC_IP_ADV_ROUTE: kwargs.update({ EVPN_ETHERNET_TAG_ID: ethernet_tag_id, MAC_ADDR: mac_addr, IP_ADDR: ip_addr, }) elif route_type == EVPN_MULTICAST_ETAG_ROUTE: kwargs.update({ EVPN_ETHERNET_TAG_ID: ethernet_tag_id, IP_ADDR: ip_addr, }) elif route_type == EVPN_ETH_SEGMENT: kwargs.update({ EVPN_ESI: esi, IP_ADDR: ip_addr, }) elif route_type == EVPN_IP_PREFIX_ROUTE: kwargs.update({ EVPN_ETHERNET_TAG_ID: ethernet_tag_id, IP_PREFIX: ip_prefix, }) else: raise ValueError('Unsupported EVPN route type: %s' % route_type) call(func_name, **kwargs) def flowspec_prefix_add(self, flowspec_family, rules, route_dist=None, actions=None): """ This method adds a new Flow Specification prefix to be advertised. ``flowspec_family`` specifies one of the flowspec family name. This parameter must be one of the following. - FLOWSPEC_FAMILY_IPV4 = 'ipv4fs' - FLOWSPEC_FAMILY_IPV6 = 'ipv6fs' - FLOWSPEC_FAMILY_VPNV4 = 'vpnv4fs' - FLOWSPEC_FAMILY_VPNV6 = 'vpnv6fs' - FLOWSPEC_FAMILY_L2VPN = 'l2vpnfs' ``rules`` specifies NLRIs of Flow Specification as a dictionary type value. For the supported NLRI types and arguments, see `from_user()` method of the following classes. - :py:mod:`os_ken.lib.packet.bgp.FlowSpecIPv4NLRI` - :py:mod:`os_ken.lib.packet.bgp.FlowSpecIPv6NLRI` - :py:mod:`os_ken.lib.packet.bgp.FlowSpecVPNv4NLRI` - :py:mod:`os_ken.lib.packet.bgp.FlowSpecVPNv6NLRI` - :py:mod:`os_ken.lib.packet.bgp.FlowSpecL2VPNNLRI` ``route_dist`` specifies a route distinguisher value. This parameter is required only if flowspec_family is one of the following address family. - FLOWSPEC_FAMILY_VPNV4 = 'vpnv4fs' - FLOWSPEC_FAMILY_VPNV6 = 'vpnv6fs' - FLOWSPEC_FAMILY_L2VPN = 'l2vpnfs' ``actions`` specifies Traffic Filtering Actions of Flow Specification as a dictionary type value. The keys are "ACTION_NAME" for each action class and values are used for the arguments to that class. For the supported "ACTION_NAME" and arguments, see the following table. =============== =============================================================== ACTION_NAME Action Class =============== =============================================================== traffic_rate :py:mod:`os_ken.lib.packet.bgp.BGPFlowSpecTrafficRateCommunity` traffic_action :py:mod:`os_ken.lib.packet.bgp.BGPFlowSpecTrafficActionCommunity` redirect :py:mod:`os_ken.lib.packet.bgp.BGPFlowSpecRedirectCommunity` traffic_marking :py:mod:`os_ken.lib.packet.bgp.BGPFlowSpecTrafficMarkingCommunity` vlan_action :py:mod:`os_ken.lib.packet.bgp.BGPFlowSpecVlanActionCommunity` tpid_action :py:mod:`os_ken.lib.packet.bgp.BGPFlowSpecTPIDActionCommunity` =============== =============================================================== Example(IPv4):: >>> speaker = BGPSpeaker(as_number=65001, router_id='172.17.0.1') >>> speaker.neighbor_add(address='172.17.0.2', ... remote_as=65002, ... enable_ipv4fs=True) >>> speaker.flowspec_prefix_add( ... flowspec_family=FLOWSPEC_FAMILY_IPV4, ... rules={ ... 'dst_prefix': '10.60.1.0/24' ... }, ... actions={ ... 'traffic_marking': { ... 'dscp': 24 ... } ... } ... ) Example(VPNv4):: >>> speaker = BGPSpeaker(as_number=65001, router_id='172.17.0.1') >>> speaker.neighbor_add(address='172.17.0.2', ... remote_as=65002, ... enable_vpnv4fs=True) >>> speaker.vrf_add(route_dist='65001:100', ... import_rts=['65001:100'], ... export_rts=['65001:100'], ... route_family=RF_VPNV4_FLOWSPEC) >>> speaker.flowspec_prefix_add( ... flowspec_family=FLOWSPEC_FAMILY_VPNV4, ... route_dist='65000:100', ... rules={ ... 'dst_prefix': '10.60.1.0/24' ... }, ... actions={ ... 'traffic_marking': { ... 'dscp': 24 ... } ... } ... ) """ func_name = 'flowspec.add' # Set required arguments kwargs = { FLOWSPEC_FAMILY: flowspec_family, FLOWSPEC_RULES: rules, FLOWSPEC_ACTIONS: actions or {}, } if flowspec_family in [FLOWSPEC_FAMILY_VPNV4, FLOWSPEC_FAMILY_VPNV6, FLOWSPEC_FAMILY_L2VPN]: func_name = 'flowspec.add_local' kwargs.update({ROUTE_DISTINGUISHER: route_dist}) call(func_name, **kwargs) def flowspec_prefix_del(self, flowspec_family, rules, route_dist=None): """ This method deletes an advertised Flow Specification route. ``flowspec_family`` specifies one of the flowspec family name. ``rules`` specifies NLRIs of Flow Specification as a dictionary type value. ``route_dist`` specifies a route distinguisher value. """ func_name = 'flowspec.del' # Set required arguments kwargs = { FLOWSPEC_FAMILY: flowspec_family, FLOWSPEC_RULES: rules, } if flowspec_family in [FLOWSPEC_FAMILY_VPNV4, FLOWSPEC_FAMILY_VPNV6, FLOWSPEC_FAMILY_L2VPN]: func_name = 'flowspec.del_local' kwargs.update({ROUTE_DISTINGUISHER: route_dist}) call(func_name, **kwargs) def vrf_add(self, route_dist, import_rts, export_rts, site_of_origins=None, route_family=RF_VPN_V4, multi_exit_disc=None): """ This method adds a new vrf used for VPN. ``route_dist`` specifies a route distinguisher value. ``import_rts`` specifies a list of route targets to be imported. ``export_rts`` specifies a list of route targets to be exported. ``site_of_origins`` specifies site_of_origin values. This parameter must be a list of string. ``route_family`` specifies route family of the VRF. This parameter must be one of the following. - RF_VPN_V4 (default) = 'ipv4' - RF_VPN_V6 = 'ipv6' - RF_L2_EVPN = 'evpn' - RF_VPNV4_FLOWSPEC = 'ipv4fs' - RF_VPNV6_FLOWSPEC = 'ipv6fs' - RF_L2VPN_FLOWSPEC = 'l2vpnfs' ``multi_exit_disc`` specifies multi exit discriminator (MED) value. It must be an integer. """ if route_family not in SUPPORTED_VRF_RF: raise ValueError('Unsupported route_family: %s' % route_family) vrf = { vrfs.ROUTE_DISTINGUISHER: route_dist, vrfs.IMPORT_RTS: import_rts, vrfs.EXPORT_RTS: export_rts, vrfs.SITE_OF_ORIGINS: site_of_origins, vrfs.VRF_RF: route_family, vrfs.MULTI_EXIT_DISC: multi_exit_disc, } call('vrf.create', **vrf) def vrf_del(self, route_dist): """ This method deletes the existing vrf. ``route_dist`` specifies a route distinguisher value. """ vrf = {vrfs.ROUTE_DISTINGUISHER: route_dist} call('vrf.delete', **vrf) def vrfs_get(self, subcommand='routes', route_dist=None, route_family='all', format='json'): """ This method returns the existing vrfs. ``subcommand`` specifies one of the following. - 'routes': shows routes present for vrf - 'summary': shows configuration and summary of vrf ``route_dist`` specifies a route distinguisher value. If route_family is not 'all', this value must be specified. ``route_family`` specifies route family of the VRF. This parameter must be one of the following. - RF_VPN_V4 = 'ipv4' - RF_VPN_V6 = 'ipv6' - RF_L2_EVPN = 'evpn' - 'all' (default) ``format`` specifies the format of the response. This parameter must be one of the following. - 'json' (default) - 'cli' """ show = { 'format': format, } if route_family in SUPPORTED_VRF_RF: assert route_dist is not None show['params'] = ['vrf', subcommand, route_dist, route_family] else: show['params'] = ['vrf', subcommand, 'all'] return call('operator.show', **show) def rib_get(self, family='all', format='json'): """ This method returns the BGP routing information in a json format. This will be improved soon. ``family`` specifies the address family of the RIB (e.g. 'ipv4'). ``format`` specifies the format of the response. This parameter must be one of the following. - 'json' (default) - 'cli' """ show = { 'params': ['rib', family], 'format': format } return call('operator.show', **show) def neighbor_get(self, route_type, address, format='json'): """ This method returns the BGP adj-RIB-in/adj-RIB-out information in a json format. ``route_type`` This parameter is necessary for only received-routes and sent-routes. - received-routes : paths received and not withdrawn by given peer - sent-routes : paths sent and not withdrawn to given peer ``address`` specifies the IP address of the peer. It must be the string representation of an IP address. ``format`` specifies the format of the response. This parameter must be one of the following. - 'json' (default) - 'cli' """ show = { 'format': format, } if route_type == 'sent-routes' or route_type == 'received-routes': show['params'] = ['neighbor', route_type, address, 'all'] else: show['params'] = ['neighbor', 'received-routes', address, 'all'] return call('operator.show', **show) def neighbors_get(self, format='json'): """ This method returns a list of the BGP neighbors. ``format`` specifies the format of the response. This parameter must be one of the following. - 'json' (default) - 'cli' """ show = { 'params': ['neighbor'], 'format': format, } return call('operator.show', **show) def _set_filter(self, filter_type, address, filters): assert filter_type in ('in', 'out'), ( "filter type must be 'in' or 'out'") assert all(isinstance(f, Filter) for f in filters), ( 'all the items in filters must be an instance of Filter sub-class') if filters is None: filters = [] func_name = 'neighbor.' + filter_type + '_filter.set' param = { neighbors.IP_ADDRESS: address, } if filter_type == 'in': param[neighbors.IN_FILTER] = filters else: param[neighbors.OUT_FILTER] = filters call(func_name, **param) def out_filter_set(self, address, filters): """ This method sets out-filter to neighbor. ``address`` specifies the IP address of the peer. ``filters`` specifies a filter list to filter the path advertisement. The contents must be an instance of Filter sub-class If you want to define out-filter that send only a particular prefix to neighbor, filters can be created as follows:: p = PrefixFilter('10.5.111.0/24', policy=PrefixFilter.POLICY_PERMIT) all = PrefixFilter('0.0.0.0/0', policy=PrefixFilter.POLICY_DENY) pList = [p, all] self.bgpspeaker.out_filter_set(neighbor_address, pList) .. Note:: out-filter evaluates paths in the order of Filter in the pList. """ self._set_filter('out', address, filters) def out_filter_get(self, address): """ This method gets out-filter setting from the specified neighbor. ``address`` specifies the IP address of the peer. Returns a list object containing an instance of Filter sub-class """ func_name = 'neighbor.out_filter.get' param = { neighbors.IP_ADDRESS: address, } return call(func_name, **param) def in_filter_set(self, address, filters): """This method sets in-bound filters to a neighbor. ``address`` specifies the IP address of the neighbor ``filters`` specifies filter list applied before advertised paths are imported to the global rib. All the items in the list must be an instance of Filter sub-class. """ self._set_filter('in', address, filters) def in_filter_get(self, address): """This method gets in-bound filters of the specified neighbor. ``address`` specifies the IP address of the neighbor. Returns a list object containing an instance of Filter sub-class """ func_name = 'neighbor.in_filter.get' param = { neighbors.IP_ADDRESS: address, } return call(func_name, **param) def bmp_server_add(self, address, port): """This method registers a new BMP (BGP monitoring Protocol) server. The BGP speaker starts to send BMP messages to the server. Currently, only one BMP server can be registered. ``address`` specifies the IP address of a BMP server. ``port`` specifies the listen port number of a BMP server. """ func_name = 'bmp.start' param = { 'host': address, 'port': port, } call(func_name, **param) def bmp_server_del(self, address, port): """ This method unregister the registered BMP server. ``address`` specifies the IP address of a BMP server. ``port`` specifies the listen port number of a BMP server. """ func_name = 'bmp.stop' param = { 'host': address, 'port': port, } call(func_name, **param) def attribute_map_set(self, address, attribute_maps, route_dist=None, route_family=RF_VPN_V4): """This method sets attribute mapping to a neighbor. attribute mapping can be used when you want to apply attribute to BGPUpdate under specific conditions. ``address`` specifies the IP address of the neighbor ``attribute_maps`` specifies attribute_map list that are used before paths are advertised. All the items in the list must be an instance of AttributeMap class ``route_dist`` specifies route dist in which attribute_maps are added. ``route_family`` specifies route family of the VRF. This parameter must be one of the following. - RF_VPN_V4 (default) = 'ipv4' - RF_VPN_V6 = 'ipv6' We can set AttributeMap to a neighbor as follows:: pref_filter = PrefixFilter('192.168.103.0/30', PrefixFilter.POLICY_PERMIT) attribute_map = AttributeMap([pref_filter], AttributeMap.ATTR_LOCAL_PREF, 250) speaker.attribute_map_set('192.168.50.102', [attribute_map]) """ if route_family not in SUPPORTED_VRF_RF: raise ValueError('Unsupported route_family: %s' % route_family) func_name = 'neighbor.attribute_map.set' param = { neighbors.IP_ADDRESS: address, neighbors.ATTRIBUTE_MAP: attribute_maps, } if route_dist is not None: param[vrfs.ROUTE_DISTINGUISHER] = route_dist param[vrfs.VRF_RF] = route_family call(func_name, **param) def attribute_map_get(self, address, route_dist=None, route_family=RF_VPN_V4): """This method gets in-bound filters of the specified neighbor. ``address`` specifies the IP address of the neighbor. ``route_dist`` specifies route distinguisher that has attribute_maps. ``route_family`` specifies route family of the VRF. This parameter must be one of the following. - RF_VPN_V4 (default) = 'ipv4' - RF_VPN_V6 = 'ipv6' Returns a list object containing an instance of AttributeMap """ if route_family not in SUPPORTED_VRF_RF: raise ValueError('Unsupported route_family: %s' % route_family) func_name = 'neighbor.attribute_map.get' param = { neighbors.IP_ADDRESS: address, } if route_dist is not None: param[vrfs.ROUTE_DISTINGUISHER] = route_dist param[vrfs.VRF_RF] = route_family return call(func_name, **param) @staticmethod def _check_rf_and_normalize(prefix): """ check prefix's route_family and if the address is IPv6 address, return IPv6 route_family and normalized IPv6 address. If the address is IPv4 address, return IPv4 route_family and the prefix itself. """ addr, masklen = prefix.split('/') if ip.valid_ipv6(addr): # normalize IPv6 address ipv6_prefix = str(netaddr.IPAddress(addr)) + '/' + masklen return vrfs.VRF_RF_IPV6, ipv6_prefix else: return vrfs.VRF_RF_IPV4, prefix ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/bmp.py0000664000175000017500000002203300000000000022036 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone 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. from os_ken.services.protocols.bgp.base import Activity from os_ken.lib import hub from os_ken.lib.packet import bmp from os_ken.lib.packet import bgp import socket import logging from calendar import timegm from os_ken.services.protocols.bgp.signals.emit import BgpSignalBus from os_ken.services.protocols.bgp.info_base.ipv4 import Ipv4Path from os_ken.lib.packet.bgp import BGPUpdate from os_ken.lib.packet.bgp import BGPPathAttributeMpUnreachNLRI LOG = logging.getLogger('bgpspeaker.bmp') class BMPClient(Activity): """A BMP client. Try to establish BMP session between a configured BMP server. If BMP session is established, transfer information about peers (e.g. received and sent open msgs, contents of adj-rib-in, other stats) """ def __init__(self, core_service, host, port): super(BMPClient, self).__init__(name='BMPClient(%s:%s)' % (host, port)) self._core_service = core_service self._core_service.signal_bus.register_listener( BgpSignalBus.BGP_ADJ_RIB_IN_CHANGED, lambda _, data: self.on_adj_rib_in_changed(data) ) self._core_service.signal_bus.register_listener( BgpSignalBus.BGP_ADJ_UP, lambda _, data: self.on_adj_up(data) ) self._core_service.signal_bus.register_listener( BgpSignalBus.BGP_ADJ_DOWN, lambda _, data: self.on_adj_down(data) ) self._socket = None self.server_address = (host, port) self._connect_retry_event = hub.Event() self._connect_retry_time = 5 def _run(self): self._connect_retry_event.set() while True: self._connect_retry_event.wait() try: self._connect_retry_event.clear() self._connect_tcp(self.server_address, self._handle_bmp_session) except socket.error: self._connect_retry_event.set() LOG.info('Will try to reconnect to %s after %s secs: %s', self.server_address, self._connect_retry_time, self._connect_retry_event.is_set()) self.pause(self._connect_retry_time) def _send(self, msg): if not self._socket: return assert isinstance(msg, bmp.BMPMessage) self._socket.send(msg.serialize()) def on_adj_rib_in_changed(self, data): peer = data['peer'] path = data['received_route'] msg = self._construct_route_monitoring(peer, path) self._send(msg) def on_adj_up(self, data): peer = data['peer'] msg = self._construct_peer_up_notification(peer) self._send(msg) def on_adj_down(self, data): peer = data['peer'] msg = self._construct_peer_down_notification(peer) self._send(msg) def _construct_peer_up_notification(self, peer): if peer.is_mpbgp_cap_valid(bgp.RF_IPv4_VPN) or \ peer.is_mpbgp_cap_valid(bgp.RF_IPv6_VPN): peer_type = bmp.BMP_PEER_TYPE_L3VPN else: peer_type = bmp.BMP_PEER_TYPE_GLOBAL peer_distinguisher = 0 peer_as = peer._neigh_conf.remote_as peer_bgp_id = peer.protocol.recv_open_msg.bgp_identifier timestamp = peer.state._established_time local_address = peer.host_bind_ip local_port = int(peer.host_bind_port) peer_address, remote_port = peer.protocol._remotename remote_port = int(remote_port) sent_open_msg = peer.protocol.sent_open_msg recv_open_msg = peer.protocol.recv_open_msg msg = bmp.BMPPeerUpNotification(local_address=local_address, local_port=local_port, remote_port=remote_port, sent_open_message=sent_open_msg, received_open_message=recv_open_msg, peer_type=peer_type, is_post_policy=False, peer_distinguisher=peer_distinguisher, peer_address=peer_address, peer_as=peer_as, peer_bgp_id=peer_bgp_id, timestamp=timestamp) return msg def _construct_peer_down_notification(self, peer): if peer.is_mpbgp_cap_valid(bgp.RF_IPv4_VPN) or \ peer.is_mpbgp_cap_valid(bgp.RF_IPv6_VPN): peer_type = bmp.BMP_PEER_TYPE_L3VPN else: peer_type = bmp.BMP_PEER_TYPE_GLOBAL peer_as = peer._neigh_conf.remote_as peer_bgp_id = peer.protocol.recv_open_msg.bgp_identifier peer_address, _ = peer.protocol._remotename return bmp.BMPPeerDownNotification(bmp.BMP_PEER_DOWN_REASON_UNKNOWN, data=None, peer_type=peer_type, is_post_policy=False, peer_distinguisher=0, peer_address=peer_address, peer_as=peer_as, peer_bgp_id=peer_bgp_id, timestamp=0) def _construct_update(self, path): # Get copy of path's path attributes. new_pathattr = [attr for attr in path.pathattr_map.values()] if path.is_withdraw: if isinstance(path, Ipv4Path): return BGPUpdate(withdrawn_routes=[path.nlri], path_attributes=new_pathattr) else: mpunreach_attr = BGPPathAttributeMpUnreachNLRI( path.route_family.afi, path.route_family.safi, [path.nlri] ) new_pathattr.append(mpunreach_attr) else: if isinstance(path, Ipv4Path): return BGPUpdate(nlri=[path.nlri], path_attributes=new_pathattr) return BGPUpdate(path_attributes=new_pathattr) def _construct_route_monitoring(self, peer, route): if peer.is_mpbgp_cap_valid(bgp.RF_IPv4_VPN) or \ peer.is_mpbgp_cap_valid(bgp.RF_IPv6_VPN): peer_type = bmp.BMP_PEER_TYPE_L3VPN else: peer_type = bmp.BMP_PEER_TYPE_GLOBAL peer_distinguisher = 0 peer_as = peer._neigh_conf.remote_as peer_bgp_id = peer.protocol.recv_open_msg.bgp_identifier peer_address, _ = peer.protocol._remotename bgp_update = self._construct_update(route.path) is_post_policy = not route.filtered timestamp = timegm(route.timestamp) msg = bmp.BMPRouteMonitoring(bgp_update=bgp_update, peer_type=peer_type, is_post_policy=is_post_policy, peer_distinguisher=peer_distinguisher, peer_address=peer_address, peer_as=peer_as, peer_bgp_id=peer_bgp_id, timestamp=timestamp) return msg def _handle_bmp_session(self, socket): self._socket = socket # send init message init_info = {'type': bmp.BMP_INIT_TYPE_STRING, 'value': 'This is OSKen BGP BMP message'} init_msg = bmp.BMPInitiation([init_info]) self._send(init_msg) # send peer-up message for each peers peer_manager = self._core_service.peer_manager for peer in (p for p in peer_manager.iterpeers if p.in_established()): msg = self._construct_peer_up_notification(peer) self._send(msg) for path in peer._adj_rib_in.values(): msg = self._construct_route_monitoring(peer, path) self._send(msg) # TODO periodically send stats to bmpstation while True: # bmpstation shouldn't send any packet to bmpclient. # this recv() is only meant to detect socket closed ret = self._socket.recv(1) if len(ret) == 0: LOG.debug('BMP socket is closed. retry connecting..') self._socket = None self._connect_retry_event.set() break # silently ignore packets from the bmpstation ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/constants.py0000664000175000017500000000336400000000000023302 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone 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. """ Module that holds various constants. This module helps in breaking circular dependencies too. """ # Various states of bgp state machine. BGP_FSM_IDLE = 'Idle' BGP_FSM_CONNECT = 'Connect' BGP_FSM_ACTIVE = 'Active' BGP_FSM_OPEN_SENT = 'OpenSent' BGP_FSM_OPEN_CONFIRM = 'OpenConfirm' BGP_FSM_ESTABLISHED = 'Established' # All valid BGP finite state machine states. BGP_FSM_VALID_STATES = (BGP_FSM_IDLE, BGP_FSM_CONNECT, BGP_FSM_ACTIVE, BGP_FSM_OPEN_SENT, BGP_FSM_OPEN_CONFIRM, BGP_FSM_ESTABLISHED) # Supported bgp protocol version number. BGP_VERSION_NUM = 4 # Standard BGP server port number. STD_BGP_SERVER_PORT_NUM = 179 # # Constants used to indicate VRF prefix source. # # It indicates prefix inside VRF table came from bgp peer to VPN table and then # to VRF table.. VPN_TABLE = 'vpn_table' VRF_TABLE = 'vrf_table' # RTC EOR timer default value # Time to wait for RTC-EOR, before we can send initial UPDATE as per RFC RTC_EOR_DEFAULT_TIME = 60 # Constants for AttributeMaps ATTR_MAPS_ORG_KEY = '__orig' ATTR_MAPS_LABEL_KEY = 'at_maps_key' ATTR_MAPS_LABEL_DEFAULT = 'default' ATTR_MAPS_VALUE = 'at_maps' ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/core.py0000664000175000017500000004471600000000000022224 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone 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 of BGPSpeaker. Provides CoreService which is responsible for establishing bgp sessions with peers and maintains VRFs and Global tables. """ import logging import netaddr import socket from os_ken.lib.packet.bgp import BGP_ERROR_CEASE from os_ken.lib.packet.bgp import BGP_ERROR_SUB_CONNECTION_RESET from os_ken.lib.packet.bgp import BGP_ERROR_SUB_CONNECTION_COLLISION_RESOLUTION from os_ken.lib.packet.bgp import RF_RTC_UC from os_ken.lib.packet.bgp import BGP_ATTR_ORIGIN_INCOMPLETE from os_ken.services.protocols.bgp.base import Activity from os_ken.services.protocols.bgp.base import add_bgp_error_metadata from os_ken.services.protocols.bgp.base import BGPSException from os_ken.services.protocols.bgp.base import CORE_ERROR_CODE from os_ken.services.protocols.bgp.constants import STD_BGP_SERVER_PORT_NUM from os_ken.services.protocols.bgp import core_managers from os_ken.services.protocols.bgp.model import FlexinetOutgoingRoute from os_ken.services.protocols.bgp.protocol import Factory from os_ken.services.protocols.bgp.signals.emit import BgpSignalBus from os_ken.services.protocols.bgp.speaker import BgpProtocol from os_ken.services.protocols.bgp.utils.rtfilter import RouteTargetManager from os_ken.services.protocols.bgp.rtconf.neighbors import CONNECT_MODE_ACTIVE from os_ken.services.protocols.bgp.utils import stats from os_ken.services.protocols.bgp.bmp import BMPClient from os_ken.lib import sockopt from os_ken.lib import ip LOG = logging.getLogger('bgpspeaker.core') # Interface IP address on which to run bgp server. Core service listens on all # interfaces of the host on port 179 - standard bgp port. CORE_IP = '::' # Required dictates that Origin attribute be incomplete EXPECTED_ORIGIN = BGP_ATTR_ORIGIN_INCOMPLETE @add_bgp_error_metadata(code=CORE_ERROR_CODE, sub_code=1, def_desc='Unknown error occurred related to core.') class BgpCoreError(BGPSException): """Base exception related to all tables and peer management. """ pass class CoreService(Factory, Activity): """A service that maintains eBGP/iBGP sessions with BGP peers. Two instances of this class don't share any BGP state with each other. Manages peers, tables for various address-families, etc. """ protocol = BgpProtocol def __init__(self, common_conf, neighbors_conf, vrfs_conf): self._common_config = common_conf self._neighbors_conf = neighbors_conf self._vrfs_conf = vrfs_conf Activity.__init__(self, name='core_service') self._signal_bus = BgpSignalBus() self._init_signal_listeners() self._rt_mgr = RouteTargetManager(self, neighbors_conf, vrfs_conf) self._table_manager = core_managers.TableCoreManager( self, common_conf ) self._importmap_manager = core_managers.ImportMapManager() # Autonomous system number of this BGP speaker. self._asn = self._common_config.local_as self._peer_manager = core_managers.PeerManager( self, self._neighbors_conf, ) # Initialize sink for flexinet-peers self._sinks = set() self._conf_manager = core_managers.ConfigurationManager( self, common_conf, vrfs_conf, neighbors_conf ) # Register Flexinet peer sink from os_ken.services.protocols.bgp.net_ctrl import NET_CONTROLLER self.register_flexinet_sink(NET_CONTROLLER) # State per route family # Key: RouteFamily # Value: BgpInstanceRf self.rf_state = {} # Protocol factories for pro-active and re-active bgp-sessions. self.client_factory = None self.server_factory = None # Key: RD:Next_Hop # Value: label self._next_hop_label = {} # BgpProcessor instance (initialized during start) self._bgp_processor = None # BMP clients key: (host, port) value: BMPClient instance self.bmpclients = {} def _init_signal_listeners(self): self._signal_bus.register_listener( BgpSignalBus.BGP_DEST_CHANGED, lambda _, dest: self.enqueue_for_bgp_processing(dest) ) self._signal_bus.register_listener( BgpSignalBus.BGP_VRF_REMOVED, lambda _, route_dist: self.on_vrf_removed(route_dist) ) self._signal_bus.register_listener( BgpSignalBus.BGP_VRF_ADDED, lambda _, vrf_conf: self.on_vrf_added(vrf_conf) ) self._signal_bus.register_listener( BgpSignalBus.BGP_VRF_STATS_CONFIG_CHANGED, lambda _, vrf_conf: self.on_stats_config_change(vrf_conf) ) @property def router_id(self): return self._common_config.router_id @property def global_interested_rts(self): return self._rt_mgr.global_interested_rts @property def asn(self): return self._asn @property def table_manager(self): return self._table_manager @property def importmap_manager(self): return self._importmap_manager @property def peer_manager(self): return self._peer_manager @property def rt_manager(self): return self._rt_mgr @property def signal_bus(self): return self._signal_bus def enqueue_for_bgp_processing(self, dest): return self._bgp_processor.enqueue(dest) def on_vrf_removed(self, route_dist): # Remove stats timer linked with this vrf. vrf_stats_timer = self._timers.get(route_dist) if vrf_stats_timer: vrf_stats_timer.stop() del self._timers[route_dist] def on_vrf_added(self, vrf_conf): # Setup statistics timer. rd = vrf_conf.route_dist rf = vrf_conf.route_family vrf_table = self._table_manager.get_vrf_table(rd, rf) vrf_stats_timer = self._create_timer( rd, stats.log, stats_source=vrf_table.get_stats_summary_dict ) # Start statistics timer if applicable. if vrf_conf.stats_log_enabled: vrf_stats_timer.start(vrf_conf.stats_time) def on_stats_config_change(self, vrf_conf): vrf_stats_timer = self._timers.get( vrf_conf.route_dist ) vrf_stats_timer.stop() vrf_stats_timer.start(vrf_conf.stats_time) def _run(self, *args, **kwargs): from os_ken.services.protocols.bgp.processor import BgpProcessor # Initialize bgp processor. self._bgp_processor = BgpProcessor(self) # Start BgpProcessor in a separate thread. processor_thread = self._spawn_activity(self._bgp_processor) # Pro-actively try to establish bgp-session with peers. for peer in self._peer_manager.iterpeers: self._spawn_activity(peer, self.start_protocol) # Reactively establish bgp-session with peer by listening on # the given server hosts and port for connection requests. waiter = kwargs.pop('waiter') waiter.set() self.listen_sockets = {} if self._common_config.bgp_server_port != 0: for host in self._common_config.bgp_server_hosts: server_thread, sockets = self._listen_tcp( (host, self._common_config.bgp_server_port), self.start_protocol) self.listen_sockets.update(sockets) server_thread.wait() processor_thread.wait() # ======================================================================== # RTC address family related utilities # ======================================================================== def update_rtfilters(self): """Updates RT filters for each peer. Should be called if a new RT Nlri's have changed based on the setting. Currently only used by `Processor` to update the RT filters after it has processed a RT destination. If RT filter has changed for a peer we call RT filter change handler. """ # Update RT filter for all peers # TODO(PH): Check if getting this map can be optimized (if expensive) new_peer_to_rtfilter_map = self._compute_rtfilter_map() # If we have new best path for RT NLRI, we have to update peer RT # filters and take appropriate action of sending them NLRIs for other # address-families as per new RT filter if necessary. for peer in self._peer_manager.iterpeers: pre_rt_filter = self._rt_mgr.peer_to_rtfilter_map.get(peer, set()) curr_rt_filter = new_peer_to_rtfilter_map.get(peer, set()) old_rts = pre_rt_filter - curr_rt_filter new_rts = curr_rt_filter - pre_rt_filter # If interested RTs for a peer changes if new_rts or old_rts: LOG.debug('RT Filter for peer %s updated: ' 'Added RTs %s, Removed Rts %s', peer.ip_address, new_rts, old_rts) self._on_update_rt_filter(peer, new_rts, old_rts) # Update to new RT filters self._peer_manager.set_peer_to_rtfilter_map(new_peer_to_rtfilter_map) self._rt_mgr.peer_to_rtfilter_map = new_peer_to_rtfilter_map LOG.debug('Updated RT filters: %s', self._rt_mgr.peer_to_rtfilter_map) # Update interested RTs i.e. RTs on the path that will be installed # into global tables self._rt_mgr.update_interested_rts() def _on_update_rt_filter(self, peer, new_rts, old_rts): """Handles update of peer RT filter. Parameters: - `peer`: (Peer) whose RT filter has changed. - `new_rts`: (set) of new RTs that peer is interested in. - `old_rts`: (set) of RTs that peers is no longer interested in. """ for table in self._table_manager._global_tables.values(): if table.route_family == RF_RTC_UC: continue self._spawn('rt_filter_chg_%s' % peer, self._rt_mgr.on_rt_filter_chg_sync_peer, peer, new_rts, old_rts, table) LOG.debug('RT Filter change handler launched for route_family %s', table.route_family) def _compute_rtfilter_map(self): """Returns neighbor's RT filter (permit/allow filter based on RT). Walks RT filter tree and computes current RT filters for each peer that have advertised RT NLRIs. Returns: dict of peer, and `set` of rts that a particular neighbor is interested in. """ rtfilter_map = {} def get_neigh_filter(neigh): neigh_filter = rtfilter_map.get(neigh) # Lazy creation of neighbor RT filter if neigh_filter is None: neigh_filter = set() rtfilter_map[neigh] = neigh_filter return neigh_filter # Check if we have to use all paths or just best path if self._common_config.max_path_ext_rtfilter_all: # We have to look at all paths for a RtDest for rtcdest in self._table_manager.get_rtc_table().values(): known_path_list = rtcdest.known_path_list for path in known_path_list: neigh = path.source # We ignore NC if neigh is None: continue neigh_filter = get_neigh_filter(neigh) neigh_filter.add(path.nlri.route_target) else: # We iterate over all destination of the RTC table and for iBGP # peers we use all known paths' RTs for RT filter and for eBGP # peers we only consider best-paths' RTs for RT filter for rtcdest in self._table_manager.get_rtc_table().values(): path = rtcdest.best_path # If this destination does not have any path, we continue if not path: continue neigh = path.source # Consider only eBGP peers and ignore NC if neigh and neigh.is_ebgp_peer(): # For eBGP peers we use only best-path to learn RT filter neigh_filter = get_neigh_filter(neigh) neigh_filter.add(path.nlri.route_target) else: # For iBGP peers we use all known paths to learn RT filter known_path_list = rtcdest.known_path_list for path in known_path_list: neigh = path.source # We ignore NC, and eBGP peers if neigh and not neigh.is_ebgp_peer(): neigh_filter = get_neigh_filter(neigh) neigh_filter.add(path.nlri.route_target) return rtfilter_map # ======================================================================== # Peer or Neighbor related handles/utilities. # ======================================================================== def register_flexinet_sink(self, sink): self._sinks.add(sink) def unregister_flexinet_sink(self, sink): self._sinks.remove(sink) def update_flexinet_peers(self, path, route_dist): for sink in self._sinks: out_route = FlexinetOutgoingRoute(path, route_dist) sink.enque_outgoing_msg(out_route) def _set_password(self, address, password): if ip.valid_ipv4(address): family = socket.AF_INET else: family = socket.AF_INET6 for sock in self.listen_sockets.values(): if sock.family == family: sockopt.set_tcp_md5sig(sock, address, password) def on_peer_added(self, peer): if peer._neigh_conf.password: self._set_password(peer._neigh_conf.ip_address, peer._neigh_conf.password) if self.started: self._spawn_activity( peer, self.start_protocol ) # We need to handle new RTC_AS if peer.rtc_as != self.asn: self._spawn( 'NEW_RTC_AS_HANDLER %s' % peer.rtc_as, self._rt_mgr.update_rtc_as_set ) def on_peer_removed(self, peer): if peer._neigh_conf.password: # setting zero length key means deleting the key self._set_password(peer._neigh_conf.ip_address, '') if peer.rtc_as != self.asn: self._spawn( 'OLD_RTC_AS_HANDLER %s' % peer.rtc_as, self._rt_mgr.update_rtc_as_set ) def build_protocol(self, socket): assert socket # Check if its a reactive connection or pro-active connection _, remote_port = self.get_remotename(socket) remote_port = int(remote_port) is_reactive_conn = True if remote_port == STD_BGP_SERVER_PORT_NUM: is_reactive_conn = False bgp_protocol = self.protocol( socket, self._signal_bus, is_reactive_conn=is_reactive_conn ) return bgp_protocol def start_protocol(self, socket): """Handler of new connection requests on bgp server port. Checks if new connection request is valid and starts new instance of protocol. """ assert socket peer_addr, peer_port = self.get_remotename(socket) peer = self._peer_manager.get_by_addr(peer_addr) bgp_proto = self.build_protocol(socket) # We reject this connection request from peer: # 1) If we have connection initiated by a peer that is not in our # configuration. # 2) If this neighbor is not enabled according to configuration. if not peer or not peer.enabled: LOG.debug('Closed connection %s %s:%s as it is not a recognized' ' peer.', 'from' if bgp_proto.is_reactive else 'to', peer_addr, peer_port) # Send connection rejected notification as per RFC code = BGP_ERROR_CEASE subcode = BGP_ERROR_SUB_CONNECTION_RESET bgp_proto.send_notification(code, subcode) elif bgp_proto.is_reactive and \ peer.connect_mode is CONNECT_MODE_ACTIVE: LOG.debug('Closed connection from %s:%s as connect_mode is' ' configured ACTIVE.', peer_addr, peer_port) # Send connection rejected notification as per RFC code = BGP_ERROR_CEASE subcode = BGP_ERROR_SUB_CONNECTION_RESET bgp_proto.send_notification(code, subcode) elif not (peer.in_idle() or peer.in_active() or peer.in_connect()): LOG.debug('Closing connection to %s:%s as we have connection' ' in state other than IDLE or ACTIVE,' ' i.e. connection resolution', peer_addr, peer_port) # Send Connection Collision Resolution notification as per RFC. code = BGP_ERROR_CEASE subcode = BGP_ERROR_SUB_CONNECTION_COLLISION_RESOLUTION bgp_proto.send_notification(code, subcode) else: bind_ip, bind_port = self.get_localname(socket) peer._host_bind_ip = bind_ip peer._host_bind_port = bind_port self._spawn_activity(bgp_proto, peer) def start_bmp(self, host, port): if (host, port) in self.bmpclients: bmpclient = self.bmpclients[(host, port)] if bmpclient.started: LOG.warning("bmpclient is already running for %s:%s", host, port) return False bmpclient = BMPClient(self, host, port) self.bmpclients[(host, port)] = bmpclient self._spawn_activity(bmpclient) return True def stop_bmp(self, host, port): if (host, port) not in self.bmpclients: LOG.warning("no bmpclient is running for %s:%s", host, port) return False bmpclient = self.bmpclients[(host, port)] bmpclient.stop() ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/core_manager.py0000664000175000017500000000471300000000000023707 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone 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 Manager module dedicated for providing CORE_MANAGER singleton """ from os_ken.services.protocols.bgp.base import Activity from os_ken.services.protocols.bgp.base import ActivityException from os_ken.services.protocols.bgp.rtconf.neighbors import NeighborsConf from os_ken.services.protocols.bgp.rtconf.vrfs import VrfsConf class _CoreManager(Activity): """Core service manager. """ def __init__(self): self._common_conf = None self._neighbors_conf = None self._vrfs_conf = None self._core_service = None super(_CoreManager, self).__init__() def _run(self, *args, **kwargs): self._common_conf = kwargs.pop('common_conf') self._neighbors_conf = NeighborsConf() self._vrfs_conf = VrfsConf() from os_ken.services.protocols.bgp.core import CoreService self._core_service = CoreService(self._common_conf, self._neighbors_conf, self._vrfs_conf) waiter = kwargs.pop('waiter') core_activity = self._spawn_activity(self._core_service, waiter=waiter) core_activity.wait() def get_core_service(self): self._check_started() return self._core_service def _check_started(self): if not self.started: raise ActivityException('Cannot access any property before ' 'activity has started') @property def common_conf(self): self._check_started() return self._common_conf @property def neighbors_conf(self): self._check_started() return self._neighbors_conf @property def vrfs_conf(self): self._check_started() return self._vrfs_conf # _CoreManager instance that manages core bgp service and configuration data. CORE_MANAGER = _CoreManager() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.1061053 os-ken-2.10.0/os_ken/services/protocols/bgp/core_managers/0000775000175000017500000000000000000000000023513 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/core_managers/__init__.py0000664000175000017500000000160500000000000025626 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone 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. from .configuration_manager import ConfigurationManager from .import_map_manager import ImportMapManager from .peer_manager import PeerManager from .table_manager import TableCoreManager __all__ = ['ImportMapManager', 'TableCoreManager', 'PeerManager', 'ConfigurationManager'] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/core_managers/configuration_manager.py0000664000175000017500000001202700000000000030430 0ustar00zuulzuul00000000000000from os_ken.services.protocols.bgp.rtconf.base import ConfWithStats from os_ken.services.protocols.bgp.rtconf.common import CommonConfListener from os_ken.services.protocols.bgp.rtconf.neighbors import NeighborsConfListener from os_ken.services.protocols.bgp.rtconf import vrfs from os_ken.services.protocols.bgp.rtconf.vrfs import VrfConf from os_ken.services.protocols.bgp.rtconf.vrfs import VrfsConfListener import logging LOG = logging.getLogger('bgpspeaker.core_managers.table_mixin') class ConfigurationManager(CommonConfListener, VrfsConfListener, NeighborsConfListener): def __init__(self, core_service, common_conf, vrfs_conf, neighbors_conf): self._signal_bus = core_service.signal_bus self._common_config = common_conf self._peer_manager = core_service.peer_manager self._table_manager = core_service.table_manager self._rt_manager = core_service.rt_manager CommonConfListener.__init__(self, common_conf) VrfsConfListener.__init__(self, vrfs_conf) NeighborsConfListener.__init__(self, neighbors_conf) def on_update_common_conf(self, evt): raise NotImplementedError() def on_add_neighbor_conf(self, evt): neigh_conf = evt.value self._peer_manager.add_peer(neigh_conf, self._common_config) def on_remove_neighbor_conf(self, evt): neigh_conf = evt.value self._peer_manager.remove_peer(neigh_conf) def on_chg_vrf_conf(self, evt): evt_value = evt.value vrf_conf = evt.src new_imp_rts, removed_imp_rts, import_maps, re_export, re_import = \ evt_value route_family = vrf_conf.route_family vrf_table = self._table_manager.get_vrf_table( vrf_conf.route_dist, route_family ) assert vrf_table # If we have new import RTs we have to update RTC table and make route # refresh request to peers not participating in RT address-family self._table_manager.update_vrf_table_links( vrf_table, new_imp_rts, removed_imp_rts ) # If other properties of VRF changed we re-install local paths. if re_export: self._table_manager.re_install_net_ctrl_paths(vrf_table) # We have to withdraw paths that do not have any RT that are or # interest vrf_table.clean_uninteresting_paths() if import_maps is not None: vrf_table.init_import_maps(import_maps) changed_dests = vrf_table.apply_import_maps() for dest in changed_dests: self._signal_bus.dest_changed(dest) # import new rts if re_import: LOG.debug( "RE-importing prefixes from VPN table to VRF %r", vrf_table ) self._table_manager.import_all_vpn_paths_to_vrf(vrf_table) else: self._table_manager.import_all_vpn_paths_to_vrf( vrf_table, new_imp_rts ) # Update local/global RT NLRIs self._rt_manager.update_local_rt_nlris() def on_remove_vrf_conf(self, evt): """Removes VRF table associated with given `vrf_conf`. Cleans up other links to this table as well. """ vrf_conf = evt.value # Detach VrfConf change listener. vrf_conf.remove_listener(VrfConf.VRF_CHG_EVT, self.on_chg_vrf_conf) self._table_manager.remove_vrf_by_vrf_conf(vrf_conf) # Update local RT NLRIs self._rt_manager.update_local_rt_nlris() self._signal_bus.vrf_removed(vrf_conf.route_dist) # Remove AttributeMaps under the removed vrf rd = vrf_conf.route_dist rf = vrf_conf.route_family peers = self._peer_manager.iterpeers for peer in peers: key = ':'.join([rd, rf]) peer.attribute_maps.pop(key, None) def on_add_vrf_conf(self, evt): """Event handler for new VrfConf. Creates a VrfTable to store routing information related to new Vrf. Also arranges for related paths to be imported to this VrfTable. """ vrf_conf = evt.value route_family = vrf_conf.route_family assert route_family in vrfs.SUPPORTED_VRF_RF # Create VRF table with given configuration. vrf_table = self._table_manager.create_and_link_vrf_table(vrf_conf) # Attach VrfConf change listeners. vrf_conf.add_listener(ConfWithStats.UPDATE_STATS_LOG_ENABLED_EVT, self.on_stats_config_change) vrf_conf.add_listener(ConfWithStats.UPDATE_STATS_TIME_EVT, self.on_stats_config_change) vrf_conf.add_listener(VrfConf.VRF_CHG_EVT, self.on_chg_vrf_conf) # Import paths from VPN table that match this VRF/VPN. self._table_manager.import_all_vpn_paths_to_vrf(vrf_table) # Update local RT NLRIs self._rt_manager.update_local_rt_nlris() self._signal_bus.vrf_added(vrf_conf) def on_stats_config_change(self, evt): vrf_conf = evt.src self._signal_bus.stats_config_changed(vrf_conf) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/core_managers/import_map_manager.py0000664000175000017500000000322600000000000027731 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone 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. from os_ken.services.protocols.bgp.info_base.vrf import VrfRtImportMap from os_ken.services.protocols.bgp.info_base.vrf4 import Vrf4NlriImportMap from os_ken.services.protocols.bgp.info_base.vrf6 import Vrf6NlriImportMap class ImportMapManager(object): def __init__(self): self._import_maps_by_name = {} def create_vpnv4_nlri_import_map(self, name, value): self._create_import_map_factory(name, value, Vrf4NlriImportMap) def create_vpnv6_nlri_import_map(self, name, value): self._create_import_map_factory(name, value, Vrf6NlriImportMap) def create_rt_import_map(self, name, value): self._create_import_map_factory(name, value, VrfRtImportMap) def _create_import_map_factory(self, name, value, cls): if self._import_maps_by_name.get(name) is not None: raise ImportMapAlreadyExistsError() self._import_maps_by_name[name] = cls(value) def get_import_map_by_name(self, name): return self._import_maps_by_name.get(name) class ImportMapAlreadyExistsError(Exception): pass ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/core_managers/peer_manager.py0000664000175000017500000003104300000000000026513 0ustar00zuulzuul00000000000000import logging import netaddr from os_ken.services.protocols.bgp.base import SUPPORTED_GLOBAL_RF from os_ken.services.protocols.bgp.model import OutgoingRoute from os_ken.services.protocols.bgp.peer import Peer from os_ken.lib.packet.bgp import BGPPathAttributeCommunities from os_ken.lib.packet.bgp import BGP_ATTR_TYPE_MULTI_EXIT_DISC from os_ken.lib.packet.bgp import BGP_ATTR_TYPE_COMMUNITIES from os_ken.lib.packet.bgp import RF_RTC_UC from os_ken.lib.packet.bgp import RouteTargetMembershipNLRI from os_ken.services.protocols.bgp.utils.bgp \ import clone_path_and_update_med_for_target_neighbor LOG = logging.getLogger('bgpspeaker.core_managers.peer_manager') class PeerManager(object): def __init__( self, core_service, neighbors_conf, ): self._core_service = core_service self._signal_bus = core_service.signal_bus self._table_manager = core_service.table_manager self._rt_manager = core_service.rt_manager self._peers = {} # Peer to RTFilter map # Key: Peer instance # Value: set of RTs that constitute RT filter for this peer self._peer_to_rtfilter_map = {} self._neighbors_conf = neighbors_conf @property def iterpeers(self): return iter(self._peers.values()) def set_peer_to_rtfilter_map(self, new_map): self._peer_to_rtfilter_map = new_map def add_peer(self, neigh_conf, common_conf): peer = Peer(common_conf, neigh_conf, self._core_service, self._signal_bus, self) self._peers[neigh_conf.ip_address] = peer self._core_service.on_peer_added(peer) def remove_peer(self, neigh_conf): neigh_ip_address = neigh_conf.ip_address peer = self._peers.get(neigh_ip_address) peer.stop() del self._peers[neigh_ip_address] self._core_service.on_peer_removed(peer) def get_by_addr(self, addr): return self._peers.get(str(netaddr.IPAddress(addr))) def on_peer_down(self, peer): """Peer down handler. Cleans up the paths in global tables that was received from this peer. """ LOG.debug('Cleaning obsolete paths whose source/version: %s/%s', peer.ip_address, peer.version_num) # Launch clean-up for each global tables. self._table_manager.clean_stale_routes(peer) def _get_non_rtc_peers(self): non_rtc_peer_list = set() for peer in self._peers.values(): if (peer.in_established() and not peer.is_mpbgp_cap_valid(RF_RTC_UC)): non_rtc_peer_list.add(peer) return non_rtc_peer_list def curr_peer_rtfilter(self, peer): return self._peer_to_rtfilter_map.get(peer) def get_peers_in_established(self): """Returns list of peers in established state.""" est_peers = [] for peer in self._peers.values(): if peer.in_established: est_peers.append(peer) return est_peers def resend_sent(self, route_family, peer): """For given `peer` re-send sent paths. Parameters: - `route-family`: (RouteFamily) of the sent paths to re-send - `peer`: (Peer) peer for which we need to re-send sent paths """ if peer not in self._peers.values(): raise ValueError('Could not find given peer (%s)' % peer) if route_family not in SUPPORTED_GLOBAL_RF: raise ValueError( 'Given route family (%s) is not supported.' % route_family ) # Iterate over the global table for given afi, safi and enqueue # out-going routes. table = self._table_manager.get_global_table_by_route_family( route_family ) for destination in table.values(): # Check if this destination's sent - routes include this peer. # i.e. check if this destinations was advertised and enqueue # the path only if it was. If the current best-path has not been # advertised before, it might already have a OutgoingRoute queued # to be sent to the peer. sent_routes = destination.sent_routes if sent_routes is None or len(sent_routes) == 0: continue for sent_route in sent_routes: if sent_route.sent_peer == peer: # update med - if previously med was set per neighbor or # wasn't set at all now it could have changed and we may # need to set new value there p = sent_route.path if p.med_set_by_target_neighbor or p.get_pattr( BGP_ATTR_TYPE_MULTI_EXIT_DISC) is None: sent_route.path = \ clone_path_and_update_med_for_target_neighbor( sent_route.path, peer.med ) ogr = OutgoingRoute(sent_route.path, for_route_refresh=True) peer.enque_outgoing_msg(ogr) def req_rr_to_non_rtc_peers(self, route_family): """Makes refresh request to all peers for given address family. Skips making request to peer that have valid RTC capability. """ assert route_family != RF_RTC_UC for peer in self._peers.values(): # First check if peer is in established state if (peer.in_established and # Check if peer has valid capability for given address # family peer.is_mbgp_cap_valid(route_family) and # Check if peer has valid capability for RTC not peer.is_mbgp_cap_valid(RF_RTC_UC)): peer.request_route_refresh(route_family) def make_route_refresh_request(self, peer_ip, *route_families): """Request route-refresh for peer with `peer_ip` for given `route_families`. Will make route-refresh request for a given `route_family` only if such capability is supported and if peer is in ESTABLISHED state. Else, such requests are ignored. Raises appropriate error in other cases. If `peer_ip` is equal to 'all' makes refresh request to all valid peers. """ LOG.debug('Route refresh requested for peer %s and route families %s', peer_ip, route_families) if not SUPPORTED_GLOBAL_RF.intersection(route_families): raise ValueError('Given route family(s) % is not supported.' % route_families) peer_list = [] # If route-refresh is requested for all peers. if peer_ip == 'all': peer_list.extend(self.get_peers_in_established()) else: given_peer = self._peers.get(peer_ip) if not given_peer: raise ValueError('Invalid/unrecognized peer %s' % peer_ip) if not given_peer.in_established: raise ValueError('Peer currently do not have established' ' session.') peer_list.append(given_peer) # Make route refresh request to valid peers. for peer in peer_list: peer.request_route_refresh(*route_families) return True def comm_all_rt_nlris(self, peer): """Shares/communicates current best rt_nlri paths with this peers. Can be used to send initial updates after we have established session with `peer` with which RTC capability is valid. Takes into account peers RTC_AS setting and filters all RT NLRIs whose origin AS do not match this setting. """ # First check if for this peer mpbgp-rtc is valid. if not peer.is_mbgp_cap_valid(RF_RTC_UC): return neigh_conf = self._neighbors_conf.get_neighbor_conf(peer.ip_address) peer_rtc_as = neigh_conf.rtc_as # Iterate over all RT_NLRI destination communicate qualifying RT_NLRIs rtc_table = self._table_manager.get_rtc_table() for dest in rtc_table.values(): best_path = dest.best_path # Ignore a destination that currently does not have best path if not best_path: continue # If this is a local path if best_path.source is None: # Check RT NLRI's origin AS matches peer RTC_AS setting origin_as = best_path.nlri.origin_as if origin_as == peer_rtc_as: peer.communicate_path(best_path) else: # Communicate all remote RT NLRIs peer.communicate_path(best_path) # Also communicate EOR as per RFC peer.enque_end_of_rib(RF_RTC_UC) def comm_all_best_paths(self, peer): """Shares/communicates current best paths with this peers. Can be used to send initial updates after we have established session with `peer`. """ LOG.debug('Communicating current best path for all afi/safi except' ' 1/132') # We will enqueue best path from all global destination. for route_family, table in self._table_manager.iter: if route_family == RF_RTC_UC: continue if peer.is_mbgp_cap_valid(route_family): for dest in table.values(): if dest.best_path: peer.communicate_path(dest.best_path) def comm_new_best_to_bgp_peers(self, new_best_path): """Communicates/enqueues given best path to be sent to all qualifying bgp peers. If this path came from iBGP peers, it is not sent to other iBGP peers. If this path has community-attribute, and if settings for recognize- well-know attributes is set, we do as per [RFC1997], and queue outgoing route only to qualifying BGP peers. """ # Filter based on standard community # If new best path has community attribute, it should be taken into # account when sending UPDATE to peers. comm_attr = new_best_path.get_pattr(BGP_ATTR_TYPE_COMMUNITIES) if comm_attr: comm_attr_na = comm_attr.has_comm_attr( BGPPathAttributeCommunities.NO_ADVERTISE ) # If we have NO_ADVERTISE attribute is present, we do not send # UPDATE to any peers if comm_attr_na: LOG.debug('New best path has community attr. NO_ADVERTISE = %s' '. Hence not advertising to any peer', comm_attr_na) return qualified_peers = self._collect_peers_of_interest( new_best_path ) # Distribute new best-path to qualified peers. for peer in qualified_peers: peer.communicate_path(new_best_path) def _collect_peers_of_interest(self, new_best_path): """Collect all peers that qualify for sharing a path with given RTs. """ path_rts = new_best_path.get_rts() qualified_peers = set(self._peers.values()) # Filter out peers based on RTC_AS setting if path is for RT_NLRI qualified_peers = self._rt_manager.filter_by_origin_as( new_best_path, qualified_peers ) # We continue to filter out qualified peer based on path RTs # If new best path has RTs, we need to share this UPDATE with # qualifying peers if path_rts: # We add Default_RTC_NLRI to path RTs so that we can send it to # peers that have expressed interest in all paths path_rts.append(RouteTargetMembershipNLRI.DEFAULT_RT) # All peers that do not have RTC capability qualify qualified_peers = set(self._get_non_rtc_peers()) # Peers that have RTC capability and have common RT with the path # also qualify peer_to_rtfilter_map = self._peer_to_rtfilter_map for peer, rt_filter in peer_to_rtfilter_map.items(): # Ignore Network Controller (its not a BGP peer) if peer is None: continue if rt_filter is None: qualified_peers.add(peer) elif rt_filter.intersection(path_rts): qualified_peers.add(peer) return qualified_peers def schedule_rr_to_non_rtc_peers(self): for route_family in SUPPORTED_GLOBAL_RF: # Since we are dealing with peers that do not support RTC, # ignore this address family if route_family == RF_RTC_UC: continue self.req_rr_to_non_rtc_peers(route_family) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/core_managers/table_manager.py0000664000175000017500000011322600000000000026653 0ustar00zuulzuul00000000000000import logging from collections import OrderedDict import netaddr from os_ken.services.protocols.bgp.base import SUPPORTED_GLOBAL_RF from os_ken.services.protocols.bgp.info_base.rtc import RtcTable from os_ken.services.protocols.bgp.info_base.ipv4 import Ipv4Path from os_ken.services.protocols.bgp.info_base.ipv4 import Ipv4Table from os_ken.services.protocols.bgp.info_base.ipv6 import Ipv6Path from os_ken.services.protocols.bgp.info_base.ipv6 import Ipv6Table from os_ken.services.protocols.bgp.info_base.vpnv4 import Vpnv4Table from os_ken.services.protocols.bgp.info_base.vpnv6 import Vpnv6Table from os_ken.services.protocols.bgp.info_base.vrf4 import Vrf4Table from os_ken.services.protocols.bgp.info_base.vrf6 import Vrf6Table from os_ken.services.protocols.bgp.info_base.vrfevpn import VrfEvpnTable from os_ken.services.protocols.bgp.info_base.evpn import EvpnTable from os_ken.services.protocols.bgp.info_base.ipv4fs import IPv4FlowSpecPath from os_ken.services.protocols.bgp.info_base.ipv4fs import IPv4FlowSpecTable from os_ken.services.protocols.bgp.info_base.vpnv4fs import VPNv4FlowSpecTable from os_ken.services.protocols.bgp.info_base.vrf4fs import Vrf4FlowSpecTable from os_ken.services.protocols.bgp.info_base.ipv6fs import IPv6FlowSpecPath from os_ken.services.protocols.bgp.info_base.ipv6fs import IPv6FlowSpecTable from os_ken.services.protocols.bgp.info_base.vpnv6fs import VPNv6FlowSpecTable from os_ken.services.protocols.bgp.info_base.vrf6fs import Vrf6FlowSpecTable from os_ken.services.protocols.bgp.info_base.l2vpnfs import L2VPNFlowSpecTable from os_ken.services.protocols.bgp.info_base.vrfl2vpnfs import L2vpnFlowSpecPath from os_ken.services.protocols.bgp.info_base.vrfl2vpnfs import L2vpnFlowSpecTable from os_ken.services.protocols.bgp.rtconf.vrfs import VRF_RF_IPV4 from os_ken.services.protocols.bgp.rtconf.vrfs import VRF_RF_IPV6 from os_ken.services.protocols.bgp.rtconf.vrfs import VRF_RF_L2_EVPN from os_ken.services.protocols.bgp.rtconf.vrfs import VRF_RF_IPV4_FLOWSPEC from os_ken.services.protocols.bgp.rtconf.vrfs import VRF_RF_IPV6_FLOWSPEC from os_ken.services.protocols.bgp.rtconf.vrfs import VRF_RF_L2VPN_FLOWSPEC from os_ken.services.protocols.bgp.rtconf.vrfs import SUPPORTED_VRF_RF from os_ken.services.protocols.bgp.utils.bgp import create_v4flowspec_actions from os_ken.services.protocols.bgp.utils.bgp import create_v6flowspec_actions from os_ken.services.protocols.bgp.utils.bgp import create_l2vpnflowspec_actions from os_ken.lib import type_desc from os_ken.lib import ip from os_ken.lib.packet.bgp import RF_IPv4_UC from os_ken.lib.packet.bgp import RF_IPv6_UC from os_ken.lib.packet.bgp import RF_IPv4_VPN from os_ken.lib.packet.bgp import RF_IPv6_VPN from os_ken.lib.packet.bgp import RF_L2_EVPN from os_ken.lib.packet.bgp import RF_IPv4_FLOWSPEC from os_ken.lib.packet.bgp import RF_IPv6_FLOWSPEC from os_ken.lib.packet.bgp import RF_VPNv4_FLOWSPEC from os_ken.lib.packet.bgp import RF_VPNv6_FLOWSPEC from os_ken.lib.packet.bgp import RF_L2VPN_FLOWSPEC from os_ken.lib.packet.bgp import RF_RTC_UC from os_ken.lib.packet.bgp import BGPPathAttributeOrigin from os_ken.lib.packet.bgp import BGPPathAttributeAsPath from os_ken.lib.packet.bgp import BGPPathAttributeExtendedCommunities from os_ken.lib.packet.bgp import BGP_ATTR_TYPE_ORIGIN from os_ken.lib.packet.bgp import BGP_ATTR_TYPE_AS_PATH from os_ken.lib.packet.bgp import BGP_ATTR_ORIGIN_IGP from os_ken.lib.packet.bgp import BGP_ATTR_TYPE_EXTENDED_COMMUNITIES from os_ken.lib.packet.bgp import EvpnEsi from os_ken.lib.packet.bgp import EvpnArbitraryEsi from os_ken.lib.packet.bgp import EvpnNLRI from os_ken.lib.packet.bgp import EvpnMacIPAdvertisementNLRI from os_ken.lib.packet.bgp import EvpnInclusiveMulticastEthernetTagNLRI from os_ken.lib.packet.bgp import IPAddrPrefix from os_ken.lib.packet.bgp import IP6AddrPrefix from os_ken.lib.packet.bgp import FlowSpecIPv4NLRI from os_ken.lib.packet.bgp import FlowSpecIPv6NLRI from os_ken.lib.packet.bgp import FlowSpecL2VPNNLRI from os_ken.services.protocols.bgp.utils.validation import is_valid_ipv4 from os_ken.services.protocols.bgp.utils.validation import is_valid_ipv4_prefix from os_ken.services.protocols.bgp.utils.validation import is_valid_ipv6 from os_ken.services.protocols.bgp.utils.validation import is_valid_ipv6_prefix LOG = logging.getLogger('bgpspeaker.core_managers.table_mixin') class TableCoreManager(object): """Methods performing core operations on tables.""" def __init__(self, core_service, common_conf): self._tables = {} self._rt_mgr = core_service.rt_manager self._signal_bus = core_service.signal_bus # (VRF) Tables to which the routes with a given route target # should be imported. # # Key: RouteTarget # Value: List of tables. self._tables_for_rt = {} # Global/Default tables, keyed by RouteFamily. self._global_tables = {} self._core_service = core_service self._signal_bus = self._core_service.signal_bus # VPN label range self._asbr_label_range = common_conf.label_range self._next_vpnv4_label = int(self._asbr_label_range[0]) self._next_hop_label = {} @property def global_tables(self): return self._global_tables def remove_vrf_by_vrf_conf(self, vrf_conf): route_family = vrf_conf.route_family assert route_family in SUPPORTED_VRF_RF table_id = (vrf_conf.route_dist, route_family) vrf_table = self._tables.pop(table_id) self._remove_links_to_vrf_table(vrf_table) # Withdraw the best-path whose source was NC since it may have been # exported to VPN table. for destination in vrf_table.values(): best_path = destination.best_path if best_path and best_path.source is None: vpn_clone = best_path.clone_to_vpn(vrf_conf.route_dist, for_withdrawal=True) self.learn_path(vpn_clone) LOG.debug('VRF with RD %s marked for removal', vrf_conf.route_dist) def import_all_vpn_paths_to_vrf(self, vrf_table, import_rts=None): """Imports VPNv4/6 or EVPN paths from Global/VPN table into given VRFv4/6 or VRFEVPN table. :param vrf_table: Vrf table to which we import :type vrf_table: VrfTable :param import_rts: import RTs to override default import_rts of vrf table for this import :type import_rts: set of strings Checks if we have any path RT common with VRF table's import RT. """ if vrf_table.route_family == Vrf4Table.ROUTE_FAMILY: vpn_table = self.get_vpn4_table() elif vrf_table.route_family == Vrf6Table.ROUTE_FAMILY: vpn_table = self.get_vpn6_table() elif vrf_table.route_family == VrfEvpnTable.ROUTE_FAMILY: vpn_table = self.get_evpn_table() elif vrf_table.route_family == Vrf4FlowSpecTable.ROUTE_FAMILY: vpn_table = self.get_vpnv4fs_table() elif vrf_table.route_family == Vrf6FlowSpecTable.ROUTE_FAMILY: vpn_table = self.get_vpnv6fs_table() elif vrf_table.route_family == L2vpnFlowSpecTable.ROUTE_FAMILY: vpn_table = self.get_l2vpnfs_table() else: raise ValueError('Invalid VRF table route family: %s' % vrf_table.route_family) vrf_table.import_vpn_paths_from_table(vpn_table, import_rts) def learn_path(self, path): """Inserts `path` into correct global table. Since known paths to `Destination` has changes, we queue it for further processing. """ # Get VPN/Global table table = self.get_global_table_by_route_family(path.route_family) gpath_dest = table.insert(path) # Since destination was updated, we enqueue it for processing. self._signal_bus.dest_changed(gpath_dest) def remember_sent_route(self, sent_route): """Records `sent_route` inside proper table. Records of `sent_route` from Adj-RIB-out. """ route_family = sent_route.path.route_family table = self.get_global_table_by_route_family(route_family) table.insert_sent_route(sent_route) def on_interesting_rts_change(self, new_global_rts, removed_global_rts): """Update global tables as interested RTs changed. Adds `new_rts` and removes `removed_rts` rt nlris. Does not check if `new_rts` or `removed_rts` are already present. Schedules refresh request to peers that do not participate in RTC address-family. """ # We add new RT NLRI and request RR for other peers. if new_global_rts: LOG.debug( 'Sending route_refresh to all neighbors that' ' did not negotiate RTC capability.' ) pm = self._core_service.peer_manager pm.schedule_rr_to_non_rtc_peers() if removed_global_rts: LOG.debug( 'Cleaning up global tables as some interested RTs were removed' ) self._clean_global_uninteresting_paths() def get_global_table_by_route_family(self, route_family): if route_family not in SUPPORTED_GLOBAL_RF: raise ValueError( 'Given route family: %s currently not supported' % route_family ) global_table = None if route_family == RF_IPv4_UC: global_table = self.get_ipv4_table() elif route_family == RF_IPv6_UC: global_table = self.get_ipv6_table() elif route_family == RF_IPv4_VPN: global_table = self.get_vpn4_table() elif route_family == RF_IPv6_VPN: global_table = self.get_vpn6_table() elif route_family == RF_L2_EVPN: global_table = self.get_evpn_table() elif route_family == RF_IPv4_FLOWSPEC: global_table = self.get_ipv4fs_table() elif route_family == RF_IPv6_FLOWSPEC: global_table = self.get_ipv6fs_table() elif route_family == RF_VPNv4_FLOWSPEC: global_table = self.get_vpnv4fs_table() elif route_family == RF_VPNv6_FLOWSPEC: global_table = self.get_vpnv6fs_table() elif route_family == RF_L2VPN_FLOWSPEC: global_table = self.get_l2vpnfs_table() elif route_family == RF_RTC_UC: global_table = self.get_rtc_table() return global_table def get_vrf_table(self, vrf_rd, vrf_rf): assert vrf_rd is not None return self._tables.get((vrf_rd, vrf_rf)) def get_vrf_tables(self, vrf_rf=None): vrf_tables = {} for (scope_id, table_id), table in self._tables.items(): if scope_id is None: continue if vrf_rf is not None and table_id != vrf_rf: continue vrf_tables[(scope_id, table_id)] = table return vrf_tables def get_ipv4_table(self): """Returns global IPv4 table. Creates the table if it does not exist. """ vpn_table = self._global_tables.get(RF_IPv4_UC) # Lazy initialize the table. if not vpn_table: vpn_table = Ipv4Table(self._core_service, self._signal_bus) self._global_tables[RF_IPv4_UC] = vpn_table self._tables[(None, RF_IPv4_UC)] = vpn_table return vpn_table def get_ipv6_table(self): table = self._global_tables.get(RF_IPv6_UC) if not table: table = Ipv6Table(self._core_service, self._signal_bus) self._global_tables[RF_IPv6_UC] = table self._tables[(None, RF_IPv6_UC)] = table return table def get_vpn6_table(self): """Returns global VPNv6 table. Creates the table if it does not exist. """ vpn_table = self._global_tables.get(RF_IPv6_VPN) # Lazy initialize the table. if not vpn_table: vpn_table = Vpnv6Table(self._core_service, self._signal_bus) self._global_tables[RF_IPv6_VPN] = vpn_table self._tables[(None, RF_IPv6_VPN)] = vpn_table return vpn_table def get_vpn4_table(self): """Returns global VPNv6 table. Creates the table if it does not exist. """ vpn_table = self._global_tables.get(RF_IPv4_VPN) # Lazy initialize the table. if not vpn_table: vpn_table = Vpnv4Table(self._core_service, self._signal_bus) self._global_tables[RF_IPv4_VPN] = vpn_table self._tables[(None, RF_IPv4_VPN)] = vpn_table return vpn_table def get_evpn_table(self): """Returns global EVPN table. Creates the table if it does not exist. """ evpn_table = self._global_tables.get(RF_L2_EVPN) # Lazy initialization of the table. if not evpn_table: evpn_table = EvpnTable(self._core_service, self._signal_bus) self._global_tables[RF_L2_EVPN] = evpn_table self._tables[(None, RF_L2_EVPN)] = evpn_table return evpn_table def get_rtc_table(self): """Returns global RTC table. Creates the table if it does not exist. """ rtc_table = self._global_tables.get(RF_RTC_UC) # Lazy initialization of the table. if not rtc_table: rtc_table = RtcTable(self._core_service, self._signal_bus) self._global_tables[RF_RTC_UC] = rtc_table self._tables[(None, RF_RTC_UC)] = rtc_table return rtc_table def get_next_vpnv4_label(self): # Get next available label lbl = self._next_vpnv4_label # Check if label is within max. range allowed. if lbl > int(self._asbr_label_range[1]): # Currently we log error message if we exceed configured range. message = 'Have reached max label range' LOG.error(message) raise ValueError(message) # Increment label by 1 as next label. self._next_vpnv4_label += 1 return lbl def get_ipv4fs_table(self): """Returns global IPv4 Flow Specification table. Creates the table if it does not exist. """ ipv4fs_table = self._global_tables.get(RF_IPv4_FLOWSPEC) # Lazy initialization of the table. if not ipv4fs_table: ipv4fs_table = IPv4FlowSpecTable(self._core_service, self._signal_bus) self._global_tables[RF_IPv4_FLOWSPEC] = ipv4fs_table self._tables[(None, RF_IPv4_FLOWSPEC)] = ipv4fs_table return ipv4fs_table def get_ipv6fs_table(self): """Returns global IPv6 Flow Specification table. Creates the table if it does not exist. """ ipv6fs_table = self._global_tables.get(RF_IPv6_FLOWSPEC) # Lazy initialization of the table. if not ipv6fs_table: ipv6fs_table = IPv6FlowSpecTable(self._core_service, self._signal_bus) self._global_tables[RF_IPv6_FLOWSPEC] = ipv6fs_table self._tables[(None, RF_IPv6_FLOWSPEC)] = ipv6fs_table return ipv6fs_table def get_vpnv4fs_table(self): """Returns global VPNv4 Flow Specification table. Creates the table if it does not exist. """ vpnv4fs_table = self._global_tables.get(RF_VPNv4_FLOWSPEC) # Lazy initialization of the table. if not vpnv4fs_table: vpnv4fs_table = VPNv4FlowSpecTable(self._core_service, self._signal_bus) self._global_tables[RF_VPNv4_FLOWSPEC] = vpnv4fs_table self._tables[(None, RF_VPNv4_FLOWSPEC)] = vpnv4fs_table return vpnv4fs_table def get_vpnv6fs_table(self): """Returns global VPNv6 Flow Specification table. Creates the table if it does not exist. """ vpnv6fs_table = self._global_tables.get(RF_VPNv6_FLOWSPEC) # Lazy initialization of the table. if not vpnv6fs_table: vpnv6fs_table = VPNv6FlowSpecTable(self._core_service, self._signal_bus) self._global_tables[RF_VPNv6_FLOWSPEC] = vpnv6fs_table self._tables[(None, RF_VPNv6_FLOWSPEC)] = vpnv6fs_table return vpnv6fs_table def get_l2vpnfs_table(self): """Returns global L2VPN Flow Specification table. Creates the table if it does not exist. """ l2vpnfs_table = self._global_tables.get(RF_L2VPN_FLOWSPEC) # Lazy initialization of the table. if not l2vpnfs_table: l2vpnfs_table = L2VPNFlowSpecTable(self._core_service, self._signal_bus) self._global_tables[RF_L2VPN_FLOWSPEC] = l2vpnfs_table self._tables[(None, RF_L2VPN_FLOWSPEC)] = l2vpnfs_table return l2vpnfs_table def get_nexthop_label(self, label_key): return self._next_hop_label.get(label_key, None) def set_nexthop_label(self, key, value): self._next_hop_label[key] = value def update_vrf_table_links(self, vrf_table, new_imp_rts, removed_imp_rts): """Update mapping from RT to VRF table.""" assert vrf_table if new_imp_rts: self._link_vrf_table(vrf_table, new_imp_rts) if removed_imp_rts: self._remove_links_to_vrf_table_for_rts(vrf_table, removed_imp_rts) def re_install_net_ctrl_paths(self, vrf_table): """Re-installs paths from NC with current BGP policy. Iterates over known paths from NC installed in `vrf4_table` and adds new path with path attributes as per current VRF configuration. """ assert vrf_table for dest in vrf_table.values(): for path in dest.known_path_list: if path.source is None: vrf_table.insert_vrf_path( nlri=path.nlri, next_hop=path.nexthop, gen_lbl=True ) LOG.debug('Re-installed NC paths with current policy for table %s.', vrf_table) def _remove_links_to_vrf_table(self, vrf_table): """Removes any links to given `vrf_table`.""" assert vrf_table vrf_conf = vrf_table.vrf_conf self._remove_links_to_vrf_table_for_rts(vrf_table, vrf_conf.import_rts) def _remove_links_to_vrf_table_for_rts(self, vrf_table, rts): rts_with_no_table = set() affected_tables = set() route_family = vrf_table.route_family for rt in rts: rt_rf_id = rt + ':' + str(route_family) rt_specific_tables = self._tables_for_rt.get(rt_rf_id) affected_tables.update(rt_specific_tables) if rt_specific_tables: try: rt_specific_tables.remove(vrf_table) except KeyError: LOG.debug('Did not find table listed as interested ' 'for its import RT: %s', rt) if len(rt_specific_tables) == 0: rts_with_no_table.add(rt) # Remove records of RT that have no tables associated with it. for rt in rts_with_no_table: rt_rf_id = rt + ':' + str(route_family) del self._tables_for_rt[rt_rf_id] def create_and_link_vrf_table(self, vrf_conf): """Factory method to create VRF table for given `vrf_conf`. Adds mapping to this table with appropriate scope. Also, adds mapping for import RT of this VRF to created table to facilitate importing/installing of paths from global tables. Returns created table. """ route_family = vrf_conf.route_family if route_family == VRF_RF_IPV4: vrf_table = Vrf4Table elif route_family == VRF_RF_IPV6: vrf_table = Vrf6Table elif route_family == VRF_RF_L2_EVPN: vrf_table = VrfEvpnTable elif route_family == VRF_RF_IPV4_FLOWSPEC: vrf_table = Vrf4FlowSpecTable elif route_family == VRF_RF_IPV6_FLOWSPEC: vrf_table = Vrf6FlowSpecTable elif route_family == VRF_RF_L2VPN_FLOWSPEC: vrf_table = L2vpnFlowSpecTable else: raise ValueError('Unsupported route family for VRF: %s' % route_family) vrf_table = vrf_table(vrf_conf, self._core_service, self._signal_bus) table_id = (vrf_conf.route_dist, route_family) self._tables[table_id] = vrf_table assert vrf_table is not None LOG.debug('Added new VrfTable with route_dist:%s and route_family:%s', vrf_conf.route_dist, route_family) import_rts = vrf_conf.import_rts # If VRF is configured with import RT, we put this table # in a list corresponding to this RT for easy access. if import_rts: self._link_vrf_table(vrf_table, import_rts) return vrf_table def _link_vrf_table(self, vrf_table, rt_list): route_family = vrf_table.route_family for rt in rt_list: rt_rf_id = rt + ':' + str(route_family) table_set = self._tables_for_rt.get(rt_rf_id) if table_set is None: table_set = set() self._tables_for_rt[rt_rf_id] = table_set table_set.add(vrf_table) LOG.debug('Added VrfTable %s to import RT table list: %s', vrf_table, rt) def _clean_global_uninteresting_paths(self): """Marks paths that do not have any route targets of interest for withdrawal. Since global tables can have paths with route targets that are not interesting any more, we have to clean these paths so that appropriate withdraw are sent out to NC and other peers. Interesting route targets change as VRF are modified or some filter is that specify what route targets are allowed are updated. This clean up should only be done when a route target is no longer considered interesting and some paths with that route target was installing in any of the global table. """ uninteresting_dest_count = 0 interested_rts = self._rt_mgr.global_interested_rts LOG.debug('Cleaning uninteresting paths. Global interested RTs %s', interested_rts) for route_family in [RF_IPv4_VPN, RF_IPv6_VPN, RF_RTC_UC]: # TODO(PH): We currently do not install RT_NLRI paths based on # extended path attributes (RT) if route_family == RF_RTC_UC: continue table = self.get_global_table_by_route_family(route_family) uninteresting_dest_count += \ table.clean_uninteresting_paths(interested_rts) LOG.debug('Found %s number of destinations had uninteresting paths.', uninteresting_dest_count) def import_single_vpn_path_to_all_vrfs(self, vpn_path, path_rts=None): """Imports *vpn_path* to qualifying VRF tables. Import RTs of VRF table is matched with RTs from *vpn4_path* and if we have any common RTs we import the path into VRF. """ LOG.debug('Importing path %s to qualifying VRFs', vpn_path) # If this path has no RTs we are done. if not path_rts: LOG.info('Encountered a path with no RTs: %s', vpn_path) return # We match path RTs with all VRFs that are interested in them. interested_tables = set() # Get route family of VRF to when this VPN Path can be imported to if vpn_path.route_family == RF_IPv4_VPN: route_family = RF_IPv4_UC elif vpn_path.route_family == RF_IPv6_VPN: route_family = RF_IPv6_UC elif vpn_path.route_family == RF_L2_EVPN: route_family = RF_L2_EVPN elif vpn_path.route_family == RF_VPNv4_FLOWSPEC: route_family = RF_IPv4_FLOWSPEC elif vpn_path.route_family == RF_VPNv6_FLOWSPEC: route_family = RF_IPv6_FLOWSPEC elif vpn_path.route_family == RF_L2VPN_FLOWSPEC: route_family = RF_L2VPN_FLOWSPEC else: raise ValueError('Unsupported route family for VRF: %s' % vpn_path.route_family) for rt in path_rts: rt_rf_id = rt + ':' + str(route_family) vrf_rt_tables = self._tables_for_rt.get(rt_rf_id) if vrf_rt_tables: interested_tables.update(vrf_rt_tables) if interested_tables: # We iterate over all VRF tables that are interested in the RT # of the given path and import this path into them. route_dist = vpn_path.nlri.route_dist for vrf_table in interested_tables: if (vpn_path.source is not None or route_dist != vrf_table.vrf_conf.route_dist): update_vrf_dest = vrf_table.import_vpn_path(vpn_path) # Queue the destination for further processing. if update_vrf_dest is not None: self._signal_bus.\ dest_changed(update_vrf_dest) else: # If we do not have any VRF with import RT that match with path RT LOG.debug('No VRF table found that imports RTs: %s', path_rts) def update_vrf_table(self, route_dist, prefix=None, next_hop=None, route_family=None, route_type=None, tunnel_type=None, is_withdraw=False, redundancy_mode=None, pmsi_tunnel_type=None, tunnel_endpoint_ip=None, mac_mobility=None, **kwargs): """Update a BGP route in the VRF table identified by `route_dist` with the given `next_hop`. If `is_withdraw` is False, which is the default, add a BGP route to the VRF table identified by `route_dist` with the given `next_hop`. If `is_withdraw` is True, remove a BGP route from the VRF table and the given `next_hop` is ignored. If `route_family` is VRF_RF_L2_EVPN, `route_type` and `kwargs` are required to construct EVPN NLRI and `prefix` is ignored. ``redundancy_mode`` specifies a redundancy mode type. ` `pmsi_tunnel_type` specifies the type of the PMSI tunnel attribute used to encode the multicast tunnel identifier. This field is advertised only if route_type is EVPN_MULTICAST_ETAG_ROUTE. `tunnel_endpoint_ip` specifies a tunnel endpoint IP other than the default local router ID; only used in EVPN_MULTICAST_ETAG_ROUTE `mac_mobility` specifies an optional integer sequence number to insert as a MAC Mobility extended community; special value `-1` is used for static MACs (MAC Mobility sequence 0 with STATIC flag set) Returns assigned VPN label. """ from os_ken.services.protocols.bgp.core import BgpCoreError assert route_dist if is_withdraw: gen_lbl = False next_hop = None else: gen_lbl = True if not (is_valid_ipv4(next_hop) or is_valid_ipv6(next_hop)): raise BgpCoreError( desc='Invalid IPv4/IPv6 nexthop: %s' % next_hop) vrf_table = self._tables.get((route_dist, route_family)) if vrf_table is None: raise BgpCoreError( desc='VRF table does not exist: route_dist=%s, ' 'route_family=%s' % (route_dist, route_family)) vni = kwargs.get('vni', None) if route_family == VRF_RF_IPV4: if not is_valid_ipv4_prefix(prefix): raise BgpCoreError(desc='Invalid IPv4 prefix: %s' % prefix) ip, masklen = prefix.split('/') prefix = IPAddrPrefix(int(masklen), ip) elif route_family == VRF_RF_IPV6: if not is_valid_ipv6_prefix(prefix): raise BgpCoreError(desc='Invalid IPv6 prefix: %s' % prefix) ip6, masklen = prefix.split('/') prefix = IP6AddrPrefix(int(masklen), ip6) elif route_family == VRF_RF_L2_EVPN: assert route_type if route_type == EvpnMacIPAdvertisementNLRI.ROUTE_TYPE_NAME: # MPLS labels will be assigned automatically kwargs['mpls_labels'] = [] if route_type == EvpnInclusiveMulticastEthernetTagNLRI.ROUTE_TYPE_NAME: # Inclusive Multicast Ethernet Tag Route does not have "vni", # omit "vni" from "kwargs" here. vni = kwargs.pop('vni', None) subclass = EvpnNLRI._lookup_type_name(route_type) kwargs['route_dist'] = route_dist esi = kwargs.get('esi', None) if esi is not None: if isinstance(esi, dict): esi_type = esi.get('type', 0) esi_class = EvpnEsi._lookup_type(esi_type) kwargs['esi'] = esi_class.from_jsondict(esi) else: # isinstance(esi, numbers.Integral) kwargs['esi'] = EvpnArbitraryEsi( type_desc.Int9.from_user(esi)) if vni is not None: # Disable to generate MPLS labels, # because encapsulation type is not MPLS. from os_ken.services.protocols.bgp.api.prefix import ( TUNNEL_TYPE_VXLAN, TUNNEL_TYPE_NVGRE) assert tunnel_type in [ None, TUNNEL_TYPE_VXLAN, TUNNEL_TYPE_NVGRE] gen_lbl = False prefix = subclass(**kwargs) else: raise BgpCoreError( desc='Unsupported route family %s' % route_family) # We do not check if we have a path to given prefix, we issue # withdrawal. Hence multiple withdrawals have not side effect. return vrf_table.insert_vrf_path( nlri=prefix, next_hop=next_hop, gen_lbl=gen_lbl, is_withdraw=is_withdraw, redundancy_mode=redundancy_mode, mac_mobility=mac_mobility, vni=vni, tunnel_type=tunnel_type, pmsi_tunnel_type=pmsi_tunnel_type) def update_flowspec_vrf_table(self, flowspec_family, route_dist, rules, actions=None, is_withdraw=False): """Update a BGP route in the VRF table for Flow Specification. ``flowspec_family`` specifies one of the flowspec family name. ``route_dist`` specifies a route distinguisher value. ``rules`` specifies NLRIs of Flow Specification as a dictionary type value. `` actions`` specifies Traffic Filtering Actions of Flow Specification as a dictionary type value. If `is_withdraw` is False, which is the default, add a BGP route to the VRF table identified by `route_dist`. If `is_withdraw` is True, remove a BGP route from the VRF table. """ from os_ken.services.protocols.bgp.core import BgpCoreError from os_ken.services.protocols.bgp.api.prefix import ( FLOWSPEC_FAMILY_VPNV4, FLOWSPEC_FAMILY_VPNV6, FLOWSPEC_FAMILY_L2VPN, ) if flowspec_family == FLOWSPEC_FAMILY_VPNV4: vrf_table = self._tables.get((route_dist, VRF_RF_IPV4_FLOWSPEC)) prefix = FlowSpecIPv4NLRI.from_user(**rules) try: communities = create_v4flowspec_actions(actions) except ValueError as e: raise BgpCoreError(desc=str(e)) elif flowspec_family == FLOWSPEC_FAMILY_VPNV6: vrf_table = self._tables.get((route_dist, VRF_RF_IPV6_FLOWSPEC)) prefix = FlowSpecIPv6NLRI.from_user(**rules) try: communities = create_v6flowspec_actions(actions) except ValueError as e: raise BgpCoreError(desc=str(e)) elif flowspec_family == FLOWSPEC_FAMILY_L2VPN: vrf_table = self._tables.get((route_dist, VRF_RF_L2VPN_FLOWSPEC)) prefix = FlowSpecL2VPNNLRI.from_user(route_dist, **rules) try: communities = create_l2vpnflowspec_actions(actions) except ValueError as e: raise BgpCoreError(desc=str(e)) else: raise BgpCoreError( desc='Unsupported flowspec_family %s' % flowspec_family) if vrf_table is None: raise BgpCoreError( desc='VRF table does not exist: route_dist=%s, ' 'flowspec_family=%s' % (route_dist, flowspec_family)) # We do not check if we have a path to given prefix, we issue # withdrawal. Hence multiple withdrawals have not side effect. vrf_table.insert_vrffs_path( nlri=prefix, communities=communities, is_withdraw=is_withdraw) def update_global_table(self, prefix, next_hop=None, is_withdraw=False): """Update a BGP route in the Global table for the given `prefix` with the given `next_hop`. If `is_withdraw` is False, which is the default, add a BGP route to the Global table. If `is_withdraw` is True, remove a BGP route from the Global table. """ src_ver_num = 1 peer = None # set mandatory path attributes origin = BGPPathAttributeOrigin(BGP_ATTR_ORIGIN_IGP) aspath = BGPPathAttributeAsPath([[]]) pathattrs = OrderedDict() pathattrs[BGP_ATTR_TYPE_ORIGIN] = origin pathattrs[BGP_ATTR_TYPE_AS_PATH] = aspath net = netaddr.IPNetwork(prefix) addr = str(net.ip) masklen = net.prefixlen if ip.valid_ipv4(addr): _nlri = IPAddrPrefix(masklen, addr) if next_hop is None: next_hop = '0.0.0.0' p = Ipv4Path else: _nlri = IP6AddrPrefix(masklen, addr) if next_hop is None: next_hop = '::' p = Ipv6Path new_path = p(peer, _nlri, src_ver_num, pattrs=pathattrs, nexthop=next_hop, is_withdraw=is_withdraw) # add to global table and propagates to neighbors self.learn_path(new_path) def update_flowspec_global_table(self, flowspec_family, rules, actions=None, is_withdraw=False): """Update a BGP route in the Global table for Flow Specification. ``flowspec_family`` specifies one of the Flow Specification family name. ``rules`` specifies NLRIs of Flow Specification as a dictionary type value. `` actions`` specifies Traffic Filtering Actions of Flow Specification as a dictionary type value. If `is_withdraw` is False, which is the default, add a BGP route to the Global table. If `is_withdraw` is True, remove a BGP route from the Global table. """ from os_ken.services.protocols.bgp.core import BgpCoreError from os_ken.services.protocols.bgp.api.prefix import ( FLOWSPEC_FAMILY_IPV4, FLOWSPEC_FAMILY_IPV6, FLOWSPEC_FAMILY_L2VPN, ) src_ver_num = 1 peer = None # set mandatory path attributes origin = BGPPathAttributeOrigin(BGP_ATTR_ORIGIN_IGP) aspath = BGPPathAttributeAsPath([[]]) pathattrs = OrderedDict() pathattrs[BGP_ATTR_TYPE_ORIGIN] = origin pathattrs[BGP_ATTR_TYPE_AS_PATH] = aspath if flowspec_family == FLOWSPEC_FAMILY_IPV4: _nlri = FlowSpecIPv4NLRI.from_user(**rules) p = IPv4FlowSpecPath try: communities = create_v4flowspec_actions(actions) except ValueError as e: raise BgpCoreError(desc=str(e)) if communities: pathattrs[BGP_ATTR_TYPE_EXTENDED_COMMUNITIES] = ( BGPPathAttributeExtendedCommunities( communities=communities)) elif flowspec_family == FLOWSPEC_FAMILY_IPV6: _nlri = FlowSpecIPv6NLRI.from_user(**rules) p = IPv6FlowSpecPath try: communities = create_v6flowspec_actions(actions) except ValueError as e: raise BgpCoreError(desc=str(e)) if communities: pathattrs[BGP_ATTR_TYPE_EXTENDED_COMMUNITIES] = ( BGPPathAttributeExtendedCommunities( communities=communities)) elif flowspec_family == FLOWSPEC_FAMILY_L2VPN: _nlri = FlowSpecL2VPNNLRI.from_user(**rules) p = L2vpnFlowSpecPath try: communities = create_l2vpnflowspec_actions(actions) except ValueError as e: raise BgpCoreError(desc=str(e)) if communities: pathattrs[BGP_ATTR_TYPE_EXTENDED_COMMUNITIES] = ( BGPPathAttributeExtendedCommunities( communities=communities)) else: raise BgpCoreError( desc='Unsupported flowspec family %s' % flowspec_family) new_path = p(peer, _nlri, src_ver_num, pattrs=pathattrs, is_withdraw=is_withdraw) # add to global table and propagates to neighbors self.learn_path(new_path) def clean_stale_routes(self, peer, route_family=None): """Removes old routes from `peer` from `route_family` table. Routes/paths version number is compared with `peer`s current version number. """ if route_family is not None: if route_family not in SUPPORTED_GLOBAL_RF: raise ValueError('Given route family %s is not supported.' % route_family) tables = [self._global_tables.get(route_family)] else: tables = self._global_tables.values() for table in tables: table.cleanup_paths_for_peer(peer) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.1101055 os-ken-2.10.0/os_ken/services/protocols/bgp/info_base/0000775000175000017500000000000000000000000022633 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/info_base/__init__.py0000664000175000017500000000012200000000000024737 0ustar00zuulzuul00000000000000""" Package for Information Base of various kind and for different afi/safi. """ ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/info_base/base.py0000664000175000017500000012450200000000000024123 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone 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. """ Defines some model classes related BGP. These class include types used in saving information sent/received over BGP sessions. """ import abc from abc import ABCMeta from abc import abstractmethod from copy import copy import logging import functools import netaddr from os_ken.lib.packet.bgp import RF_IPv4_UC from os_ken.lib.packet.bgp import RouteTargetMembershipNLRI from os_ken.lib.packet.bgp import BGP_ATTR_TYPE_EXTENDED_COMMUNITIES from os_ken.lib.packet.bgp import BGPPathAttributeLocalPref from os_ken.lib.packet.bgp import BGP_ATTR_TYPE_AS_PATH from os_ken.services.protocols.bgp.base import OrderedDict from os_ken.services.protocols.bgp.constants import VPN_TABLE from os_ken.services.protocols.bgp.constants import VRF_TABLE from os_ken.services.protocols.bgp.model import OutgoingRoute from os_ken.services.protocols.bgp.processor import BPR_ONLY_PATH from os_ken.services.protocols.bgp.processor import BPR_UNKNOWN LOG = logging.getLogger('bgpspeaker.info_base.base') class Table(object, metaclass=abc.ABCMeta): """A container for holding information about destination/prefixes. Routing information base for a particular afi/safi. This is a base class which should be sub-classed for different route family. A table can be uniquely identified by (Route Family, Scope Id). """ ROUTE_FAMILY = RF_IPv4_UC def __init__(self, scope_id, core_service, signal_bus): self._destinations = dict() # Scope in which this table exists. # If this table represents the VRF, then this could be a VPN ID. # For global/VPN tables this should be None self._scope_id = scope_id self._signal_bus = signal_bus self._core_service = core_service @property def route_family(self): return self.__class__.ROUTE_FAMILY @property def core_service(self): return self._core_service @property def scope_id(self): return self._scope_id @abstractmethod def _create_dest(self, nlri): """Creates destination specific for this table. Returns destination that stores information of paths to *nlri*. """ raise NotImplementedError() def values(self): return iter(self._destinations.values()) def insert(self, path): self._validate_path(path) self._validate_nlri(path.nlri) if path.is_withdraw: updated_dest = self._insert_withdraw(path) else: updated_dest = self._insert_path(path) return updated_dest def insert_sent_route(self, sent_route): self._validate_path(sent_route.path) dest = self._get_or_create_dest(sent_route.path.nlri) dest.add_sent_route(sent_route) def _insert_path(self, path): """Add new path to destination identified by given prefix. """ assert path.is_withdraw is False dest = self._get_or_create_dest(path.nlri) # Add given path to matching Dest. dest.add_new_path(path) # Return updated destination. return dest def _insert_withdraw(self, path): """Appends given path to withdraw list of Destination for given prefix. """ assert path.is_withdraw is True dest = self._get_or_create_dest(path.nlri) # Add given path to matching destination. dest.add_withdraw(path) # Return updated destination. return dest def cleanup_paths_for_peer(self, peer): """Remove old paths from whose source is `peer` Old paths have source version number that is less than current peer version number. Also removes sent paths to this peer. """ LOG.debug('Cleaning paths from table %s for peer %s', self, peer) for dest in self.values(): # Remove paths learned from this source paths_deleted = dest.remove_old_paths_from_source(peer) # Remove sent paths to this peer had_sent = dest.remove_sent_route(peer) if had_sent: LOG.debug('Removed sent route %s for %s', dest.nlri, peer) # If any paths are removed we enqueue respective destination for # future processing. if paths_deleted: self._signal_bus.dest_changed(dest) def clean_uninteresting_paths(self, interested_rts): """Cleans table of any path that do not have any RT in common with `interested_rts`. Parameters: - `interested_rts`: (set) of RT that are of interest/that need to be preserved """ LOG.debug('Cleaning table %s for given interested RTs %s', self, interested_rts) uninteresting_dest_count = 0 for dest in self.values(): added_withdraw = \ dest.withdraw_uninteresting_paths(interested_rts) if added_withdraw: self._signal_bus.dest_changed(dest) uninteresting_dest_count += 1 return uninteresting_dest_count def delete_dest_by_nlri(self, nlri): """Deletes the destination identified by given prefix. Returns the deleted destination if a match is found. If not match is found return None. """ self._validate_nlri(nlri) dest = self._get_dest(nlri) if dest: self._destinations.pop(dest) return dest def delete_dest(self, dest): del self._destinations[self._table_key(dest.nlri)] def _validate_nlri(self, nlri): """Validated *nlri* is the type that this table stores/supports. """ if not nlri or not (nlri.ROUTE_FAMILY == self.route_family): raise ValueError('Invalid Vpnv4 prefix given.') def _validate_path(self, path): """Check if given path is an instance of *Path*. Raises ValueError if given is not a instance of *Path*. """ if not path or not (path.route_family == self.route_family): raise ValueError('Invalid path. Expected instance of' ' Vpnv4 route family path, got %s.' % path) def _get_or_create_dest(self, nlri): table_key = self._table_key(nlri) dest = self._destinations.get(table_key) # If destination for given prefix does not exist we create it. if dest is None: dest = self._create_dest(nlri) self._destinations[table_key] = dest return dest def _get_dest(self, nlri): table_key = self._table_key(nlri) dest = self._destinations.get(table_key) return dest def is_for_vrf(self): """Returns true if this table instance represents a VRF. """ return self.scope_id is not None def __str__(self): return 'Table(scope_id: %s, rf: %s)' % (self.scope_id, self.route_family) @abstractmethod def _table_key(self, nlri): """Return a key that will uniquely identify this NLRI inside this table. """ raise NotImplementedError() class NonVrfPathProcessingMixin(object): """Mixin reacting to best-path selection algorithm on main table level. Intended to use with "Destination" subclasses. Applies to most of Destinations except for VrfDest because they are processed at VRF level, so different logic applies. """ def __init__(self): self._core_service = None # not assigned yet self._known_path_list = [] def _best_path_lost(self): self._best_path = None if self._sent_routes: # We have to send update-withdraw to all peers to whom old best # path was sent. for sent_route in self._sent_routes.values(): sent_path = sent_route.path withdraw_clone = sent_path.clone(for_withdrawal=True) outgoing_route = OutgoingRoute(withdraw_clone) sent_route.sent_peer.enque_outgoing_msg(outgoing_route) LOG.debug('Sending withdrawal to %s for %s', sent_route.sent_peer, outgoing_route) # Have to clear sent_route list for this destination as # best path is removed. self._sent_routes = {} def _new_best_path(self, new_best_path): old_best_path = self._best_path self._best_path = new_best_path LOG.debug('New best path selected for destination %s', self) # If old best path was withdrawn if (old_best_path and old_best_path not in self._known_path_list and self._sent_routes): # Have to clear sent_route list for this destination as # best path is removed. self._sent_routes = {} # Communicate that we have new best path to all qualifying # bgp-peers. pm = self._core_service.peer_manager pm.comm_new_best_to_bgp_peers(new_best_path) # withdraw old best path if old_best_path and self._sent_routes: for sent_route in self._sent_routes.values(): sent_path = sent_route.path withdraw_clone = sent_path.clone(for_withdrawal=True) outgoing_route = OutgoingRoute(withdraw_clone) sent_route.sent_peer.enque_outgoing_msg(outgoing_route) LOG.debug('Sending withdrawal to %s for %s', sent_route.sent_peer, outgoing_route) self._sent_routes = {} class Destination(object, metaclass=abc.ABCMeta): """State about a particular destination. For example, an IP prefix. This is the data-structure that is hung of the a routing information base table *Table*. """ ROUTE_FAMILY = RF_IPv4_UC def __init__(self, table, nlri): # Validate arguments. if table.route_family != self.__class__.ROUTE_FAMILY: raise ValueError('Table and destination route family ' 'do not match.') # Back-pointer to the table that contains this destination. self._table = table self._core_service = table.core_service self._nlri = nlri # List of all known processed paths, self._known_path_list = [] # List of new un-processed paths. self._new_path_list = [] # Pointer to best-path. One from the the known paths. self._best_path = None # Reason current best path was chosen as best path. self._best_path_reason = None # List of withdrawn paths. self._withdraw_list = [] # List of SentRoute objects. This is the Adj-Rib-Out for this # destination. (key/value: peer/sent_route) self._sent_routes = {} # This is an (optional) list of paths that were created as a # result of exporting this route to other tables. # self.exported_paths = None # Automatically generated # # On work queue for BGP processor. # self.next_dest_to_process # self.prev_dest_to_process @property def route_family(self): return self.__class__.ROUTE_FAMILY @property def nlri(self): return self._nlri @property def nlri_str(self): return self._nlri.formatted_nlri_str @property def best_path(self): return self._best_path @property def best_path_reason(self): return self._best_path_reason @property def known_path_list(self): return self._known_path_list[:] @property def sent_routes(self): return list(self._sent_routes.values()) def add_new_path(self, new_path): self._validate_path(new_path) self._new_path_list.append(new_path) def add_withdraw(self, withdraw): self._validate_path(withdraw) self._withdraw_list.append(withdraw) def add_sent_route(self, sent_route): self._sent_routes[sent_route.sent_peer] = sent_route def remove_sent_route(self, peer): if self.was_sent_to(peer): del self._sent_routes[peer] return True return False def was_sent_to(self, peer): if peer in self._sent_routes.keys(): return True return False def _process(self): """Calculate best path for this destination. A destination is processed when known paths to this destination has changed. We might have new paths or withdrawals of last known paths. Removes withdrawals and adds new learned paths from known path list. Uses bgp best-path calculation algorithm on new list of known paths to choose new best-path. Communicates best-path to core service. """ LOG.debug('Processing destination: %s', self) new_best_path, reason = self._process_paths() self._best_path_reason = reason if self._best_path == new_best_path: return if new_best_path is None: # we lost best path assert not self._known_path_list, repr(self._known_path_list) return self._best_path_lost() else: return self._new_best_path(new_best_path) @abstractmethod def _best_path_lost(self): raise NotImplementedError() @abstractmethod def _new_best_path(self, new_best_path): raise NotImplementedError() @classmethod def _validate_path(cls, path): if not path or path.route_family != cls.ROUTE_FAMILY: raise ValueError( 'Invalid path. Expected %s path got %s' % (cls.ROUTE_FAMILY, path) ) def process(self): self._process() if not self._known_path_list and not self._best_path: self._remove_dest_from_table() def _remove_dest_from_table(self): self._table.delete_dest(self) def remove_old_paths_from_source(self, source): """Removes known old paths from *source*. Returns *True* if any of the known paths were found to be old and removed/deleted. """ assert(source and hasattr(source, 'version_num')) removed_paths = [] # Iterate over the paths in reverse order as we want to delete paths # whose source is this peer. source_ver_num = source.version_num for path_idx in range(len(self._known_path_list) - 1, -1, -1): path = self._known_path_list[path_idx] if (path.source == source and path.source_version_num < source_ver_num): # If this peer is source of any paths, remove those path. del(self._known_path_list[path_idx]) removed_paths.append(path) return removed_paths def withdraw_if_sent_to(self, peer): """Sends a withdraw for this destination to given `peer`. Check the records if we indeed advertise this destination to given peer and if so, creates a withdraw for advertised route and sends it to the peer. Parameter: - `peer`: (Peer) peer to send withdraw to """ from os_ken.services.protocols.bgp.peer import Peer if not isinstance(peer, Peer): raise TypeError('Currently we only support sending withdrawal' ' to instance of peer') sent_route = self._sent_routes.pop(peer, None) if not sent_route: return False sent_path = sent_route.path withdraw_clone = sent_path.clone(for_withdrawal=True) outgoing_route = OutgoingRoute(withdraw_clone) sent_route.sent_peer.enque_outgoing_msg(outgoing_route) return True def _process_paths(self): """Calculates best-path among known paths for this destination. Returns: - Best path Modifies destination's state related to stored paths. Removes withdrawn paths from known paths. Also, adds new paths to known paths. """ # First remove the withdrawn paths. # Note: If we want to support multiple paths per destination we may # have to maintain sent-routes per path. self._remove_withdrawals() # Have to select best-path from available paths and new paths. # If we do not have any paths, then we no longer have best path. if not self._known_path_list and len(self._new_path_list) == 1: # If we do not have any old but one new path # it becomes best path. self._known_path_list.append(self._new_path_list[0]) del(self._new_path_list[0]) return self._known_path_list[0], BPR_ONLY_PATH # If we have a new version of old/known path we use it and delete old # one. self._remove_old_paths() # Collect all new paths into known paths. self._known_path_list.extend(self._new_path_list) # Clear new paths as we copied them. del(self._new_path_list[:]) # If we do not have any paths to this destination, then we do not have # new best path. if not self._known_path_list: return None, BPR_UNKNOWN # Compute new best path current_best_path, reason = self._compute_best_known_path() return current_best_path, reason def _remove_withdrawals(self): """Removes withdrawn paths. Note: We may have disproportionate number of withdraws compared to know paths since not all paths get installed into the table due to bgp policy and we can receive withdraws for such paths and withdrawals may not be stopped by the same policies. """ LOG.debug('Removing %s withdrawals', len(self._withdraw_list)) # If we have no withdrawals, we have nothing to do. if not self._withdraw_list: return # If we have some withdrawals and no know-paths, it means it is safe to # delete these withdraws. if not self._known_path_list: LOG.debug('Found %s withdrawals for path(s) that did not get' ' installed.', len(self._withdraw_list)) del(self._withdraw_list[:]) return # If we have some known paths and some withdrawals, we find matches and # delete them first. matches = set() w_matches = set() # Match all withdrawals from destination paths. for withdraw in self._withdraw_list: match = None for path in self._known_path_list: # We have a match if the source are same. if path.source == withdraw.source: match = path matches.add(path) w_matches.add(withdraw) # One withdraw can remove only one path. break # We do no have any match for this withdraw. if not match: LOG.debug('No matching path for withdraw found, may be path ' 'was not installed into table: %s', withdraw) # If we have partial match. if len(matches) != len(self._withdraw_list): LOG.debug('Did not find match for some withdrawals. Number of ' 'matches(%s), number of withdrawals (%s)', len(matches), len(self._withdraw_list)) # Clear matching paths and withdrawals. for match in matches: self._known_path_list.remove(match) for w_match in w_matches: self._withdraw_list.remove(w_match) def _remove_old_paths(self): """Identifies which of known paths are old and removes them. Known paths will no longer have paths whose new version is present in new paths. """ new_paths = self._new_path_list known_paths = self._known_path_list for new_path in new_paths: old_paths = [] for path in known_paths: # Here we just check if source is same and not check if path # version num. as new_paths are implicit withdrawal of old # paths and when doing RouteRefresh (not EnhancedRouteRefresh) # we get same paths again. if new_path.source == path.source: old_paths.append(path) break for old_path in old_paths: known_paths.remove(old_path) LOG.debug('Implicit withdrawal of old path, since we have' ' learned new path from same source: %s', old_path) def _compute_best_known_path(self): """Computes the best path among known paths. Returns current best path among `known_paths`. """ if not self._known_path_list: from os_ken.services.protocols.bgp.processor import BgpProcessorError raise BgpProcessorError(desc='Need at-least one known path to' ' compute best path') # We pick the first path as current best path. This helps in breaking # tie between two new paths learned in one cycle for which best-path # calculation steps lead to tie. current_best_path = self._known_path_list[0] best_path_reason = BPR_ONLY_PATH for next_path in self._known_path_list[1:]: from os_ken.services.protocols.bgp.processor import compute_best_path # Compare next path with current best path. new_best_path, reason = \ compute_best_path(self._core_service.asn, current_best_path, next_path) best_path_reason = reason if new_best_path is not None: current_best_path = new_best_path return current_best_path, best_path_reason def withdraw_uninteresting_paths(self, interested_rts): """Withdraws paths that are no longer interesting. For all known paths that do not have any route target in common with given `interested_rts` we add a corresponding withdraw. Returns True if we added any withdraws. """ add_withdraws = False for path in self._known_path_list: if not path.has_rts_in(interested_rts): self.withdraw_path(path) add_withdraws = True return add_withdraws def withdraw_path(self, path): if path not in self.known_path_list: raise ValueError("Path not known, no need to withdraw") withdraw = path.clone(for_withdrawal=True) self._withdraw_list.append(withdraw) def to_dict(self): return {'table': str(self._table), 'nlri': str(self._nlri), 'paths': self._known_path_list[:], 'withdraws': self._get_num_withdraws()} def __str__(self): return ('Destination(table: %s, nlri: %s, paths: %s, withdraws: %s,' ' new paths: %s)' % (self._table, str(self._nlri), len(self._known_path_list), len(self._withdraw_list), len(self._new_path_list))) def _get_num_valid_paths(self): return len(self._known_path_list) def _get_num_withdraws(self): return len(self._withdraw_list) def sent_routes_by_peer(self, peer): """get sent routes corresponding to specified peer. Returns SentRoute list. """ result = [] for route in self._sent_routes.values(): if route.sent_peer == peer: result.append(route) return result def __lt__(self, other): return str(self) < str(other) def __le__(self, other): return str(self) <= str(other) def __eq__(self, other): return str(self) == str(other) def __ne__(self, other): return str(self) != str(other) def __gt__(self, other): return str(self) > str(other) def __ge__(self, other): return str(self) >= str(other) class Path(object, metaclass=abc.ABCMeta): """Represents a way of reaching an IP destination. Also contains other meta-data given to us by a specific source (such as a peer). """ __slots__ = ('_source', '_path_attr_map', '_nlri', '_source_version_num', '_exported_from', '_nexthop', 'next_path', 'prev_path', '_is_withdraw', 'med_set_by_target_neighbor') ROUTE_FAMILY = RF_IPv4_UC def __init__(self, source, nlri, src_ver_num, pattrs=None, nexthop=None, is_withdraw=False, med_set_by_target_neighbor=False): """Initializes Ipv4 path. If this path is not a withdraw, then path attribute and nexthop both should be provided. Parameters: - `source`: (Peer/str) source of this path. - `nlri`: (Vpnv4) Nlri instance for Vpnv4 route family. - `src_ver_num`: (int) version number of *source* when this path was learned. - `pattrs`: (OrderedDict) various path attributes for this path. - `nexthop`: (str) nexthop advertised for this path. - `is_withdraw`: (bool) True if this represents a withdrawal. """ self.med_set_by_target_neighbor = med_set_by_target_neighbor if nlri.ROUTE_FAMILY != self.__class__.ROUTE_FAMILY: raise ValueError('NLRI and Path route families do not' ' match (%s, %s).' % (nlri.ROUTE_FAMILY, self.__class__.ROUTE_FAMILY)) # Currently paths injected directly into VRF has only one source # src_peer can be None to denote NC else has to be instance of Peer. # Paths can be exported from one VRF and then imported into another # VRF, in such cases it source is denoted as string VPN_TABLE. if not (source is None or hasattr(source, 'version_num') or source in (VRF_TABLE, VPN_TABLE)): raise ValueError('Invalid or Unsupported source for path: %s' % source) # If this path is not a withdraw path, than it should have path- # attributes and nexthop. if not is_withdraw and not (pattrs and nexthop): raise ValueError('Need to provide nexthop and patattrs ' 'for path that is not a withdraw.') # The entity (peer) that gave us this path. self._source = source # Path attribute of this path. if pattrs: self._path_attr_map = copy(pattrs) else: self._path_attr_map = OrderedDict() # NLRI that this path represents. self._nlri = nlri # If given nlri is withdrawn. self._is_withdraw = is_withdraw # @see Source.version_num self._source_version_num = src_ver_num self._nexthop = nexthop # Automatically generated. # # self.next_path # self.prev_path # The Destination from which this path was exported, if any. self._exported_from = None @property def source_version_num(self): return self._source_version_num @property def source(self): return self._source @property def route_family(self): return self.__class__.ROUTE_FAMILY @property def nlri(self): return self._nlri @property def nlri_str(self): return self._nlri.formatted_nlri_str @property def is_withdraw(self): return self._is_withdraw @property def pathattr_map(self): return copy(self._path_attr_map) @property def nexthop(self): return self._nexthop def get_pattr(self, pattr_type, default=None): """Returns path attribute of given type. Returns None if we do not attribute of type *pattr_type*. """ return self._path_attr_map.get(pattr_type, default) def clone(self, for_withdrawal=False): pathattrs = None if not for_withdrawal: pathattrs = self.pathattr_map clone = self.__class__( self.source, self.nlri, self.source_version_num, pattrs=pathattrs, nexthop=self.nexthop, is_withdraw=for_withdrawal ) return clone def get_rts(self): extcomm_attr = self._path_attr_map.get( BGP_ATTR_TYPE_EXTENDED_COMMUNITIES) if extcomm_attr is None: rts = [] else: rts = extcomm_attr.rt_list return rts def has_rts_in(self, interested_rts): """Returns True if this `Path` has any `ExtCommunity` attribute route target common with `interested_rts`. """ assert isinstance(interested_rts, set) curr_rts = self.get_rts() # Add default RT to path RTs so that we match interest for peers who # advertised default RT curr_rts.append(RouteTargetMembershipNLRI.DEFAULT_RT) return not interested_rts.isdisjoint(curr_rts) def is_local(self): return self._source is None def has_nexthop(self): return self._nexthop and self._nexthop not in ('0.0.0.0', '::') def __str__(self): return ( 'Path(source: %s, nlri: %s, source ver#: %s, ' 'path attrs.: %s, nexthop: %s, is_withdraw: %s)' % ( self._source, self._nlri, self._source_version_num, self._path_attr_map, self._nexthop, self._is_withdraw ) ) def __repr__(self): return ('Path(%s, %s, %s, %s, %s, %s)' % ( self._source, self._nlri, self._source_version_num, self._path_attr_map, self._nexthop, self._is_withdraw)) class Filter(object, metaclass=abc.ABCMeta): """Represents a general filter for in-bound and out-bound filter ================ ================================================== Attribute Description ================ ================================================== policy Filter.POLICY_PERMIT or Filter.POLICY_DENY ================ ================================================== """ ROUTE_FAMILY = RF_IPv4_UC POLICY_DENY = 0 POLICY_PERMIT = 1 def __init__(self, policy=POLICY_DENY): self._policy = policy @property def policy(self): return self._policy @abstractmethod def evaluate(self, path): """ This method evaluates the path. Returns this object's policy and the result of matching. If the specified prefix matches this object's prefix and ge and le condition, this method returns True as the matching result. ``path`` specifies the path. prefix must be string. """ raise NotImplementedError() @abstractmethod def clone(self): """ This method clones Filter object. Returns Filter object that has the same values with the original one. """ raise NotImplementedError() @functools.total_ordering class PrefixFilter(Filter): """ Used to specify a prefix for filter. We can create PrefixFilter object as follows:: prefix_filter = PrefixFilter('10.5.111.0/24', policy=PrefixFilter.POLICY_PERMIT) ================ ================================================== Attribute Description ================ ================================================== prefix A prefix used for this filter policy One of the following values. | PrefixFilter.POLICY.PERMIT | PrefixFilter.POLICY_DENY ge Prefix length that will be applied to this filter. ge means greater than or equal. le Prefix length that will be applied to this filter. le means less than or equal. ================ ================================================== For example, when PrefixFilter object is created as follows:: p = PrefixFilter('10.5.111.0/24', policy=PrefixFilter.POLICY_DENY, ge=26, le=28) Prefixes which match 10.5.111.0/24 and its length matches from 26 to 28 will be filtered. When this filter is used as an out-filter, it will stop sending the path to neighbor because of POLICY_DENY. When this filter is used as in-filter, it will stop importing the path to the global rib because of POLICY_DENY. If you specify POLICY_PERMIT, the path is sent to neighbor or imported to the global rib. If you don't want to send prefixes 10.5.111.64/26 and 10.5.111.32/27 and 10.5.111.16/28, and allow to send other 10.5.111.0's prefixes, you can do it by specifying as follows:: p = PrefixFilter('10.5.111.0/24', policy=PrefixFilter.POLICY_DENY, ge=26, le=28). """ def __init__(self, prefix, policy, ge=None, le=None): super(PrefixFilter, self).__init__(policy) self._prefix = prefix self._network = netaddr.IPNetwork(prefix) self._ge = ge self._le = le def __lt__(self, other): return self._network < other._network def __eq__(self, other): return self._network == other._network def __repr__(self): policy = 'PERMIT' \ if self._policy == self.POLICY_PERMIT else 'DENY' return 'PrefixFilter(prefix=%s,policy=%s,ge=%s,le=%s)'\ % (self._prefix, policy, self._ge, self._le) @property def prefix(self): return self._prefix @property def policy(self): return self._policy @property def ge(self): return self._ge @property def le(self): return self._le def evaluate(self, path): """ This method evaluates the prefix. Returns this object's policy and the result of matching. If the specified prefix matches this object's prefix and ge and le condition, this method returns True as the matching result. ``path`` specifies the path that has prefix. """ nlri = path.nlri result = False length = nlri.length net = netaddr.IPNetwork(nlri.prefix) if net in self._network: if self._ge is None and self._le is None: result = True elif self._ge is None and self._le: if length <= self._le: result = True elif self._ge and self._le is None: if self._ge <= length: result = True elif self._ge and self._le: if self._ge <= length <= self._le: result = True return self.policy, result def clone(self): """ This method clones PrefixFilter object. Returns PrefixFilter object that has the same values with the original one. """ return self.__class__(self.prefix, policy=self._policy, ge=self._ge, le=self._le) @functools.total_ordering class ASPathFilter(Filter): """ Used to specify a prefix for AS_PATH attribute. We can create ASPathFilter object as follows:: as_path_filter = ASPathFilter(65000,policy=ASPathFilter.TOP) ================ ================================================== Attribute Description ================ ================================================== as_number A AS number used for this filter policy One of the following values. | ASPathFilter.POLICY_TOP | ASPathFilter.POLICY_END | ASPathFilter.POLICY_INCLUDE | ASPathFilter.POLICY_NOT_INCLUDE ================ ================================================== Meaning of each policy is as follows: ================== ================================================== Policy Description ================== ================================================== POLICY_TOP Filter checks if the specified AS number is at the top of AS_PATH attribute. POLICY_END Filter checks is the specified AS number is at the last of AS_PATH attribute. POLICY_INCLUDE Filter checks if specified AS number exists in AS_PATH attribute. POLICY_NOT_INCLUDE Opposite to POLICY_INCLUDE. ================== ================================================== """ POLICY_TOP = 2 POLICY_END = 3 POLICY_INCLUDE = 4 POLICY_NOT_INCLUDE = 5 def __init__(self, as_number, policy): super(ASPathFilter, self).__init__(policy) self._as_number = as_number def __lt__(self, other): return self.as_number < other.as_number def __eq__(self, other): return self.as_number == other.as_number def __repr__(self): policy = 'TOP' if self._policy == self.POLICY_INCLUDE: policy = 'INCLUDE' elif self._policy == self.POLICY_NOT_INCLUDE: policy = 'NOT_INCLUDE' elif self._policy == self.POLICY_END: policy = 'END' return 'ASPathFilter(as_number=%s,policy=%s)'\ % (self._as_number, policy) @property def as_number(self): return self._as_number @property def policy(self): return self._policy def evaluate(self, path): """ This method evaluates as_path list. Returns this object's policy and the result of matching. If the specified AS number matches this object's AS number according to the policy, this method returns True as the matching result. ``path`` specifies the path. """ path_aspath = path.pathattr_map.get(BGP_ATTR_TYPE_AS_PATH) path_seg_list = path_aspath.path_seg_list if path_seg_list: path_seg = path_seg_list[0] else: path_seg = [] result = False LOG.debug("path_seg : %s", path_seg) if self.policy == ASPathFilter.POLICY_TOP: if len(path_seg) > 0 and path_seg[0] == self._as_number: result = True elif self.policy == ASPathFilter.POLICY_INCLUDE: for aspath in path_seg: LOG.debug("POLICY_INCLUDE as_number : %s", aspath) if aspath == self._as_number: result = True break elif self.policy == ASPathFilter.POLICY_END: if len(path_seg) > 0 and path_seg[-1] == self._as_number: result = True elif self.policy == ASPathFilter.POLICY_NOT_INCLUDE: if self._as_number not in path_seg: result = True return self.policy, result def clone(self): """ This method clones ASPathFilter object. Returns ASPathFilter object that has the same values with the original one. """ return self.__class__(self._as_number, policy=self._policy) class AttributeMap(object): """ This class is used to specify an attribute to add if the path matches filters. We can create AttributeMap object as follows:: pref_filter = PrefixFilter('192.168.103.0/30', PrefixFilter.POLICY_PERMIT) attribute_map = AttributeMap([pref_filter], AttributeMap.ATTR_LOCAL_PREF, 250) speaker.attribute_map_set('192.168.50.102', [attribute_map]) AttributeMap.ATTR_LOCAL_PREF means that 250 is set as a local preference value if nlri in the path matches pref_filter. ASPathFilter is also available as a filter. ASPathFilter checks if AS_PATH attribute in the path matches AS number in the filter. =================== ================================================== Attribute Description =================== ================================================== filters A list of filter. Each object should be a Filter class or its sub-class attr_type A type of attribute to map on filters. Currently AttributeMap.ATTR_LOCAL_PREF is available. attr_value A attribute value =================== ================================================== """ ATTR_LOCAL_PREF = '_local_pref' def __init__(self, filters, attr_type, attr_value): assert all(isinstance(f, Filter) for f in filters),\ 'all the items in filters must be an instance of Filter sub-class' self.filters = filters self.attr_type = attr_type self.attr_value = attr_value def evaluate(self, path): """ This method evaluates attributes of the path. Returns the cause and result of matching. Both cause and result are returned from filters that this object contains. ``path`` specifies the path. """ result = False cause = None for f in self.filters: cause, result = f.evaluate(path) if not result: break return cause, result def get_attribute(self): func = getattr(self, 'get' + self.attr_type) return func() def get_local_pref(self): local_pref_attr = BGPPathAttributeLocalPref(value=self.attr_value) return local_pref_attr def clone(self): """ This method clones AttributeMap object. Returns AttributeMap object that has the same values with the original one. """ cloned_filters = [f.clone() for f in self.filters] return self.__class__(cloned_filters, self.attr_type, self.attr_value) def __repr__(self): attr_type = 'LOCAL_PREF'\ if self.attr_type == self.ATTR_LOCAL_PREF else None filter_string = ','.join(repr(f) for f in self.filters) return ('AttributeMap(filters=[%s],' 'attribute_type=%s,' 'attribute_value=%s)' % (filter_string, attr_type, self.attr_value)) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/info_base/evpn.py0000664000175000017500000000344400000000000024162 0ustar00zuulzuul00000000000000# Copyright (C) 2016 Nippon Telegraph and Telephone 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. """ Defines data types and models required specifically for EVPN support. """ import logging from os_ken.lib.packet.bgp import EvpnNLRI from os_ken.lib.packet.bgp import RF_L2_EVPN from os_ken.services.protocols.bgp.info_base.vpn import VpnDest from os_ken.services.protocols.bgp.info_base.vpn import VpnPath from os_ken.services.protocols.bgp.info_base.vpn import VpnTable LOG = logging.getLogger('bgpspeaker.info_base.evpn') class EvpnDest(VpnDest): """EVPN Destination Store EVPN Paths. """ ROUTE_FAMILY = RF_L2_EVPN class EvpnTable(VpnTable): """Global table to store EVPN routing information. Uses `EvpnDest` to store destination information for each known EVPN paths. """ ROUTE_FAMILY = RF_L2_EVPN VPN_DEST_CLASS = EvpnDest class EvpnPath(VpnPath): """Represents a way of reaching an EVPN destination.""" ROUTE_FAMILY = RF_L2_EVPN VRF_PATH_CLASS = None # defined in init - anti cyclic import hack NLRI_CLASS = EvpnNLRI def __init__(self, *args, **kwargs): super(EvpnPath, self).__init__(*args, **kwargs) from os_ken.services.protocols.bgp.info_base.vrfevpn import VrfEvpnPath self.VRF_PATH_CLASS = VrfEvpnPath ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/info_base/ipv4.py0000664000175000017500000000571200000000000024074 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone 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. """ Defines data types and models required specifically for IPv4 support. """ import logging from os_ken.lib.packet.bgp import IPAddrPrefix from os_ken.lib.packet.bgp import RF_IPv4_UC from os_ken.services.protocols.bgp.info_base.base import Path from os_ken.services.protocols.bgp.info_base.base import Table from os_ken.services.protocols.bgp.info_base.base import Destination from os_ken.services.protocols.bgp.info_base.base import NonVrfPathProcessingMixin from os_ken.services.protocols.bgp.info_base.base import PrefixFilter LOG = logging.getLogger('bgpspeaker.info_base.ipv4') class IPv4Dest(Destination, NonVrfPathProcessingMixin): """VPNv4 Destination Store IPv4 Paths. """ ROUTE_FAMILY = RF_IPv4_UC def _best_path_lost(self): old_best_path = self._best_path NonVrfPathProcessingMixin._best_path_lost(self) self._core_service._signal_bus.best_path_changed(old_best_path, True) def _new_best_path(self, best_path): NonVrfPathProcessingMixin._new_best_path(self, best_path) self._core_service._signal_bus.best_path_changed(best_path, False) class Ipv4Table(Table): """Global table to store IPv4 routing information. Uses `IPv4Dest` to store destination information for each known vpnv4 paths. """ ROUTE_FAMILY = RF_IPv4_UC VPN_DEST_CLASS = IPv4Dest def __init__(self, core_service, signal_bus): super(Ipv4Table, self).__init__(None, core_service, signal_bus) def _table_key(self, nlri): """Return a key that will uniquely identify this NLRI inside this table. """ return nlri.prefix def _create_dest(self, nlri): return self.VPN_DEST_CLASS(self, nlri) def __str__(self): return '%s(scope_id: %s, rf: %s)' % ( self.__class__.__name__, self.scope_id, self.route_family ) class Ipv4Path(Path): """Represents a way of reaching an VPNv4 destination.""" ROUTE_FAMILY = RF_IPv4_UC VRF_PATH_CLASS = None # defined in init - anti cyclic import hack NLRI_CLASS = IPAddrPrefix def __init__(self, *args, **kwargs): super(Ipv4Path, self).__init__(*args, **kwargs) from os_ken.services.protocols.bgp.info_base.vrf4 import Vrf4Path self.VRF_PATH_CLASS = Vrf4Path class Ipv4PrefixFilter(PrefixFilter): """IPv4 Prefix Filter class""" ROUTE_FAMILY = RF_IPv4_UC ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/info_base/ipv4fs.py0000664000175000017500000000631000000000000024420 0ustar00zuulzuul00000000000000# Copyright (C) 2017 Nippon Telegraph and Telephone 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. """ Defines data types and models required specifically for Ipv4 Flow Specification support. """ import logging from os_ken.lib.packet.bgp import FlowSpecIPv4NLRI from os_ken.lib.packet.bgp import RF_IPv4_FLOWSPEC from os_ken.services.protocols.bgp.info_base.base import Path from os_ken.services.protocols.bgp.info_base.base import Table from os_ken.services.protocols.bgp.info_base.base import Destination from os_ken.services.protocols.bgp.info_base.base import NonVrfPathProcessingMixin LOG = logging.getLogger('bgpspeaker.info_base.ipv4fs') class IPv4FlowSpecDest(Destination, NonVrfPathProcessingMixin): """IPv4 Flow Specification Destination Store Flow Specification Paths. """ ROUTE_FAMILY = RF_IPv4_FLOWSPEC def _best_path_lost(self): old_best_path = self._best_path NonVrfPathProcessingMixin._best_path_lost(self) self._core_service._signal_bus.best_path_changed(old_best_path, True) def _new_best_path(self, best_path): NonVrfPathProcessingMixin._new_best_path(self, best_path) self._core_service._signal_bus.best_path_changed(best_path, False) class IPv4FlowSpecTable(Table): """Global table to store IPv4 Flow Specification routing information. Uses `FlowSpecIpv4Dest` to store destination information for each known Flow Specification paths. """ ROUTE_FAMILY = RF_IPv4_FLOWSPEC VPN_DEST_CLASS = IPv4FlowSpecDest def __init__(self, core_service, signal_bus): super(IPv4FlowSpecTable, self).__init__(None, core_service, signal_bus) def _table_key(self, nlri): """Return a key that will uniquely identify this NLRI inside this table. """ return nlri.prefix def _create_dest(self, nlri): return self.VPN_DEST_CLASS(self, nlri) def __str__(self): return '%s(scope_id: %s, rf: %s)' % ( self.__class__.__name__, self.scope_id, self.route_family ) class IPv4FlowSpecPath(Path): """Represents a way of reaching an IPv4 Flow Specification destination.""" ROUTE_FAMILY = RF_IPv4_FLOWSPEC VRF_PATH_CLASS = None # defined in init - anti cyclic import hack NLRI_CLASS = FlowSpecIPv4NLRI def __init__(self, *args, **kwargs): # Set dummy IP address. kwargs['nexthop'] = '0.0.0.0' super(IPv4FlowSpecPath, self).__init__(*args, **kwargs) from os_ken.services.protocols.bgp.info_base.vrf4fs import ( Vrf4FlowSpecPath) self.VRF_PATH_CLASS = Vrf4FlowSpecPath # Because the IPv4 Flow Specification does not require nexthop, # initialize with None. self._nexthop = None ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/info_base/ipv6.py0000664000175000017500000000570400000000000024077 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone 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. """ Defines data types and models required specifically for IPv4 support. """ import logging from os_ken.lib.packet.bgp import IPAddrPrefix from os_ken.lib.packet.bgp import RF_IPv6_UC from os_ken.services.protocols.bgp.info_base.base import Path from os_ken.services.protocols.bgp.info_base.base import Table from os_ken.services.protocols.bgp.info_base.base import Destination from os_ken.services.protocols.bgp.info_base.base import NonVrfPathProcessingMixin from os_ken.services.protocols.bgp.info_base.base import PrefixFilter LOG = logging.getLogger('bgpspeaker.info_base.ipv6') class IPv6Dest(Destination, NonVrfPathProcessingMixin): """v6 Destination Store IPv6 Paths. """ ROUTE_FAMILY = RF_IPv6_UC def _best_path_lost(self): old_best_path = self._best_path NonVrfPathProcessingMixin._best_path_lost(self) self._core_service._signal_bus.best_path_changed(old_best_path, True) def _new_best_path(self, best_path): NonVrfPathProcessingMixin._new_best_path(self, best_path) self._core_service._signal_bus.best_path_changed(best_path, False) class Ipv6Table(Table): """Global table to store IPv4 routing information. Uses `IPv6Dest` to store destination information for each known vpnv6 paths. """ ROUTE_FAMILY = RF_IPv6_UC VPN_DEST_CLASS = IPv6Dest def __init__(self, core_service, signal_bus): super(Ipv6Table, self).__init__(None, core_service, signal_bus) def _table_key(self, nlri): """Return a key that will uniquely identify this NLRI inside this table. """ return nlri.prefix def _create_dest(self, nlri): return self.VPN_DEST_CLASS(self, nlri) def __str__(self): return '%s(scope_id: %s, rf: %s)' % ( self.__class__.__name__, self.scope_id, self.route_family ) class Ipv6Path(Path): """Represents a way of reaching an v6 destination.""" ROUTE_FAMILY = RF_IPv6_UC VRF_PATH_CLASS = None # defined in init - anti cyclic import hack NLRI_CLASS = IPAddrPrefix def __init__(self, *args, **kwargs): super(Ipv6Path, self).__init__(*args, **kwargs) from os_ken.services.protocols.bgp.info_base.vrf6 import Vrf6Path self.VRF_PATH_CLASS = Vrf6Path class Ipv6PrefixFilter(PrefixFilter): """IPv6 Prefix Filter class""" ROUTE_FAMILY = RF_IPv6_UC ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/info_base/ipv6fs.py0000664000175000017500000000630300000000000024424 0ustar00zuulzuul00000000000000# Copyright (C) 2017 Nippon Telegraph and Telephone 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. """ Defines data types and models required specifically for Ipv6 Flow Specification support. """ import logging from os_ken.lib.packet.bgp import FlowSpecIPv6NLRI from os_ken.lib.packet.bgp import RF_IPv6_FLOWSPEC from os_ken.services.protocols.bgp.info_base.base import Path from os_ken.services.protocols.bgp.info_base.base import Table from os_ken.services.protocols.bgp.info_base.base import Destination from os_ken.services.protocols.bgp.info_base.base import NonVrfPathProcessingMixin LOG = logging.getLogger('bgpspeaker.info_base.ipv6fs') class IPv6FlowSpecDest(Destination, NonVrfPathProcessingMixin): """IPv6 Flow Specification Destination Store Flow Specification Paths. """ ROUTE_FAMILY = RF_IPv6_FLOWSPEC def _best_path_lost(self): old_best_path = self._best_path NonVrfPathProcessingMixin._best_path_lost(self) self._core_service._signal_bus.best_path_changed(old_best_path, True) def _new_best_path(self, best_path): NonVrfPathProcessingMixin._new_best_path(self, best_path) self._core_service._signal_bus.best_path_changed(best_path, False) class IPv6FlowSpecTable(Table): """Global table to store IPv6 Flow Specification routing information. Uses `FlowSpecIpv6Dest` to store destination information for each known Flow Specification paths. """ ROUTE_FAMILY = RF_IPv6_FLOWSPEC VPN_DEST_CLASS = IPv6FlowSpecDest def __init__(self, core_service, signal_bus): super(IPv6FlowSpecTable, self).__init__(None, core_service, signal_bus) def _table_key(self, nlri): """Return a key that will uniquely identify this NLRI inside this table. """ return nlri.prefix def _create_dest(self, nlri): return self.VPN_DEST_CLASS(self, nlri) def __str__(self): return '%s(scope_id: %s, rf: %s)' % ( self.__class__.__name__, self.scope_id, self.route_family ) class IPv6FlowSpecPath(Path): """Represents a way of reaching an IPv6 Flow Specification destination.""" ROUTE_FAMILY = RF_IPv6_FLOWSPEC VRF_PATH_CLASS = None # defined in init - anti cyclic import hack NLRI_CLASS = FlowSpecIPv6NLRI def __init__(self, *args, **kwargs): # Set dummy IP address. kwargs['nexthop'] = '::' super(IPv6FlowSpecPath, self).__init__(*args, **kwargs) from os_ken.services.protocols.bgp.info_base.vrf6fs import ( Vrf6FlowSpecPath) self.VRF_PATH_CLASS = Vrf6FlowSpecPath # Because the IPv6 Flow Specification does not require nexthop, # initialize with None. self._nexthop = None ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/info_base/l2vpnfs.py0000664000175000017500000000434200000000000024602 0ustar00zuulzuul00000000000000# Copyright (C) 2017 Nippon Telegraph and Telephone 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. """ Defines data types and models required specifically for L2VPN Flow Specification support. """ import logging from os_ken.lib.packet.bgp import FlowSpecL2VPNNLRI from os_ken.lib.packet.bgp import RF_L2VPN_FLOWSPEC from os_ken.services.protocols.bgp.info_base.vpn import VpnDest from os_ken.services.protocols.bgp.info_base.vpn import VpnPath from os_ken.services.protocols.bgp.info_base.vpn import VpnTable LOG = logging.getLogger('bgpspeaker.info_base.l2vpnfs') class L2VPNFlowSpecDest(VpnDest): """L2VPN Flow Specification Destination Store Flow Specification Paths. """ ROUTE_FAMILY = RF_L2VPN_FLOWSPEC class L2VPNFlowSpecTable(VpnTable): """Global table to store L2VPN Flow Specification routing information. Uses `L2VPNFlowSpecDest` to store destination information for each known Flow Specification paths. """ ROUTE_FAMILY = RF_L2VPN_FLOWSPEC VPN_DEST_CLASS = L2VPNFlowSpecDest class L2VPNFlowSpecPath(VpnPath): """Represents a way of reaching an L2VPN Flow Specification destination.""" ROUTE_FAMILY = RF_L2VPN_FLOWSPEC VRF_PATH_CLASS = None # defined in init - anti cyclic import hack NLRI_CLASS = FlowSpecL2VPNNLRI def __init__(self, *args, **kwargs): # Set dummy IP address. kwargs['nexthop'] = '0.0.0.0' super(L2VPNFlowSpecPath, self).__init__(*args, **kwargs) from os_ken.services.protocols.bgp.info_base.vrfl2vpnfs import ( L2vpnFlowSpecPath) self.VRF_PATH_CLASS = L2vpnFlowSpecPath # Because the L2VPN Flow Specification does not require nexthop, # initialize with None. self._nexthop = None ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/info_base/rtc.py0000664000175000017500000000466200000000000024005 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone 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. """ Defines data types and models required specifically for RTC support. """ import logging from os_ken.lib.packet.bgp import RF_RTC_UC from os_ken.services.protocols.bgp.info_base.base import Destination from os_ken.services.protocols.bgp.info_base.base import NonVrfPathProcessingMixin from os_ken.services.protocols.bgp.info_base.base import Path from os_ken.services.protocols.bgp.info_base.base import Table LOG = logging.getLogger('bgpspeaker.info_base.rtc') class RtcTable(Table): """Global table to store RT membership information. Uses `RtDest` to store destination information for each known RT NLRI path. """ ROUTE_FAMILY = RF_RTC_UC def __init__(self, core_service, signal_bus): Table.__init__(self, None, core_service, signal_bus) def _table_key(self, rtc_nlri): """Return a key that will uniquely identify this RT NLRI inside this table. """ return str(rtc_nlri.origin_as) + ':' + rtc_nlri.route_target def _create_dest(self, nlri): return RtcDest(self, nlri) def __str__(self): return 'RtcTable(scope_id: %s, rf: %s)' % (self.scope_id, self.route_family) class RtcDest(Destination, NonVrfPathProcessingMixin): ROUTE_FAMILY = RF_RTC_UC def _new_best_path(self, new_best_path): NonVrfPathProcessingMixin._new_best_path(self, new_best_path) def _best_path_lost(self): NonVrfPathProcessingMixin._best_path_lost(self) class RtcPath(Path): ROUTE_FAMILY = RF_RTC_UC def __init__(self, source, nlri, src_ver_num, pattrs=None, nexthop='0.0.0.0', is_withdraw=False, med_set_by_target_neighbor=False): Path.__init__(self, source, nlri, src_ver_num, pattrs, nexthop, is_withdraw, med_set_by_target_neighbor) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/info_base/vpn.py0000664000175000017500000000772400000000000024022 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone 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. """ Defines base data types and models required specifically for VPN support. """ import abc import logging from os_ken.lib.packet.bgp import RF_L2_EVPN from os_ken.services.protocols.bgp.info_base.base import Destination from os_ken.services.protocols.bgp.info_base.base import NonVrfPathProcessingMixin from os_ken.services.protocols.bgp.info_base.base import Path from os_ken.services.protocols.bgp.info_base.base import Table LOG = logging.getLogger('bgpspeaker.info_base.vpn') class VpnTable(Table): """Global table to store VPNv4 routing information. Uses `VpnvXDest` to store destination information for each known vpnvX paths. """ ROUTE_FAMILY = None VPN_DEST_CLASS = None def __init__(self, core_service, signal_bus): super(VpnTable, self).__init__(None, core_service, signal_bus) def _table_key(self, vpn_nlri): """Return a key that will uniquely identify this vpnvX NLRI inside this table. """ return vpn_nlri.route_dist + ':' + vpn_nlri.prefix def _create_dest(self, nlri): return self.VPN_DEST_CLASS(self, nlri) def __str__(self): return '%s(scope_id: %s, rf: %s)' % ( self.__class__.__name__, self.scope_id, self.route_family ) class VpnPath(Path, metaclass=abc.ABCMeta): ROUTE_FAMILY = None VRF_PATH_CLASS = None NLRI_CLASS = None def clone_to_vrf(self, is_withdraw=False): if self.ROUTE_FAMILY == RF_L2_EVPN: # Because NLRI class is the same if the route family is EVPN, # we re-use the NLRI instance. vrf_nlri = self._nlri else: # self.ROUTE_FAMILY in [RF_IPv4_VPN, RF_IPv46_VPN] vrf_nlri = self.NLRI_CLASS(self._nlri.prefix) pathattrs = None if not is_withdraw: pathattrs = self.pathattr_map vrf_path = self.VRF_PATH_CLASS( puid=self.VRF_PATH_CLASS.create_puid( self._nlri.route_dist, self._nlri.prefix), source=self.source, nlri=vrf_nlri, src_ver_num=self.source_version_num, pattrs=pathattrs, nexthop=self.nexthop, is_withdraw=is_withdraw, label_list=self._nlri.label_list) return vrf_path class VpnDest(Destination, NonVrfPathProcessingMixin, metaclass=abc.ABCMeta): """Base class for VPN destinations.""" def _best_path_lost(self): old_best_path = self._best_path NonVrfPathProcessingMixin._best_path_lost(self) self._core_service._signal_bus.best_path_changed(old_best_path, True) # Best-path might have been imported into VRF tables, we have to # withdraw from them, if the source is a peer. if old_best_path: withdraw_clone = old_best_path.clone(for_withdrawal=True) tm = self._core_service.table_manager tm.import_single_vpn_path_to_all_vrfs( withdraw_clone, path_rts=old_best_path.get_rts() ) def _new_best_path(self, best_path): NonVrfPathProcessingMixin._new_best_path(self, best_path) self._core_service._signal_bus.best_path_changed(best_path, False) # Extranet feature requires that we import new best path into VRFs. tm = self._core_service.table_manager tm.import_single_vpn_path_to_all_vrfs( self._best_path, self._best_path.get_rts()) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/info_base/vpnv4.py0000664000175000017500000000346300000000000024270 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone 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. """ Defines data types and models required specifically for VPNv4 support. """ import logging from os_ken.lib.packet.bgp import IPAddrPrefix from os_ken.lib.packet.bgp import RF_IPv4_VPN from os_ken.services.protocols.bgp.info_base.vpn import VpnDest from os_ken.services.protocols.bgp.info_base.vpn import VpnPath from os_ken.services.protocols.bgp.info_base.vpn import VpnTable LOG = logging.getLogger('bgpspeaker.info_base.vpnv4') class Vpnv4Dest(VpnDest): """VPNv4 Destination Store IPv4 Paths. """ ROUTE_FAMILY = RF_IPv4_VPN class Vpnv4Table(VpnTable): """Global table to store VPNv4 routing information. Uses `Vpnv4Dest` to store destination information for each known vpnv4 paths. """ ROUTE_FAMILY = RF_IPv4_VPN VPN_DEST_CLASS = Vpnv4Dest class Vpnv4Path(VpnPath): """Represents a way of reaching an VPNv4 destination.""" ROUTE_FAMILY = RF_IPv4_VPN VRF_PATH_CLASS = None # defined in init - anti cyclic import hack NLRI_CLASS = IPAddrPrefix def __init__(self, *args, **kwargs): super(Vpnv4Path, self).__init__(*args, **kwargs) from os_ken.services.protocols.bgp.info_base.vrf4 import Vrf4Path self.VRF_PATH_CLASS = Vrf4Path ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/info_base/vpnv4fs.py0000664000175000017500000000433300000000000024616 0ustar00zuulzuul00000000000000# Copyright (C) 2017 Nippon Telegraph and Telephone 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. """ Defines data types and models required specifically for VPNv4 Flow Specification support. """ import logging from os_ken.lib.packet.bgp import FlowSpecVPNv4NLRI from os_ken.lib.packet.bgp import RF_VPNv4_FLOWSPEC from os_ken.services.protocols.bgp.info_base.vpn import VpnDest from os_ken.services.protocols.bgp.info_base.vpn import VpnPath from os_ken.services.protocols.bgp.info_base.vpn import VpnTable LOG = logging.getLogger('bgpspeaker.info_base.vpnv4fs') class VPNv4FlowSpecDest(VpnDest): """VPNv4 Flow Specification Destination Store Flow Specification Paths. """ ROUTE_FAMILY = RF_VPNv4_FLOWSPEC class VPNv4FlowSpecTable(VpnTable): """Global table to store VPNv4 Flow Specification routing information. Uses `VPNv4FlowSpecDest` to store destination information for each known Flow Specification paths. """ ROUTE_FAMILY = RF_VPNv4_FLOWSPEC VPN_DEST_CLASS = VPNv4FlowSpecDest class VPNv4FlowSpecPath(VpnPath): """Represents a way of reaching an VPNv4 Flow Specification destination.""" ROUTE_FAMILY = RF_VPNv4_FLOWSPEC VRF_PATH_CLASS = None # defined in init - anti cyclic import hack NLRI_CLASS = FlowSpecVPNv4NLRI def __init__(self, *args, **kwargs): # Set dummy IP address. kwargs['nexthop'] = '0.0.0.0' super(VPNv4FlowSpecPath, self).__init__(*args, **kwargs) from os_ken.services.protocols.bgp.info_base.vrf4fs import ( Vrf4FlowSpecPath) self.VRF_PATH_CLASS = Vrf4FlowSpecPath # Because the IPv4 Flow Specification does not require nexthop, # initialize with None. self._nexthop = None ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/info_base/vpnv6.py0000664000175000017500000000346500000000000024274 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone 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. """ Defines data types and models required specifically for VPNv6 support. """ import logging from os_ken.lib.packet.bgp import IP6AddrPrefix from os_ken.lib.packet.bgp import RF_IPv6_VPN from os_ken.services.protocols.bgp.info_base.vpn import VpnDest from os_ken.services.protocols.bgp.info_base.vpn import VpnPath from os_ken.services.protocols.bgp.info_base.vpn import VpnTable LOG = logging.getLogger('bgpspeaker.info_base.vpnv6') class Vpnv6Dest(VpnDest): """VPNv6 destination Stores IPv6 paths. """ ROUTE_FAMILY = RF_IPv6_VPN class Vpnv6Table(VpnTable): """Global table to store VPNv6 routing information Uses `Vpnv6Dest` to store destination information for each known vpnv6 paths. """ ROUTE_FAMILY = RF_IPv6_VPN VPN_DEST_CLASS = Vpnv6Dest class Vpnv6Path(VpnPath): """Represents a way of reaching an VPNv4 destination.""" ROUTE_FAMILY = RF_IPv6_VPN VRF_PATH_CLASS = None # defined in init - anti cyclic import hack NLRI_CLASS = IP6AddrPrefix def __init__(self, *args, **kwargs): super(Vpnv6Path, self).__init__(*args, **kwargs) from os_ken.services.protocols.bgp.info_base.vrf6 import Vrf6Path self.VRF_PATH_CLASS = Vrf6Path ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/info_base/vpnv6fs.py0000664000175000017500000000432600000000000024622 0ustar00zuulzuul00000000000000# Copyright (C) 2017 Nippon Telegraph and Telephone 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. """ Defines data types and models required specifically for VPNv6 Flow Specification support. """ import logging from os_ken.lib.packet.bgp import FlowSpecVPNv6NLRI from os_ken.lib.packet.bgp import RF_VPNv6_FLOWSPEC from os_ken.services.protocols.bgp.info_base.vpn import VpnDest from os_ken.services.protocols.bgp.info_base.vpn import VpnPath from os_ken.services.protocols.bgp.info_base.vpn import VpnTable LOG = logging.getLogger('bgpspeaker.info_base.vpnv6fs') class VPNv6FlowSpecDest(VpnDest): """VPNv6 Flow Specification Destination Store Flow Specification Paths. """ ROUTE_FAMILY = RF_VPNv6_FLOWSPEC class VPNv6FlowSpecTable(VpnTable): """Global table to store VPNv6 Flow Specification routing information. Uses `VPNv6FlowSpecDest` to store destination information for each known Flow Specification paths. """ ROUTE_FAMILY = RF_VPNv6_FLOWSPEC VPN_DEST_CLASS = VPNv6FlowSpecDest class VPNv6FlowSpecPath(VpnPath): """Represents a way of reaching an VPNv6 Flow Specification destination.""" ROUTE_FAMILY = RF_VPNv6_FLOWSPEC VRF_PATH_CLASS = None # defined in init - anti cyclic import hack NLRI_CLASS = FlowSpecVPNv6NLRI def __init__(self, *args, **kwargs): # Set dummy IP address. kwargs['nexthop'] = '::' super(VPNv6FlowSpecPath, self).__init__(*args, **kwargs) from os_ken.services.protocols.bgp.info_base.vrf6fs import ( Vrf6FlowSpecPath) self.VRF_PATH_CLASS = Vrf6FlowSpecPath # Because the IPv6 Flow Specification does not require nexthop, # initialize with None. self._nexthop = None ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/info_base/vrf.py0000664000175000017500000006367500000000000024023 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone 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. """ Defines base data types and models required specifically for VRF support. """ import abc import logging from os_ken.lib.packet.bgp import BGP_ATTR_TYPE_ORIGIN from os_ken.lib.packet.bgp import BGP_ATTR_TYPE_AS_PATH from os_ken.lib.packet.bgp import BGP_ATTR_TYPE_EXTENDED_COMMUNITIES from os_ken.lib.packet.bgp import BGP_ATTR_TYEP_PMSI_TUNNEL_ATTRIBUTE from os_ken.lib.packet.bgp import BGP_ATTR_TYPE_MULTI_EXIT_DISC from os_ken.lib.packet.bgp import BGPPathAttributeOrigin from os_ken.lib.packet.bgp import BGPPathAttributeAsPath from os_ken.lib.packet.bgp import EvpnEthernetSegmentNLRI from os_ken.lib.packet.bgp import BGPPathAttributeExtendedCommunities from os_ken.lib.packet.bgp import BGPPathAttributeMultiExitDisc from os_ken.lib.packet.bgp import BGPEncapsulationExtendedCommunity from os_ken.lib.packet.bgp import BGPEvpnEsiLabelExtendedCommunity from os_ken.lib.packet.bgp import BGPEvpnEsImportRTExtendedCommunity from os_ken.lib.packet.bgp import BGPPathAttributePmsiTunnel from os_ken.lib.packet.bgp import PmsiTunnelIdIngressReplication from os_ken.lib.packet.bgp import RF_L2_EVPN from os_ken.lib.packet.bgp import EvpnMacIPAdvertisementNLRI from os_ken.lib.packet.bgp import EvpnIpPrefixNLRI from os_ken.lib.packet.safi import ( IP_FLOWSPEC, VPN_FLOWSPEC, ) from os_ken.services.protocols.bgp.base import OrderedDict from os_ken.services.protocols.bgp.constants import VPN_TABLE from os_ken.services.protocols.bgp.constants import VRF_TABLE from os_ken.services.protocols.bgp.info_base.base import Destination from os_ken.services.protocols.bgp.info_base.base import Path from os_ken.services.protocols.bgp.info_base.base import Table from os_ken.services.protocols.bgp.utils.bgp import create_rt_extended_community from os_ken.services.protocols.bgp.utils.stats import LOCAL_ROUTES from os_ken.services.protocols.bgp.utils.stats import REMOTE_ROUTES from os_ken.services.protocols.bgp.utils.stats import RESOURCE_ID from os_ken.services.protocols.bgp.utils.stats import RESOURCE_NAME LOG = logging.getLogger('bgpspeaker.info_base.vrf') class VrfTable(Table, metaclass=abc.ABCMeta): """Virtual Routing and Forwarding information base. Keeps destination imported to given vrf in represents. """ ROUTE_FAMILY = None VPN_ROUTE_FAMILY = None NLRI_CLASS = None VRF_PATH_CLASS = None VRF_DEST_CLASS = None def __init__(self, vrf_conf, core_service, signal_bus): Table.__init__(self, vrf_conf.route_dist, core_service, signal_bus) self._vrf_conf = vrf_conf self._import_maps = [] self.init_import_maps(vrf_conf.import_maps) def init_import_maps(self, import_maps): LOG.debug( "Initializing import maps (%s) for %r", import_maps, self ) del self._import_maps[:] importmap_manager = self._core_service.importmap_manager for name in import_maps: import_map = importmap_manager.get_import_map_by_name(name) if import_map is None: raise KeyError('No import map with name %s' % name) self._import_maps.append(import_map) @property def import_rts(self): return self._vrf_conf.import_rts @property def vrf_conf(self): return self._vrf_conf def _table_key(self, nlri): """Return a key that will uniquely identify this NLRI inside this table. """ # Note: We use `prefix` representation of the NLRI, because # BGP route can be identified without the route distinguisher # value in the VRF space. return nlri.prefix def _create_dest(self, nlri): return self.VRF_DEST_CLASS(self, nlri) def append_import_map(self, import_map): self._import_maps.append(import_map) def remove_import_map(self, import_map): self._import_maps.remove(import_map) def get_stats_summary_dict(self): """Returns count of local and remote paths.""" remote_route_count = 0 local_route_count = 0 for dest in self.values(): for path in dest.known_path_list: if (hasattr(path.source, 'version_num') or path.source == VPN_TABLE): remote_route_count += 1 else: local_route_count += 1 return {RESOURCE_ID: self._vrf_conf.id, RESOURCE_NAME: self._vrf_conf.name, REMOTE_ROUTES: remote_route_count, LOCAL_ROUTES: local_route_count} def import_vpn_paths_from_table(self, vpn_table, import_rts=None): for vpn_dest in vpn_table.values(): vpn_path = vpn_dest.best_path if not vpn_path: continue if import_rts is None: import_rts = set(self.import_rts) else: import_rts = set(import_rts) path_rts = vpn_path.get_rts() if import_rts.intersection(path_rts): # TODO(PH): When (re-)implementing extranet, check what should # be the label reported back to NC for local paths coming from # other VRFs. self.import_vpn_path(vpn_path) def import_vpn_path(self, vpn_path): """Imports `vpnv(4|6)_path` into `vrf(4|6)_table` or `evpn_path` into vrfevpn_table`. :Parameters: - `vpn_path`: (Path) VPN path that will be cloned and imported into VRF. Note: Does not do any checking if this import is valid. """ assert vpn_path.route_family == self.VPN_ROUTE_FAMILY # If source of given vpnv4 path is NC we import it to given VRF # table because of extranet setting. Hence we identify source of # EXTRANET prefixes as VRF_TABLE, else VPN_TABLE. source = vpn_path.source if not source: source = VRF_TABLE if self.VPN_ROUTE_FAMILY == RF_L2_EVPN: # Because NLRI class is the same if the route family is EVPN, # we re-use the NLRI instance. vrf_nlri = vpn_path.nlri elif self.ROUTE_FAMILY.safi in [IP_FLOWSPEC, VPN_FLOWSPEC]: vrf_nlri = self.NLRI_CLASS(rules=vpn_path.nlri.rules) else: # self.VPN_ROUTE_FAMILY in [RF_IPv4_VPN, RF_IPv6_VPN] # Copy NLRI instance ip, masklen = vpn_path.nlri.prefix.split('/') vrf_nlri = self.NLRI_CLASS(length=int(masklen), addr=ip) vrf_path = self.VRF_PATH_CLASS( puid=self.VRF_PATH_CLASS.create_puid( vpn_path.nlri.route_dist, vpn_path.nlri.prefix), source=source, nlri=vrf_nlri, src_ver_num=vpn_path.source_version_num, pattrs=vpn_path.pathattr_map, nexthop=vpn_path.nexthop, is_withdraw=vpn_path.is_withdraw, label_list=getattr(vpn_path.nlri, 'label_list', None), ) if self._is_vrf_path_already_in_table(vrf_path): return None if self._is_vrf_path_filtered_out_by_import_maps(vrf_path): return None else: vrf_dest = self.insert(vrf_path) self._signal_bus.dest_changed(vrf_dest) def _is_vrf_path_filtered_out_by_import_maps(self, vrf_path): for import_map in self._import_maps: if import_map.match(vrf_path): return True return False def _is_vrf_path_already_in_table(self, vrf_path): dest = self._get_dest(vrf_path.nlri) if dest is None: return False return vrf_path in dest.known_path_list def apply_import_maps(self): changed_dests = [] for dest in self.values(): assert isinstance(dest, VrfDest) for import_map in self._import_maps: for path in dest.known_path_list: if import_map.match(path): dest.withdraw_path(path) changed_dests.append(dest) return changed_dests def insert_vrf_path(self, nlri, next_hop=None, gen_lbl=False, is_withdraw=False, **kwargs): assert nlri pattrs = None label_list = [] vrf_conf = self.vrf_conf if not is_withdraw: table_manager = self._core_service.table_manager if gen_lbl and next_hop: # Label per next_hop demands we use a different label # per next_hop. Here connected interfaces are advertised per # VRF. label_key = (vrf_conf.route_dist, next_hop) nh_label = table_manager.get_nexthop_label(label_key) if not nh_label: nh_label = table_manager.get_next_vpnv4_label() table_manager.set_nexthop_label(label_key, nh_label) label_list.append(nh_label) elif gen_lbl: # If we do not have next_hop, get a new label. label_list.append(table_manager.get_next_vpnv4_label()) # Set MPLS labels with the generated labels if gen_lbl and isinstance(nlri, EvpnMacIPAdvertisementNLRI): nlri.mpls_labels = label_list[:2] elif gen_lbl and isinstance(nlri, EvpnIpPrefixNLRI): nlri.mpls_label = label_list[0] # Create a dictionary for path-attrs. pattrs = OrderedDict() # MpReachNlri and/or MpUnReachNlri attribute info. is contained # in the path. Hence we do not add these attributes here. from os_ken.services.protocols.bgp.core import EXPECTED_ORIGIN pattrs[BGP_ATTR_TYPE_ORIGIN] = BGPPathAttributeOrigin( EXPECTED_ORIGIN) pattrs[BGP_ATTR_TYPE_AS_PATH] = BGPPathAttributeAsPath([]) communities = [] # Set ES-Import Route Target if isinstance(nlri, EvpnEthernetSegmentNLRI): subtype = 2 es_import = nlri.esi.mac_addr communities.append(BGPEvpnEsImportRTExtendedCommunity( subtype=subtype, es_import=es_import)) for rt in vrf_conf.export_rts: communities.append(create_rt_extended_community(rt, 2)) for soo in vrf_conf.soo_list: communities.append(create_rt_extended_community(soo, 3)) # Set Tunnel Encapsulation Attribute tunnel_type = kwargs.get('tunnel_type', None) if tunnel_type: communities.append( BGPEncapsulationExtendedCommunity.from_str(tunnel_type)) # Set ESI Label Extended Community redundancy_mode = kwargs.get('redundancy_mode', None) if redundancy_mode is not None: subtype = 1 flags = 0 from os_ken.services.protocols.bgp.api.prefix import ( REDUNDANCY_MODE_SINGLE_ACTIVE) if redundancy_mode == REDUNDANCY_MODE_SINGLE_ACTIVE: flags |= BGPEvpnEsiLabelExtendedCommunity.SINGLE_ACTIVE_BIT vni = kwargs.get('vni', None) if vni is not None: communities.append(BGPEvpnEsiLabelExtendedCommunity( subtype=subtype, flags=flags, vni=vni)) else: communities.append(BGPEvpnEsiLabelExtendedCommunity( subtype=subtype, flags=flags, mpls_label=label_list[0])) # Add MAC Move functionality # see https://datatracker.ietf.org/doc/html/rfc7432#section-7.7 mac_mobility_seq = kwargs.get('mac_mobility', None) if mac_mobility_seq is not None: from os_ken.lib.packet.bgp import BGPEvpnMacMobilityExtendedCommunity is_static = (mac_mobility_seq == -1) # Magic value for static MACs communities.append(BGPEvpnMacMobilityExtendedCommunity( subtype=0, flags=1 if is_static else 0, # 0x1 = sticky (static) MAC sequence_number=mac_mobility_seq if not is_static else 0)) pattrs[BGP_ATTR_TYPE_EXTENDED_COMMUNITIES] = \ BGPPathAttributeExtendedCommunities(communities=communities) if vrf_conf.multi_exit_disc: pattrs[BGP_ATTR_TYPE_MULTI_EXIT_DISC] = \ BGPPathAttributeMultiExitDisc(vrf_conf.multi_exit_disc) # Set PMSI Tunnel Attribute pmsi_tunnel_type = kwargs.get('pmsi_tunnel_type', None) if pmsi_tunnel_type is not None: from os_ken.services.protocols.bgp.api.prefix import ( PMSI_TYPE_INGRESS_REP) if pmsi_tunnel_type == PMSI_TYPE_INGRESS_REP: # Support other VTEP IP than local router_id vtep = kwargs.get('tunnel_endpoint_ip', self._core_service.router_id) tunnel_id = PmsiTunnelIdIngressReplication(tunnel_endpoint_ip=vtep) else: # pmsi_tunnel_type == PMSI_TYPE_NO_TUNNEL_INFO tunnel_id = None pattrs[BGP_ATTR_TYEP_PMSI_TUNNEL_ATTRIBUTE] = \ BGPPathAttributePmsiTunnel(pmsi_flags=0, tunnel_type=pmsi_tunnel_type, tunnel_id=tunnel_id, vni=kwargs.get('vni', None)) puid = self.VRF_PATH_CLASS.create_puid( vrf_conf.route_dist, nlri.prefix) path = self.VRF_PATH_CLASS( puid, None, nlri, 0, pattrs=pattrs, nexthop=next_hop, label_list=label_list, is_withdraw=is_withdraw ) # Insert the path into VRF table, get affected destination so that we # can process it further. eff_dest = self.insert(path) # Enqueue the eff_dest for further processing. self._signal_bus.dest_changed(eff_dest) return label_list def clean_uninteresting_paths(self, interested_rts=None): if interested_rts is None: interested_rts = set(self.vrf_conf.import_rts) return super(VrfTable, self).clean_uninteresting_paths(interested_rts) class VrfDest(Destination, metaclass=abc.ABCMeta): """Base class for VRF destination.""" def __init__(self, table, nlri): super(VrfDest, self).__init__(table, nlri) self._route_dist = self._table.vrf_conf.route_dist @property def nlri_str(self): # Returns `prefix` without the route distinguisher value, because # a destination in VRF space can be identified without the route # distinguisher. return self._nlri.prefix def _best_path_lost(self): # Have to send update messages for withdraw of best-path to Network # controller or Global table. old_best_path = self._best_path self._best_path = None if old_best_path is None: return if old_best_path.source is not None: # Send update-withdraw msg. to Sink. Create withdraw path # out of old best path and queue it into flexinet sinks. old_best_path = old_best_path.clone(for_withdrawal=True) self._core_service.update_flexinet_peers(old_best_path, self._route_dist) else: # Create withdraw-path out of old best path. gpath = old_best_path.clone_to_vpn(self._route_dist, for_withdrawal=True) # Insert withdraw into global table and enqueue the destination # for further processing. tm = self._core_service.table_manager tm.learn_path(gpath) def _new_best_path(self, best_path): LOG.debug('New best path selected for destination %s', self) old_best_path = self._best_path assert (best_path != old_best_path) self._best_path = best_path # Distribute new best-path to flexinet-peers. if best_path.source is not None: # Since route-refresh just causes the version number to # go up and this changes best-path, we check if new- # best-path is really different than old-best-path that # warrants sending update to flexinet peers. def really_diff(): old_labels = old_best_path.label_list new_labels = best_path.label_list return old_best_path.nexthop != best_path.nexthop \ or set(old_labels) != set(new_labels) if not old_best_path or (old_best_path and really_diff()): # Create OutgoingRoute and queue it into NC sink. self._core_service.update_flexinet_peers( best_path, self._route_dist ) else: # If NC is source, we create new path and insert into global # table. gpath = best_path.clone_to_vpn(self._route_dist) tm = self._core_service.table_manager tm.learn_path(gpath) LOG.debug('VRF table %s has new best path: %s', self._route_dist, self.best_path) def _remove_withdrawals(self): """Removes withdrawn paths. Note: We may have disproportionate number of withdraws compared to know paths since not all paths get installed into the table due to bgp policy and we can receive withdraws for such paths and withdrawals may not be stopped by the same policies. """ LOG.debug('Removing %s withdrawals', len(self._withdraw_list)) # If we have not withdrawals, we have nothing to do. if not self._withdraw_list: return # If we have some withdrawals and no know-paths, it means it is safe to # delete these withdraws. if not self._known_path_list: LOG.debug('Found %s withdrawals for path(s) that did not get' ' installed.', len(self._withdraw_list)) del (self._withdraw_list[:]) return # If we have some known paths and some withdrawals, we find matches and # delete them first. matches = [] w_matches = [] # Match all withdrawals from destination paths. for withdraw in self._withdraw_list: match = None for path in self._known_path_list: # We have a match if the source are same. if path.puid == withdraw.puid: match = path matches.append(path) w_matches.append(withdraw) # One withdraw can remove only one path. break # We do no have any match for this withdraw. if not match: LOG.debug('No matching path for withdraw found, may be path ' 'was not installed into table: %s', withdraw) # If we have partial match. if len(matches) != len(self._withdraw_list): LOG.debug('Did not find match for some withdrawals. Number of ' 'matches(%s), number of withdrawals (%s)', len(matches), len(self._withdraw_list)) # Clear matching paths and withdrawals. for match in matches: self._known_path_list.remove(match) for w_match in w_matches: self._withdraw_list.remove(w_match) def _remove_old_paths(self): """Identifies which of known paths are old and removes them. Known paths will no longer have paths whose new version is present in new paths. """ new_paths = self._new_path_list known_paths = self._known_path_list for new_path in new_paths: old_paths = [] for path in known_paths: # Here we just check if source is same and not check if path # version num. as new_paths are implicit withdrawal of old # paths and when doing RouteRefresh (not EnhancedRouteRefresh) # we get same paths again. if new_path.puid == path.puid: old_paths.append(path) break for old_path in old_paths: known_paths.remove(old_path) LOG.debug('Implicit withdrawal of old path, since we have' ' learned new path from same source: %s', old_path) def _validate_path(self, path): if not path or not hasattr(path, 'label_list'): raise ValueError('Invalid value of path. Expected type ' 'with attribute label_list got %s' % path) class VrfPath(Path, metaclass=abc.ABCMeta): """Represents a way of reaching an IP destination with a VPN. """ __slots__ = ('_label_list', '_puid') ROUTE_FAMILY = None VPN_PATH_CLASS = None VPN_NLRI_CLASS = None def __init__(self, puid, source, nlri, src_ver_num, pattrs=None, nexthop=None, is_withdraw=False, label_list=None): """Initializes a Vrf path. Parameters: - `puid`: (str) path ID, identifies VPN path from which this VRF path was imported. - `label_list`: (list) List of labels for this path. Note: other parameters are as documented in super class. """ if self.ROUTE_FAMILY.safi in [IP_FLOWSPEC, VPN_FLOWSPEC]: nexthop = '0.0.0.0' Path.__init__(self, source, nlri, src_ver_num, pattrs, nexthop, is_withdraw) if label_list is None: label_list = [] self._label_list = label_list self._puid = puid @property def puid(self): return self._puid @property def origin_rd(self): tokens = self.puid.split(':') return tokens[0] + ':' + tokens[1] @property def label_list(self): return self._label_list[:] @property def nlri_str(self): # Returns `prefix` without the route distinguisher value, because # a destination in VRF space can be identified without the route # distinguisher. return self._nlri.prefix @staticmethod def create_puid(route_dist, ip_prefix): assert route_dist and ip_prefix return str(route_dist) + ':' + ip_prefix def clone(self, for_withdrawal=False): pathattrs = None if not for_withdrawal: pathattrs = self.pathattr_map clone = self.__class__( self.puid, self._source, self.nlri, self.source_version_num, pattrs=pathattrs, nexthop=self.nexthop, is_withdraw=for_withdrawal, label_list=self.label_list ) return clone def clone_to_vpn(self, route_dist, for_withdrawal=False): if self.ROUTE_FAMILY == RF_L2_EVPN: # Because NLRI class is the same if the route family is EVPN, # we re-use the NLRI instance. vpn_nlri = self._nlri elif self.ROUTE_FAMILY.safi in [IP_FLOWSPEC, VPN_FLOWSPEC]: vpn_nlri = self.VPN_NLRI_CLASS(route_dist=route_dist, rules=self.nlri.rules) else: # self.ROUTE_FAMILY in [RF_IPv4_UC, RF_IPv6_UC] ip, masklen = self._nlri.prefix.split('/') vpn_nlri = self.VPN_NLRI_CLASS(length=int(masklen), addr=ip, labels=self.label_list, route_dist=route_dist) pathattrs = None if not for_withdrawal: pathattrs = self.pathattr_map vpnv_path = self.VPN_PATH_CLASS( source=self.source, nlri=vpn_nlri, src_ver_num=self.source_version_num, pattrs=pathattrs, nexthop=self.nexthop, is_withdraw=for_withdrawal) return vpnv_path def __eq__(self, b_path): if not isinstance(b_path, self.__class__): return False if not self.route_family == b_path.route_family: return False if not self.puid == b_path.puid: return False if not self.label_list == b_path.label_list: return False if not self.nexthop == b_path.nexthop: return False if not self.pathattr_map == b_path.pathattr_map: return False return True class ImportMap(object): def match(self, vrf_path): raise NotImplementedError() class VrfNlriImportMap(ImportMap): VRF_PATH_CLASS = None NLRI_CLASS = None def __init__(self, prefix): assert self.VRF_PATH_CLASS is not None assert self.NLRI_CLASS is not None self._nlri = self.NLRI_CLASS(prefix) def match(self, vrf_path): if vrf_path.route_family != self.VRF_PATH_CLASS.ROUTE_FAMILY: LOG.error( "vrf_paths route_family does not match importmaps" "route_family. Applied to wrong table?") return False return vrf_path.nlri == self._nlri class VrfRtImportMap(ImportMap): def __init__(self, rt): self._rt = rt def match(self, vrf_path): extcomm = vrf_path.pathattr_map.get(BGP_ATTR_TYPE_EXTENDED_COMMUNITIES) return extcomm is not None and self._rt in extcomm.rt_list ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/info_base/vrf4.py0000664000175000017500000000400000000000000024060 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone 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. """ Defines data types and models required specifically for VRF (for IPv4) support. Represents data structures for VRF not VPN/global. (Inside VRF you have IPv4 prefixes and inside VPN you have VPNv4 prefixes) """ import logging from os_ken.lib.packet.bgp import RF_IPv4_UC from os_ken.lib.packet.bgp import RF_IPv4_VPN from os_ken.lib.packet.bgp import IPAddrPrefix from os_ken.lib.packet.bgp import LabelledVPNIPAddrPrefix from os_ken.services.protocols.bgp.info_base.vpnv4 import Vpnv4Path from os_ken.services.protocols.bgp.info_base.vrf import VrfDest from os_ken.services.protocols.bgp.info_base.vrf import VrfNlriImportMap from os_ken.services.protocols.bgp.info_base.vrf import VrfPath from os_ken.services.protocols.bgp.info_base.vrf import VrfTable LOG = logging.getLogger('bgpspeaker.info_base.vrf4') class Vrf4Path(VrfPath): """Represents a way of reaching an IP destination with a VPN.""" ROUTE_FAMILY = RF_IPv4_UC VPN_PATH_CLASS = Vpnv4Path VPN_NLRI_CLASS = LabelledVPNIPAddrPrefix class Vrf4Dest(VrfDest): ROUTE_FAMILY = RF_IPv4_UC class Vrf4Table(VrfTable): """Virtual Routing and Forwarding information base for IPv4.""" ROUTE_FAMILY = RF_IPv4_UC VPN_ROUTE_FAMILY = RF_IPv4_VPN NLRI_CLASS = IPAddrPrefix VRF_PATH_CLASS = Vrf4Path VRF_DEST_CLASS = Vrf4Dest class Vrf4NlriImportMap(VrfNlriImportMap): VRF_PATH_CLASS = Vrf4Path NLRI_CLASS = IPAddrPrefix ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/info_base/vrf4fs.py0000664000175000017500000000412300000000000024417 0ustar00zuulzuul00000000000000# Copyright (C) 2017 Nippon Telegraph and Telephone 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. """ Defines data types and models required specifically for VRF (for IPv4 Flow Specification) support. Represents data structures for VRF not VPN/global. (Inside VRF you have IPv4 Flow Specification prefixes and inside VPN you have VPNv4 Flow Specification prefixes) """ import logging from os_ken.lib.packet.bgp import RF_IPv4_FLOWSPEC from os_ken.lib.packet.bgp import RF_VPNv4_FLOWSPEC from os_ken.lib.packet.bgp import FlowSpecIPv4NLRI from os_ken.lib.packet.bgp import FlowSpecVPNv4NLRI from os_ken.services.protocols.bgp.info_base.vpnv4fs import VPNv4FlowSpecPath from os_ken.services.protocols.bgp.info_base.vrffs import VRFFlowSpecDest from os_ken.services.protocols.bgp.info_base.vrffs import VRFFlowSpecPath from os_ken.services.protocols.bgp.info_base.vrffs import VRFFlowSpecTable LOG = logging.getLogger('bgpspeaker.info_base.vrf4fs') class Vrf4FlowSpecPath(VRFFlowSpecPath): """Represents a way of reaching an IP destination with a VPN Flow Specification. """ ROUTE_FAMILY = RF_IPv4_FLOWSPEC VPN_PATH_CLASS = VPNv4FlowSpecPath VPN_NLRI_CLASS = FlowSpecVPNv4NLRI class Vrf4FlowSpecDest(VRFFlowSpecDest): ROUTE_FAMILY = RF_IPv4_FLOWSPEC class Vrf4FlowSpecTable(VRFFlowSpecTable): """Virtual Routing and Forwarding information base for IPv4 Flow Specification. """ ROUTE_FAMILY = RF_IPv4_FLOWSPEC VPN_ROUTE_FAMILY = RF_VPNv4_FLOWSPEC NLRI_CLASS = FlowSpecIPv4NLRI VRF_PATH_CLASS = Vrf4FlowSpecPath VRF_DEST_CLASS = Vrf4FlowSpecDest ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/info_base/vrf6.py0000664000175000017500000000405200000000000024071 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone 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. """ Defines data types and models required specifically for VRF (for IPv6) support. Represents data structures for VRF not VPN/global. (Inside VRF you have IPv4 prefixes and inside VPN you have VPNv6 prefixes) """ import logging from os_ken.lib.packet.bgp import RF_IPv6_UC from os_ken.lib.packet.bgp import RF_IPv6_VPN from os_ken.lib.packet.bgp import IP6AddrPrefix from os_ken.lib.packet.bgp import LabelledVPNIP6AddrPrefix from os_ken.services.protocols.bgp.info_base.vpnv6 import Vpnv6Path from os_ken.services.protocols.bgp.info_base.vrf import VrfDest from os_ken.services.protocols.bgp.info_base.vrf import VrfNlriImportMap from os_ken.services.protocols.bgp.info_base.vrf import VrfPath from os_ken.services.protocols.bgp.info_base.vrf import VrfTable LOG = logging.getLogger('bgpspeaker.info_base.vrf6') class Vrf6Path(VrfPath): """Represents a way of reaching an IP destination with a VPN.""" ROUTE_FAMILY = RF_IPv6_UC VPN_PATH_CLASS = Vpnv6Path VPN_NLRI_CLASS = LabelledVPNIP6AddrPrefix class Vrf6Dest(VrfDest): """Destination for IPv6 VRFs.""" ROUTE_FAMILY = RF_IPv6_UC class Vrf6Table(VrfTable): """Virtual Routing and Forwarding information base for IPv6.""" ROUTE_FAMILY = RF_IPv6_UC VPN_ROUTE_FAMILY = RF_IPv6_VPN NLRI_CLASS = IP6AddrPrefix VRF_PATH_CLASS = Vrf6Path VRF_DEST_CLASS = Vrf6Dest class Vrf6NlriImportMap(VrfNlriImportMap): VRF_PATH_CLASS = Vrf6Path NLRI_CLASS = IP6AddrPrefix ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/info_base/vrf6fs.py0000664000175000017500000000412300000000000024421 0ustar00zuulzuul00000000000000# Copyright (C) 2017 Nippon Telegraph and Telephone 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. """ Defines data types and models required specifically for VRF (for IPv6 Flow Specification) support. Represents data structures for VRF not VPN/global. (Inside VRF you have IPv6 Flow Specification prefixes and inside VPN you have VPNV6 Flow Specification prefixes) """ import logging from os_ken.lib.packet.bgp import RF_IPv6_FLOWSPEC from os_ken.lib.packet.bgp import RF_VPNv6_FLOWSPEC from os_ken.lib.packet.bgp import FlowSpecIPv6NLRI from os_ken.lib.packet.bgp import FlowSpecVPNv6NLRI from os_ken.services.protocols.bgp.info_base.vpnv6fs import VPNv6FlowSpecPath from os_ken.services.protocols.bgp.info_base.vrffs import VRFFlowSpecDest from os_ken.services.protocols.bgp.info_base.vrffs import VRFFlowSpecPath from os_ken.services.protocols.bgp.info_base.vrffs import VRFFlowSpecTable LOG = logging.getLogger('bgpspeaker.info_base.vrf6fs') class Vrf6FlowSpecPath(VRFFlowSpecPath): """Represents a way of reaching an IP destination with a VPN Flow Specification. """ ROUTE_FAMILY = RF_IPv6_FLOWSPEC VPN_PATH_CLASS = VPNv6FlowSpecPath VPN_NLRI_CLASS = FlowSpecVPNv6NLRI class Vrf6FlowSpecDest(VRFFlowSpecDest): ROUTE_FAMILY = RF_IPv6_FLOWSPEC class Vrf6FlowSpecTable(VRFFlowSpecTable): """Virtual Routing and Forwarding information base for IPv6 Flow Specification. """ ROUTE_FAMILY = RF_IPv6_FLOWSPEC VPN_ROUTE_FAMILY = RF_VPNv6_FLOWSPEC NLRI_CLASS = FlowSpecIPv6NLRI VRF_PATH_CLASS = Vrf6FlowSpecPath VRF_DEST_CLASS = Vrf6FlowSpecDest ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/info_base/vrfevpn.py0000664000175000017500000000355400000000000024702 0ustar00zuulzuul00000000000000# Copyright (C) 2016 Nippon Telegraph and Telephone 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. """ Defines data types and models required specifically for VRF (for EVPN) support. Represents data structures for VRF not VPN/global. """ import logging from os_ken.lib.packet.bgp import RF_L2_EVPN from os_ken.lib.packet.bgp import EvpnNLRI from os_ken.services.protocols.bgp.info_base.evpn import EvpnPath from os_ken.services.protocols.bgp.info_base.vrf import VrfDest from os_ken.services.protocols.bgp.info_base.vrf import VrfNlriImportMap from os_ken.services.protocols.bgp.info_base.vrf import VrfPath from os_ken.services.protocols.bgp.info_base.vrf import VrfTable LOG = logging.getLogger('bgpspeaker.info_base.vrfevpn') class VrfEvpnPath(VrfPath): """Represents a way of reaching an EVPN destination with a VPN.""" ROUTE_FAMILY = RF_L2_EVPN VPN_PATH_CLASS = EvpnPath VPN_NLRI_CLASS = EvpnNLRI class VrfEvpnDest(VrfDest): """Destination for EVPN VRFs.""" ROUTE_FAMILY = RF_L2_EVPN class VrfEvpnTable(VrfTable): """Virtual Routing and Forwarding information base for EVPN.""" ROUTE_FAMILY = RF_L2_EVPN VPN_ROUTE_FAMILY = RF_L2_EVPN NLRI_CLASS = EvpnNLRI VRF_PATH_CLASS = VrfEvpnPath VRF_DEST_CLASS = VrfEvpnDest class VrfEvpnNlriImportMap(VrfNlriImportMap): VRF_PATH_CLASS = VrfEvpnPath NLRI_CLASS = EvpnNLRI ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/info_base/vrffs.py0000664000175000017500000000622300000000000024336 0ustar00zuulzuul00000000000000# Copyright (C) 2017 Nippon Telegraph and Telephone 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. """ Defines base data types and models required specifically for VRF Flow Specification support. """ import abc import logging from os_ken.lib.packet.bgp import BGP_ATTR_TYPE_ORIGIN from os_ken.lib.packet.bgp import BGP_ATTR_TYPE_AS_PATH from os_ken.lib.packet.bgp import BGP_ATTR_TYPE_EXTENDED_COMMUNITIES from os_ken.lib.packet.bgp import BGPPathAttributeOrigin from os_ken.lib.packet.bgp import BGPPathAttributeAsPath from os_ken.lib.packet.bgp import BGPPathAttributeExtendedCommunities from os_ken.services.protocols.bgp.base import OrderedDict from os_ken.services.protocols.bgp.info_base.vrf import VrfTable from os_ken.services.protocols.bgp.info_base.vrf import VrfDest from os_ken.services.protocols.bgp.info_base.vrf import VrfPath from os_ken.services.protocols.bgp.utils.bgp import create_rt_extended_community LOG = logging.getLogger('bgpspeaker.info_base.vrffs') class VRFFlowSpecTable(VrfTable, metaclass=abc.ABCMeta): """Virtual Routing and Forwarding information base. Keeps destination imported to given VRF Flow Specification in represents. """ def insert_vrffs_path(self, nlri, communities, is_withdraw=False): assert nlri assert isinstance(communities, list) vrf_conf = self.vrf_conf from os_ken.services.protocols.bgp.core import EXPECTED_ORIGIN pattrs = OrderedDict() pattrs[BGP_ATTR_TYPE_ORIGIN] = BGPPathAttributeOrigin( EXPECTED_ORIGIN) pattrs[BGP_ATTR_TYPE_AS_PATH] = BGPPathAttributeAsPath([]) for rt in vrf_conf.export_rts: communities.append(create_rt_extended_community(rt, 2)) for soo in vrf_conf.soo_list: communities.append(create_rt_extended_community(soo, 3)) pattrs[BGP_ATTR_TYPE_EXTENDED_COMMUNITIES] = ( BGPPathAttributeExtendedCommunities(communities=communities)) puid = self.VRF_PATH_CLASS.create_puid( vrf_conf.route_dist, nlri.prefix) path = self.VRF_PATH_CLASS( puid, None, nlri, 0, pattrs=pattrs, is_withdraw=is_withdraw ) # Insert the path into VRF table, get affected destination so that we # can process it further. eff_dest = self.insert(path) # Enqueue the eff_dest for further processing. self._signal_bus.dest_changed(eff_dest) class VRFFlowSpecDest(VrfDest, metaclass=abc.ABCMeta): """Base class for VRF Flow Specification.""" class VRFFlowSpecPath(VrfPath, metaclass=abc.ABCMeta): """Represents a way of reaching an IP destination with a VPN Flow Specification. """ ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/info_base/vrfl2vpnfs.py0000664000175000017500000000374200000000000025323 0ustar00zuulzuul00000000000000# Copyright (C) 2017 Nippon Telegraph and Telephone 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. """ Defines data types and models required specifically for L2VPN support. Represents data structures for VRF not VPN/global. (Inside VRF you have L2VPN Flow Specification prefixes and inside VPN you have L2VPN Flow Specification prefixes) """ import logging from os_ken.lib.packet.bgp import RF_L2VPN_FLOWSPEC from os_ken.lib.packet.bgp import FlowSpecL2VPNNLRI from os_ken.services.protocols.bgp.info_base.l2vpnfs import L2VPNFlowSpecPath from os_ken.services.protocols.bgp.info_base.vrffs import VRFFlowSpecDest from os_ken.services.protocols.bgp.info_base.vrffs import VRFFlowSpecPath from os_ken.services.protocols.bgp.info_base.vrffs import VRFFlowSpecTable LOG = logging.getLogger('bgpspeaker.info_base.vrfl2vpnfs') class L2vpnFlowSpecPath(VRFFlowSpecPath): """Represents a way of reaching an IP destination with a L2VPN Flow Specification. """ ROUTE_FAMILY = RF_L2VPN_FLOWSPEC VPN_PATH_CLASS = L2VPNFlowSpecPath VPN_NLRI_CLASS = FlowSpecL2VPNNLRI class L2vpnFlowSpecDest(VRFFlowSpecDest): ROUTE_FAMILY = RF_L2VPN_FLOWSPEC class L2vpnFlowSpecTable(VRFFlowSpecTable): """Virtual Routing and Forwarding information base for L2VPN Flow Specification. """ ROUTE_FAMILY = RF_L2VPN_FLOWSPEC VPN_ROUTE_FAMILY = RF_L2VPN_FLOWSPEC NLRI_CLASS = FlowSpecL2VPNNLRI VRF_PATH_CLASS = L2vpnFlowSpecPath VRF_DEST_CLASS = L2vpnFlowSpecDest ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/model.py0000664000175000017500000001326600000000000022370 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone 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. """ Defines some model classes related BGP. These class include types used in saving information sent/received over BGP sessions. """ import logging from time import gmtime LOG = logging.getLogger('bgpspeaker.model') class Counter(object): """Simple counter for keeping count of several keys.""" def __init__(self): self._counters = {} def incr(self, counter_name, incr_by=1): self._counters[counter_name] = \ self._counters.get(counter_name, 0) + incr_by def get_count(self, counter_name): return self._counters.get(counter_name, 0) def get_counters(self): return self._counters.copy() class OutgoingRoute(object): """Holds state about a route that is queued for being sent to a given sink. """ __slots__ = ('_path', '_for_route_refresh', 'sink', 'next_outgoing_route', 'prev_outgoing_route', 'next_sink_out_route', 'prev_sink_out_route') def __init__(self, path, for_route_refresh=False): assert(path) self.sink = None self._path = path # Is this update in response for route-refresh request. # No sent-route is queued for the destination for this update. self._for_route_refresh = for_route_refresh # Automatically generated, for list off of Destination. # # self.next_outgoing_route # self.prev_outgoing_route # Automatically generated for list off of sink. # # self.next_sink_out_route # self.prev_sink_out_route @property def path(self): return self._path @property def for_route_refresh(self): return self._for_route_refresh def __str__(self): return ('OutgoingRoute(path: %s, for_route_refresh: %s)' % (self.path, self.for_route_refresh)) class FlexinetOutgoingRoute(object): """Holds state about a route that is queued for being sent to a given sink. In this case the sink is flexinet peer and this route information is from a VRF which holds Ipv4(v6) NLRIs. """ __slots__ = ('_path', 'sink', 'next_outgoing_route', 'prev_outgoing_route', 'next_sink_out_route', 'prev_sink_out_route', '_route_dist') def __init__(self, path, route_dist): from os_ken.services.protocols.bgp.info_base.vrf4 import Vrf4Path from os_ken.services.protocols.bgp.info_base.vrf6 import Vrf6Path from os_ken.services.protocols.bgp.info_base.vrfevpn import VrfEvpnPath from os_ken.services.protocols.bgp.info_base.vrf4fs import ( Vrf4FlowSpecPath) from os_ken.services.protocols.bgp.info_base.vrf6fs import ( Vrf6FlowSpecPath) from os_ken.services.protocols.bgp.info_base.vrfl2vpnfs import ( L2vpnFlowSpecPath) assert path.route_family in (Vrf4Path.ROUTE_FAMILY, Vrf6Path.ROUTE_FAMILY, VrfEvpnPath.ROUTE_FAMILY, Vrf4FlowSpecPath.ROUTE_FAMILY, Vrf6FlowSpecPath.ROUTE_FAMILY, L2vpnFlowSpecPath.ROUTE_FAMILY, ) self.sink = None self._path = path self._route_dist = route_dist # Automatically generated, for list off of Destination. # # self.next_outgoing_route # self.prev_outgoing_route # Automatically generated for list off of sink. # # self.next_sink_out_route # self.prev_sink_out_route @property def path(self): return self._path @property def route_dist(self): return self._route_dist def __str__(self): return ('FlexinetOutgoingRoute(path: %s, route_dist: %s)' % (self.path, self.route_dist)) class SentRoute(object): """Holds the information that has been sent to one or more sinks about a particular BGP destination. """ def __init__(self, path, peer, filtered=None, timestamp=None): assert(path and hasattr(peer, 'version_num')) self.path = path # Peer to which this path was sent. self._sent_peer = peer self.filtered = filtered if timestamp: self.timestamp = timestamp else: self.timestamp = gmtime() # Automatically generated. # # self.next_sent_route # self.prev_sent_route @property def sent_peer(self): return self._sent_peer class ReceivedRoute(object): """Holds the information that has been received to one sinks about a particular BGP destination. """ def __init__(self, path, peer, filtered=None, timestamp=None): assert(path and hasattr(peer, 'version_num')) self.path = path # Peer to which this path was received. self._received_peer = peer self.filtered = filtered if timestamp: self.timestamp = timestamp else: self.timestamp = gmtime() @property def received_peer(self): return self._received_peer ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/net_ctrl.py0000664000175000017500000003664100000000000023104 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone 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. """ Network Controller interface to BGP. Network controller w.r.t BGPS for APGW Automation project is named as APGW Agent and Route Server. """ import logging import socket import traceback import msgpack from os_ken.lib.packet import safi as subaddr_family from os_ken.services.protocols.bgp import api from os_ken.services.protocols.bgp.api.base import ApiException from os_ken.services.protocols.bgp.api.base import NEXT_HOP from os_ken.services.protocols.bgp.api.base import ORIGIN_RD from os_ken.services.protocols.bgp.api.base import PREFIX from os_ken.services.protocols.bgp.api.base import ROUTE_DISTINGUISHER from os_ken.services.protocols.bgp.api.base import VPN_LABEL from os_ken.services.protocols.bgp.base import Activity from os_ken.services.protocols.bgp.base import add_bgp_error_metadata from os_ken.services.protocols.bgp.base import BGPSException from os_ken.services.protocols.bgp.base import FlexinetPeer from os_ken.services.protocols.bgp.base import NET_CTRL_ERROR_CODE from os_ken.services.protocols.bgp.constants import VRF_TABLE from os_ken.services.protocols.bgp.rtconf.vrfs import VRF_RF from os_ken.services.protocols.bgp.rtconf.vrfs import VrfConf from os_ken.services.protocols.bgp.utils.validation import is_valid_ipv4 # Logger instance for this module. LOG = logging.getLogger('bgpspeaker.net_ctrl') # Network controller service socket constants. NC_RPC_BIND_IP = 'apgw_rpc_bind_ip' NC_RPC_BIND_PORT = 'apgw_rpc_bind_port' # Notification symbols NOTIFICATION_ADD_REMOTE_PREFIX = 'prefix.add_remote' NOTIFICATION_DELETE_REMOTE_PREFIX = 'prefix.delete_remote' NOTIFICATION_ADD_LOCAL_PREFIX = 'prefix.add_local' NOTIFICATION_DELETE_LOCAL_PREFIX = 'prefix.delete_local' NOTIFICATION_LOG = 'logging' # MessagePackRPC message type constants RPC_MSG_REQUEST = 0 RPC_MSG_RESPONSE = 1 RPC_MSG_NOTIFY = 2 # # Indexes for various RPC message types. # RPC_IDX_MSG_TYP = 0 RPC_IDX_MSG_ID = 1 RPC_IDX_REQ_SYM = 2 RPC_IDX_REQ_PARAM = 3 RPC_IDX_RES_ERR = 2 RPC_IDX_RES_RST = 3 RPC_IDX_NTF_SYM = 1 RPC_IDX_NTF_PARAM = 2 # RPC socket receive buffer size in bytes. RPC_SOCK_BUFF_SIZE = 4096 @add_bgp_error_metadata(code=NET_CTRL_ERROR_CODE, sub_code=1, def_desc='Unknown Network controller exception') class NetworkControllerError(BGPSException): """Common base class for exceptions related to RPC calls. """ pass class RpcSession(Activity): """Provides message-pack RPC abstraction for one session. It contains message-pack packer, un-packer, message ID sequence and utilities that use these. It also cares about socket communication w/ RPC peer. """ NAME_FMT = 'RpcSession%s' def __init__(self, sock, outgoing_msg_sink_iter): self.peer_name = str(sock.getpeername()) super(RpcSession, self).__init__(self.NAME_FMT % self.peer_name) # NOTE(ralonsoh): msgpack>=1.0.0 self._packer = msgpack.Packer() # The strict_map_key=False option is required to use int keys in # maps; it is disabled by default to prevent hash collision denial # of service attacks (hashdos) in scenarios where an attacker can # control the keys to be hashed. self._unpacker = msgpack.Unpacker(strict_map_key=False) self._next_msgid = 0 self._socket = sock self._outgoing_msg_sink_iter = outgoing_msg_sink_iter self.is_connected = True self.green_in = None self.green_out = None def stop(self): super(RpcSession, self).stop() self.is_connected = False LOG.info('RPC Session to %s stopped', self.peer_name) def _run(self): # Process outgoing messages in new thread. self.green_out = self._spawn('net_ctrl._process_outgoing', self._process_outgoing_msg, self._outgoing_msg_sink_iter) # Process incoming messages in new thread. self.green_in = self._spawn('net_ctrl._process_incoming', self._process_incoming_msgs) LOG.info('RPC Session to %s started', self.peer_name) self.green_in.wait() self.green_out.wait() def _next_msg_id(self): this_id = self._next_msgid self._next_msgid += 1 return this_id def create_request(self, method, params): msgid = self._next_msg_id() return self._packer.pack([RPC_MSG_REQUEST, msgid, method, params]) def create_error_response(self, msgid, error): if error is None: raise NetworkControllerError(desc='Creating error without body!') return self._packer.pack([RPC_MSG_RESPONSE, msgid, error, None]) def create_success_response(self, msgid, result): if result is None: raise NetworkControllerError(desc='Creating response without ' 'body!') return self._packer.pack([RPC_MSG_RESPONSE, msgid, None, result]) def create_notification(self, method, params): return self._packer.pack([RPC_MSG_NOTIFY, method, params]) def feed_and_get_messages(self, data): self._unpacker.feed(data) messages = [] for msg in self._unpacker: messages.append(msg) return messages def feed_and_get_first_message(self, data): self._unpacker.feed(data) for msg in self._unpacker: return msg def _send_error_response(self, request, err_msg): rpc_msg = self.create_error_response(request[RPC_IDX_MSG_ID], str(err_msg)) return self._sendall(rpc_msg) def _send_success_response(self, request, result): rpc_msg = self.create_success_response(request[RPC_IDX_MSG_ID], result) return self._sendall(rpc_msg) def send_notification(self, method, params): rpc_msg = self.create_notification(method, params) return self._sendall(rpc_msg) def _process_incoming_msgs(self): LOG.debug('NetworkController started processing incoming messages') assert self._socket while self.is_connected: # Wait for request/response/notification from peer. msg_buff = self._recv() if len(msg_buff) == 0: LOG.info('Peer %s disconnected.', self.peer_name) self.is_connected = False self._socket.close() break messages = self.feed_and_get_messages(msg_buff) for msg in messages: if msg[0] == RPC_MSG_REQUEST: try: result = _handle_request(msg) self._send_success_response(msg, result) except BGPSException as e: self._send_error_response(msg, e.message) elif msg[0] == RPC_MSG_RESPONSE: _handle_response(msg) elif msg[0] == RPC_MSG_NOTIFY: _handle_notification(msg) else: LOG.error('Invalid message type: %r', msg) self.pause(0) # Stop outgoing connection. if self.green_out: self.green_out.kill() def _process_outgoing_msg(self, sink_iter): """For every message we construct a corresponding RPC message to be sent over the given socket inside given RPC session. This function should be launched in a new green thread as it loops forever. """ LOG.debug('NetworkController processing outgoing request list.') # TODO(PH): We should try not to sent routes from bgp peer that is not # in established state. from os_ken.services.protocols.bgp.model import ( FlexinetOutgoingRoute) while self.is_connected: # sink iter is Sink instance and next is blocking so this isn't # active wait. for outgoing_msg in sink_iter: if not self.is_connected: self._socket.close() return if isinstance(outgoing_msg, FlexinetOutgoingRoute): rpc_msg = _create_prefix_notification(outgoing_msg, self) else: raise NotImplementedError( 'Do not handle out going message of type %s' % outgoing_msg.__class__) if rpc_msg: self._sendall(rpc_msg) self.pause(0) # Stop incoming connection. if self.green_in: self.green_in.kill() def _recv(self): return self._sock_wrap(self._socket.recv)(RPC_SOCK_BUFF_SIZE) def _sendall(self, msg): return self._sock_wrap(self._socket.sendall)(msg) def _sock_wrap(self, func): def wrapper(*args, **kwargs): try: ret = func(*args, **kwargs) except socket.error: LOG.error(traceback.format_exc()) self._socket_error() return return ret return wrapper def _socket_error(self): if self.started: self.stop() def _create_prefix_notification(outgoing_msg, rpc_session): """Constructs prefix notification with data from given outgoing message. Given RPC session is used to create RPC notification message. """ assert outgoing_msg path = outgoing_msg.path assert path vpn_nlri = path.nlri assert path.source is not None if path.source != VRF_TABLE: # Extract relevant info for update-add/update-delete. params = [{ROUTE_DISTINGUISHER: outgoing_msg.route_dist, PREFIX: vpn_nlri.prefix, NEXT_HOP: path.nexthop, VRF_RF: VrfConf.rf_2_vrf_rf(path.route_family)}] if path.nlri.ROUTE_FAMILY.safi not in (subaddr_family.IP_FLOWSPEC, subaddr_family.VPN_FLOWSPEC): params[VPN_LABEL] = path.label_list[0] if not path.is_withdraw: # Create notification to NetworkController. rpc_msg = rpc_session.create_notification( NOTIFICATION_ADD_REMOTE_PREFIX, params) else: # Create update-delete request to NetworkController. rpc_msg = rpc_session.create_notification( NOTIFICATION_DELETE_REMOTE_PREFIX, params) else: # Extract relevant info for update-add/update-delete. params = [{ROUTE_DISTINGUISHER: outgoing_msg.route_dist, PREFIX: vpn_nlri.prefix, NEXT_HOP: path.nexthop, VRF_RF: VrfConf.rf_2_vrf_rf(path.route_family), ORIGIN_RD: path.origin_rd}] if not path.is_withdraw: # Create notification to NetworkController. rpc_msg = rpc_session.create_notification( NOTIFICATION_ADD_LOCAL_PREFIX, params) else: # Create update-delete request to NetworkController. rpc_msg = rpc_session.create_notification( NOTIFICATION_DELETE_LOCAL_PREFIX, params) return rpc_msg def _validate_rpc_ip(rpc_server_ip): """Validates given ip for use as rpc host bind address. """ if not is_valid_ipv4(rpc_server_ip): raise NetworkControllerError(desc='Invalid rpc ip address.') return rpc_server_ip def _validate_rpc_port(port): """Validates give port for use as rpc server port. """ if not port: raise NetworkControllerError(desc='Invalid rpc port number.') if isinstance(port, str): port = int(port) if port <= 0: raise NetworkControllerError(desc='Invalid rpc port number %s' % port) return port class _NetworkController(FlexinetPeer, Activity): """Network controller peer. Provides MessagePackRPC interface for flexinet peers like Network controller to peer and have RPC session with BGPS process. This RPC interface provides access to BGPS API. """ def __init__(self): FlexinetPeer.__init__(self) Activity.__init__(self, name='NETWORK_CONTROLLER') # Outstanding requests, i.e. requests for which we are yet to receive # response from peer. We currently do not have any requests going out. self._outstanding_reqs = {} # Dictionary for Peer name to RPC session. self._rpc_sessions = {} def _run(self, *args, **kwargs): """Runs RPC server. Wait for peer to connect and start rpc session with it. For every connection we start and new rpc session. """ apgw_rpc_bind_ip = _validate_rpc_ip(kwargs.pop(NC_RPC_BIND_IP)) apgw_rpc_bind_port = _validate_rpc_port(kwargs.pop(NC_RPC_BIND_PORT)) sock_addr = (apgw_rpc_bind_ip, apgw_rpc_bind_port) LOG.debug('NetworkController started listening for connections...') server_thread, _ = self._listen_tcp(sock_addr, self._start_rpc_session) self.pause(0) server_thread.wait() def _start_rpc_session(self, sock): """Starts a new RPC session with given connection. """ session_name = RpcSession.NAME_FMT % str(sock.getpeername()) self._stop_child_activities(session_name) rpc_session = RpcSession(sock, self) self._spawn_activity(rpc_session) def _send_rpc_notification_to_session(self, session, method, params): if not session.is_connected: # Stops disconnected RPC session. self._stop_child_activities(session.name) return return session.send_notification(method, params) def send_rpc_notification(self, method, params): if not self.started: return for session in list(self._child_activity_map.values()): if not isinstance(session, RpcSession): continue self._send_rpc_notification_to_session(session, method, params) def _handle_response(response): raise NotImplementedError('BGPS is not making any request hence should not' ' get any response. Response: %s' % response) def _handle_notification(notification): LOG.debug('Notification from NetworkController<<: %s %s', notification[RPC_IDX_NTF_SYM], notification[RPC_IDX_NTF_PARAM]) operation, params = notification[1], notification[2] return api.base.call(operation, **params[0]) def _handle_request(request): LOG.debug('Request from NetworkController<<: %s %s', request[RPC_IDX_REQ_SYM], request[RPC_IDX_REQ_PARAM]) operation, params = request[2], request[3] kwargs = {} if len(params) > 0: kwargs = params[0] try: return api.base.call(operation, **kwargs) except TypeError: LOG.error(traceback.format_exc()) raise ApiException(desc='Invalid type for RPC parameter.') # Network controller singleton NET_CONTROLLER = _NetworkController() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.1101055 os-ken-2.10.0/os_ken/services/protocols/bgp/operator/0000775000175000017500000000000000000000000022541 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/operator/__init__.py0000664000175000017500000000000000000000000024640 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/operator/command.py0000664000175000017500000002224500000000000024536 0ustar00zuulzuul00000000000000from collections import namedtuple import json import logging import pprint import re (STATUS_OK, STATUS_ERROR) = range(2) CommandsResponse = namedtuple('CommandsResponse', ['status', 'value']) LOG = logging.getLogger('bgpspeaker.operator.command') def default_help_formatter(quick_helps): """Apply default formatting for help messages :param quick_helps: list of tuples containing help info """ ret = '' for line in quick_helps: cmd_path, param_hlp, cmd_hlp = line ret += ' '.join(cmd_path) + ' ' if param_hlp: ret += param_hlp + ' ' ret += '- ' + cmd_hlp + '\n' return ret class Command(object): """Command class is used as a node in tree of commands. Each command can do some action or have some sub-commands, just like in IOS Command with it's sub-commands form tree. Each command can have one or more parameters. Parameters have to be distinguishable from sub-commands. One can inject dependency into command Cmd(api=my_object). This dependency will be injected to every sub-command. And can be used to interact with model/data etc. Example of path in command tree `show count all`. """ help_msg = '' param_help_msg = '' command = '' cli_resp_line_template = '{0}: {1}\n' def __init__(self, api=None, parent=None, help_formatter=default_help_formatter, resp_formatter_name='cli'): """:param api: object which is saved as self.api and re-injected to every sub-command. You can use it to manipulate your model from inside Commands' :param parent: parent command instance. :param help_formatter: function used to format output of '?'command. Is re-injected to every sub-command as well. :param resp_formatter_name: used to select function to format output of _action. cli_resp_formatter and json_resp_formatter are defined by default, but you can define your own formatters. If you use custom formatter(not cli nor json) remember to implement it for every sub-command. """ self.resp_formatter_name = resp_formatter_name if hasattr(self, resp_formatter_name + '_resp_formatter'): self.resp_formatter = \ getattr(self, resp_formatter_name + '_resp_formatter') else: self.resp_formatter = self.cli_resp_formatter self.api = api self.parent_cmd = parent self.help_formatter = help_formatter if not hasattr(self, 'subcommands'): self.subcommands = {} def __call__(self, params): """You run command by calling it. :param params: As params you give list of subcommand names and params to final subcommand. Kind of like in cisco ios cli, ie. show int eth1 / 1, where show is command, int subcommand and eth1 / 1 is param for subcommand. :return: returns tuple of CommandsResponse and class of sub - command on which _action was called. (last sub - command) CommandsResponse.status is action status, and CommandsResponse.value is formatted response. """ if len(params) == 0: return self._action_wrapper([]) first_param = params[0] if first_param == '?': return self.question_mark() if first_param in self.subcommands: return self._instantiate_subcommand(first_param)(params[1:]) return self._action_wrapper(params) @classmethod def cli_resp_formatter(cls, resp): """Override this method to provide custom formatting of cli response. """ if not resp.value: return '' if resp.status == STATUS_OK: if type(resp.value) in (str, bool, int, float, str): return str(resp.value) ret = '' val = resp.value if not isinstance(val, list): val = [val] for line in val: for k, v in line.items(): if isinstance(v, dict): ret += cls.cli_resp_line_template.format( k, '\n' + pprint.pformat(v) ) else: ret += cls.cli_resp_line_template.format(k, v) return ret else: return "Error: {0}".format(resp.value) @classmethod def json_resp_formatter(cls, resp): """Override this method to provide custom formatting of json response. """ return json.dumps(resp.value) @classmethod def dict_resp_formatter(cls, resp): return resp.value def _action_wrapper(self, params): filter_params = [] if '|' in params: ind = params.index('|') new_params = params[:ind] filter_params = params[ind:] params = new_params action_resp = self.action(params) if len(filter_params) > 1: # we don't pass '|' around so filter_params[1:] action_resp = self.filter_resp(action_resp, filter_params[1:]) action_resp = CommandsResponse( action_resp.status, self.resp_formatter(action_resp) ) return action_resp, self.__class__ def action(self, params): """Override this method to define what command should do. :param params: list of text parameters applied to this command. :return: returns CommandsResponse instance. CommandsResponse.status can be STATUS_OK or STATUS_ERROR CommandsResponse.value should be dict or str """ return CommandsResponse(STATUS_ERROR, 'Not implemented') def filter_resp(self, action_resp, filter_params): """Filter response of action. Used to make printed results more specific :param action_resp: named tuple (CommandsResponse) containing response from action. :param filter_params: params used after '|' specific for given filter :return: filtered response. """ if action_resp.status == STATUS_OK: try: return CommandsResponse( STATUS_OK, TextFilter.filter(action_resp.value, filter_params) ) except FilterError as e: return CommandsResponse(STATUS_ERROR, str(e)) else: return action_resp def question_mark(self): """Shows help for this command and it's sub-commands. """ ret = [] if self.param_help_msg or len(self.subcommands) == 0: ret.append(self._quick_help()) if len(self.subcommands) > 0: for k, _ in sorted(self.subcommands.items()): command_path, param_help, cmd_help = \ self._instantiate_subcommand(k)._quick_help(nested=True) if command_path or param_help or cmd_help: ret.append((command_path, param_help, cmd_help)) return ( CommandsResponse(STATUS_OK, self.help_formatter(ret)), self.__class__ ) def _quick_help(self, nested=False): """:param nested: True if help is requested directly for this command and False when help is requested for a list of possible completions. """ if nested: return self.command_path(), None, self.help_msg else: return self.command_path(), self.param_help_msg, self.help_msg def command_path(self): if self.parent_cmd: return self.parent_cmd.command_path() + [self.command] else: return [self.command] def _instantiate_subcommand(self, key): return self.subcommands[key]( api=self.api, parent=self, help_formatter=self.help_formatter, resp_formatter_name=self.resp_formatter_name ) class TextFilter(object): @classmethod def filter(cls, action_resp_value, filter_params): try: action, expected_value = filter_params except ValueError: raise FilterError('Wrong number of filter parameters') if action == 'regexp': if isinstance(action_resp_value, list): resp = list(action_resp_value) iterator = enumerate(action_resp_value) else: resp = dict(action_resp_value) iterator = iter(action_resp_value.items()) remove = [] for key, value in iterator: if not re.search(expected_value, str(value)): remove.append(key) if isinstance(resp, list): resp = [resp[key] for key, value in enumerate(resp) if key not in remove] else: resp = dict([(key, value) for key, value in resp.items() if key not in remove]) return resp else: raise FilterError('Unknown filter') class FilterError(Exception): pass ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.1101055 os-ken-2.10.0/os_ken/services/protocols/bgp/operator/commands/0000775000175000017500000000000000000000000024342 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/operator/commands/__init__.py0000664000175000017500000000000000000000000026441 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/operator/commands/clear.py0000664000175000017500000000310500000000000026001 0ustar00zuulzuul00000000000000from os_ken.services.protocols.bgp.operator.command import Command from os_ken.services.protocols.bgp.operator.command import CommandsResponse from os_ken.services.protocols.bgp.operator.command import STATUS_OK from os_ken.services.protocols.bgp.operator.commands.responses import \ WrongParamResp class BGPCmd(Command): help_msg = ('reset bgp connections, no afi/safi is ' 'treated as - all supported address-families') param_help_msg = ' [ ]' command = 'bgp' def __init__(self, *args, **kwargs): super(BGPCmd, self).__init__(*args, **kwargs) self.subcommands = {'all': self.All} def action(self, params): if len(params) == 0: return WrongParamResp() peer = afi = safi = None try: peer = params[0] afi = params[1] safi = params[2] except IndexError: pass self.api.route_refresh(peer, afi, safi) return CommandsResponse(STATUS_OK, '') class All(Command): help_msg = 'reset all connections' param_help_msg = '[ ]' command = 'all' def action(self, params): peer = afi = safi = None try: afi = params[0] safi = params[1] except IndexError: pass self.api.route_refresh(peer, afi, safi) return CommandsResponse(STATUS_OK, '') class ClearCmd(Command): help_msg = 'allows to reset BGP connections' command = 'clear' subcommands = {'bgp': BGPCmd} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/operator/commands/responses.py0000664000175000017500000000230500000000000026735 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone 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. """ Defines classes related to incorrect parameters. """ from os_ken.services.protocols.bgp.operator.command import CommandsResponse from os_ken.services.protocols.bgp.operator.command import STATUS_ERROR from os_ken.services.protocols.bgp.operator.internal_api import WrongParamError class WrongParamResp(object): def __new__(cls, e=None): return cls.wrong_param_resp_factory(e) @staticmethod def wrong_param_resp_factory(e=None): if not e: e = WrongParamError() desc = 'wrong parameters: %s' % str(e) return CommandsResponse(STATUS_ERROR, desc) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/operator/commands/root.py0000664000175000017500000000062700000000000025704 0ustar00zuulzuul00000000000000from os_ken.services.protocols.bgp.operator.command import Command from os_ken.services.protocols.bgp.operator.commands.clear import ClearCmd from os_ken.services.protocols.bgp.operator.commands.set import SetCmd from os_ken.services.protocols.bgp.operator.commands.show import ShowCmd class RootCmd(Command): subcommands = { 'show': ShowCmd, 'set': SetCmd, 'clear': ClearCmd} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/operator/commands/set.py0000664000175000017500000000422500000000000025512 0ustar00zuulzuul00000000000000import logging from os_ken.services.protocols.bgp.operator.command import Command from os_ken.services.protocols.bgp.operator.command import CommandsResponse from os_ken.services.protocols.bgp.operator.command import STATUS_OK from os_ken.services.protocols.bgp.operator.command import STATUS_ERROR from os_ken.services.protocols.bgp.operator.commands.responses import \ WrongParamResp class LoggingCmd(Command): command = 'logging' help_msg = 'turn on/off logging at current level' def __init__(self, *args, **kwargs): super(LoggingCmd, self).__init__(*args, **kwargs) self.subcommands = { 'on': self.On, 'off': self.Off, 'level': self.Level } def action(self, params): return CommandsResponse(STATUS_ERROR, 'Command incomplete') class On(Command): command = 'on' help_msg = 'turn-on the logging at the current level' def action(self, params): logging.getLogger('bgpspeaker').addHandler(self.api.log_handler) return CommandsResponse(STATUS_OK, True) class Off(Command): command = 'off' help_msg = 'turn-off the logging' def action(self, params): logging.getLogger('bgpspeaker').removeHandler(self.api.log_handler) return CommandsResponse(STATUS_OK, True) class Level(Command): command = 'level' help_msg = 'set logging level' param_help_msg = '[debug/info/error]' def action(self, params): lvls = { 'debug': logging.DEBUG, 'error': logging.ERROR, 'info': logging.INFO } if len(params) == 1 and params[0] in lvls: self.api.log_handler.setLevel( lvls.get(params[0], logging.ERROR) ) return CommandsResponse(STATUS_OK, True) else: return WrongParamResp() class SetCmd(Command): help_msg = 'set runtime settings' command = 'set' subcommands = {'logging': LoggingCmd} def action(self, params): return CommandsResponse(STATUS_ERROR, 'Command incomplete') ././@PaxHeader0000000000000000000000000000003300000000000011451 xustar000000000000000027 mtime=1724334546.114106 os-ken-2.10.0/os_ken/services/protocols/bgp/operator/commands/show/0000775000175000017500000000000000000000000025322 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/operator/commands/show/__init__.py0000664000175000017500000000401700000000000027435 0ustar00zuulzuul00000000000000from os_ken.services.protocols.bgp.operator.command import Command from os_ken.services.protocols.bgp.operator.command import CommandsResponse from os_ken.services.protocols.bgp.operator.command import STATUS_OK from os_ken.services.protocols.bgp.operator.command import STATUS_ERROR from os_ken.services.protocols.bgp.operator.commands.show import count from os_ken.services.protocols.bgp.operator.commands.show import importmap from os_ken.services.protocols.bgp.operator.commands.show import memory from os_ken.services.protocols.bgp.operator.commands.show import neighbor from os_ken.services.protocols.bgp.operator.commands.show import rib from os_ken.services.protocols.bgp.operator.commands.show import vrf class ShowCmd(Command): help_msg = 'shows runtime state information' command = 'show' def __init__(self, *args, **kwargs): super(ShowCmd, self).__init__(*args, **kwargs) self.subcommands = { 'count': self.Count, 'logging': self.Logging, 'rib': self.Rib, 'vrf': self.Vrf, 'memory': self.Memory, 'neighbor': self.Neighbor, 'importmap': self.Importmap } def action(self, params): return CommandsResponse(STATUS_ERROR, 'Command incomplete') class Count(count.Count): pass class Rib(rib.Rib): pass class Vrf(vrf.Vrf): pass class Importmap(importmap.Importmap): pass class Memory(memory.Memory): pass class Neighbor(neighbor.Neighbor): pass class Logging(Command): command = 'logging' help_msg = 'shows if logging is on/off and current logging level.' def action(self, params): if self.api.check_logging(): ret = {'logging': self.api.check_logging(), 'level': self.api.check_logging_level()} else: ret = {'logging': self.api.check_logging(), 'level': None} return CommandsResponse(STATUS_OK, ret) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/operator/commands/show/count.py0000664000175000017500000000350200000000000027024 0ustar00zuulzuul00000000000000import logging from os_ken.services.protocols.bgp.operator.command import Command from os_ken.services.protocols.bgp.operator.command import CommandsResponse from os_ken.services.protocols.bgp.operator.command import STATUS_ERROR from os_ken.services.protocols.bgp.operator.command import STATUS_OK from os_ken.services.protocols.bgp.operator.commands.responses import \ WrongParamResp LOG = logging.getLogger('bgpspeaker.operator.commands.show.count') class Count(Command): help_msg = 'show counters' param_help_msg = ' {ipv4, ipv6}' command = 'count' cli_resp_line_template = 'BGP route count for VPN {0} is {1}\n' def __init__(self, *args, **kwargs): super(Count, self).__init__(*args, **kwargs) self.subcommands = { 'all': self.All } def action(self, params): if len(params) < 1: return CommandsResponse(STATUS_ERROR, 'Not enough params') else: vrf_name = params[0] if len(params) == 2: vrf_rf = params[1] else: vrf_rf = 'ipv4' from os_ken.services.protocols.bgp.operator.internal_api import \ WrongParamError try: return CommandsResponse( STATUS_OK, self.api.count_single_vrf_routes(vrf_name, vrf_rf) ) except WrongParamError as e: return WrongParamResp(e) class All(Command): help_msg = 'shows number of routes for all VRFs' command = 'all' cli_resp_line_template = 'BGP route count for VPN {0} is {1}\n' def action(self, params): if len(params) > 0: return WrongParamResp() return CommandsResponse(STATUS_OK, self.api.count_all_vrf_routes()) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/operator/commands/show/importmap.py0000664000175000017500000000271200000000000027706 0ustar00zuulzuul00000000000000from os_ken.services.protocols.bgp.operator.command import Command from os_ken.services.protocols.bgp.operator.command import CommandsResponse from os_ken.services.protocols.bgp.operator.command import STATUS_ERROR from os_ken.services.protocols.bgp.operator.command import STATUS_OK from os_ken.services.protocols.bgp.operator.commands.responses import \ WrongParamResp from os_ken.services.protocols.bgp.operator.views.bgp import CoreServiceDetailView class Importmap(Command): help_msg = 'show importmaps' param_help_msg = 'all | ' command = 'importmap' def __init__(self, *args, **kwargs): super(Importmap, self).__init__(*args, **kwargs) def action(self, params): if len(params) != 1: return WrongParamResp() core_service = self.api.get_core_service() core_service_view = CoreServiceDetailView(core_service) importmap_manager = core_service_view.rel('importmap_manager') importmaps_view = importmap_manager.rel('importmaps') importmap_name = params[0] if importmap_name == 'all': encoded = importmaps_view.encode() else: encoded = importmaps_view.encode().get(importmap_name) if encoded is None: return CommandsResponse( STATUS_ERROR, 'Wrong importmap name.' ) return CommandsResponse( STATUS_OK, encoded ) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/operator/commands/show/memory.py0000664000175000017500000000564700000000000027220 0ustar00zuulzuul00000000000000import gc import sys from os_ken.services.protocols.bgp.operator.command import Command from os_ken.services.protocols.bgp.operator.command import CommandsResponse from os_ken.services.protocols.bgp.operator.command import STATUS_ERROR from os_ken.services.protocols.bgp.operator.command import STATUS_OK class Memory(Command): help_msg = 'show memory information' command = 'memory' def __init__(self, *args, **kwargs): super(Memory, self).__init__(*args, **kwargs) self.subcommands = { 'summary': self.Summary} class Summary(Command): help_msg = 'shows total memory used and how it is getting used' command = 'summary' def action(self, params): count = {} size = {} total_size = 0 unreachable = gc.collect() for obj in gc.get_objects(): inst_name = type(obj).__name__ c = count.get(inst_name, None) if not c: count[inst_name] = 0 s = size.get(inst_name, None) if not s: size[inst_name] = 0 count[inst_name] += 1 s = sys.getsizeof(obj) size[inst_name] += s total_size += s # Total size in MB total_size = total_size // 1000000 ret = { 'unreachable': unreachable, 'total': total_size, 'summary': []} for class_name, s in size.items(): # Calculate size in MB size_mb = s // 1000000 # We are only interested in class which take-up more than a MB if size_mb > 0: ret['summary'].append( { 'class': class_name, 'instances': count.get(class_name, None), 'size': size_mb } ) return CommandsResponse(STATUS_OK, ret) @classmethod def cli_resp_formatter(cls, resp): if resp.status == STATUS_ERROR: return Command.cli_resp_formatter(resp) val = resp.value ret = 'Unreachable objects: {0}\n'.format( val.get('unreachable', None) ) ret += 'Total memory used (MB): {0}\n'.format( val.get('total', None) ) ret += 'Classes with instances that take-up more than one MB:\n' ret += '{0:<20s} {1:>16s} {2:>16s}\n'.format( 'Class', '#Instance', 'Size(MB)' ) for s in val.get('summary', []): ret += '{0:<20s} {1:>16d} {2:>16d}\n'.format( s.get('class', None), s.get('instances', None), s.get('size', None) ) return ret ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/operator/commands/show/neighbor.py0000664000175000017500000001517300000000000027500 0ustar00zuulzuul00000000000000import logging from time import strftime from os_ken.services.protocols.bgp.operator.command import Command from os_ken.services.protocols.bgp.operator.command import CommandsResponse from os_ken.services.protocols.bgp.operator.command import STATUS_ERROR from os_ken.services.protocols.bgp.operator.command import STATUS_OK from os_ken.services.protocols.bgp.operator.commands.responses import \ WrongParamResp from os_ken.services.protocols.bgp.operator.views.bgp import CoreServiceDetailView from os_ken.lib.packet.bgp import RF_IPv4_UC from os_ken.lib.packet.bgp import RF_IPv6_UC from os_ken.lib.packet.bgp import RF_IPv4_VPN from os_ken.lib.packet.bgp import RF_IPv6_VPN from os_ken.lib.packet.bgp import BGP_ATTR_ORIGIN_IGP from os_ken.lib.packet.bgp import BGP_ATTR_ORIGIN_EGP from os_ken.lib.packet.bgp import BGP_ATTR_ORIGIN_INCOMPLETE LOG = logging.getLogger('bgpspeaker.operator.commands.show.neighbor') class NeighborSummary(Command): help_msg = 'show summarized neighbor information' command = 'summary' def action(self, params): requested_peers = [] if len(params) > 0: requested_peers = [str(p) for p in params] core_service = self.api.get_core_service() core_service_view = CoreServiceDetailView(core_service) peers_view = core_service_view.rel('peer_manager').rel('peers_summary') def filter_requested(peer_id, peer_obj): return not requested_peers or peer_id in requested_peers peers_view.apply_filter(filter_requested) ret = peers_view.encode() return CommandsResponse(STATUS_OK, ret) class SentRoutes(Command): help_msg = 'paths sent and not withdrawn to given peer' command = 'sent-routes' param_help_msg = ' {vpnv4, vpnv6, ipv4, ipv6, all}' fmtstr = ' {0:<2s} {1:<19s} {2:<32s} {3:<8s} {4:<20s} '\ '{5:<6s} {6:<6s} {7:<}\n' def action(self, params): if len(params) != 2: return WrongParamResp() ip_addr, addr_family = params if addr_family == 'ipv4': rf = RF_IPv4_UC elif addr_family == 'ipv6': rf = RF_IPv6_UC elif addr_family == 'vpnv4': rf = RF_IPv4_VPN elif addr_family == 'vpnv6': rf = RF_IPv6_VPN elif addr_family == 'all': rf = None else: return WrongParamResp('wrong addr_family name') ret = self._retrieve_paths(addr_family, rf, ip_addr).encode() return CommandsResponse(STATUS_OK, ret) def _retrieve_paths(self, addr_family, route_family, ip_addr): peer_view = self._retrieve_peer_view(ip_addr) adj_rib_out = peer_view.c_rel('adj_rib_out') adj_rib_out.apply_filter(lambda k, v: addr_family == 'all' or v.path.route_family == route_family) return adj_rib_out def _retrieve_peer_view(self, ip_addr): core_service = self.api.get_core_service() core_sv = CoreServiceDetailView(core_service) peers_view = core_sv.rel('peer_manager').rel('peers') peers_view.apply_filter(lambda k, v: v.ip_address == ip_addr) return peers_view @classmethod def cli_resp_formatter(cls, resp): if resp.status == STATUS_ERROR: return Command.cli_resp_formatter(resp) return cls._format_header() + cls._format_value(resp.value) @classmethod def _format_header(cls): ret = '' ret += ('Status codes: x filtered\n') ret += ('Origin codes: i - IGP, e - EGP, ? - incomplete\n') ret += cls.fmtstr.format('', 'Timestamp', 'Network', 'Labels', 'Next Hop', 'Metric', 'LocPrf', 'Path') return ret @classmethod def _format_value(cls, value): ret = '' for v in value: path = v.get('path') aspath = path.get('as_path') origin = path.get('origin') if origin == BGP_ATTR_ORIGIN_IGP: origin = 'i' elif origin == BGP_ATTR_ORIGIN_EGP: origin = 'e' elif origin == BGP_ATTR_ORIGIN_INCOMPLETE: origin = '?' if origin: aspath = aspath + [origin] next_hop = path.get('nexthop') med = path.get('metric') labels = path.get('labels') localpref = path.get('local_pref') prefix = path.get('nlri').get('prefix') path_status = '' if v.get('filtered'): path_status = 'x' time = 'N/A' if v.get('timestamp'): time = strftime("%Y/%m/%d %H:%M:%S", v.get('timestamp')) ret += cls.fmtstr.format(path_status, time, prefix, labels, str(next_hop), str(med), str(localpref), ' '.join(map(str, aspath))) return ret class ReceivedRoutes(SentRoutes): help_msg = 'paths received and not withdrawn by given peer' command = 'received-routes' def _retrieve_paths(self, addr_family, route_family, ip_addr): peer_view = self._retrieve_peer_view(ip_addr) adj_rib_in = peer_view.c_rel('adj_rib_in') adj_rib_in.apply_filter(lambda k, v: addr_family == 'all' or v.path.route_family == route_family) return adj_rib_in class Neighbor(Command): help_msg = 'show neighbor information' command = 'neighbor' subcommands = { 'summary': NeighborSummary, 'sent-routes': SentRoutes, 'received-routes': ReceivedRoutes } fmtstr = ' {0:<12s} {1:<12s} {2:<}\n' def action(self, params): core_service = self.api.get_core_service() core_service_view = CoreServiceDetailView(core_service) peers_view = core_service_view.rel('peer_manager').rel('peers') ret = peers_view.encode() return CommandsResponse(STATUS_OK, [{'ip_addr': k, 'as_num': str(v['remote_as']), 'bgp_state': v['stats']['bgp_state']} for k, v in ret.items()]) @classmethod def cli_resp_formatter(cls, resp): if resp.status == STATUS_ERROR: return Command.cli_resp_formatter(resp) return cls._format_header() + cls._format_value(resp.value) @classmethod def _format_header(cls): return cls.fmtstr.format('IP Address', 'AS Number', 'BGP State') @classmethod def _format_value(cls, value): ret = '' for v in value: ret += cls.fmtstr.format(v['ip_addr'], v['as_num'], v['bgp_state']) return ret ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/operator/commands/show/rib.py0000664000175000017500000000514400000000000026454 0ustar00zuulzuul00000000000000 from os_ken.services.protocols.bgp.base import ActivityException from os_ken.services.protocols.bgp.operator.command import Command from os_ken.services.protocols.bgp.operator.command import CommandsResponse from os_ken.services.protocols.bgp.operator.command import STATUS_ERROR from os_ken.services.protocols.bgp.operator.command import STATUS_OK from os_ken.services.protocols.bgp.operator.commands.responses import ( WrongParamResp) from .route_formatter_mixin import RouteFormatterMixin class RibBase(Command, RouteFormatterMixin): supported_families = [ 'ipv4', 'ipv6', 'vpnv4', 'vpnv6', 'rtfilter', 'evpn', 'ipv4fs', 'ipv6fs', 'vpnv4fs', 'vpnv6fs', 'l2vpnfs', ] class Rib(RibBase): help_msg = 'show all routes for address family' param_help_msg = '' command = 'rib' def __init__(self, *args, **kwargs): super(Rib, self).__init__(*args, **kwargs) self.subcommands = { 'all': self.All} def action(self, params): if len(params) != 1 or params[0] not in self.supported_families: return WrongParamResp() from os_ken.services.protocols.bgp.operator.internal_api \ import WrongParamError try: return CommandsResponse( STATUS_OK, self.api.get_single_rib_routes(params[0]) ) except WrongParamError as e: return WrongParamResp(e) @classmethod def cli_resp_formatter(cls, resp): if resp.status == STATUS_ERROR: return RibBase.cli_resp_formatter(resp) return cls._format_family_header() + cls._format_family(resp.value) class All(RibBase): help_msg = 'show routes for all RIBs' command = 'all' def action(self, params): if len(params) != 0: return WrongParamResp() ret = {} try: for family in self.supported_families: ret[family] = self.api.get_single_rib_routes(family) return CommandsResponse(STATUS_OK, ret) except ActivityException as e: return CommandsResponse(STATUS_ERROR, e) @classmethod def cli_resp_formatter(cls, resp): if resp.status == STATUS_ERROR: return RibBase.cli_resp_formatter(resp) ret = cls._format_family_header() for family, data in resp.value.items(): ret += 'Family: {0}\n'.format(family) ret += cls._format_family(data) return ret ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/operator/commands/show/route_formatter_mixin.py0000664000175000017500000000343100000000000032322 0ustar00zuulzuul00000000000000import io class RouteFormatterMixin(object): fmtstr = ' {0:<3s} {1:<32s} {2:<8s} {3:<20s} {4:<15s} '\ '{5:<6s} {6:<6s} {7:<}\n' @classmethod def _format_family_header(cls): ret = '' ret += ('Status codes: * valid, > best\n') ret += ('Origin codes: i - IGP, e - EGP, ? - incomplete\n') ret += cls.fmtstr.format('', 'Network', 'Labels', 'Next Hop', 'Reason', 'Metric', 'LocPrf', 'Path') return ret @classmethod def _format_family(cls, dest_list): msg = io.StringIO() def _append_path_info(buff, path, is_best, show_prefix): aspath = path.get('aspath') origin = path.get('origin') if origin: aspath.append(origin) bpr = path.get('bpr') next_hop = path.get('nexthop') med = path.get('metric') labels = path.get('labels') localpref = path.get('localpref') # Construct path status string. path_status = '*' if is_best: path_status += '>' # Check if we want to show prefix. prefix = '' if show_prefix: prefix = path.get('prefix') # Append path info to String buffer. buff.write(cls.fmtstr.format(path_status, prefix, str(labels), str(next_hop), bpr, str(med), str(localpref), ' '.join(map(str, aspath)))) for dist in dest_list: for idx, path in enumerate(dist.get('paths')): _append_path_info(msg, path, path['best'], (idx == 0)) ret = msg.getvalue() msg.close() return ret ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/operator/commands/show/vrf.py0000664000175000017500000001247700000000000026504 0ustar00zuulzuul00000000000000 import logging import pprint from os_ken.services.protocols.bgp.operator.command import Command from os_ken.services.protocols.bgp.operator.command import CommandsResponse from os_ken.services.protocols.bgp.operator.command import STATUS_ERROR from os_ken.services.protocols.bgp.operator.command import STATUS_OK from os_ken.services.protocols.bgp.operator.commands.responses import \ WrongParamResp from os_ken.services.protocols.bgp.operator.views.conf import ConfDetailView from os_ken.services.protocols.bgp.operator.views.conf import ConfDictView from .route_formatter_mixin import RouteFormatterMixin LOG = logging.getLogger('bgpspeaker.operator.commands.show.vrf') SUPPORTED_VRF_RF = ('ipv4', 'ipv6', 'evpn') class Routes(Command, RouteFormatterMixin): help_msg = 'show routes present for vrf' param_help_msg = ' %s' % str(SUPPORTED_VRF_RF) command = 'routes' def __init__(self, *args, **kwargs): super(Routes, self).__init__(*args, **kwargs) self.subcommands = { 'all': self.All, } def action(self, params): if len(params) != 2: return WrongParamResp() vrf_name = params[0] vrf_rf = params[1] if vrf_rf not in SUPPORTED_VRF_RF: return WrongParamResp('route-family not one of %s' % str(SUPPORTED_VRF_RF)) from os_ken.services.protocols.bgp.operator.internal_api import \ WrongParamError try: return CommandsResponse( STATUS_OK, self.api.get_single_vrf_routes(vrf_name, vrf_rf) ) except WrongParamError as e: return CommandsResponse( STATUS_ERROR, 'wrong parameters: %s' % str(e) ) @classmethod def cli_resp_formatter(cls, resp): if resp.status == STATUS_ERROR: return super(Routes, cls).cli_resp_formatter(resp) return cls._format_family_header() + cls._format_family(resp.value) class All(Command, RouteFormatterMixin): help_msg = 'show routes for all VRFs' command = 'all' def action(self, params): if len(params) != 0: return WrongParamResp() return CommandsResponse( STATUS_OK, self.api.get_all_vrf_routes() ) @classmethod def cli_resp_formatter(cls, resp): if resp.status == STATUS_ERROR: return Command.cli_resp_formatter(resp) ret = cls._format_family_header() for family, data in resp.value.items(): ret += 'VPN: {0}\n'.format(family) ret += cls._format_family(data) return ret class CountRoutesMixin(object): api = None # not assigned yet def _count_routes(self, vrf_name, vrf_rf): return len(self.api.get_single_vrf_routes(vrf_name, vrf_rf)) class Summary(Command, CountRoutesMixin): help_msg = 'show configuration and summary of vrf' param_help_msg = ' | all' command = 'summary' def __init__(self, *args, **kwargs): super(Summary, self).__init__(*args, **kwargs) self.subcommands = { 'all': self.All } def action(self, params): if len(params) == 0: return WrongParamResp('Not enough params') vrf_confs = self.api.get_vrfs_conf() if len(params) < 2: vrf_rf = 'ipv4' else: vrf_rf = params[1] vrf_key = params[0], vrf_rf if vrf_key in vrf_confs: view = ConfDetailView(vrf_confs[vrf_key]) encoded = view.encode() encoded['routes_count'] = self._count_routes(params[0], vrf_rf) else: return WrongParamResp('No vrf matched by %s' % str(vrf_key)) return CommandsResponse( STATUS_OK, encoded ) @classmethod def cli_resp_formatter(cls, resp): if resp.status == STATUS_ERROR: return Command.cli_resp_formatter(resp) return pprint.pformat(resp.value) class All(Command, CountRoutesMixin): command = 'all' help_msg = 'shows all vrfs configurations and summary' def action(self, params): vrf_confs = self.api.get_vrfs_conf() view = ConfDictView(vrf_confs) encoded = view.encode() for vrf_key, conf in encoded.items(): vrf_name, vrf_rf = vrf_key conf['routes_count'] = self._count_routes( vrf_name, vrf_rf ) encoded = dict([(str(k), v) for k, v in encoded.items()]) return CommandsResponse( STATUS_OK, encoded ) def _count_routes(self, vrf_name, vrf_rf): return len(self.api.get_single_vrf_routes(vrf_name, vrf_rf)) class Vrf(Routes): """Main node for vrf related commands. Acts also as Routes node (that's why it inherits from it) for legacy reasons. """ help_msg = 'vrf related commands subtree' command = 'vrf' def __init__(self, *args, **kwargs): super(Vrf, self).__init__(*args, **kwargs) self.subcommands.update({ 'routes': Routes, 'summary': Summary }) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/operator/internal_api.py0000664000175000017500000001661600000000000025572 0ustar00zuulzuul00000000000000import logging import traceback from os_ken.lib.packet.bgp import RouteFamily from os_ken.lib.packet.bgp import RF_IPv4_UC from os_ken.lib.packet.bgp import RF_IPv6_UC from os_ken.lib.packet.bgp import RF_IPv4_VPN from os_ken.lib.packet.bgp import RF_IPv6_VPN from os_ken.lib.packet.bgp import RF_L2_EVPN from os_ken.lib.packet.bgp import RF_IPv4_FLOWSPEC from os_ken.lib.packet.bgp import RF_IPv6_FLOWSPEC from os_ken.lib.packet.bgp import RF_VPNv4_FLOWSPEC from os_ken.lib.packet.bgp import RF_VPNv6_FLOWSPEC from os_ken.lib.packet.bgp import RF_L2VPN_FLOWSPEC from os_ken.lib.packet.bgp import RF_RTC_UC from os_ken.lib.packet.bgp import BGP_ATTR_TYPE_ORIGIN from os_ken.lib.packet.bgp import BGP_ATTR_TYPE_AS_PATH from os_ken.lib.packet.bgp import BGP_ATTR_TYPE_MULTI_EXIT_DISC from os_ken.lib.packet.bgp import BGP_ATTR_TYPE_LOCAL_PREF from os_ken.lib.packet.bgp import BGP_ATTR_ORIGIN_IGP from os_ken.lib.packet.bgp import BGP_ATTR_ORIGIN_EGP from os_ken.lib.packet.bgp import BGP_ATTR_ORIGIN_INCOMPLETE from os_ken.services.protocols.bgp.base import add_bgp_error_metadata from os_ken.services.protocols.bgp.base import BGPSException from os_ken.services.protocols.bgp.base import SUPPORTED_GLOBAL_RF from os_ken.services.protocols.bgp.core_manager import CORE_MANAGER LOG = logging.getLogger('bgpspeaker.operator.internal_api') INTERNAL_API_ERROR = 100 INTERNAL_API_SUB_ERROR = 101 class InternalApi(object): def __init__(self, log_handler=None): self.log_handler = log_handler def count_all_vrf_routes(self): vrf_tables = self._get_vrf_tables() ret = {} for key in vrf_tables.keys(): vrf_name, vrf_rf = key ret.update(self.count_single_vrf_routes(vrf_name, vrf_rf)) return ret def count_single_vrf_routes(self, vrf_name, vrf_rf): vrf = self._get_vrf_tables().get((vrf_name, vrf_rf)) if vrf is None: raise WrongParamError('wrong vpn key %s' % str((vrf_name, vrf_rf))) vrf_name = vrf_name.encode('ascii', 'ignore') route_count = \ len([d for d in vrf.values() if d.best_path]) return {str((vrf_name, vrf_rf)): route_count} def get_vrfs_conf(self): return CORE_MANAGER.vrfs_conf.vrfs_by_rd_rf_id def get_all_vrf_routes(self): vrfs = self._get_vrf_tables() ret = {} for (vrf_id, vrf_rf), table in sorted(vrfs.items()): ret[str((vrf_id, vrf_rf))] = self._get_single_vrf_routes(table) return ret def get_single_vrf_routes(self, vrf_id, vrf_rf): vrf = self._get_vrf_table(vrf_id, vrf_rf) if not vrf: raise WrongParamError('wrong vpn name %s' % str((vrf_id, vrf_rf))) return [self._dst_to_dict(d) for d in vrf.values()] def _get_single_vrf_routes(self, vrf_table): return [self._dst_to_dict(d) for d in vrf_table.values()] def _get_vrf_table(self, vrf_name, vrf_rf): return CORE_MANAGER.get_core_service()\ .table_manager.get_vrf_table(vrf_name, vrf_rf) def _get_vrf_tables(self): return CORE_MANAGER.get_core_service().table_manager.get_vrf_tables() def get_single_rib_routes(self, addr_family): rfs = { 'ipv4': RF_IPv4_UC, 'ipv6': RF_IPv6_UC, 'vpnv4': RF_IPv4_VPN, 'vpnv6': RF_IPv6_VPN, 'evpn': RF_L2_EVPN, 'ipv4fs': RF_IPv4_FLOWSPEC, 'ipv6fs': RF_IPv6_FLOWSPEC, 'vpnv4fs': RF_VPNv4_FLOWSPEC, 'vpnv6fs': RF_VPNv6_FLOWSPEC, 'l2vpnfs': RF_L2VPN_FLOWSPEC, 'rtfilter': RF_RTC_UC } if addr_family not in rfs: raise WrongParamError('Unknown or unsupported family: %s' % addr_family) rf = rfs.get(addr_family) table_manager = self.get_core_service().table_manager gtable = table_manager.get_global_table_by_route_family(rf) if gtable is not None: return [self._dst_to_dict(dst) for dst in sorted(gtable.values())] else: return [] def _dst_to_dict(self, dst): ret = {'paths': [], 'prefix': dst.nlri_str} def _path_to_dict(dst, path): path_seg_list = path.get_pattr(BGP_ATTR_TYPE_AS_PATH).path_seg_list if isinstance(path_seg_list, list): aspath = [] for as_path_seg in path_seg_list: for as_num in as_path_seg: aspath.append(as_num) else: aspath = '' origin = path.get_pattr(BGP_ATTR_TYPE_ORIGIN) origin = origin.value if origin else None if origin == BGP_ATTR_ORIGIN_IGP: origin = 'i' elif origin == BGP_ATTR_ORIGIN_EGP: origin = 'e' elif origin == BGP_ATTR_ORIGIN_INCOMPLETE: origin = '?' nexthop = path.nexthop # Get the MED path attribute med = path.get_pattr(BGP_ATTR_TYPE_MULTI_EXIT_DISC) med = med.value if med else '' # Get best path reason bpr = dst.best_path_reason if path == dst.best_path else '' # Get local preference localpref = path.get_pattr(BGP_ATTR_TYPE_LOCAL_PREF) localpref = localpref.value if localpref else '' if hasattr(path.nlri, 'label_list'): labels = path.nlri.label_list else: labels = None return {'best': (path == dst.best_path), 'bpr': bpr, 'prefix': path.nlri_str, 'labels': labels, 'nexthop': nexthop, 'metric': med, 'aspath': aspath, 'origin': origin, 'localpref': localpref} for path in dst.known_path_list: ret['paths'].append(_path_to_dict(dst, path)) return ret def check_logging(self): return self.log_handler and self._has_log_handler(self.log_handler) def check_logging_level(self): return logging.getLevelName(self.log_handler.level) def _has_log_handler(self, log_handler): if log_handler in logging.getLogger('bgpspeaker').handlers: return True return False def route_refresh(self, peer_ip=None, afi=None, safi=None): if not peer_ip: peer_ip = 'all' try: route_families = [] if afi is None and safi is None: route_families.extend(SUPPORTED_GLOBAL_RF) else: route_family = RouteFamily(afi, safi) if route_family not in SUPPORTED_GLOBAL_RF: raise WrongParamError('Not supported address-family' ' %s, %s' % (afi, safi)) route_families.append(route_family) pm = CORE_MANAGER.get_core_service().peer_manager pm.make_route_refresh_request(peer_ip, *route_families) except Exception as e: LOG.error(traceback.format_exc()) raise WrongParamError(str(e)) return None def get_core_service(self): return CORE_MANAGER.get_core_service() @add_bgp_error_metadata(code=INTERNAL_API_ERROR, sub_code=INTERNAL_API_SUB_ERROR, def_desc='Unknown internal api exception.') class WrongParamError(BGPSException): pass ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/operator/ssh.py0000664000175000017500000004176200000000000023722 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013 YAMAMOTO Takashi # # 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. """ CLI application for SSH management. """ from copy import copy import logging import os.path import sys import paramiko from os_ken import version from os_ken.lib import hub from os_ken.services.protocols.bgp.base import Activity from os_ken.services.protocols.bgp.operator.command import Command from os_ken.services.protocols.bgp.operator.command import CommandsResponse from os_ken.services.protocols.bgp.operator.command import STATUS_OK from os_ken.services.protocols.bgp.operator.commands.root import RootCmd from os_ken.services.protocols.bgp.operator.internal_api import InternalApi SSH_PORT = "ssh_port" SSH_HOST = "ssh_host" SSH_HOST_KEY = "ssh_host_key" SSH_USERNAME = "ssh_username" SSH_PASSWORD = "ssh_password" DEFAULT_SSH_PORT = 4990 DEFAULT_SSH_HOST = "localhost" DEFAULT_SSH_HOST_KEY = None DEFAULT_SSH_USERNAME = "os_ken" DEFAULT_SSH_PASSWORD = "os_ken" CONF = { SSH_PORT: DEFAULT_SSH_PORT, SSH_HOST: DEFAULT_SSH_HOST, SSH_HOST_KEY: DEFAULT_SSH_HOST_KEY, SSH_USERNAME: DEFAULT_SSH_USERNAME, SSH_PASSWORD: DEFAULT_SSH_PASSWORD, } LOG = logging.getLogger('bgpspeaker.cli') def find_ssh_server_key(): if CONF[SSH_HOST_KEY]: return paramiko.RSAKey.from_private_key_file(CONF[SSH_HOST_KEY]) elif os.path.exists("/etc/ssh_host_rsa_key"): # OSX return paramiko.RSAKey.from_private_key_file( "/etc/ssh_host_rsa_key") elif os.path.exists("/etc/ssh/ssh_host_rsa_key"): # Linux return paramiko.RSAKey.from_private_key_file( "/etc/ssh/ssh_host_rsa_key") else: return paramiko.RSAKey.generate(1024) class SshServer(paramiko.ServerInterface): TERM = "ansi" PROMPT = "bgpd> " WELCOME = "\n\rHello, this is OSKen BGP speaker (version %s).\n\r" % version class HelpCmd(Command): help_msg = 'show this help' command = 'help' def action(self, params): return self.parent_cmd.question_mark()[0] class QuitCmd(Command): help_msg = 'exit this session' command = 'quit' def action(self, params): self.api.sshserver.end_session() return CommandsResponse(STATUS_OK, True) def __init__(self, sock, addr): super(SshServer, self).__init__() self.sock = sock self.addr = addr self.is_connected = True # For pylint self.buf = None self.chan = None self.curpos = None self.histindex = None self.history = None self.prompted = None self.promptlen = None # tweak InternalApi and RootCmd for non-bgp related commands self.api = InternalApi(log_handler=logging.StreamHandler(sys.stderr)) setattr(self.api, 'sshserver', self) self.root = RootCmd(self.api) self.root.subcommands['help'] = self.HelpCmd self.root.subcommands['quit'] = self.QuitCmd self.transport = paramiko.Transport(self.sock) self.transport.load_server_moduli() host_key = find_ssh_server_key() self.transport.add_server_key(host_key) self.transport.start_server(server=self) def check_auth_none(self, username): return paramiko.AUTH_SUCCESSFUL def check_auth_password(self, username, password): if (username == CONF[SSH_USERNAME] and password == CONF[SSH_PASSWORD]): return paramiko.AUTH_SUCCESSFUL return paramiko.AUTH_FAILED def check_channel_request(self, kind, chanid): if kind == 'session': return paramiko.OPEN_SUCCEEDED return paramiko.OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED def check_channel_shell_request(self, channel): hub.spawn(self._handle_shell_request) return True def check_channel_pty_request(self, channel, term, width, height, pixelwidth, pixelheight, modes): self.TERM = term return True def check_channel_window_change_request(self, channel, width, height, pixelwidth, pixelheight): return True @staticmethod def _is_echoable(c): return not (c < chr(0x20) or c == chr(0x7F)) @staticmethod def _is_enter(c): return c == chr(0x0d) @staticmethod def _is_eof(c): return c == chr(0x03) @staticmethod def _is_esc(c): return c == chr(0x1b) @staticmethod def _is_hist(c): return c == chr(0x10) or c == chr(0x0e) @staticmethod def _is_del(c): return (c == chr(0x04) or c == chr(0x08) or c == chr(0x15) or c == chr(0x17) or c == chr(0x0c) or c == chr(0x7f)) @staticmethod def _is_curmov(c): return c == chr(0x01) or c == chr(0x02) or c == chr(0x05) \ or c == chr(0x06) @staticmethod def _is_cmpl(c): return c == chr(0x09) def _handle_csi_seq(self): c = self.chan.recv(1) c = c.decode() # For Python3 compatibility if c == 'A': self._lookup_hist_up() elif c == 'B': self._lookup_hist_down() elif c == 'C': self._movcursor(self.curpos + 1) elif c == 'D': self._movcursor(self.curpos - 1) else: LOG.error("unknown CSI sequence. do nothing: %c", c) def _handle_esc_seq(self): c = self.chan.recv(1) c = c.decode() # For Python3 compatibility if c == '[': self._handle_csi_seq() else: LOG.error("non CSI sequence. do nothing") def _send_csi_seq(self, cmd): self.chan.send('\x1b[' + cmd) def _movcursor(self, curpos): if self.prompted and curpos < len(self.PROMPT): self.curpos = len(self.PROMPT) elif self.prompted and curpos > (len(self.PROMPT) + len(self.buf)): self.curpos = len(self.PROMPT) + len(self.buf) else: self._send_csi_seq('%dG' % (curpos + 1)) self.curpos = curpos def _clearscreen(self, prompt=None): if not prompt and self.prompted: prompt = self.PROMPT # clear screen self._send_csi_seq('2J') # move cursor to the top self._send_csi_seq('d') # redraw prompt and buf self._refreshline(prompt=prompt) def _clearline(self, prompt=None): if not prompt and self.prompted: prompt = self.PROMPT self.prompted = False self._movcursor(0) self._send_csi_seq('2K') if prompt: self.prompted = True self.chan.send(prompt) self._movcursor(len(prompt)) self.buf = [] def _refreshline(self, prompt=None): if not prompt and self.prompted: prompt = self.PROMPT buf = copy(self.buf) curpos = copy(self.curpos) self._clearline(prompt=prompt) self.chan.send(''.join(buf)) self.buf = buf self.curpos = curpos self._movcursor(curpos) def _refreshnewline(self, prompt=None): if not prompt and self.prompted: prompt = self.PROMPT buf = copy(self.buf) curpos = copy(self.curpos) self._startnewline(prompt) self.chan.send(''.join(buf)) self.buf = buf self.curpos = curpos self._movcursor(curpos) def _startnewline(self, prompt=None, buf=None): buf = buf or [] if not prompt and self.prompted: prompt = self.PROMPT if isinstance(buf, str): buf = list(buf) if self.chan: self.buf = buf if prompt: self.chan.send('\n\r' + prompt + ''.join(buf)) self.curpos = len(prompt) + len(buf) self.prompted = True else: self.chan.send('\n\r' + ''.join(buf)) self.curpos = len(buf) self.prompted = False def _lookup_hist_up(self): if len(self.history) == 0: return self.buf = self.history[self.histindex] self.curpos = self.promptlen + len(self.buf) self._refreshline() if self.histindex + 1 < len(self.history): self.histindex += 1 def _lookup_hist_down(self): if self.histindex > 0: self.histindex -= 1 self.buf = self.history[self.histindex] self.curpos = self.promptlen + len(self.buf) self._refreshline() else: self._clearline() def _do_cmpl(self, buf, is_exec=False): cmpleter = self.root is_spaced = buf[-1] == ' ' if len(buf) > 0 else False cmds = [tkn.strip() for tkn in ''.join(buf).split()] ret = [] for i, cmd in enumerate(cmds): subcmds = cmpleter.subcommands matches = [x for x in subcmds.keys() if x.startswith(cmd)] if len(matches) == 1: cmpled_cmd = matches[0] cmpleter = subcmds[cmpled_cmd](self.api) if is_exec: ret.append(cmpled_cmd) continue if (i + 1) == len(cmds): if is_spaced: result, cmd = cmpleter('?') result = result.value.replace('\n', '\n\r').rstrip() self.prompted = False buf = copy(buf) self._startnewline(buf=result) self.prompted = True self._startnewline(buf=buf) else: self.buf = buf[:(-1 * len(cmd))] + \ list(cmpled_cmd + ' ') self.curpos += len(cmpled_cmd) - len(cmd) + 1 self._refreshline() else: self.prompted = False buf = copy(self.buf) if len(matches) == 0: if cmpleter.param_help_msg: self.prompted = True ret.append(cmd) continue else: self._startnewline(buf='Error: Not implemented') else: if (i + 1) < len(cmds): self._startnewline(buf='Error: Ambiguous command') else: self._startnewline(buf=', '.join(matches)) ret = [] self.prompted = True if not is_exec: self._startnewline(buf=buf) break return ret def _execute_cmd(self, cmds): result, _ = self.root(cmds) LOG.debug("result: %s", result) if cmds[0] == 'quit': self.is_connected = False return result.status self.prompted = False self._startnewline() output = result.value.replace('\n', '\n\r').rstrip() self.chan.send(output) self.prompted = True self._startnewline() return result.status def end_session(self): self._startnewline(prompt=False, buf='bye.\n\r') self.chan.close() def _handle_shell_request(self): LOG.info("session start") chan = self.transport.accept(20) if not chan: LOG.info("transport.accept timed out") return self.chan = chan self.buf = [] self.curpos = 0 self.history = [] self.histindex = 0 self.prompted = True self.chan.send(self.WELCOME) self._startnewline() while self.is_connected: c = self.chan.recv(1) c = c.decode() # For Python3 compatibility if len(c) == 0: break LOG.debug("ord:%d, hex:0x%x", ord(c), ord(c)) self.promptlen = len(self.PROMPT) if self.prompted else 0 if c == '?': cmpleter = self.root cmds = [tkn.strip() for tkn in ''.join(self.buf).split()] for i, cmd in enumerate(cmds): subcmds = cmpleter.subcommands matches = [x for x in subcmds.keys() if x.startswith(cmd)] if len(matches) == 1: cmpled_cmd = matches[0] cmpleter = subcmds[cmpled_cmd](self.api) result, cmd = cmpleter('?') result = result.value.replace('\n', '\n\r').rstrip() self.prompted = False buf = copy(self.buf) self._startnewline(buf=result) self.prompted = True self._startnewline(buf=buf) elif self._is_echoable(c): self.buf.insert(self.curpos - self.promptlen, c) self.curpos += 1 self._refreshline() elif self._is_esc(c): self._handle_esc_seq() elif self._is_eof(c): self.end_session() elif self._is_curmov(c): # if c == chr(0x01): self._movcursor(self.promptlen) # elif c == chr(0x02): self._movcursor(self.curpos - 1) # elif c == chr(0x05): self._movcursor(self.promptlen + len(self.buf)) # elif c == chr(0x06): self._movcursor(self.curpos + 1) else: LOG.error("unknown cursor move cmd.") continue elif self._is_hist(c): # if c == chr(0x10): self._lookup_hist_up() # elif c == chr(0x0e): self._lookup_hist_down() elif self._is_del(c): # if c == chr(0x04): if self.curpos < (self.promptlen + len(self.buf)): self.buf.pop(self.curpos - self.promptlen) self._refreshline() # or delete elif c == chr(0x08) or c == chr(0x7f): if self.curpos > self.promptlen: self.buf.pop(self.curpos - self.promptlen - 1) self.curpos -= 1 self._refreshline() # elif c == chr(0x15): self._clearline() # elif c == chr(0x17): pos = self.curpos - self.promptlen i = pos flag = False for c in reversed(self.buf[:pos]): if flag and c == ' ': break if c != ' ': flag = True i -= 1 del self.buf[i:pos] self.curpos = self.promptlen + i self._refreshline() # elif c == chr(0x0c): self._clearscreen() elif self._is_cmpl(c): self._do_cmpl(self.buf) elif self._is_enter(c): if len(''.join(self.buf).strip()) != 0: # cmd line interpretation cmds = self._do_cmpl(self.buf, is_exec=True) if cmds: self.history.insert(0, self.buf) self.histindex = 0 self._execute_cmd(cmds) else: LOG.debug("no command is interpreted. " "just start a new line.") self._startnewline() else: LOG.debug("blank buf is detected. " "just start a new line.") self._startnewline() LOG.debug("curpos: %d, buf: %s, prompted: %s", self.curpos, self.buf, self.prompted) LOG.info("session end") def ssh_server_factory(sock, addr): SshServer(sock, addr) class Cli(Activity): def __init__(self): super(Cli, self).__init__() def _run(self, *args, **kwargs): for k, v in kwargs.items(): if k in CONF: CONF[k] = v listen_info = (CONF[SSH_HOST], CONF[SSH_PORT]) LOG.info("starting ssh server at %s:%d" % listen_info) server = hub.StreamServer(listen_info, ssh_server_factory) server.serve_forever() SSH_CLI_CONTROLLER = Cli() ././@PaxHeader0000000000000000000000000000003300000000000011451 xustar000000000000000027 mtime=1724334546.114106 os-ken-2.10.0/os_ken/services/protocols/bgp/operator/views/0000775000175000017500000000000000000000000023676 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/operator/views/__init__.py0000664000175000017500000000002300000000000026002 0ustar00zuulzuul00000000000000__author__ = 'yak' ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/operator/views/base.py0000664000175000017500000002374200000000000025172 0ustar00zuulzuul00000000000000""" This module's purpose is to enable us to present internals of objects in well-defined way to operator. To do this we can define "views" on some objects. View is a definition of how to present object and relations to other objects which also have their views defined. By using views we can avoid making all interesting internal values public. They will stay private and only "view" will access them (think friend-class from C++) """ import logging from os_ken.services.protocols.bgp.operator.views import fields LOG = logging.getLogger('bgpspeaker.operator.views.base') class RdyToFlattenCollection(object): pass class RdyToFlattenList(list, RdyToFlattenCollection): pass class RdyToFlattenDict(dict, RdyToFlattenCollection): pass class OperatorAbstractView(object): """Abstract base class for operator views. It isn't meant to be instantiated. """ def __init__(self, obj, filter_func=None): """Init :param obj: data model for view. In other words object we are creating view for. In case of ListView it should be a list and in case of DictView it should be a dict. :param filter_func: function to filter models """ self._filter_func = filter_func self._fields = self._collect_fields() self._obj = obj @classmethod def _collect_fields(cls): names = [attr for attr in dir(cls) if isinstance(getattr(cls, attr), fields.Field)] return dict([(name, getattr(cls, name)) for name in names]) def combine_related(self, field_name): """Combines related views. In case of DetailView it just returns one-element list containing related view wrapped in CombinedViewsWrapper. In case of ListView and DictView it returns a list of related views for every element of model collection also wrapped in CombinedViewsWrapper. :param field_name: field name of related view :returns: vectorized form of related views. You can access them as if you had only one view and you will receive flattened list of responses from related views. Look at docstring of CombinedViewsWrapper """ raise NotImplementedError() def c_rel(self, *args, **kwargs): """Shortcut for combine_related. Look above """ return self.combine_related(*args, **kwargs) def get_field(self, field_name): """Get value of data field. :return: value of data-field of this view """ raise NotImplementedError() def encode(self): """Representation of view which is using only python standard types. :return: dict representation of this views data. However it doesn't have to be a dict. In case of ListView it would return a list. It should return wrapped types for list - RdyToFlattenList, for dict - RdyToFlattenDict """ raise NotImplementedError() @property def model(self): """Getter for data model being presented by this view. Every view is associated with some data model. :return: underlaying data of this view """ raise NotImplementedError() def apply_filter(self, filter_func): """Sets filter function to apply on model :param filter_func: function which takes the model and returns it filtered """ self._filter_func = filter_func def clear_filter(self): self._filter_func = None class OperatorDetailView(OperatorAbstractView): def combine_related(self, field_name): f = self._fields[field_name] return CombinedViewsWrapper([f.retrieve_and_wrap(self._obj)]) def get_field(self, field_name): f = self._fields[field_name] return f.get(self._obj) def encode(self): encoded = {} for field_name, field in self._fields.items(): if isinstance(field, fields.DataField): encoded[field_name] = field.get(self._obj) return encoded def rel(self, field_name): f = self._fields[field_name] return f.retrieve_and_wrap(self._obj) @property def model(self): return self._obj class OperatorListView(OperatorAbstractView): def __init__(self, obj, filter_func=None): assert isinstance(obj, list) obj = RdyToFlattenList(obj) super(OperatorListView, self).__init__(obj, filter_func) def combine_related(self, field_name): f = self._fields[field_name] return CombinedViewsWrapper(RdyToFlattenList( [f.retrieve_and_wrap(obj) for obj in self.model] )) def get_field(self, field_name): f = self._fields[field_name] return RdyToFlattenList([f.get(obj) for obj in self.model]) def encode(self): encoded_list = [] for obj in self.model: encoded_item = {} for field_name, field in self._fields.items(): if isinstance(field, fields.DataField): encoded_item[field_name] = field.get(obj) encoded_list.append(encoded_item) return RdyToFlattenList(encoded_list) @property def model(self): if self._filter_func is not None: return RdyToFlattenList(filter(self._filter_func, self._obj)) else: return self._obj class OperatorDictView(OperatorAbstractView): def __init__(self, obj, filter_func=None): assert isinstance(obj, dict) obj = RdyToFlattenDict(obj) super(OperatorDictView, self).__init__(obj, filter_func) def combine_related(self, field_name): f = self._fields[field_name] return CombinedViewsWrapper(RdyToFlattenList( [f.retrieve_and_wrap(obj) for obj in self.model.values()]) ) def get_field(self, field_name): f = self._fields[field_name] dict_to_flatten = {} for key, obj in self.model.items(): dict_to_flatten[key] = f.get(obj) return RdyToFlattenDict(dict_to_flatten) def encode(self): outer_dict_to_flatten = {} for key, obj in self.model.items(): inner_dict_to_flatten = {} for field_name, field in self._fields.items(): if isinstance(field, fields.DataField): inner_dict_to_flatten[field_name] = field.get(obj) outer_dict_to_flatten[key] = inner_dict_to_flatten return RdyToFlattenDict(outer_dict_to_flatten) @property def model(self): if self._filter_func is not None: new_model = RdyToFlattenDict() for k, v in self._obj.items(): if self._filter_func(k, v): new_model[k] = v return new_model else: return self._obj class CombinedViewsWrapper(RdyToFlattenList): """List-like wrapper for views. It provides same interface as any other views but enables as to access all views in bulk. It wraps and return responses from all views as a list. Be aware that in case of DictViews wrapped in CombinedViewsWrapper you loose information about dict keys. """ def __init__(self, obj): super(CombinedViewsWrapper, self).__init__(obj) self._obj = obj def combine_related(self, field_name): return CombinedViewsWrapper( list(_flatten( [obj.combine_related(field_name) for obj in self._obj] )) ) def c_rel(self, *args, **kwargs): return self.combine_related(*args, **kwargs) def encode(self): return list(_flatten([obj.encode() for obj in self._obj])) def get_field(self, field_name): return list(_flatten([obj.get_field(field_name) for obj in self._obj])) @property def model(self): return list(_flatten([obj.model for obj in self._obj])) def apply_filter(self, filter_func): for obj in self._obj: obj.apply_filter(filter_func) def clear_filter(self): for obj in self._obj: obj.clear_filter() def _flatten(l, max_level=10): """Generator function going deep in tree-like structures (i.e. dicts in dicts or lists in lists etc.) and returning all elements as a flat list. It's flattening only lists and dicts which are subclasses of RdyToFlattenCollection. Regular lists and dicts are treated as a single items. :param l: some iterable to be flattened :return: flattened iterator """ if max_level >= 0: _iter = l.values() if isinstance(l, dict) else l for el in _iter: if isinstance(el, RdyToFlattenCollection): for sub in _flatten(el, max_level=max_level - 1): yield sub else: yield el else: yield l def _create_collection_view(detail_view_class, name, encode=None, view_class=None): assert issubclass(detail_view_class, OperatorDetailView) class_fields = detail_view_class._collect_fields() if encode is not None: class_fields.update({'encode': encode}) return type(name, (view_class,), class_fields) # function creating ListView from DetailView def create_dict_view_class(detail_view_class, name): encode = None if 'encode' in dir(detail_view_class): def encode(self): dict_to_flatten = {} for key, obj in self.model.items(): dict_to_flatten[key] = detail_view_class(obj).encode() return RdyToFlattenDict(dict_to_flatten) return _create_collection_view( detail_view_class, name, encode, OperatorDictView ) # function creating DictView from DetailView def create_list_view_class(detail_view_class, name): encode = None if 'encode' in dir(detail_view_class): def encode(self): return RdyToFlattenList([detail_view_class(obj).encode() for obj in self.model]) return _create_collection_view( detail_view_class, name, encode, OperatorListView ) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/operator/views/bgp.py0000664000175000017500000002515700000000000025032 0ustar00zuulzuul00000000000000from os_ken.services.protocols.bgp.operator.views.base import \ create_dict_view_class from os_ken.services.protocols.bgp.operator.views.base import \ create_list_view_class from os_ken.services.protocols.bgp.operator.views.base import OperatorDetailView from os_ken.services.protocols.bgp.operator.views import fields from os_ken.lib.packet.bgp import BGP_ATTR_TYPE_AS_PATH from os_ken.lib.packet.bgp import BGP_ATTR_TYPE_ORIGIN from os_ken.lib.packet.bgp import BGP_ATTR_TYPE_MULTI_EXIT_DISC from os_ken.lib.packet.bgp import BGP_ATTR_TYPE_LOCAL_PREF from os_ken.lib.packet.bgp import BGP_ATTR_TYPE_EXTENDED_COMMUNITIES class CoreServiceDetailView(OperatorDetailView): rf_state = fields.RelatedViewField( 'rf_state', 'os_ken.services.protocols.bgp.operator.views.bgp.RfStateDetailView' ) importmap_manager = fields.RelatedDictViewField( '_importmap_manager', 'os_ken.services.protocols.bgp.operator' '.views.other.ImportmapManagerDetailView' ) table_manager = fields.RelatedViewField( '_table_manager', 'os_ken.services.protocols.bgp.operator.views.bgp.TableManagerDetailView' ) peer_manager = fields.RelatedViewField( '_peer_manager', 'os_ken.services.protocols.bgp.operator.views.bgp.PeerManagerDetailView' ) router_id = fields.DataField('router_id') class TableManagerDetailView(OperatorDetailView): tables = fields.RelatedDictViewField( '_tables', 'os_ken.services.protocols.bgp.operator.views.bgp.TableDictView' ) tables_for_rt = fields.RelatedDictViewField( '_tables_for_rt', 'os_ken.services.protocols.bgp.operator.views.bgp.TableDictView' ) global_tables = fields.RelatedDictViewField( '_global_tables', 'os_ken.services.protocols.bgp.operator.views.bgp.TableDictView' ) asbr_label_range = fields.DataField('_asbr_label_range') next_hop_label = fields.DataField('_next_hop_label') next_vpnv4_label = fields.DataField('_next_vpnv4_label') class PeerManagerDetailView(OperatorDetailView): peers = fields.RelatedListViewField( '_peers', 'os_ken.services.protocols.bgp.operator.views.bgp.PeerDictView' ) peers_summary = fields.RelatedListViewField( '_peers', 'os_ken.services.protocols.bgp.operator.views.bgp.PeerDictSummaryView' ) class RfStateDetailView(OperatorDetailView): pass class PeerStateDetailView(OperatorDetailView): bgp_state = fields.DataField('_bgp_state') last_error = fields.DataField('_last_bgp_error') def encode(self): ret = super(PeerStateDetailView, self).encode() ret.update(self._obj.get_stats_summary_dict()) return ret class PeerDetailView(OperatorDetailView): remote_as = fields.DataField('remote_as') ip_address = fields.DataField('ip_address') enabled = fields.DataField('enabled') adj_rib_in = fields.RelatedViewField( 'adj_rib_in', 'os_ken.services.protocols.bgp.operator.views.bgp.ReceivedRouteDictView' ) adj_rib_out = fields.RelatedViewField( 'adj_rib_out', 'os_ken.services.protocols.bgp.operator.views.bgp.SentRouteDictView' ) neigh_conf = fields.RelatedViewField( '_neigh_conf', 'os_ken.services.protocols.bgp.operator.views.conf.ConfDetailView' ) common_conf = fields.RelatedViewField( '_common_conf', 'os_ken.services.protocols.bgp.operator.views.conf.ConfDetailView' ) state = fields.RelatedViewField( 'state', 'os_ken.services.protocols.bgp.operator.views.bgp.PeerStateDetailView' ) def encode(self): ret = super(PeerDetailView, self).encode() ret.update({ 'stats': self.rel('state').encode(), 'settings': self.rel('neigh_conf').encode() }) return ret class PeerDetailSummaryView(PeerDetailView): def encode(self): return { 'conf': self.rel('neigh_conf').encode(), 'info': self.rel('state').encode() } class PeerRfDetailView(OperatorDetailView): rf = fields.DataField('rf') enabled = fields.DataField('enabled') peer = fields.RelatedViewField( 'peer', 'os_ken.services.protocols.bgp.operator.views.bgp.PeerDetailView' ) class TableDetailView(OperatorDetailView): scope_id = fields.DataField('scope_id') route_family = fields.DataField('route_family') destinations = fields.RelatedDictViewField( '_destinations', 'os_ken.services.protocols.bgp.operator.views.bgp.DestinationDictView' ) class PathDetailView(OperatorDetailView): source_version_num = fields.DataField('source_version_num') route_family = fields.RelatedViewField( 'route_family', 'os_ken.services.protocols.bgp.operator.views.bgp.RouteFamilyView' ) nlri = fields.RelatedViewField( 'nlri', 'os_ken.services.protocols.bgp.operator.views.bgp.NlriDetailView' ) is_withdraw = fields.DataField('is_withdraw') nexthop = fields.DataField('nexthop') pathattr_map = fields.DataField('pathattr_map') source = fields.RelatedViewField( 'source', 'os_ken.services.protocols.bgp.operator.views.bgp.PeerDetailView' ) def encode(self): ret = super(PathDetailView, self).encode() ret['nlri'] = self.rel('nlri').encode() ret['route_family'] = self.rel('route_family').encode() as_path = self.get_field('pathattr_map').get(BGP_ATTR_TYPE_AS_PATH) origin = self.get_field('pathattr_map').get(BGP_ATTR_TYPE_ORIGIN) metric = self.get_field('pathattr_map').get( BGP_ATTR_TYPE_MULTI_EXIT_DISC) local_pref = self.get_field('pathattr_map').get( BGP_ATTR_TYPE_LOCAL_PREF ) ret['as_path'] = as_path.value if as_path else None ret['origin'] = origin.value if origin else None ret['metric'] = metric.value if metric else None ret['local_pref'] = local_pref.value if local_pref else None ext = ret['pathattr_map'].get(BGP_ATTR_TYPE_EXTENDED_COMMUNITIES) del ret['pathattr_map'] if ext: ret['rt_list'] = ext.rt_list ret['soo_list'] = ext.soo_list return ret class SentRouteDetailView(OperatorDetailView): timestamp = fields.DataField('timestamp') filtered = fields.DataField('filtered') path = fields.RelatedViewField( 'path', 'os_ken.services.protocols.bgp.operator.views.bgp.PathDetailView', ) peer = fields.RelatedViewField( 'sent_peer', 'os_ken.services.protocols.bgp.operator.views.bgp.PeerDetailView' ) def encode(self): ret = super(SentRouteDetailView, self).encode() ret.update({ 'path': self.rel('path').encode(), }) return ret class ReceivedRouteDetailView(OperatorDetailView): timestamp = fields.DataField('timestamp') filtered = fields.DataField('filtered') path = fields.RelatedViewField( 'path', 'os_ken.services.protocols.bgp.operator.views.bgp.PathDetailView', ) peer = fields.RelatedViewField( 'received_peer', 'os_ken.services.protocols.bgp.operator.views.bgp.PeerDetailView' ) def encode(self): ret = super(ReceivedRouteDetailView, self).encode() ret.update({ 'path': self.rel('path').encode(), }) return ret class DestinationDetailView(OperatorDetailView): table = fields.RelatedViewField( '_table', 'os_ken.services.protocols.bgp.operator.views.bgp.TableDetailView', ) best_path = fields.RelatedViewField( 'best_path', 'os_ken.services.protocols.bgp.operator.views.bgp.PathDetailView' ) known_path_list = fields.RelatedListViewField( 'known_path_list', 'os_ken.services.protocols.bgp.operator.views.bgp.PathListView' ) new_path_list = fields.RelatedListViewField( '_new_path_list', 'os_ken.services.protocols.bgp.operator.views.bgp.PathListView' ) withdraw_list = fields.RelatedListViewField( '_withdraw_list', 'os_ken.services.protocols.bgp.operator.views.bgp.PathListView' ) sent_routes = fields.RelatedListViewField( 'sent_routes', 'os_ken.services.protocols.bgp.operator.views.bgp.SentRouteListView' ) nlri = fields.DataField('nlri') route_family = fields.DataField('route_family') class IpNlriDetailView(OperatorDetailView): formatted_nlri = fields.DataField('formatted_nlri_str') prefix = fields.DataField('prefix') class VpnNlriDetailView(IpNlriDetailView): labels = fields.DataField('label_list') rd = fields.DataField('route_dist') class NlriDetailView(OperatorDetailView): def __new__(cls, obj, filter_func=None): from os_ken.lib.packet.bgp import LabelledVPNIPAddrPrefix from os_ken.lib.packet.bgp import LabelledVPNIP6AddrPrefix from os_ken.lib.packet.bgp import IPAddrPrefix, IP6AddrPrefix if isinstance(obj, (LabelledVPNIPAddrPrefix, LabelledVPNIP6AddrPrefix)): return VpnNlriDetailView(obj) elif isinstance(obj, (IPAddrPrefix, IP6AddrPrefix)): return IpNlriDetailView(obj) else: return OperatorDetailView(obj, filter_func) def encode(self): return self._obj.formatted_nlri_str class RouteFamilyView(OperatorDetailView): afi = fields.DataField('afi') safi = fields.DataField('safi') ################################################################## # Declarations of list and dict views based on detail views above ################################################################## PeerListView = create_list_view_class(PeerDetailView, 'PeerListView') PeerDictView = create_dict_view_class(PeerDetailView, 'PeerDictView') PeerListSummaryView = create_list_view_class( PeerDetailSummaryView, 'PeerListSummaryView' ) PeerDictSummaryView = create_dict_view_class( PeerDetailSummaryView, 'PeerDictSummaryView' ) TableDictView = create_dict_view_class(TableDetailView, 'TableDictView') DestinationListView = create_list_view_class( DestinationDetailView, 'DestinationListView' ) DestinationDictView = create_dict_view_class( DestinationDetailView, 'DestinationDictView' ) PathListView = create_list_view_class(PathDetailView, 'PathListView') PathDictView = create_dict_view_class(PathDetailView, 'PathDictView') SentRouteListView = create_list_view_class( SentRouteDetailView, 'SentRouteListView' ) SentRouteDictView = create_dict_view_class( SentRouteDetailView, 'SentRouteDictView' ) ReceivedRouteDictView = create_dict_view_class( ReceivedRouteDetailView, 'ReceivedRouteDictView' ) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/operator/views/conf.py0000664000175000017500000000071600000000000025201 0ustar00zuulzuul00000000000000from os_ken.services.protocols.bgp.operator.views.base import \ create_dict_view_class from os_ken.services.protocols.bgp.operator.views.base import OperatorDetailView from os_ken.services.protocols.bgp.operator.views import fields class ConfDetailView(OperatorDetailView): settings = fields.DataField('_settings') def encode(self): return self.get_field('settings') ConfDictView = create_dict_view_class(ConfDetailView, 'ConfDictView') ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/operator/views/fields.py0000664000175000017500000000351400000000000025521 0ustar00zuulzuul00000000000000import importlib import inspect class Field(object): def __init__(self, field_name): self.field_name = field_name def get(self, obj): return getattr(obj, self.field_name) class RelatedViewField(Field): def __init__(self, field_name, operator_view_class): super(RelatedViewField, self).__init__(field_name) self.__operator_view_class = operator_view_class @property def _operator_view_class(self): if inspect.isclass(self.__operator_view_class): return self.__operator_view_class elif isinstance(self.__operator_view_class, str): try: module_name, class_name =\ self.__operator_view_class.rsplit('.', 1) return class_for_name(module_name, class_name) except (AttributeError, ValueError, ImportError): raise WrongOperatorViewClassError( 'There is no "%s" class' % self.__operator_view_class ) def retrieve_and_wrap(self, obj): related_obj = self.get(obj) return self.wrap(related_obj) def wrap(self, obj): return self._operator_view_class(obj) class RelatedListViewField(RelatedViewField): pass class RelatedDictViewField(RelatedViewField): pass class DataField(Field): pass class OptionalDataField(DataField): def get(self, obj): if hasattr(obj, self.field_name): return getattr(obj, self.field_name) else: return None class WrongOperatorViewClassError(Exception): pass def class_for_name(module_name, class_name): # load the module, will raise ImportError if module cannot be loaded m = importlib.import_module(module_name) # get the class, will raise AttributeError if class cannot be found c = getattr(m, class_name) return c ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/operator/views/other.py0000664000175000017500000000166600000000000025402 0ustar00zuulzuul00000000000000from os_ken.services.protocols.bgp.operator.views.base import \ create_dict_view_class from os_ken.services.protocols.bgp.operator.views.base import OperatorDetailView from os_ken.services.protocols.bgp.operator.views import fields class ImportmapManagerDetailView(OperatorDetailView): importmaps = fields.RelatedDictViewField( '_import_maps_by_name', 'os_ken.services.protocols.bgp.operator.views.other.ImportmapDictView' ) class ImportmapDetailView(OperatorDetailView): nlri = fields.OptionalDataField('_nlri') rt = fields.OptionalDataField('_rt') def encode(self): ret = {} nlri = self.get_field('nlri') if nlri is not None: ret.update({'nlri': nlri}) rt = self.get_field('rt') if rt is not None: ret.update({'rt': rt}) return ret ImportmapDictView = create_dict_view_class( ImportmapDetailView, 'ImportmapDictView' ) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/peer.py0000664000175000017500000027746300000000000022236 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone 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. """ BGP peer related classes and utils. """ from collections import namedtuple import itertools import logging import socket import time import traceback from os_ken.services.protocols.bgp.base import Activity from os_ken.services.protocols.bgp.base import Sink from os_ken.services.protocols.bgp.base import Source from os_ken.services.protocols.bgp.base import SUPPORTED_GLOBAL_RF from os_ken.services.protocols.bgp import constants as const from os_ken.services.protocols.bgp.model import OutgoingRoute from os_ken.services.protocols.bgp.model import SentRoute from os_ken.services.protocols.bgp.info_base.base import PrefixFilter from os_ken.services.protocols.bgp.info_base.base import AttributeMap from os_ken.services.protocols.bgp.model import ReceivedRoute from os_ken.services.protocols.bgp.net_ctrl import NET_CONTROLLER from os_ken.services.protocols.bgp.rtconf.neighbors import NeighborConfListener from os_ken.services.protocols.bgp.rtconf.neighbors import CONNECT_MODE_PASSIVE from os_ken.services.protocols.bgp.signals.emit import BgpSignalBus from os_ken.services.protocols.bgp.speaker import BgpProtocol from os_ken.services.protocols.bgp.info_base.ipv4 import Ipv4Path from os_ken.services.protocols.bgp.info_base.vpnv4 import Vpnv4Path from os_ken.services.protocols.bgp.info_base.vpnv6 import Vpnv6Path from os_ken.services.protocols.bgp.rtconf.vrfs import VRF_RF_IPV4, VRF_RF_IPV6 from os_ken.services.protocols.bgp.utils import bgp as bgp_utils from os_ken.services.protocols.bgp.utils.evtlet import EventletIOFactory from os_ken.services.protocols.bgp.utils import stats from os_ken.services.protocols.bgp.utils.validation import is_valid_old_asn from os_ken.lib.packet import bgp from os_ken.lib.packet.bgp import RouteFamily from os_ken.lib.packet.bgp import RF_IPv4_UC from os_ken.lib.packet.bgp import RF_IPv6_UC from os_ken.lib.packet.bgp import RF_IPv4_VPN from os_ken.lib.packet.bgp import RF_IPv6_VPN from os_ken.lib.packet.bgp import RF_IPv4_FLOWSPEC from os_ken.lib.packet.bgp import RF_VPNv4_FLOWSPEC from os_ken.lib.packet.bgp import RF_RTC_UC from os_ken.lib.packet.bgp import get_rf from os_ken.lib.packet.bgp import BGPOpen from os_ken.lib.packet.bgp import BGPUpdate from os_ken.lib.packet.bgp import BGPRouteRefresh from os_ken.lib.packet.bgp import BGP_ERROR_CEASE from os_ken.lib.packet.bgp import BGP_ERROR_SUB_ADMINISTRATIVE_SHUTDOWN from os_ken.lib.packet.bgp import BGP_ERROR_SUB_CONNECTION_COLLISION_RESOLUTION from os_ken.lib.packet.bgp import BGP_MSG_UPDATE from os_ken.lib.packet.bgp import BGP_MSG_KEEPALIVE from os_ken.lib.packet.bgp import BGP_MSG_ROUTE_REFRESH from os_ken.lib.packet.bgp import BGPPathAttributeNextHop from os_ken.lib.packet.bgp import BGPPathAttributeAsPath from os_ken.lib.packet.bgp import BGPPathAttributeAs4Path from os_ken.lib.packet.bgp import BGPPathAttributeLocalPref from os_ken.lib.packet.bgp import BGPPathAttributeExtendedCommunities from os_ken.lib.packet.bgp import BGPPathAttributeOriginatorId from os_ken.lib.packet.bgp import BGPPathAttributeClusterList from os_ken.lib.packet.bgp import BGPPathAttributeMpReachNLRI from os_ken.lib.packet.bgp import BGPPathAttributeMpUnreachNLRI from os_ken.lib.packet.bgp import BGPPathAttributeCommunities from os_ken.lib.packet.bgp import BGPPathAttributeMultiExitDisc from os_ken.lib.packet.bgp import BGP_ATTR_TYPE_ORIGIN from os_ken.lib.packet.bgp import BGP_ATTR_TYPE_AGGREGATOR from os_ken.lib.packet.bgp import BGP_ATTR_TYPE_AS4_AGGREGATOR from os_ken.lib.packet.bgp import BGP_ATTR_TYPE_AS_PATH from os_ken.lib.packet.bgp import BGP_ATTR_TYPE_AS4_PATH from os_ken.lib.packet.bgp import BGP_ATTR_TYPE_NEXT_HOP from os_ken.lib.packet.bgp import BGP_ATTR_TYPE_MP_REACH_NLRI from os_ken.lib.packet.bgp import BGP_ATTR_TYPE_MP_UNREACH_NLRI from os_ken.lib.packet.bgp import BGP_ATTR_TYPE_MULTI_EXIT_DISC from os_ken.lib.packet.bgp import BGP_ATTR_TYPE_COMMUNITIES from os_ken.lib.packet.bgp import BGP_ATTR_TYPE_ORIGINATOR_ID from os_ken.lib.packet.bgp import BGP_ATTR_TYPE_CLUSTER_LIST from os_ken.lib.packet.bgp import BGP_ATTR_TYPE_EXTENDED_COMMUNITIES from os_ken.lib.packet.bgp import BGP_ATTR_TYEP_PMSI_TUNNEL_ATTRIBUTE from os_ken.lib.packet.bgp import BGPTwoOctetAsSpecificExtendedCommunity from os_ken.lib.packet.bgp import BGPIPv4AddressSpecificExtendedCommunity from os_ken.lib.packet import safi as subaddr_family LOG = logging.getLogger('bgpspeaker.peer') def is_valid_state(state): """Returns True if given state is a valid bgp finite state machine state. """ return state in const.BGP_FSM_VALID_STATES class PeerRf(object): """State maintained per-RouteFamily for a Peer.""" def __init__(self, peer, route_family, enabled=False): assert peer and route_family self.enabled = enabled # Back pointers. self.peer = peer self.rf = route_family PeerCounterNames = namedtuple( 'PeerCounterNames', ('RECV_PREFIXES', 'RECV_UPDATES', 'SENT_UPDATES', 'RECV_NOTIFICATION', 'SENT_NOTIFICATION', 'SENT_REFRESH', 'RECV_REFRESH', 'FSM_ESTB_TRANSITIONS') )( 'recv_prefixes', 'recv_updates', 'sent_updates', 'recv_notification', 'sent_notification', 'sent_refresh', 'recv_refresh', 'fms_established_transitions' ) class PeerState(object): """A BGP neighbor state. Think of this class as of information and stats container for Peer. """ def __init__(self, peer, signal_bus): # Back pointer to peer whose stats this instances represents. self.peer = peer # Current state of BGP finite state machine. self._bgp_state = const.BGP_FSM_IDLE self._established_time = 0 self._last_bgp_error = None self.counters = { 'recv_prefixes': 0, 'recv_updates': 0, 'sent_updates': 0, 'recv_notification': 0, 'sent_notification': 0, 'sent_refresh': 0, 'recv_refresh': 0, 'fms_established_transitions': 0, } self._signal_bus = signal_bus # TODO(JK): refactor other counters to use signals also self._signal_bus.register_listener( ('error', 'bgp', self.peer), self._remember_last_bgp_error ) self._signal_bus.register_listener( BgpSignalBus.BGP_NOTIFICATION_RECEIVED + (self.peer,), lambda _, msg: self.incr(PeerCounterNames.RECV_NOTIFICATION) ) self._signal_bus.register_listener( BgpSignalBus.BGP_NOTIFICATION_SENT + (self.peer,), lambda _, msg: self.incr(PeerCounterNames.SENT_NOTIFICATION) ) def _remember_last_bgp_error(self, identifier, data): self._last_bgp_error = dict([(k, v) for k, v in data.items() if k != 'peer']) @property def recv_prefix(self): # Number of prefixes received from peer. return self.counters[PeerCounterNames.RECV_PREFIXES] @property def bgp_state(self): return self._bgp_state @bgp_state.setter def bgp_state(self, new_state): old_state = self._bgp_state if old_state == new_state: return self._bgp_state = new_state NET_CONTROLLER.send_rpc_notification( 'neighbor.state', { 'ip_address': self.peer.ip_address, 'state': new_state } ) # transition to Established from another state if new_state == const.BGP_FSM_ESTABLISHED: self.incr(PeerCounterNames.FSM_ESTB_TRANSITIONS) self._established_time = time.time() self._signal_bus.adj_up(self.peer) NET_CONTROLLER.send_rpc_notification( 'neighbor.up', {'ip_address': self.peer.ip_address} ) # transition from Established to another state elif old_state == const.BGP_FSM_ESTABLISHED: self._established_time = 0 self._signal_bus.adj_down(self.peer) NET_CONTROLLER.send_rpc_notification( 'neighbor.down', {'ip_address': self.peer.ip_address} ) LOG.debug('Peer %s BGP FSM went from %s to %s', self.peer.ip_address, old_state, self.bgp_state) def incr(self, counter_name, incr_by=1): if counter_name not in self.counters: raise ValueError('Un-recognized counter name: %s' % counter_name) counter = self.counters.setdefault(counter_name, 0) counter += incr_by self.counters[counter_name] = counter def get_count(self, counter_name): if counter_name not in self.counters: raise ValueError('Un-recognized counter name: %s' % counter_name) return self.counters.get(counter_name, 0) @property def total_msg_sent(self): """Returns total number of UPDATE, NOTIFICATION and ROUTE_REFRESH message sent to this peer. """ return (self.get_count(PeerCounterNames.SENT_REFRESH) + self.get_count(PeerCounterNames.SENT_UPDATES)) @property def total_msg_recv(self): """Returns total number of UPDATE, NOTIFICATION and ROUTE_REFRESH messages received from this peer. """ return (self.get_count(PeerCounterNames.RECV_UPDATES) + self.get_count(PeerCounterNames.RECV_REFRESH) + self.get_count(PeerCounterNames.RECV_NOTIFICATION)) def get_stats_summary_dict(self): """Returns basic stats. Returns a `dict` with various counts and stats, see below. """ uptime = time.time() - self._established_time \ if self._established_time != 0 else -1 return { stats.UPDATE_MSG_IN: self.get_count(PeerCounterNames.RECV_UPDATES), stats.UPDATE_MSG_OUT: self.get_count( PeerCounterNames.SENT_UPDATES ), stats.TOTAL_MSG_IN: self.total_msg_recv, stats.TOTAL_MSG_OUT: self.total_msg_sent, stats.FMS_EST_TRANS: self.get_count( PeerCounterNames.FSM_ESTB_TRANSITIONS ), stats.UPTIME: uptime } class Peer(Source, Sink, NeighborConfListener, Activity): """A BGP neighbor/peer. Listens on neighbor configuration changes and handles change events appropriately. If peering is enabled tries 'actively'/'pro-actively' to establish session with peer. Allows binding of `BgpProtocol` instances to allow 'passive'/'reactive' establishment of bgp session with peer. Maintains BGP state machine (may not be fully compliant with RFC). Handles bgp UPDATE messages. Provides a queue to send update message to peer. """ RTC_EOR_TIMER_NAME = 'RTC_EOR_Timer' def __init__(self, common_conf, neigh_conf, core_service, signal_bus, peer_manager): peer_activity_name = 'Peer: %s' % neigh_conf.ip_address Activity.__init__(self, name=peer_activity_name) Source.__init__(self, version_num=1) Sink.__init__(self) # Add listener for configuration changes. NeighborConfListener.__init__(self, neigh_conf) # Current configuration of this peer. self._neigh_conf = neigh_conf self._common_conf = common_conf self._core_service = core_service self._signal_bus = signal_bus self._peer_manager = peer_manager # Host Bind IP self._host_bind_ip = None self._host_bind_port = None # TODO(PH): revisit maintaining state/stats information. # Peer state. self.state = PeerState(self, self._signal_bus) self._periodic_stats_logger = \ self._create_timer('Peer State Summary Stats Timer', stats.log, stats_resource=self._neigh_conf, stats_source=self.state.get_stats_summary_dict) if self._neigh_conf.stats_log_enabled: self._periodic_stats_logger.start(self._neigh_conf.stats_time) # State per route family, {RouteFamily: PeerRf,}. self.rf_state = {} # Get vpnv4 route family settings. prf = PeerRf(self, RF_IPv4_VPN, enabled=self._neigh_conf.cap_mbgp_vpnv4) self.rf_state[RF_IPv4_VPN] = prf # Get vpnv6 route family settings. prf = PeerRf(self, RF_IPv6_VPN, self._neigh_conf.cap_mbgp_vpnv6) self.rf_state[RF_IPv6_VPN] = prf # Bound protocol instance self._protocol = None # Setting this event starts the connect_loop loop again # Clearing this event will stop the connect_loop loop self._connect_retry_event = EventletIOFactory.create_custom_event() # Reference to threads related to enhanced refresh timers. self._refresh_stalepath_timer = None self._refresh_max_eor_timer = None # Latest valid Open Message self.curr_open_msg = None # RTC end-of-rib timer self._rtc_eor_timer = None self._sent_init_non_rtc_update = False self._init_rtc_nlri_path = [] # in-bound filters self._in_filters = self._neigh_conf.in_filter # out-bound filters self._out_filters = self._neigh_conf.out_filter # Adj-rib-in self._adj_rib_in = {} # Adj-rib-out self._adj_rib_out = {} # attribute maps self._attribute_maps = {} @property def remote_as(self): return self._neigh_conf.remote_as @property def rtc_as(self): return self._neigh_conf.rtc_as @property def ip_address(self): return self._neigh_conf.ip_address @property def protocol(self): return self._protocol @property def host_bind_ip(self): return self._host_bind_ip @property def host_bind_port(self): return self._host_bind_port @property def enabled(self): return self._neigh_conf.enabled @property def med(self): return self._neigh_conf.multi_exit_disc @property def local_as(self): return self._neigh_conf.local_as @property def cap_four_octet_as_number(self): return self._neigh_conf.cap_four_octet_as_number @property def in_filters(self): return self._in_filters @in_filters.setter def in_filters(self, filters): self._in_filters = [f.clone() for f in filters] LOG.debug('set in-filter : %s', filters) self.on_update_in_filter() @property def out_filters(self): return self._out_filters @out_filters.setter def out_filters(self, filters): self._out_filters = [f.clone() for f in filters] LOG.debug('set out-filter : %s', filters) self.on_update_out_filter() @property def adj_rib_in(self): return self._adj_rib_in @property def adj_rib_out(self): return self._adj_rib_out @property def is_route_server_client(self): return self._neigh_conf.is_route_server_client @property def is_route_reflector_client(self): return self._neigh_conf.is_route_reflector_client @property def check_first_as(self): return self._neigh_conf.check_first_as @property def connect_mode(self): return self._neigh_conf.connect_mode @property def attribute_maps(self): return self._attribute_maps @attribute_maps.setter def attribute_maps(self, attribute_maps): _attr_maps = {} _attr_maps.setdefault(const.ATTR_MAPS_ORG_KEY, []) # key is 'default' or rd_rf that represents RD and route_family key = attribute_maps[const.ATTR_MAPS_LABEL_KEY] at_maps = attribute_maps[const.ATTR_MAPS_VALUE] for a in at_maps: cloned = a.clone() LOG.debug("AttributeMap attr_type: %s, attr_value: %s", cloned.attr_type, cloned.attr_value) attr_list = _attr_maps.setdefault(cloned.attr_type, []) attr_list.append(cloned) # preserve original order of attribute_maps _attr_maps[const.ATTR_MAPS_ORG_KEY].append(cloned) self._attribute_maps[key] = _attr_maps self.on_update_attribute_maps() def is_mpbgp_cap_valid(self, route_family): if not self.in_established: raise ValueError('Invalid request: Peer not in established state') return self._protocol.is_mbgp_cap_valid(route_family) def is_four_octet_as_number_cap_valid(self): if not self.in_established: raise ValueError('Invalid request: Peer not in established state') return self._protocol.is_four_octet_as_number_cap_valid() def is_ebgp_peer(self): """Returns *True* if this is a eBGP peer, else *False*.""" return self._common_conf.local_as != self._neigh_conf.remote_as def in_established(self): return self.state.bgp_state == const.BGP_FSM_ESTABLISHED def in_idle(self): return self.state.bgp_state == const.BGP_FSM_IDLE def in_active(self): return self.state.bgp_state == const.BGP_FSM_ACTIVE def in_open_sent(self): return self.state.bgp_state == const.BGP_FSM_OPEN_SENT def in_open_confirm(self): return self.state.bgp_state == const.BGP_FSM_OPEN_CONFIRM def in_connect(self): return self.state.bgp_state == const.BGP_FSM_CONNECT def curr_fms_state(self): return self.state.bgp_state def is_mbgp_cap_valid(self, route_family): if not self.in_established(): return False return self._protocol.is_mbgp_cap_valid(route_family) def on_chg_stats_time_conf_with_stats(self, evt): # TODO(PH): provide implementation when updating neighbor is needed pass def on_chg_stats_enabled_conf_with_stats(self, evt): # TODO(PH): provide implementation when updating neighbor is needed pass def on_update_enabled(self, conf_evt): """Implements neighbor configuration change listener. """ enabled = conf_evt.value # If we do not have any protocol bound and configuration asks us to # enable this peer, we try to establish connection again. if enabled: LOG.info('%s enabled', self) if self._protocol and self._protocol.started: LOG.error('Tried to enable neighbor that is already enabled') else: self.state.bgp_state = const.BGP_FSM_CONNECT # Restart connect loop if not already running. if not self._connect_retry_event.is_set(): self._connect_retry_event.set() LOG.debug('Starting connect loop as neighbor is enabled.') else: LOG.info('%s disabled', self) if self._protocol: # Stopping protocol will eventually trigger connection_lost # handler which will do some clean-up. # But the greenlet that is in charge of the socket may be kill # when we stop the protocol, hence we call connection_lost # here as we triggered socket to close. self._protocol.send_notification( BGP_ERROR_CEASE, BGP_ERROR_SUB_ADMINISTRATIVE_SHUTDOWN ) self._protocol.stop() self._protocol = None self.state.bgp_state = const.BGP_FSM_IDLE # If this peer is not enabled any-more we stop trying to make any # connection. LOG.debug('Disabling connect-retry as neighbor was disabled') self._connect_retry_event.clear() def on_update_med(self, conf_evt): LOG.debug('on_update_med fired') if self._protocol is not None and self._protocol.started: negotiated_afs = self._protocol.negotiated_afs for af in negotiated_afs: self._fire_route_refresh(af) def _on_update_connect_mode(self, mode): if mode is not CONNECT_MODE_PASSIVE and \ 'peer.connect_loop' not in self._child_thread_map: LOG.debug("start connect loop. (mode: %s)", mode) self._spawn('peer.connect_loop', self._connect_loop, self._client_factory) elif mode is CONNECT_MODE_PASSIVE: LOG.debug("stop connect loop. (mode: %s)", mode) self._stop_child_threads('peer.connect_loop') def on_update_connect_mode(self, conf_evt): self._on_update_connect_mode(conf_evt.value) def _apply_filter(self, filters, path): block = False blocked_cause = None for filter_ in filters: if filter_.ROUTE_FAMILY != path.ROUTE_FAMILY: continue policy, is_matched = filter_.evaluate(path) if policy == PrefixFilter.POLICY_PERMIT and is_matched: block = False break elif policy == PrefixFilter.POLICY_DENY and is_matched: block = True blocked_cause = filter_.prefix + ' - DENY' break return block, blocked_cause def _apply_in_filter(self, path): return self._apply_filter(self._in_filters, path) def _apply_out_filter(self, path): return self._apply_filter(self._out_filters, path) def on_update_in_filter(self): LOG.debug('on_update_in_filter fired') for received_path in self._adj_rib_in.values(): LOG.debug('received_path: %s', received_path) path = received_path.path nlri_str = path.nlri.formatted_nlri_str block, blocked_reason = self._apply_in_filter(path) if block == received_path.filtered: LOG.debug('block situation not changed: %s', block) continue elif block: # path wasn't blocked, but must be blocked by this update path = path.clone(for_withdrawal=True) LOG.debug('withdraw %s because of in filter update', nlri_str) else: # path was blocked, but mustn't be blocked by this update LOG.debug('learn blocked %s because of in filter update', nlri_str) received_path.filtered = block tm = self._core_service.table_manager tm.learn_path(path) def on_update_out_filter(self): LOG.debug('on_update_out_filter fired') for sent_path in self._adj_rib_out.values(): LOG.debug('sent_path: %s', sent_path) path = sent_path.path nlri_str = path.nlri.formatted_nlri_str block, blocked_reason = self._apply_out_filter(path) if block == sent_path.filtered: LOG.debug('block situation not changed: %s', block) continue elif block: # path wasn't blocked, but must be blocked by this update withdraw_clone = path.clone(for_withdrawal=True) outgoing_route = OutgoingRoute(withdraw_clone) LOG.debug('send withdraw %s because of out filter update', nlri_str) else: # path was blocked, but mustn't be blocked by this update outgoing_route = OutgoingRoute(path) LOG.debug('send blocked %s because of out filter update', nlri_str) sent_path.filtered = block self.enque_outgoing_msg(outgoing_route) def on_update_attribute_maps(self): # resend sent_route in case of filter matching LOG.debug('on_update_attribute_maps fired') for sent_path in self._adj_rib_out.values(): LOG.debug('resend path: %s', sent_path) path = sent_path.path self.enque_outgoing_msg(OutgoingRoute(path)) def __str__(self): return 'Peer(ip: %s, asn: %s)' % (self._neigh_conf.ip_address, self._neigh_conf.remote_as) def _run(self, client_factory): LOG.debug('Started peer %s', self) self._client_factory = client_factory # Tries actively to establish session if CONNECT_MODE is not PASSIVE self._on_update_connect_mode(self._neigh_conf.connect_mode) # Start sink processing self._process_outgoing_msg_list() def _send_outgoing_route_refresh_msg(self, rr_msg): """Sends given message `rr_msg` to peer. Parameters: - rr_msg: (RouteRefresh) route refresh message to send to peer. Update appropriate counters and set appropriate timers. """ assert rr_msg.type == BGP_MSG_ROUTE_REFRESH self._protocol.send(rr_msg) LOG.debug('RouteRefresh %s>> %s', self._neigh_conf.ip_address, rr_msg) # Collect update statistics for sent refresh request. if rr_msg.demarcation == 0: self.state.incr(PeerCounterNames.SENT_REFRESH) # If SOR is sent, we set Max. EOR timer if needed. elif (rr_msg.demarcation == 1 and self._common_conf.refresh_max_eor_time != 0): eor_timer = self._common_conf.refresh_max_eor_time # Set timer to send EOR demarcation. self._spawn_after('end-of-rib-timer', eor_timer, self._enqueue_eor_msg, rr_msg) LOG.debug('Enhanced RR max. EOR timer set.') def _send_outgoing_route(self, outgoing_route): """Constructs `Update` message from given `outgoing_route` and sends it to peer. Also, checks if any policies prevent sending this message. Populates Adj-RIB-out with corresponding `SentRoute`. """ path = outgoing_route.path block, blocked_cause = self._apply_out_filter(path) nlri_str = outgoing_route.path.nlri.formatted_nlri_str sent_route = SentRoute(outgoing_route.path, self, block) self._adj_rib_out[nlri_str] = sent_route self._signal_bus.adj_rib_out_changed(self, sent_route) # TODO(PH): optimized by sending several prefixes per update. # Construct and send update message. if not block: update_msg = self._construct_update(outgoing_route) self._protocol.send(update_msg) # Collect update statistics. self.state.incr(PeerCounterNames.SENT_UPDATES) else: LOG.debug('prefix : %s is not sent by filter : %s', path.nlri, blocked_cause) # We have to create sent_route for every OutgoingRoute which is # not a withdraw or was for route-refresh msg. if (not outgoing_route.path.is_withdraw and not outgoing_route.for_route_refresh): # Update the destination with new sent route. tm = self._core_service.table_manager tm.remember_sent_route(sent_route) def _process_outgoing_msg_list(self): while True: outgoing_msg = None if self._protocol is not None: # We pick the first outgoing msg. available and send it. outgoing_msg = self.outgoing_msg_list.pop_first() # If we do not have any outgoing route, we wait. if outgoing_msg is None: self.outgoing_msg_event.clear() self.outgoing_msg_event.wait() continue # Check currently supported out-going msgs. assert isinstance( outgoing_msg, (BGPRouteRefresh, BGPUpdate, OutgoingRoute) ), ('Peer cannot process object: %s in its outgoing queue' % outgoing_msg) # Send msg. to peer. if isinstance(outgoing_msg, BGPRouteRefresh): self._send_outgoing_route_refresh_msg(outgoing_msg) elif isinstance(outgoing_msg, OutgoingRoute): self._send_outgoing_route(outgoing_msg) # EOR are enqueued as plain Update messages. elif isinstance(outgoing_msg, BGPUpdate): self._protocol.send(outgoing_msg) LOG.debug('Update %s>> %s', self._neigh_conf.ip_address, outgoing_msg) self.state.incr(PeerCounterNames.SENT_UPDATES) def request_route_refresh(self, *route_families): """Request route refresh to peer for given `route_families`. If no `route_families` are given, we make request for all supported route families with this peer. Parameters: - `route_families`: list of route families to request route refresh for. If this peer is currently not in Established state, we raise exception. If any of the `route_families` are invalid we raise exception. """ # If this peer has not established session yet if not self.in_established: raise ValueError('Peer not in established state to satisfy' ' this request.') skip_validation = False # If request is made for all supported route_families for current # session, we collect all route_families for valid for current session. if len(route_families) == 0: route_families = [] # We skip validation of route families that we collect ourselves # below. skip_validation = True for route_family in SUPPORTED_GLOBAL_RF: if self.is_mbgp_cap_valid(route_family): route_families.append(route_family) for route_family in route_families: if (skip_validation or ((route_family in SUPPORTED_GLOBAL_RF) and # We ignore request for route_family not valid # for current session. self._protocol.is_mbgp_cap_valid(route_family))): rr_req = BGPRouteRefresh(route_family.afi, route_family.safi) self.enque_outgoing_msg(rr_req) LOG.debug('Enqueued Route Refresh message to ' 'peer %s for rf: %s', self, route_family) def enque_end_of_rib(self, route_family): # MP_UNREACH_NLRI Attribute. mpunreach_attr = BGPPathAttributeMpUnreachNLRI(route_family.afi, route_family.safi, []) update = BGPUpdate(path_attributes=[mpunreach_attr]) self.enque_outgoing_msg(update) def _session_next_hop(self, path): """Returns nexthop address relevant to current session Nexthop used can depend on capabilities of the session. If VPNv6 capability is active and session is on IPv4 connection, we have to use IPv4 mapped IPv6 address. In other cases we can use connection end point/local ip address. """ route_family = path.route_family # By default we use BGPS's interface IP with this peer as next_hop. if self._neigh_conf.next_hop: next_hop = self._neigh_conf.next_hop else: next_hop = self.host_bind_ip if route_family == RF_IPv6_VPN: next_hop = self._ipv4_mapped_ipv6(next_hop) return next_hop @staticmethod def _ipv4_mapped_ipv6(ipv4_address): # Next hop ipv4_mapped ipv6 from netaddr import IPAddress return str(IPAddress(ipv4_address).ipv6()) def _construct_as_path_attr(self, as_path_attr, as4_path_attr): """Marge AS_PATH and AS4_PATH attribute instances into a single AS_PATH instance.""" def _listify(li): """Reconstruct AS_PATH list. Example:: >>> _listify([[1, 2, 3], {4, 5}, [6, 7]]) [1, 2, 3, {4, 5}, 6, 7] """ lo = [] for l in li: if isinstance(l, list): lo.extend(l) elif isinstance(l, set): lo.append(l) else: pass return lo # If AS4_PATH attribute is None, returns the given AS_PATH attribute if as4_path_attr is None: return as_path_attr # If AS_PATH is shorter than AS4_PATH, AS4_PATH should be ignored. if as_path_attr.get_as_path_len() < as4_path_attr.get_as_path_len(): return as_path_attr org_as_path_list = _listify(as_path_attr.path_seg_list) as4_path_list = _listify(as4_path_attr.path_seg_list) # Reverse to compare backward. org_as_path_list.reverse() as4_path_list.reverse() new_as_path_list = [] tmp_list = [] for as_path, as4_path in itertools.zip_longest(org_as_path_list, as4_path_list): if as4_path is None: if isinstance(as_path, int): tmp_list.insert(0, as_path) elif isinstance(as_path, set): if tmp_list: new_as_path_list.insert(0, tmp_list) tmp_list = [] new_as_path_list.insert(0, as_path) else: pass elif isinstance(as4_path, int): tmp_list.insert(0, as4_path) elif isinstance(as4_path, set): if tmp_list: new_as_path_list.insert(0, tmp_list) tmp_list = [] new_as_path_list.insert(0, as4_path) else: pass if tmp_list: new_as_path_list.insert(0, tmp_list) return bgp.BGPPathAttributeAsPath(new_as_path_list) def _trans_as_path(self, as_path_list): """Translates Four-Octet AS number to AS_TRANS and separates AS_PATH list into AS_PATH and AS4_PATH lists if needed. If the neighbor does not support Four-Octet AS number, this method constructs AS4_PATH list from AS_PATH list and swaps non-mappable AS number in AS_PATH with AS_TRANS, then returns AS_PATH list and AS4_PATH list. If the neighbor supports Four-Octet AS number, returns the given AS_PATH list and None. """ def _swap(n): if is_valid_old_asn(n): # mappable return n else: # non-mappable return bgp.AS_TRANS # If the neighbor supports Four-Octet AS number, returns # the given AS_PATH list and None. if self.is_four_octet_as_number_cap_valid(): return as_path_list, None # If the neighbor does not support Four-Octet AS number, # constructs AS4_PATH list from AS_PATH list and swaps # non-mappable AS number in AS_PATH with AS_TRANS. else: new_as_path_list = [] for as_path in as_path_list: if isinstance(as_path, set): path_set = set() for as_num in as_path: path_set.add(_swap(as_num)) new_as_path_list.append(path_set) elif isinstance(as_path, list): path_list = list() for as_num in as_path: path_list.append(_swap(as_num)) new_as_path_list.append(path_list) else: # Ignore invalid as_path type pass # If all of the AS_PATH list is composed of mappable four-octet # AS numbers only, returns the given AS_PATH list # Assumption: If the constructed AS_PATH list is the same as # the given AS_PATH list, all AS number is mappable. if as_path_list == new_as_path_list: return as_path_list, None return new_as_path_list, as_path_list def _construct_update(self, outgoing_route): """Construct update message with Outgoing-routes path attribute appropriately cloned/copied/updated. """ update = None path = outgoing_route.path # Get copy of path's path attributes. pathattr_map = path.pathattr_map new_pathattr = [] if path.is_withdraw: if isinstance(path, Ipv4Path): update = BGPUpdate(withdrawn_routes=[path.nlri]) return update else: mpunreach_attr = BGPPathAttributeMpUnreachNLRI( path.route_family.afi, path.route_family.safi, [path.nlri] ) new_pathattr.append(mpunreach_attr) elif self.is_route_server_client: nlri_list = [path.nlri] new_pathattr.extend(pathattr_map.values()) else: if self.is_route_reflector_client: # Append ORIGINATOR_ID attribute if not already exist. if BGP_ATTR_TYPE_ORIGINATOR_ID not in pathattr_map: originator_id = path.source if originator_id is None: originator_id = self._common_conf.router_id elif isinstance(path.source, Peer): originator_id = path.source.ip_address new_pathattr.append( BGPPathAttributeOriginatorId(value=originator_id)) # Preppend own CLUSTER_ID into CLUSTER_LIST attribute if exist. # Otherwise append CLUSTER_LIST attribute. cluster_lst_attr = pathattr_map.get(BGP_ATTR_TYPE_CLUSTER_LIST) if cluster_lst_attr: cluster_list = list(cluster_lst_attr.value) if self._common_conf.cluster_id not in cluster_list: cluster_list.insert(0, self._common_conf.cluster_id) new_pathattr.append( BGPPathAttributeClusterList(cluster_list)) else: new_pathattr.append( BGPPathAttributeClusterList( [self._common_conf.cluster_id])) # Supported and un-supported/unknown attributes. origin_attr = None nexthop_attr = None as_path_attr = None as4_path_attr = None aggregator_attr = None as4_aggregator_attr = None extcomm_attr = None community_attr = None localpref_attr = None pmsi_tunnel_attr = None unknown_opttrans_attrs = None nlri_list = [path.nlri] if path.route_family.safi in (subaddr_family.IP_FLOWSPEC, subaddr_family.VPN_FLOWSPEC): # Flow Specification does not have next_hop. next_hop = [] elif self.is_ebgp_peer(): next_hop = self._session_next_hop(path) if path.is_local() and path.has_nexthop(): next_hop = path.nexthop else: next_hop = path.nexthop # RFC 4271 allows us to change next_hop # if configured to announce its own ip address. # Also if the BGP route is configured without next_hop, # we use path._session_next_hop() as next_hop. if (self._neigh_conf.is_next_hop_self or (path.is_local() and not path.has_nexthop())): next_hop = self._session_next_hop(path) LOG.debug('using %s as a next_hop address instead' ' of path.nexthop %s', next_hop, path.nexthop) nexthop_attr = BGPPathAttributeNextHop(next_hop) assert nexthop_attr, 'Missing NEXTHOP mandatory attribute.' if not isinstance(path, Ipv4Path): # We construct mpreach-nlri attribute. mpnlri_attr = BGPPathAttributeMpReachNLRI( path.route_family.afi, path.route_family.safi, next_hop, nlri_list ) # ORIGIN Attribute. # According to RFC this attribute value SHOULD NOT be changed by # any other speaker. origin_attr = pathattr_map.get(BGP_ATTR_TYPE_ORIGIN) assert origin_attr, 'Missing ORIGIN mandatory attribute.' # AS_PATH Attribute. # Construct AS-path-attr using paths AS_PATH attr. with local AS as # first item. path_aspath = pathattr_map.get(BGP_ATTR_TYPE_AS_PATH) assert path_aspath, 'Missing AS_PATH mandatory attribute.' # Deep copy AS_PATH attr value as_path_list = path_aspath.path_seg_list # If this is a iBGP peer. if not self.is_ebgp_peer(): # When a given BGP speaker advertises the route to an internal # peer, the advertising speaker SHALL NOT modify the AS_PATH # attribute associated with the route. pass else: # When a given BGP speaker advertises the route to an external # peer, the advertising speaker updates the AS_PATH attribute # as follows: # 1) if the first path segment of the AS_PATH is of type # AS_SEQUENCE, the local system prepends its own AS num as # the last element of the sequence (put it in the left-most # position with respect to the position of octets in the # protocol message). If the act of prepending will cause an # overflow in the AS_PATH segment (i.e., more than 255 # ASes), it SHOULD prepend a new segment of type AS_SEQUENCE # and prepend its own AS number to this new segment. # # 2) if the first path segment of the AS_PATH is of type AS_SET # , the local system prepends a new path segment of type # AS_SEQUENCE to the AS_PATH, including its own AS number in # that segment. # # 3) if the AS_PATH is empty, the local system creates a path # segment of type AS_SEQUENCE, places its own AS into that # segment, and places that segment into the AS_PATH. if (len(as_path_list) > 0 and isinstance(as_path_list[0], list) and len(as_path_list[0]) < 255): as_path_list[0].insert(0, self.local_as) else: as_path_list.insert(0, [self.local_as]) # Construct AS4_PATH list from AS_PATH list and swap # non-mappable AS number with AS_TRANS in AS_PATH. as_path_list, as4_path_list = self._trans_as_path( as_path_list) # If the neighbor supports Four-Octet AS number, send AS_PATH # in Four-Octet. if self.is_four_octet_as_number_cap_valid(): as_path_attr = BGPPathAttributeAsPath( as_path_list, as_pack_str='!I') # specify Four-Octet. # Otherwise, send AS_PATH in Two-Octet. else: as_path_attr = BGPPathAttributeAsPath(as_path_list) # If needed, send AS4_PATH attribute. if as4_path_list: as4_path_attr = BGPPathAttributeAs4Path(as4_path_list) # AGGREGATOR Attribute. aggregator_attr = pathattr_map.get(BGP_ATTR_TYPE_AGGREGATOR) # If the neighbor does not support Four-Octet AS number, # swap non-mappable AS number with AS_TRANS. if (aggregator_attr and not self.is_four_octet_as_number_cap_valid()): # If AS number of AGGREGATOR is Four-Octet AS number, # swap with AS_TRANS, else do not. aggregator_as_number = aggregator_attr.as_number if not is_valid_old_asn(aggregator_as_number): aggregator_attr = bgp.BGPPathAttributeAggregator( bgp.AS_TRANS, aggregator_attr.addr) as4_aggregator_attr = bgp.BGPPathAttributeAs4Aggregator( aggregator_as_number, aggregator_attr.addr) # MULTI_EXIT_DISC Attribute. # For eBGP session we can send multi-exit-disc if configured. multi_exit_disc = None if self.is_ebgp_peer(): if self._neigh_conf.multi_exit_disc: multi_exit_disc = BGPPathAttributeMultiExitDisc( self._neigh_conf.multi_exit_disc ) else: pass if not self.is_ebgp_peer(): multi_exit_disc = pathattr_map.get( BGP_ATTR_TYPE_MULTI_EXIT_DISC) # LOCAL_PREF Attribute. if not self.is_ebgp_peer(): # For iBGP peers we are required to send local-pref attribute # for connected or local prefixes. We check if the path matches # attribute_maps and set local-pref value. # If the path doesn't match, we set default local-pref given # from the user. The default value is 100. localpref_attr = BGPPathAttributeLocalPref( self._common_conf.local_pref) key = const.ATTR_MAPS_LABEL_DEFAULT if isinstance(path, (Vpnv4Path, Vpnv6Path)): nlri = nlri_list[0] rf = VRF_RF_IPV4 if isinstance(path, Vpnv4Path)\ else VRF_RF_IPV6 key = ':'.join([nlri.route_dist, rf]) attr_type = AttributeMap.ATTR_LOCAL_PREF at_maps = self._attribute_maps.get(key, {}) result = self._lookup_attribute_map(at_maps, attr_type, path) if result: localpref_attr = result # COMMUNITY Attribute. community_attr = pathattr_map.get(BGP_ATTR_TYPE_COMMUNITIES) # EXTENDED COMMUNITY Attribute. # Construct ExtCommunity path-attr based on given. path_extcomm_attr = pathattr_map.get( BGP_ATTR_TYPE_EXTENDED_COMMUNITIES ) if path_extcomm_attr: # SOO list can be configured per VRF and/or per Neighbor. # NeighborConf has this setting we add this to existing list. communities = path_extcomm_attr.communities if self._neigh_conf.soo_list: # construct extended community soo_list = self._neigh_conf.soo_list subtype = 0x03 for soo in soo_list: first, second = soo.split(':') if '.' in first: c = BGPIPv4AddressSpecificExtendedCommunity( subtype=subtype, ipv4_address=first, local_administrator=int(second)) else: c = BGPTwoOctetAsSpecificExtendedCommunity( subtype=subtype, as_number=int(first), local_administrator=int(second)) communities.append(c) extcomm_attr = BGPPathAttributeExtendedCommunities( communities=communities ) pmsi_tunnel_attr = pathattr_map.get( BGP_ATTR_TYEP_PMSI_TUNNEL_ATTRIBUTE ) # UNKNOWN Attributes. # Get optional transitive path attributes unknown_opttrans_attrs = bgp_utils.get_unknown_opttrans_attr(path) # Ordering path attributes according to type as RFC says. We set # MPReachNLRI first as advised by experts as a new trend in BGP # implementation. if isinstance(path, Ipv4Path): new_pathattr.append(nexthop_attr) else: new_pathattr.append(mpnlri_attr) new_pathattr.append(origin_attr) new_pathattr.append(as_path_attr) if as4_path_attr: new_pathattr.append(as4_path_attr) if aggregator_attr: new_pathattr.append(aggregator_attr) if as4_aggregator_attr: new_pathattr.append(as4_aggregator_attr) if multi_exit_disc: new_pathattr.append(multi_exit_disc) if localpref_attr: new_pathattr.append(localpref_attr) if community_attr: new_pathattr.append(community_attr) if extcomm_attr: new_pathattr.append(extcomm_attr) if pmsi_tunnel_attr: new_pathattr.append(pmsi_tunnel_attr) if unknown_opttrans_attrs: new_pathattr.extend(unknown_opttrans_attrs.values()) if isinstance(path, Ipv4Path): update = BGPUpdate(path_attributes=new_pathattr, nlri=nlri_list) else: update = BGPUpdate(path_attributes=new_pathattr) return update def _connect_loop(self, client_factory): """In the current greenlet we try to establish connection with peer. This greenlet will spin another greenlet to handle incoming data from the peer once connection is established. """ # If current configuration allow, enable active session establishment. if self._neigh_conf.enabled: self._connect_retry_event.set() while True: self._connect_retry_event.wait() # Reconnecting immediately after closing connection may be not very # well seen by some peers (ALU?) self.pause(1.0) if self.state.bgp_state in \ (const.BGP_FSM_IDLE, const.BGP_FSM_ACTIVE): # Check if we have to stop or retry self.state.bgp_state = const.BGP_FSM_CONNECT # If we have specific host interface to bind to, we will do so # else we will bind to system default. if self._neigh_conf.host_bind_ip and \ self._neigh_conf.host_bind_port: bind_addr = (self._neigh_conf.host_bind_ip, self._neigh_conf.host_bind_port) else: bind_addr = None peer_address = (self._neigh_conf.ip_address, self._neigh_conf.port) if bind_addr: LOG.debug('%s trying to connect from' '%s to %s', self, bind_addr, peer_address) else: LOG.debug('%s trying to connect to %s', self, peer_address) tcp_conn_timeout = self._common_conf.tcp_conn_timeout try: password = self._neigh_conf.password self._connect_tcp(peer_address, client_factory, time_out=tcp_conn_timeout, bind_address=bind_addr, password=password) except socket.error: self.state.bgp_state = const.BGP_FSM_ACTIVE if LOG.isEnabledFor(logging.DEBUG): LOG.debug('Socket could not be created in time' ' (%s secs), reason %s', tcp_conn_timeout, traceback.format_exc()) LOG.info('Will try to reconnect to %s after %s secs: %s', self._neigh_conf.ip_address, self._common_conf.bgp_conn_retry_time, self._connect_retry_event.is_set()) self.pause(self._common_conf.bgp_conn_retry_time) def _set_protocol(self, proto): self._protocol = proto # Update state attributes self.state.peer_ip, self.state.peer_port = self._protocol._remotename self.state.local_ip, self.state.local_port = self._protocol._localname # self.state.bgp_state = self._protocol.state # Stop connect_loop retry timer as we are now connected if self._protocol and self._connect_retry_event.is_set(): self._connect_retry_event.clear() LOG.debug('Connect retry event for %s is cleared', self) if self._protocol and self.outgoing_msg_event.is_set(): # Start processing sink. self.outgoing_msg_event.set() LOG.debug('Processing of outgoing msg. started for %s.', self) def _send_collision_err_and_stop(self, protocol): code = BGP_ERROR_CEASE subcode = BGP_ERROR_SUB_CONNECTION_COLLISION_RESOLUTION self._signal_bus.bgp_error(self, code, subcode, None) protocol.send_notification(code, subcode) protocol.stop() def bind_protocol(self, proto): """Tries to bind given protocol to this peer. Should only be called by `proto` trying to bind. Once bound this protocol instance will be used to communicate with peer. If another protocol is already bound, connection collision resolution takes place. """ LOG.debug('Trying to bind protocol %s to peer %s', proto, self) # Validate input. if not isinstance(proto, BgpProtocol): raise ValueError('Currently only supports valid instances of' ' `BgpProtocol`') if proto.state != const.BGP_FSM_OPEN_CONFIRM: raise ValueError('Only protocols in OpenConfirm state can be' ' bound') # If we are not bound to any protocol is_bound = False if not self._protocol: self._set_protocol(proto) is_bound = True else: # If existing protocol is already established, we raise exception. if self.state.bgp_state != const.BGP_FSM_IDLE: LOG.debug('Currently in %s state, hence will send collision' ' Notification to close this protocol.', self.state.bgp_state) self._send_collision_err_and_stop(proto) return # If we have a collision that need to be resolved assert proto.is_colliding(self._protocol), \ ('Tried to bind second protocol that is not colliding with ' 'first/bound protocol') LOG.debug('Currently have one protocol in %s state and ' 'another protocol in %s state', self._protocol.state, proto.state) # Protocol that is already bound first_protocol = self._protocol assert ((first_protocol.is_reactive and not proto.is_reactive) or (proto.is_reactive and not first_protocol.is_reactive)) # Connection initiated by peer. reactive_proto = None # Connection initiated locally. proactive_proto = None # Identify which protocol was initiated by which peer. if proto.is_reactive: reactive_proto = proto proactive_proto = self._protocol else: reactive_proto = self._protocol proactive_proto = proto LOG.debug('Pro-active/Active protocol %s', proactive_proto) # We compare bgp local and remote router id and keep the protocol # that was initiated by peer with highest id. if proto.is_local_router_id_greater(): self._set_protocol(proactive_proto) else: self._set_protocol(reactive_proto) if self._protocol is not proto: # If new proto did not win collision we return False to # indicate this. is_bound = False else: # If first protocol did not win collision resolution we # we send notification to peer and stop it self._send_collision_err_and_stop(first_protocol) is_bound = True return is_bound def create_open_msg(self): """Create `Open` message using current settings. Current setting include capabilities, timers and ids. """ asnum = self.local_as # If local AS number is not Two-Octet AS number, swaps with AS_TRANS. if not is_valid_old_asn(asnum): asnum = bgp.AS_TRANS bgpid = self._common_conf.router_id holdtime = self._neigh_conf.hold_time def flatten(L): if isinstance(L, list): for i in range(len(L)): for e in flatten(L[i]): yield e else: yield L opts = list(flatten( list(self._neigh_conf.get_configured_capabilities().values()))) open_msg = BGPOpen( my_as=asnum, bgp_identifier=bgpid, version=const.BGP_VERSION_NUM, hold_time=holdtime, opt_param=opts ) return open_msg def _validate_update_msg(self, update_msg): """Validate update message as per RFC. Here we validate the message after it has been parsed. Message has already been validated against some errors inside parsing library. """ # TODO(PH): finish providing implementation, currently low priority assert update_msg.type == BGP_MSG_UPDATE # An UPDATE message may be received only in the Established state. # Receiving an UPDATE message in any other state is an error. if self.state.bgp_state != const.BGP_FSM_ESTABLISHED: LOG.error('Received UPDATE message when not in ESTABLISHED' ' state.') raise bgp.FiniteStateMachineError() mp_reach_attr = update_msg.get_path_attr( BGP_ATTR_TYPE_MP_REACH_NLRI ) mp_unreach_attr = update_msg.get_path_attr( BGP_ATTR_TYPE_MP_UNREACH_NLRI ) # non-MPBGP Update msg. if not (mp_reach_attr or mp_unreach_attr): if not self.is_mpbgp_cap_valid(RF_IPv4_UC): LOG.error('Got UPDATE message with un-available' ' afi/safi %s', RF_IPv4_UC) nlri_list = update_msg.nlri if len(nlri_list) > 0: # Check for missing well-known mandatory attributes. aspath = update_msg.get_path_attr(BGP_ATTR_TYPE_AS_PATH) if not aspath: raise bgp.MissingWellKnown( BGP_ATTR_TYPE_AS_PATH) if (self.check_first_as and self.is_ebgp_peer() and not aspath.has_matching_leftmost(self.remote_as)): LOG.error('First AS check fails. Raise appropriate' ' exception.') raise bgp.MalformedAsPath() origin = update_msg.get_path_attr(BGP_ATTR_TYPE_ORIGIN) if not origin: raise bgp.MissingWellKnown(BGP_ATTR_TYPE_ORIGIN) nexthop = update_msg.get_path_attr(BGP_ATTR_TYPE_NEXT_HOP) if not nexthop: raise bgp.MissingWellKnown(BGP_ATTR_TYPE_NEXT_HOP) return True # Check if received MP_UNREACH path attribute is of available afi/safi if mp_unreach_attr: if not self.is_mpbgp_cap_valid(mp_unreach_attr.route_family): LOG.error('Got UPDATE message with un-available afi/safi for' ' MP_UNREACH path attribute (non-negotiated' ' afi/safi) %s', mp_unreach_attr.route_family) # raise bgp.OptAttrError() if mp_reach_attr: # Check if received MP_REACH path attribute is of available # afi/safi if not self.is_mpbgp_cap_valid(mp_reach_attr.route_family): LOG.error('Got UPDATE message with un-available afi/safi for' ' MP_UNREACH path attribute (non-negotiated' ' afi/safi) %s', mp_reach_attr.route_family) # raise bgp.OptAttrError() # Check for missing well-known mandatory attributes. aspath = update_msg.get_path_attr(BGP_ATTR_TYPE_AS_PATH) if not aspath: raise bgp.MissingWellKnown(BGP_ATTR_TYPE_AS_PATH) if (self.check_first_as and self.is_ebgp_peer() and not aspath.has_matching_leftmost(self.remote_as)): LOG.error('First AS check fails. Raise appropriate exception.') raise bgp.MalformedAsPath() origin = update_msg.get_path_attr(BGP_ATTR_TYPE_ORIGIN) if not origin: raise bgp.MissingWellKnown(BGP_ATTR_TYPE_ORIGIN) # Validate Next hop. if mp_reach_attr.route_family.safi in ( subaddr_family.IP_FLOWSPEC, subaddr_family.VPN_FLOWSPEC): # Because the Flow Specification does not have nexthop, # skips check. pass elif (not mp_reach_attr.next_hop or mp_reach_attr.next_hop == self.host_bind_ip): LOG.error('Nexthop of received UPDATE msg. (%s) same as local' ' interface address %s.', mp_reach_attr.next_hop, self.host_bind_ip) return False return True def _handle_update_msg(self, update_msg): """Extracts and processes new paths or withdrawals in given `update_msg`. Parameter: - `update_msg`: update message to process. - `valid_rts`: current valid/interesting rts to the application according to configuration of all VRFs. Assumes Multiprotocol Extensions capability is supported and enabled. """ assert self.state.bgp_state == const.BGP_FSM_ESTABLISHED # Increment count of update received. self.state.incr(PeerCounterNames.RECV_UPDATES) if not self._validate_update_msg(update_msg): # If update message was not valid for some reason, we ignore its # routes. LOG.error('UPDATE message was invalid, hence ignoring its routes.') return # Extract advertised path attributes and reconstruct AS_PATH attribute self._extract_and_reconstruct_as_path(update_msg) # Check if path attributes have loops. if self._is_looped_path_attrs(update_msg): return umsg_pattrs = update_msg.pathattr_map mp_reach_attr = umsg_pattrs.get(BGP_ATTR_TYPE_MP_REACH_NLRI, None) if mp_reach_attr: # Extract advertised MP-BGP paths from given message. self._extract_and_handle_mpbgp_new_paths(update_msg) mp_unreach_attr = umsg_pattrs.get(BGP_ATTR_TYPE_MP_UNREACH_NLRI, None) if mp_unreach_attr: # Extract MP-BGP withdraws from given message. self._extract_and_handle_mpbgp_withdraws(mp_unreach_attr) nlri_list = update_msg.nlri if nlri_list: # Extract advertised BGP paths from given message. self._extract_and_handle_bgp4_new_paths(update_msg) withdraw_list = update_msg.withdrawn_routes if withdraw_list: # Extract BGP withdraws from given message. self._extract_and_handle_bgp4_withdraws(withdraw_list) def _extract_and_reconstruct_as_path(self, update_msg): """Extracts advertised AS path attributes in the given update message and reconstructs AS_PATH from AS_PATH and AS4_PATH if needed.""" umsg_pattrs = update_msg.pathattr_map as_aggregator = umsg_pattrs.get(BGP_ATTR_TYPE_AGGREGATOR, None) as4_aggregator = umsg_pattrs.get(BGP_ATTR_TYPE_AS4_AGGREGATOR, None) if as_aggregator and as4_aggregator: # When both AGGREGATOR and AS4_AGGREGATOR are received, # if the AS number in the AGGREGATOR attribute is not AS_TRANS, # then: # - the AS4_AGGREGATOR attribute and the AS4_PATH attribute SHALL # be ignored, # - the AGGREGATOR attribute SHALL be taken as the information # about the aggregating node, and # - the AS_PATH attribute SHALL be taken as the AS path # information. if as_aggregator.as_number != bgp.AS_TRANS: update_msg.path_attributes.remove(as4_aggregator) as4_path = umsg_pattrs.pop(BGP_ATTR_TYPE_AS4_PATH, None) if as4_path: update_msg.path_attributes.remove(as4_path) # Otherwise, # - the AGGREGATOR attribute SHALL be ignored, # - the AS4_AGGREGATOR attribute SHALL be taken as the # information about the aggregating node, and # - the AS path information would need to be constructed, # as in all other cases. else: update_msg.path_attributes.remove(as_aggregator) update_msg.path_attributes.remove(as4_aggregator) update_msg.path_attributes.append( bgp.BGPPathAttributeAggregator( as_number=as4_aggregator.as_number, addr=as4_aggregator.addr, ) ) as_path = umsg_pattrs.get(BGP_ATTR_TYPE_AS_PATH, None) as4_path = umsg_pattrs.get(BGP_ATTR_TYPE_AS4_PATH, None) if as_path and as4_path: # If the number of AS numbers in the AS_PATH attribute is # less than the number of AS numbers in the AS4_PATH attribute, # then the AS4_PATH attribute SHALL be ignored, and the AS_PATH # attribute SHALL be taken as the AS path information. if as_path.get_as_path_len() < as4_path.get_as_path_len(): update_msg.path_attributes.remove(as4_path) # If the number of AS numbers in the AS_PATH attribute is larger # than or equal to the number of AS numbers in the AS4_PATH # attribute, then the AS path information SHALL be constructed # by taking as many AS numbers and path segments as necessary # from the leading part of the AS_PATH attribute, and then # prepending them to the AS4_PATH attribute so that the AS path # information has a number of AS numbers identical to that of # the AS_PATH attribute. else: update_msg.path_attributes.remove(as_path) update_msg.path_attributes.remove(as4_path) as_path = self._construct_as_path_attr(as_path, as4_path) update_msg.path_attributes.append(as_path) def _is_looped_path_attrs(self, update_msg): """ Extracts path attributes from the given UPDATE message and checks if the given attributes have loops or not. :param update_msg: UPDATE message instance. :return: True if attributes have loops. Otherwise False. """ umsg_pattrs = update_msg.pathattr_map recv_open_msg = self.protocol.recv_open_msg # Check if AS_PATH has loops. aspath = umsg_pattrs.get(BGP_ATTR_TYPE_AS_PATH) if (aspath is not None and aspath.has_local_as( self.local_as, max_count=self._common_conf.allow_local_as_in_count)): LOG.error( 'AS_PATH on UPDATE message has loops. ' 'Ignoring this message: %s', update_msg) return # Check if ORIGINATOR_ID has loops. [RFC4456] originator_id = umsg_pattrs.get(BGP_ATTR_TYPE_ORIGINATOR_ID, None) if (originator_id and recv_open_msg.bgp_identifier == originator_id): LOG.error( 'ORIGINATOR_ID on UPDATE message has loops. ' 'Ignoring this message: %s', update_msg) return # Check if CLUSTER_LIST has loops. [RFC4456] cluster_list = umsg_pattrs.get(BGP_ATTR_TYPE_CLUSTER_LIST, None) if (cluster_list and self._common_conf.cluster_id in cluster_list.value): LOG.error( 'CLUSTER_LIST on UPDATE message has loops. ' 'Ignoring this message: %s', update_msg) return def _extract_and_handle_bgp4_new_paths(self, update_msg): """Extracts new paths advertised in the given update message's *MpReachNlri* attribute. Assumes MPBGP capability is enabled and message was validated. Parameters: - update_msg: (Update) is assumed to be checked for all bgp message errors. - valid_rts: (iterable) current valid/configured RTs. Extracted paths are added to appropriate *Destination* for further processing. """ umsg_pattrs = update_msg.pathattr_map next_hop = update_msg.get_path_attr(BGP_ATTR_TYPE_NEXT_HOP).value # Nothing to do if we do not have any new NLRIs in this message. msg_nlri_list = update_msg.nlri if not msg_nlri_list: LOG.debug('Update message did not have any new MP_REACH_NLRIs.') return # Create path instances for each NLRI from the update message. for msg_nlri in msg_nlri_list: LOG.debug('NLRI: %s', msg_nlri) new_path = bgp_utils.create_path( self, msg_nlri, pattrs=umsg_pattrs, nexthop=next_hop ) LOG.debug('Extracted paths from Update msg.: %s', new_path) block, blocked_cause = self._apply_in_filter(new_path) nlri_str = new_path.nlri.formatted_nlri_str received_route = ReceivedRoute(new_path, self, block) self._adj_rib_in[nlri_str] = received_route self._signal_bus.adj_rib_in_changed(self, received_route) if not block: # Update appropriate table with new paths. tm = self._core_service.table_manager tm.learn_path(new_path) else: LOG.debug('prefix : %s is blocked by in-bound filter: %s', msg_nlri, blocked_cause) # If update message had any qualifying new paths, do some book-keeping. if msg_nlri_list: # Update prefix statistics. self.state.incr(PeerCounterNames.RECV_PREFIXES, incr_by=len(msg_nlri_list)) # Check if we exceed max. prefixes allowed for this neighbor. if self._neigh_conf.exceeds_max_prefix_allowed( self.state.get_count(PeerCounterNames.RECV_PREFIXES)): LOG.error('Max. prefix allowed for this neighbor ' 'exceeded.') def _extract_and_handle_bgp4_withdraws(self, withdraw_list): """Extracts withdraws advertised in the given update message's *MpUnReachNlri* attribute. Assumes MPBGP capability is enabled. Parameters: - update_msg: (Update) is assumed to be checked for all bgp message errors. Extracted withdraws are added to appropriate *Destination* for further processing. """ msg_rf = RF_IPv4_UC w_nlris = withdraw_list if not w_nlris: # If this is EOR of some kind, handle it self._handle_eor(msg_rf) for w_nlri in w_nlris: w_path = bgp_utils.create_path( self, w_nlri, is_withdraw=True ) block, blocked_cause = self._apply_in_filter(w_path) received_route = ReceivedRoute(w_path, self, block) nlri_str = w_nlri.formatted_nlri_str if nlri_str in self._adj_rib_in: del self._adj_rib_in[nlri_str] self._signal_bus.adj_rib_in_changed(self, received_route) if not block: # Update appropriate table with withdraws. tm = self._core_service.table_manager tm.learn_path(w_path) else: LOG.debug('prefix : %s is blocked by in-bound filter: %s', nlri_str, blocked_cause) def _extract_and_handle_mpbgp_new_paths(self, update_msg): """Extracts new paths advertised in the given update message's *MpReachNlri* attribute. Assumes MPBGP capability is enabled and message was validated. Parameters: - update_msg: (Update) is assumed to be checked for all bgp message errors. - valid_rts: (iterable) current valid/configured RTs. Extracted paths are added to appropriate *Destination* for further processing. """ umsg_pattrs = update_msg.pathattr_map mpreach_nlri_attr = umsg_pattrs.get(BGP_ATTR_TYPE_MP_REACH_NLRI) assert mpreach_nlri_attr msg_rf = mpreach_nlri_attr.route_family # Check if this route family is among supported route families. if msg_rf not in SUPPORTED_GLOBAL_RF: LOG.info(('Received route for route family %s which is' ' not supported. Ignoring paths from this UPDATE: %s') % (msg_rf, update_msg)) return if msg_rf in (RF_IPv4_VPN, RF_IPv6_VPN): # Check if we have Extended Communities Attribute. # TODO(PH): Check if RT_NLRI afi/safi will ever have this attribute ext_comm_attr = umsg_pattrs.get(BGP_ATTR_TYPE_EXTENDED_COMMUNITIES) # Check if we have at-least one RT is of interest to us. if not ext_comm_attr: LOG.info('Missing Extended Communities Attribute. ' 'Ignoring paths from this UPDATE: %s', update_msg) return msg_rts = ext_comm_attr.rt_list # If we do not have any RTs associated with this msg., we do not # extract any paths. if not msg_rts: LOG.info('Received route with no RTs. Ignoring paths in this' ' UPDATE: %s', update_msg) return # If none of the RTs in the message are of interest, we do not # extract any paths. interested_rts = self._core_service.global_interested_rts if not interested_rts.intersection(msg_rts): LOG.info('Received route with RT %s that is of no interest to' ' any VRFs or Peers %s.' ' Ignoring paths from this UPDATE: %s', msg_rts, interested_rts, update_msg) return next_hop = mpreach_nlri_attr.next_hop # Nothing to do if we do not have any new NLRIs in this message. msg_nlri_list = mpreach_nlri_attr.nlri if not msg_nlri_list: LOG.debug('Update message did not have any new MP_REACH_NLRIs.') return # Create path instances for each NLRI from the update message. for msg_nlri in msg_nlri_list: new_path = bgp_utils.create_path( self, msg_nlri, pattrs=umsg_pattrs, nexthop=next_hop ) LOG.debug('Extracted paths from Update msg.: %s', new_path) block, blocked_cause = self._apply_in_filter(new_path) received_route = ReceivedRoute(new_path, self, block) nlri_str = msg_nlri.formatted_nlri_str self._adj_rib_in[nlri_str] = received_route self._signal_bus.adj_rib_in_changed(self, received_route) if not block: if msg_rf == RF_RTC_UC \ and self._init_rtc_nlri_path is not None: self._init_rtc_nlri_path.append(new_path) else: # Update appropriate table with new paths. tm = self._core_service.table_manager tm.learn_path(new_path) else: LOG.debug('prefix : %s is blocked by in-bound filter: %s', msg_nlri, blocked_cause) # If update message had any qualifying new paths, do some book-keeping. if msg_nlri_list: # Update prefix statistics. self.state.incr(PeerCounterNames.RECV_PREFIXES, incr_by=len(msg_nlri_list)) # Check if we exceed max. prefixes allowed for this neighbor. if self._neigh_conf.exceeds_max_prefix_allowed( self.state.get_count(PeerCounterNames.RECV_PREFIXES)): LOG.error('Max. prefix allowed for this neighbor ' 'exceeded.') def _extract_and_handle_mpbgp_withdraws(self, mp_unreach_attr): """Extracts withdraws advertised in the given update message's *MpUnReachNlri* attribute. Assumes MPBGP capability is enabled. Parameters: - update_msg: (Update) is assumed to be checked for all bgp message errors. Extracted withdraws are added to appropriate *Destination* for further processing. """ msg_rf = mp_unreach_attr.route_family # Check if this route family is among supported route families. if msg_rf not in SUPPORTED_GLOBAL_RF: LOG.info( 'Received route family %s is not supported. ' 'Ignoring withdraw routes on this UPDATE message.', msg_rf) return w_nlris = mp_unreach_attr.withdrawn_routes if not w_nlris: # If this is EOR of some kind, handle it self._handle_eor(msg_rf) for w_nlri in w_nlris: w_path = bgp_utils.create_path( self, w_nlri, is_withdraw=True ) block, blocked_cause = self._apply_in_filter(w_path) received_route = ReceivedRoute(w_path, self, block) nlri_str = w_nlri.formatted_nlri_str if nlri_str in self._adj_rib_in: del self._adj_rib_in[nlri_str] self._signal_bus.adj_rib_in_changed(self, received_route) if not block: # Update appropriate table with withdraws. tm = self._core_service.table_manager tm.learn_path(w_path) else: LOG.debug('prefix : %s is blocked by in-bound filter: %s', w_nlri, blocked_cause) def _handle_eor(self, route_family): """Currently we only handle EOR for RTC address-family. We send non-rtc initial updates if not already sent. """ LOG.debug('Handling EOR for %s', route_family) # assert (route_family in SUPPORTED_GLOBAL_RF) # assert self.is_mbgp_cap_valid(route_family) if route_family == RF_RTC_UC: self._unschedule_sending_init_updates() # Learn all rt_nlri at the same time As RT are learned and RT # filter get updated, qualifying NLRIs are automatically sent to # peer including initial update tm = self._core_service.table_manager for rt_nlri in self._init_rtc_nlri_path: tm.learn_path(rt_nlri) # Give chance to process new RT_NLRI so that we have updated RT # filter for all peer including this peer before we communicate # NLRIs for other address-families self.pause(0) # Clear collection of initial RTs as we no longer need to wait for # EOR for RT NLRIs and to indicate that new RT NLRIs should be # handled in a regular fashion self._init_rtc_nlri_path = None def handle_msg(self, msg): """BGP message handler. BGP message handling is shared between protocol instance and peer. Peer only handles limited messages under suitable state. Here we handle KEEPALIVE, UPDATE and ROUTE_REFRESH messages. UPDATE and ROUTE_REFRESH messages are handled only after session is established. """ if msg.type == BGP_MSG_KEEPALIVE: # If we receive a Keep Alive message in open_confirm state, we # transition to established state. if self.state.bgp_state == const.BGP_FSM_OPEN_CONFIRM: self.state.bgp_state = const.BGP_FSM_ESTABLISHED self._enqueue_init_updates() elif msg.type == BGP_MSG_UPDATE: assert self.state.bgp_state == const.BGP_FSM_ESTABLISHED # Will try to process this UDPATE message further self._handle_update_msg(msg) elif msg.type == BGP_MSG_ROUTE_REFRESH: # If its route-refresh message assert self.state.bgp_state == const.BGP_FSM_ESTABLISHED self._handle_route_refresh_msg(msg) else: # Open/Notification messages are currently handled by protocol and # nothing is done inside peer, so should not see them here. raise ValueError('Peer does not support handling of %s' ' message during %s state' % (msg, self.state.bgp_state)) def _handle_err_sor_msg(self, afi, safi): # Check if ERR capability is enabled for this peer. if not self._protocol.is_enhanced_rr_cap_valid(): LOG.error('Received Start-of-RIB (SOR) even though ERR is not' ' enabled') return # Increment the version number of this peer so that we can identify # inconsistencies/stale routes. self.version_num += 1 # Check if refresh_stalepath_time is enabled. rst = self._common_conf.refresh_stalepath_time if rst != 0: # Set a timer to clean the stale paths at configured time. # Clean/track inconsistent/stale routes. route_family = RouteFamily(afi, safi) if route_family in SUPPORTED_GLOBAL_RF: self._refresh_stalepath_timer = self._spawn_after( 'err-refresh-stale-path-timer', rst, self._core_service.table_manager.clean_stale_routes, self, route_family) LOG.debug('Refresh Stale Path timer set (%s sec).', rst) def _handle_route_refresh_msg(self, msg): afi = msg.afi safi = msg.safi demarcation = msg.demarcation # If this normal route-refresh request. if demarcation == 0: self._handle_route_refresh_req(afi, safi) # If this is start of RIB (SOR) message. elif demarcation == 1: self._handle_err_sor_msg(afi, safi) # If this is end of RIB (EOR) message. elif demarcation == 2: # Clean/track inconsistent/stale routes. route_family = RouteFamily(afi, safi) if route_family in SUPPORTED_GLOBAL_RF: tm = self._core_service.table_manager tm.clean_stale_routes(self, route_family) else: LOG.error('Route refresh message has invalid demarcation %s', demarcation) def _handle_route_refresh_req(self, afi, safi): rr_af = get_rf(afi, safi) self.state.incr(PeerCounterNames.RECV_REFRESH) # Check if peer has asked for route-refresh for af that was advertised if not self._protocol.is_route_family_adv(rr_af): LOG.info('Peer asked for route - refresh for un - advertised ' 'address - family %s', rr_af) return self._fire_route_refresh(rr_af) def _fire_route_refresh(self, af): # Check if enhanced route refresh is enabled/valid. sor = None if self._protocol.is_enhanced_rr_cap_valid(): # If enhanced route-refresh is valid/enabled, enqueue SOR. afi = af.afi safi = af.safi sor = BGPRouteRefresh(afi, safi, demarcation=1) self.enque_first_outgoing_msg(sor) # Ask core to re-send sent routes self._peer_manager.resend_sent(af, self) # If enhanced route-refresh is valid/enabled, then we enqueue EOR. if sor is not None: self._enqueue_eor_msg(sor) def _enqueue_eor_msg(self, sor): """Enqueues Enhanced RR EOR if for given SOR a EOR is not already sent. """ if self._protocol.is_enhanced_rr_cap_valid() and not sor.eor_sent: afi = sor.afi safi = sor.safi eor = BGPRouteRefresh(afi, safi, demarcation=2) self.enque_outgoing_msg(eor) sor.eor_sent = True def _schedule_sending_init_updates(self): """Setup timer for sending best-paths for all other address-families that qualify. Setup timer for sending initial updates to peer. """ def _enqueue_non_rtc_init_updates(): LOG.debug('Scheduled queuing of initial Non-RTC UPDATEs') tm = self._core_service.table_manager self.comm_all_best_paths(tm.global_tables) self._sent_init_non_rtc_update = True # Stop the timer as we have handled RTC EOR self._rtc_eor_timer.stop() self._rtc_eor_timer = None self._sent_init_non_rtc_update = False self._rtc_eor_timer = self._create_timer( Peer.RTC_EOR_TIMER_NAME, _enqueue_non_rtc_init_updates ) # Start timer for sending initial updates self._rtc_eor_timer.start(const.RTC_EOR_DEFAULT_TIME, now=False) LOG.debug('Scheduled sending of initial Non-RTC UPDATEs after:' ' %s sec', const.RTC_EOR_DEFAULT_TIME) def _unschedule_sending_init_updates(self): """Un-schedules sending of initial updates Stops the timer if set for sending initial updates. Returns: - True if timer was stopped - False if timer was already stopped and nothing was done """ LOG.debug('Un-scheduling sending of initial Non-RTC UPDATEs' ' (init. UPDATEs already sent: %s)', self._sent_init_non_rtc_update) if self._rtc_eor_timer: self._rtc_eor_timer.stop() self._rtc_eor_timer = None return True return False def _enqueue_init_updates(self): """Enqueues current routes to be shared with this peer.""" assert self.state.bgp_state == const.BGP_FSM_ESTABLISHED if self.is_mbgp_cap_valid(RF_RTC_UC): # Enqueues all best-RTC_NLRIs to be sent as initial update to this # peer. self._peer_manager.comm_all_rt_nlris(self) self._schedule_sending_init_updates() else: # Enqueues all best-path to be sent as initial update to this peer # expect for RTC route-family. tm = self._core_service.table_manager self.comm_all_best_paths(tm.global_tables) def comm_all_best_paths(self, global_tables): """Shares/communicates current best paths with this peers. Can be used to send initial updates after we have established session with `peer`. """ LOG.debug('Communicating current best path for all afi/safi except' ' 1/132') # We will enqueue best path from all global destination. for route_family, table in global_tables.items(): if route_family == RF_RTC_UC: continue if self.is_mbgp_cap_valid(route_family): for dest in table.values(): if dest.best_path: self.communicate_path(dest.best_path) def communicate_path(self, path): """Communicates `path` to this peer if it qualifies. Checks if `path` should be shared/communicated with this peer according to various conditions: like bgp state, transmit side loop, local and remote AS path, community attribute, etc. """ LOG.debug('Peer %s asked to communicate path', self) if not path: raise ValueError('Invalid path %s given.' % path) # We do not send anything to peer who is not in established state. if not self.in_established(): LOG.debug('Skipping sending path as peer is not in ' 'ESTABLISHED state %s', path) return # Check if this session is available for given paths afi/safi path_rf = path.route_family if not (self.is_mpbgp_cap_valid(path_rf) or path_rf in [RF_IPv4_UC, RF_IPv6_UC]): LOG.debug('Skipping sending path as %s route family is not' ' available for this session', path_rf) return # If RTC capability is available and path afi/saif is other than RT # nlri if path_rf != RF_RTC_UC and \ self.is_mpbgp_cap_valid(RF_RTC_UC): rtfilter = self._peer_manager.curr_peer_rtfilter(self) # If peer does not have any rtfilter or if rtfilter does not have # any RTs common with path RTs we do not share this path with the # peer if rtfilter and not path.has_rts_in(rtfilter): LOG.debug('Skipping sending path as rffilter %s and path ' 'rts %s have no RT in common', rtfilter, path.get_rts()) return # Transmit side loop detection: We check if leftmost AS matches # peers AS, if so we do not send UPDATE message to this peer. as_path = path.get_pattr(BGP_ATTR_TYPE_AS_PATH) if as_path and as_path.has_matching_leftmost(self.remote_as): LOG.debug('Skipping sending path as AS_PATH has peer AS %s', self.remote_as) return # If this peer is a route server client, we forward the path # regardless of AS PATH loop, whether the connection is iBGP or eBGP, # or path's communities. if self.is_route_server_client: outgoing_route = OutgoingRoute(path) self.enque_outgoing_msg(outgoing_route) if self._neigh_conf.multi_exit_disc: med_attr = path.get_pattr(BGP_ATTR_TYPE_MULTI_EXIT_DISC) if not med_attr: path = bgp_utils.clone_path_and_update_med_for_target_neighbor( path, self._neigh_conf.multi_exit_disc ) # For connected/local-prefixes, we send update to all peers. if path.source is None: # Construct OutgoingRoute specific for this peer and put it in # its sink. outgoing_route = OutgoingRoute(path) self.enque_outgoing_msg(outgoing_route) # If path from a bgp-peer is new best path, we share it with # all bgp-peers except the source peer and other peers in his AS. # This is default Junos setting that in Junos can be disabled with # 'advertise-peer-as' setting. elif (self != path.source or self.remote_as != path.source.remote_as): # When BGP speaker receives an UPDATE message from an internal # peer, the receiving BGP speaker SHALL NOT re-distribute the # routing information contained in that UPDATE message to other # internal peers (unless the speaker acts as a BGP Route # Reflector) [RFC4271]. if (self.remote_as == self._core_service.asn and self.remote_as == path.source.remote_as and isinstance(path.source, Peer) and not path.source.is_route_reflector_client and not self.is_route_reflector_client): LOG.debug( 'Skipping sending iBGP route to iBGP peer %s AS %s', self.ip_address, self.remote_as) return # If new best path has community attribute, it should be taken into # account when sending UPDATE to peers. comm_attr = path.get_pattr(BGP_ATTR_TYPE_COMMUNITIES) if comm_attr: comm_attr_na = comm_attr.has_comm_attr( BGPPathAttributeCommunities.NO_ADVERTISE ) # If we have NO_ADVERTISE attribute present, we do not send # UPDATE to any peers if comm_attr_na: LOG.debug('Path has community attr. NO_ADVERTISE = %s' '. Hence not advertising to peer', comm_attr_na) return comm_attr_ne = comm_attr.has_comm_attr( BGPPathAttributeCommunities.NO_EXPORT ) comm_attr_nes = comm_attr.has_comm_attr( BGPPathAttributeCommunities.NO_EXPORT_SUBCONFED ) # If NO_EXPORT_SUBCONFED/NO_EXPORT is one of the attribute, we # do not advertise to eBGP peers as we do not have any # confederation feature at this time. if ((comm_attr_nes or comm_attr_ne) and (self.remote_as != self._core_service.asn)): LOG.debug('Skipping sending UPDATE to peer: %s as per ' 'community attribute configuration', self) return # Construct OutgoingRoute specific for this peer and put it in # its sink. outgoing_route = OutgoingRoute(path) self.enque_outgoing_msg(outgoing_route) LOG.debug('Enqueued outgoing route %s for peer %s', outgoing_route.path.nlri, self) def connection_made(self): """Protocols connection established handler """ LOG.info( 'Connection to peer: %s established', self._neigh_conf.ip_address, extra={ 'resource_name': self._neigh_conf.name, 'resource_id': self._neigh_conf.id } ) def connection_lost(self, reason): """Protocols connection lost handler. """ LOG.info( 'Connection to peer %s lost, reason: %s Resetting ' 'retry connect loop: %s' % (self._neigh_conf.ip_address, reason, self._connect_retry_event.is_set()), extra={ 'resource_name': self._neigh_conf.name, 'resource_id': self._neigh_conf.id } ) self.state.bgp_state = const.BGP_FSM_IDLE if self._protocol: self._protocol.stop() self._protocol = None # Create new collection for initial RT NLRIs self._init_rtc_nlri_path = [] self._sent_init_non_rtc_update = False # Clear sink. self.clear_outgoing_msg_list() # Un-schedule timers self._unschedule_sending_init_updates() # Increment the version number of this source. self.version_num += 1 self._peer_manager.on_peer_down(self) # Check configuration if neighbor is still enabled, we try # reconnecting. if self._neigh_conf.enabled: if not self._connect_retry_event.is_set(): self._connect_retry_event.set() @staticmethod def _lookup_attribute_map(attribute_map, attr_type, path): result_attr = None if attr_type in attribute_map: maps = attribute_map[attr_type] for m in maps: cause, result = m.evaluate(path) LOG.debug( "local_pref evaluation result:%s, cause:%s", result, cause) if result: result_attr = m.get_attribute() break return result_attr ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/processor.py0000664000175000017500000004505400000000000023307 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone 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. """ Module related to processing bgp paths. """ import logging from os_ken.services.protocols.bgp.base import Activity from os_ken.services.protocols.bgp.base import add_bgp_error_metadata from os_ken.services.protocols.bgp.base import BGP_PROCESSOR_ERROR_CODE from os_ken.services.protocols.bgp.base import BGPSException from os_ken.services.protocols.bgp.utils import circlist from os_ken.services.protocols.bgp.utils.evtlet import EventletIOFactory from os_ken.lib.packet.bgp import RF_RTC_UC from os_ken.lib.packet.bgp import BGP_ATTR_TYPE_AS_PATH from os_ken.lib.packet.bgp import BGP_ATTR_TYPE_LOCAL_PREF from os_ken.lib.packet.bgp import BGP_ATTR_TYPE_MULTI_EXIT_DISC from os_ken.lib.packet.bgp import BGP_ATTR_TYPE_ORIGIN from os_ken.lib.packet.bgp import BGP_ATTR_TYPE_ORIGINATOR_ID from os_ken.lib.packet.bgp import BGP_ATTR_TYPE_CLUSTER_LIST from os_ken.lib.packet.bgp import BGP_ATTR_ORIGIN_IGP from os_ken.lib.packet.bgp import BGP_ATTR_ORIGIN_EGP from os_ken.lib.packet.bgp import BGP_ATTR_ORIGIN_INCOMPLETE from os_ken.services.protocols.bgp.constants import VRF_TABLE LOG = logging.getLogger('bgpspeaker.processor') @add_bgp_error_metadata(code=BGP_PROCESSOR_ERROR_CODE, sub_code=1, def_desc='Error occurred when processing bgp ' 'destination.') class BgpProcessorError(BGPSException): """Base exception related to all destination path processing errors. """ pass # Disabling known bug in pylint. # pylint: disable=R0921 class BgpProcessor(Activity): """Worker that processes queued `Destination'. `Destination` that have updates related to its paths need to be (re)processed. Only one instance of this processor is enough for normal cases. If you want more control on which destinations get processed faster compared to other destinations, you can create several instance of this works to achieve the desired work flow. """ # Max. number of destinations processed per cycle. MAX_DEST_PROCESSED_PER_CYCLE = 100 # # DestQueue # # A circular list type in which objects are linked to each # other using the 'next_dest_to_process' and 'prev_dest_to_process' # attributes. # _DestQueue = circlist.CircularListType( next_attr_name='next_dest_to_process', prev_attr_name='prev_dest_to_process') def __init__(self, core_service, work_units_per_cycle=None): Activity.__init__(self) # Back pointer to core service instance that created this processor. self._core_service = core_service self._dest_queue = BgpProcessor._DestQueue() self._rtdest_queue = BgpProcessor._DestQueue() self.dest_que_evt = EventletIOFactory.create_custom_event() self.work_units_per_cycle =\ work_units_per_cycle or BgpProcessor.MAX_DEST_PROCESSED_PER_CYCLE def _run(self, *args, **kwargs): # Sit in tight loop, getting destinations from the queue and processing # one at a time. while True: LOG.debug('Starting new processing run...') # We process all RT destination first so that we get a new RT # filter that apply for each peer self._process_rtdest() # We then process a batch of other destinations (we do not process # all destination here as we want to give change to other # greenthread to run) self._process_dest() if self._dest_queue.is_empty(): # If we have no destinations queued for processing, we wait. self.dest_que_evt.clear() self.dest_que_evt.wait() else: self.pause(0) def _process_dest(self): dest_processed = 0 LOG.debug('Processing destination...') while (dest_processed < self.work_units_per_cycle and not self._dest_queue.is_empty()): # We process the first destination in the queue. next_dest = self._dest_queue.pop_first() if next_dest: next_dest.process() dest_processed += 1 def _process_rtdest(self): LOG.debug('Processing RT NLRI destination...') if self._rtdest_queue.is_empty(): return else: processed_any = False while not self._rtdest_queue.is_empty(): # We process the first destination in the queue. next_dest = self._rtdest_queue.pop_first() if next_dest: next_dest.process() processed_any = True if processed_any: # Since RT destination were updated we update RT filters self._core_service.update_rtfilters() def enqueue(self, destination): """Enqueues given destination for processing. Given instance should be a valid destination. """ if not destination: raise BgpProcessorError('Invalid destination %s.' % destination) dest_queue = self._dest_queue # RtDest are queued in a separate queue if destination.route_family == RF_RTC_UC: dest_queue = self._rtdest_queue # We do not add given destination to the queue for processing if # it is already on the queue. if not dest_queue.is_on_list(destination): dest_queue.append(destination) # Wake-up processing thread if sleeping. self.dest_que_evt.set() # ============================================================================= # Best path computation related utilities. # ============================================================================= # Various reasons a path is chosen as best path. BPR_UNKNOWN = 'Unknown' BPR_ONLY_PATH = 'Only Path' BPR_REACHABLE_NEXT_HOP = 'Reachable Next Hop' BPR_HIGHEST_WEIGHT = 'Highest Weight' BPR_LOCAL_PREF = 'Local Pref' BPR_LOCAL_ORIGIN = 'Local Origin' BPR_ASPATH = 'AS Path' BPR_ORIGIN = 'Origin' BPR_MED = 'MED' BPR_ASN = 'ASN' BPR_IGP_COST = 'IGP Cost' BPR_ROUTER_ID = 'Router ID' BPR_CLUSTER_LIST = 'Cluster List' def _compare_by_version(path1, path2): """Returns the current/latest learned path. Checks if given paths are from same source/peer and then compares their version number to determine which path is received later. If paths are from different source/peer return None. """ if path1.source == path2.source: if path1.source_version_num > path2.source_version_num: return path1 else: return path2 return None def compute_best_path(local_asn, path1, path2): """Compares given paths and returns best path. Parameters: -`local_asn`: asn of local bgpspeaker -`path1`: first path to compare -`path2`: second path to compare Best path processing will involve following steps: 1. Select a path with a reachable next hop. 2. Select the path with the highest weight. 3. If path weights are the same, select the path with the highest local preference value. 4. Prefer locally originated routes (network routes, redistributed routes, or aggregated routes) over received routes. 5. Select the route with the shortest AS-path length. 6. If all paths have the same AS-path length, select the path based on origin: IGP is preferred over EGP; EGP is preferred over Incomplete. 7. If the origins are the same, select the path with lowest MED value. 8. If the paths have the same MED values, select the path learned via EBGP over one learned via IBGP. 9. Select the route with the lowest IGP cost to the next hop. 10. Select the route received from the peer with the lowest BGP router ID. 11. Select the route received from the peer with the shorter CLUSTER_LIST length. Returns None if best-path among given paths cannot be computed else best path. Assumes paths from NC has source equal to None. """ best_path = None best_path_reason = BPR_UNKNOWN # Follow best path calculation algorithm steps. if best_path is None: best_path = _cmp_by_reachable_nh(path1, path2) best_path_reason = BPR_REACHABLE_NEXT_HOP if best_path is None: best_path = _cmp_by_highest_wg(path1, path2) best_path_reason = BPR_HIGHEST_WEIGHT if best_path is None: best_path = _cmp_by_local_pref(path1, path2) best_path_reason = BPR_LOCAL_PREF if best_path is None: best_path = _cmp_by_local_origin(path1, path2) best_path_reason = BPR_LOCAL_ORIGIN if best_path is None: best_path = _cmp_by_aspath(path1, path2) best_path_reason = BPR_ASPATH if best_path is None: best_path = _cmp_by_origin(path1, path2) best_path_reason = BPR_ORIGIN if best_path is None: best_path = _cmp_by_med(path1, path2) best_path_reason = BPR_MED if best_path is None: best_path = _cmp_by_asn(local_asn, path1, path2) best_path_reason = BPR_ASN if best_path is None: best_path = _cmp_by_igp_cost(path1, path2) best_path_reason = BPR_IGP_COST if best_path is None: best_path = _cmp_by_router_id(local_asn, path1, path2) best_path_reason = BPR_ROUTER_ID if best_path is None: best_path = _cmp_by_cluster_list(path1, path2) best_path_reason = BPR_CLUSTER_LIST if best_path is None: best_path_reason = BPR_UNKNOWN return best_path, best_path_reason def _cmp_by_reachable_nh(path1, path2): """Compares given paths and selects best path based on reachable next-hop. If no path matches this criteria, return None. """ # TODO(PH): Currently we do not have a way to check if a IGP route to # NEXT_HOP exists from BGPS. return None def _cmp_by_highest_wg(path1, path2): """Selects a path with highest weight. Weight is BGPS specific parameter. It is local to the router on which it is configured. Return: None if best path among given paths cannot be decided, else best path. """ # TODO(PH): Revisit this when BGPS has concept of policy to be applied to # in-bound NLRIs. return None def _cmp_by_local_pref(path1, path2): """Selects a path with highest local-preference. Unlike the weight attribute, which is only relevant to the local router, local preference is an attribute that routers exchange in the same AS. Highest local-pref is preferred. If we cannot decide, we return None. """ # TODO(PH): Revisit this when BGPS has concept of policy to be applied to # in-bound NLRIs. # Default local-pref values is 100 lp1 = path1.get_pattr(BGP_ATTR_TYPE_LOCAL_PREF) lp2 = path2.get_pattr(BGP_ATTR_TYPE_LOCAL_PREF) if not (lp1 and lp2): return None # Highest local-preference value is preferred. lp1 = lp1.value lp2 = lp2.value if lp1 > lp2: return path1 elif lp2 > lp1: return path2 else: return None def _cmp_by_local_origin(path1, path2): """Select locally originating path as best path. Locally originating routes are network routes, redistributed routes, or aggregated routes. For now we are going to prefer routes received through a Flexinet-Peer as locally originating route compared to routes received from a BGP peer. Returns None if given paths have same source. """ # If both paths are from same sources we cannot compare them here. if path1.source == path2.source: return None # Here we consider prefix from NC as locally originating static route. # Hence it is preferred. if path1.source is None: return path1 if path2.source is None: return path2 return None def _cmp_by_aspath(path1, path2): """Calculated the best-paths by comparing as-path lengths. Shortest as-path length is preferred. If both path have same lengths, we return None. """ as_path1 = path1.get_pattr(BGP_ATTR_TYPE_AS_PATH) as_path2 = path2.get_pattr(BGP_ATTR_TYPE_AS_PATH) assert as_path1 and as_path2 l1 = as_path1.get_as_path_len() l2 = as_path2.get_as_path_len() assert l1 is not None and l2 is not None if l1 > l2: return path2 elif l2 > l1: return path1 else: return None def _cmp_by_origin(path1, path2): """Select the best path based on origin attribute. IGP is preferred over EGP; EGP is preferred over Incomplete. If both paths have same origin, we return None. """ def get_origin_pref(origin): if origin.value == BGP_ATTR_ORIGIN_IGP: return 3 elif origin.value == BGP_ATTR_ORIGIN_EGP: return 2 elif origin.value == BGP_ATTR_ORIGIN_INCOMPLETE: return 1 else: LOG.error('Invalid origin value encountered %s.', origin) return 0 origin1 = path1.get_pattr(BGP_ATTR_TYPE_ORIGIN) origin2 = path2.get_pattr(BGP_ATTR_TYPE_ORIGIN) assert origin1 is not None and origin2 is not None # If both paths have same origins if origin1.value == origin2.value: return None # Translate origin values to preference. origin1 = get_origin_pref(origin1) origin2 = get_origin_pref(origin2) # Return preferred path. if origin1 == origin2: return None elif origin1 > origin2: return path1 return path2 def _cmp_by_med(path1, path2): """Select the path based with lowest MED value. If both paths have same MED, return None. By default, a route that arrives with no MED value is treated as if it had a MED of 0, the most preferred value. RFC says lower MED is preferred over higher MED value. """ def get_path_med(path): med = path.get_pattr(BGP_ATTR_TYPE_MULTI_EXIT_DISC) if not med: return 0 return med.value med1 = get_path_med(path1) med2 = get_path_med(path2) if med1 == med2: return None elif med1 < med2: return path1 return path2 def _cmp_by_asn(local_asn, path1, path2): """Select the path based on source (iBGP/eBGP) peer. eBGP path is preferred over iBGP. If both paths are from same kind of peers, return None. """ def get_path_source_asn(path): asn = None if path.source is None or path.source == VRF_TABLE: asn = local_asn else: asn = path.source.remote_as return asn p1_asn = get_path_source_asn(path1) p2_asn = get_path_source_asn(path2) # If path1 is from ibgp peer and path2 is from ebgp peer. if (p1_asn == local_asn) and (p2_asn != local_asn): return path2 # If path2 is from ibgp peer and path1 is from ebgp peer, if (p2_asn == local_asn) and (p1_asn != local_asn): return path1 # If both paths are from ebgp or ibpg peers, we cannot decide. return None def _cmp_by_igp_cost(path1, path2): """Select the route with the lowest IGP cost to the next hop. Return None if igp cost is same. """ # TODO(PH): Currently BGPS has no concept of IGP and IGP cost. return None def _cmp_by_router_id(local_asn, path1, path2): """Select the route received from the peer with the lowest BGP router ID. If both paths are eBGP paths, then we do not do any tie breaking, i.e we do not pick best-path based on this criteria. RFC: http://tools.ietf.org/html/rfc5004 We pick best path between two iBGP paths as usual. """ def get_asn(path_source): if path_source is None: return local_asn else: return path_source.remote_as def get_router_id(path, local_bgp_id): path_source = path.source if path_source is None: return local_bgp_id else: originator_id = path.get_pattr(BGP_ATTR_TYPE_ORIGINATOR_ID) if originator_id: return originator_id.value return path_source.protocol.recv_open_msg.bgp_identifier path_source1 = path1.source path_source2 = path2.source # If both paths are from NC we have same router Id, hence cannot compare. if path_source1 is None and path_source2 is None: return None asn1 = get_asn(path_source1) asn2 = get_asn(path_source2) is_ebgp1 = asn1 != local_asn is_ebgp2 = asn2 != local_asn # If both paths are from eBGP peers, then according to RFC we need # not tie break using router id. if is_ebgp1 and is_ebgp2: return None if ((is_ebgp1 is True and is_ebgp2 is False) or (is_ebgp1 is False and is_ebgp2 is True)): raise ValueError('This method does not support comparing ebgp with' ' ibgp path') # At least one path is not coming from NC, so we get local bgp id. if path_source1 is not None: local_bgp_id = path_source1.protocol.sent_open_msg.bgp_identifier else: local_bgp_id = path_source2.protocol.sent_open_msg.bgp_identifier # Get router ids. router_id1 = get_router_id(path1, local_bgp_id) router_id2 = get_router_id(path2, local_bgp_id) # If both router ids are same/equal we cannot decide. # This case is possible since router ids are arbitrary. if router_id1 == router_id2: return None # Select the path with lowest router Id. from os_ken.services.protocols.bgp.utils.bgp import from_inet_ptoi if from_inet_ptoi(router_id1) < from_inet_ptoi(router_id2): return path1 else: return path2 def _cmp_by_cluster_list(path1, path2): """Selects the route received from the peer with the shorter CLUSTER_LIST length. [RFC4456] The CLUSTER_LIST length is evaluated as zero if a route does not carry the CLUSTER_LIST attribute. """ def _get_cluster_list_len(path): c_list = path.get_pattr(BGP_ATTR_TYPE_CLUSTER_LIST) if c_list is None: return 0 else: return len(c_list.value) c_list_len1 = _get_cluster_list_len(path1) c_list_len2 = _get_cluster_list_len(path2) if c_list_len1 < c_list_len2: return path1 elif c_list_len1 > c_list_len2: return path2 else: return None ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/protocol.py0000664000175000017500000000522300000000000023123 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone 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. """ Module defines protocol based classes and utils. """ import abc class Protocol(object, metaclass=abc.ABCMeta): """Interface for various protocols. Protocol usually encloses a transport/connection/socket to peer/client/server and encodes and decodes communication/messages. Protocol can also maintain any related state machine, protocol message encoding or decoding utilities. This interface identifies minimum methods to support to facilitate or provide hooks to sub-classes to override behavior as appropriate. """ @abc.abstractmethod def data_received(self, data): """Handler for date received over connection/transport. Here *data* is in raw bytes. This *data* should further be converted to protocol specific messages and as appropriate transition to new state machine state or send appropriate response. """ pass @abc.abstractmethod def connection_made(self): """Called when connection has been established according to protocol. This is the right place to do some initialization or sending initial hello messages. """ pass @abc.abstractmethod def connection_lost(self, reason): """Handler called when connection to peer/remote according to protocol has been lost. Here we can do any clean-up related to connection/transport/timers/etc. """ pass class Factory(object, metaclass=abc.ABCMeta): """This is a factory which produces protocols. Can also act as context for protocols. """ # Put a subclass of Protocol here: protocol = None @abc.abstractmethod def build_protocol(self, socket): """Create an instance of a subclass of Protocol. Override this method to alter how Protocol instances get created. """ raise NotImplementedError() @abc.abstractmethod def start_protocol(self, socket): """Launch protocol instance to handle input on an incoming connection. """ raise NotImplementedError() ././@PaxHeader0000000000000000000000000000003300000000000011451 xustar000000000000000027 mtime=1724334546.114106 os-ken-2.10.0/os_ken/services/protocols/bgp/rtconf/0000775000175000017500000000000000000000000022201 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/rtconf/__init__.py0000664000175000017500000000000000000000000024300 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/rtconf/base.py0000664000175000017500000006623500000000000023501 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone 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. """ Running or runtime configuration base classes. """ import abc from abc import ABCMeta from abc import abstractmethod import functools import numbers import logging import uuid from os_ken.services.protocols.bgp.base import add_bgp_error_metadata from os_ken.services.protocols.bgp.base import BGPSException from os_ken.services.protocols.bgp.base import get_validator from os_ken.services.protocols.bgp.base import RUNTIME_CONF_ERROR_CODE from os_ken.services.protocols.bgp.base import validate from os_ken.services.protocols.bgp.utils import validation from os_ken.services.protocols.bgp.utils.validation import is_valid_asn LOG = logging.getLogger('bgpspeaker.rtconf.base') # # Nested settings. # CAP_REFRESH = 'cap_refresh' CAP_ENHANCED_REFRESH = 'cap_enhanced_refresh' CAP_FOUR_OCTET_AS_NUMBER = 'cap_four_octet_as_number' CAP_MBGP_IPV4 = 'cap_mbgp_ipv4' CAP_MBGP_IPV6 = 'cap_mbgp_ipv6' CAP_MBGP_VPNV4 = 'cap_mbgp_vpnv4' CAP_MBGP_VPNV6 = 'cap_mbgp_vpnv6' CAP_MBGP_EVPN = 'cap_mbgp_evpn' CAP_MBGP_IPV4FS = 'cap_mbgp_ipv4fs' CAP_MBGP_IPV6FS = 'cap_mbgp_ipv6fs' CAP_MBGP_VPNV4FS = 'cap_mbgp_vpnv4fs' CAP_MBGP_VPNV6FS = 'cap_mbgp_vpnv6fs' CAP_MBGP_L2VPNFS = 'cap_mbgp_l2vpnfs' CAP_RTC = 'cap_rtc' RTC_AS = 'rtc_as' HOLD_TIME = 'hold_time' # To control how many prefixes can be received from a neighbor. # 0 value indicates no limit and other related options will be ignored. # Current behavior is to log that limit has reached. MAX_PREFIXES = 'max_prefixes' # Has same meaning as: http://www.juniper.net/techpubs/software/junos/junos94 # /swconfig-routing/disabling-suppression-of-route- # advertisements.html#id-13255463 ADVERTISE_PEER_AS = 'advertise_peer_as' # MED - MULTI_EXIT_DISC MULTI_EXIT_DISC = 'multi_exit_disc' # Extended community attribute route origin. SITE_OF_ORIGINS = 'site_of_origins' # Constants related to errors. CONF_NAME = 'conf_name' CONF_VALUE = 'conf_value' # Max. value limits MAX_NUM_IMPORT_RT = 1000 MAX_NUM_EXPORT_RT = 250 MAX_NUM_SOO = 10 # ============================================================================= # Runtime configuration errors or exceptions. # ============================================================================= @add_bgp_error_metadata(code=RUNTIME_CONF_ERROR_CODE, sub_code=1, def_desc='Error with runtime-configuration.') class RuntimeConfigError(BGPSException): """Base class for all runtime configuration errors. """ pass @add_bgp_error_metadata(code=RUNTIME_CONF_ERROR_CODE, sub_code=2, def_desc='Missing required configuration.') class MissingRequiredConf(RuntimeConfigError): """Exception raised when trying to configure with missing required settings. """ def __init__(self, **kwargs): conf_name = kwargs.get('conf_name') if conf_name: super(MissingRequiredConf, self).__init__( desc='Missing required configuration: %s' % conf_name) else: super(MissingRequiredConf, self).__init__(desc=kwargs.get('desc')) @add_bgp_error_metadata(code=RUNTIME_CONF_ERROR_CODE, sub_code=3, def_desc='Incorrect Type for configuration.') class ConfigTypeError(RuntimeConfigError): """Exception raised when configuration value type miss-match happens. """ def __init__(self, **kwargs): conf_name = kwargs.get(CONF_NAME) conf_value = kwargs.get(CONF_VALUE) if conf_name and conf_value: super(ConfigTypeError, self).__init__( desc='Incorrect Type %s for configuration: %s' % (conf_value, conf_name)) elif conf_name: super(ConfigTypeError, self).__init__( desc='Incorrect Type for configuration: %s' % conf_name) else: super(ConfigTypeError, self).__init__(desc=kwargs.get('desc')) @add_bgp_error_metadata(code=RUNTIME_CONF_ERROR_CODE, sub_code=4, def_desc='Incorrect Value for configuration.') class ConfigValueError(RuntimeConfigError): """Exception raised when configuration value is of correct type but incorrect value. """ def __init__(self, **kwargs): conf_name = kwargs.get(CONF_NAME) conf_value = kwargs.get(CONF_VALUE) if conf_name and conf_value: super(ConfigValueError, self).__init__( desc='Incorrect Value %s for configuration: %s' % (conf_value, conf_name)) elif conf_name: super(ConfigValueError, self).__init__( desc='Incorrect Value for configuration: %s' % conf_name) else: super(ConfigValueError, self).__init__(desc=kwargs.get('desc')) # ============================================================================= # Configuration base classes. # ============================================================================= class BaseConf(object, metaclass=abc.ABCMeta): """Base class for a set of configuration values. Configurations can be required or optional. Also acts as a container of configuration change listeners. """ def __init__(self, **kwargs): self._req_settings = self.get_req_settings() self._opt_settings = self.get_opt_settings() self._valid_evts = self.get_valid_evts() self._listeners = {} self._settings = {} # validate required and unknown settings self._validate_req_unknown_settings(**kwargs) # Initialize configuration settings. self._init_req_settings(**kwargs) self._init_opt_settings(**kwargs) @property def settings(self): """Returns a copy of current settings.""" return self._settings.copy() @classmethod def get_valid_evts(cls): return set() @classmethod def get_req_settings(cls): return set() @classmethod def get_opt_settings(cls): return set() @abstractmethod def _init_opt_settings(self, **kwargs): """Sub-classes should override this method to initialize optional settings. """ pass @abstractmethod def update(self, **kwargs): # Validate given values self._validate_req_unknown_settings(**kwargs) def _validate_req_unknown_settings(self, **kwargs): """Checks if required settings are present. Also checks if unknown requirements are present. """ # Validate given configuration. self._all_attrs = (self._req_settings | self._opt_settings) if not kwargs and len(self._req_settings) > 0: raise MissingRequiredConf(desc='Missing all required attributes.') given_attrs = frozenset(kwargs.keys()) unknown_attrs = given_attrs - self._all_attrs if unknown_attrs: raise RuntimeConfigError(desc=( 'Unknown attributes: %s' % ', '.join([str(i) for i in unknown_attrs]))) missing_req_settings = self._req_settings - given_attrs if missing_req_settings: raise MissingRequiredConf(conf_name=list(missing_req_settings)) def _init_req_settings(self, **kwargs): for req_attr in self._req_settings: req_attr_value = kwargs.get(req_attr) if req_attr_value is None: raise MissingRequiredConf(conf_name=req_attr_value) # Validate attribute value req_attr_value = get_validator(req_attr)(req_attr_value) self._settings[req_attr] = req_attr_value def add_listener(self, evt, callback): # if (evt not in self.get_valid_evts()): # raise RuntimeConfigError(desc=('Unknown event %s' % evt)) listeners = self._listeners.get(evt, None) if not listeners: listeners = set() self._listeners[evt] = listeners listeners.update([callback]) def remove_listener(self, evt, callback): if evt in self.get_valid_evts(): listeners = self._listeners.get(evt, None) if listeners and (callback in listeners): listeners.remove(callback) return True return False def _notify_listeners(self, evt, value): listeners = self._listeners.get(evt, []) for callback in listeners: callback(ConfEvent(self, evt, value)) def __repr__(self): return '%s(%r)' % (self.__class__, self._settings) class ConfWithId(BaseConf): """Configuration settings related to identity.""" # Config./resource identifier. ID = 'id' # Config./resource name. NAME = 'name' # Config./resource description. DESCRIPTION = 'description' UPDATE_NAME_EVT = 'update_name_evt' UPDATE_DESCRIPTION_EVT = 'update_description_evt' VALID_EVT = frozenset([UPDATE_NAME_EVT, UPDATE_DESCRIPTION_EVT]) OPTIONAL_SETTINGS = frozenset([ID, NAME, DESCRIPTION]) def __init__(self, **kwargs): super(ConfWithId, self).__init__(**kwargs) @classmethod def get_opt_settings(cls): self_confs = super(ConfWithId, cls).get_opt_settings() self_confs.update(ConfWithId.OPTIONAL_SETTINGS) return self_confs @classmethod def get_req_settings(cls): self_confs = super(ConfWithId, cls).get_req_settings() return self_confs @classmethod def get_valid_evts(cls): self_valid_evts = super(ConfWithId, cls).get_valid_evts() self_valid_evts.update(ConfWithId.VALID_EVT) return self_valid_evts def _init_opt_settings(self, **kwargs): super(ConfWithId, self)._init_opt_settings(**kwargs) self._settings[ConfWithId.ID] = \ compute_optional_conf(ConfWithId.ID, str(uuid.uuid4()), **kwargs) self._settings[ConfWithId.NAME] = \ compute_optional_conf(ConfWithId.NAME, str(self), **kwargs) self._settings[ConfWithId.DESCRIPTION] = \ compute_optional_conf(ConfWithId.DESCRIPTION, str(self), **kwargs) @property def id(self): return self._settings[ConfWithId.ID] @property def name(self): return self._settings[ConfWithId.NAME] @name.setter def name(self, new_name): old_name = self.name if not new_name: new_name = repr(self) else: get_validator(ConfWithId.NAME)(new_name) if old_name != new_name: self._settings[ConfWithId.NAME] = new_name self._notify_listeners(ConfWithId.UPDATE_NAME_EVT, (old_name, self.name)) @property def description(self): return self._settings[ConfWithId.DESCRIPTION] @description.setter def description(self, new_description): old_desc = self.description if not new_description: new_description = str(self) else: get_validator(ConfWithId.DESCRIPTION)(new_description) if old_desc != new_description: self._settings[ConfWithId.DESCRIPTION] = new_description self._notify_listeners(ConfWithId.UPDATE_DESCRIPTION_EVT, (old_desc, self.description)) def update(self, **kwargs): # Update inherited configurations super(ConfWithId, self).update(**kwargs) self.name = compute_optional_conf(ConfWithId.NAME, str(self), **kwargs) self.description = compute_optional_conf(ConfWithId.DESCRIPTION, str(self), **kwargs) class ConfWithStats(BaseConf): """Configuration settings related to statistics collection.""" # Enable or disable statistics logging. STATS_LOG_ENABLED = 'statistics_log_enabled' DEFAULT_STATS_LOG_ENABLED = False # Statistics logging time. STATS_TIME = 'statistics_interval' DEFAULT_STATS_TIME = 60 UPDATE_STATS_LOG_ENABLED_EVT = 'update_stats_log_enabled_evt' UPDATE_STATS_TIME_EVT = 'update_stats_time_evt' VALID_EVT = frozenset([UPDATE_STATS_LOG_ENABLED_EVT, UPDATE_STATS_TIME_EVT]) OPTIONAL_SETTINGS = frozenset([STATS_LOG_ENABLED, STATS_TIME]) def __init__(self, **kwargs): super(ConfWithStats, self).__init__(**kwargs) def _init_opt_settings(self, **kwargs): super(ConfWithStats, self)._init_opt_settings(**kwargs) self._settings[ConfWithStats.STATS_LOG_ENABLED] = \ compute_optional_conf(ConfWithStats.STATS_LOG_ENABLED, ConfWithStats.DEFAULT_STATS_LOG_ENABLED, **kwargs) self._settings[ConfWithStats.STATS_TIME] = \ compute_optional_conf(ConfWithStats.STATS_TIME, ConfWithStats.DEFAULT_STATS_TIME, **kwargs) @property def stats_log_enabled(self): return self._settings[ConfWithStats.STATS_LOG_ENABLED] @stats_log_enabled.setter def stats_log_enabled(self, enabled): get_validator(ConfWithStats.STATS_LOG_ENABLED)(enabled) if enabled != self.stats_log_enabled: self._settings[ConfWithStats.STATS_LOG_ENABLED] = enabled self._notify_listeners(ConfWithStats.UPDATE_STATS_LOG_ENABLED_EVT, enabled) @property def stats_time(self): return self._settings[ConfWithStats.STATS_TIME] @stats_time.setter def stats_time(self, stats_time): get_validator(ConfWithStats.STATS_TIME)(stats_time) if stats_time != self.stats_time: self._settings[ConfWithStats.STATS_TIME] = stats_time self._notify_listeners(ConfWithStats.UPDATE_STATS_TIME_EVT, stats_time) @classmethod def get_opt_settings(cls): confs = super(ConfWithStats, cls).get_opt_settings() confs.update(ConfWithStats.OPTIONAL_SETTINGS) return confs @classmethod def get_valid_evts(cls): valid_evts = super(ConfWithStats, cls).get_valid_evts() valid_evts.update(ConfWithStats.VALID_EVT) return valid_evts def update(self, **kwargs): # Update inherited configurations super(ConfWithStats, self).update(**kwargs) self.stats_log_enabled = \ compute_optional_conf(ConfWithStats.STATS_LOG_ENABLED, ConfWithStats.DEFAULT_STATS_LOG_ENABLED, **kwargs) self.stats_time = \ compute_optional_conf(ConfWithStats.STATS_TIME, ConfWithStats.DEFAULT_STATS_TIME, **kwargs) class BaseConfListener(object, metaclass=abc.ABCMeta): """Base class of all configuration listeners.""" def __init__(self, base_conf): pass # TODO(PH): re-vist later and check if we need this check # if not isinstance(base_conf, BaseConf): # raise TypeError('Currently we only support listening to ' # 'instances of BaseConf') class ConfWithIdListener(BaseConfListener): def __init__(self, conf_with_id): assert conf_with_id super(ConfWithIdListener, self).__init__(conf_with_id) conf_with_id.add_listener(ConfWithId.UPDATE_NAME_EVT, self.on_chg_name_conf_with_id) conf_with_id.add_listener(ConfWithId.UPDATE_DESCRIPTION_EVT, self.on_chg_desc_conf_with_id) def on_chg_name_conf_with_id(self, conf_evt): # Note did not makes this method abstract as this is not important # event. raise NotImplementedError() def on_chg_desc_conf_with_id(self, conf_evt): # Note did not makes this method abstract as this is not important # event. raise NotImplementedError() class ConfWithStatsListener(BaseConfListener): def __init__(self, conf_with_stats): assert conf_with_stats super(ConfWithStatsListener, self).__init__(conf_with_stats) conf_with_stats.add_listener( ConfWithStats.UPDATE_STATS_LOG_ENABLED_EVT, self.on_chg_stats_enabled_conf_with_stats) conf_with_stats.add_listener(ConfWithStats.UPDATE_STATS_TIME_EVT, self.on_chg_stats_time_conf_with_stats) @abstractmethod def on_chg_stats_time_conf_with_stats(self, conf_evt): raise NotImplementedError() @abstractmethod def on_chg_stats_enabled_conf_with_stats(self, conf_evt): raise NotImplementedError() @functools.total_ordering class ConfEvent(object): """Encapsulates configuration settings change/update event.""" def __init__(self, evt_src, evt_name, evt_value): """Creates an instance using given parameters. Parameters: -`evt_src`: (BaseConf) source of the event -`evt_name`: (str) name of event, has to be one of the valid event of `evt_src` - `evt_value`: (tuple) event context that helps event handler """ if evt_name not in evt_src.get_valid_evts(): raise ValueError('Event %s is not a valid event for type %s.' % (evt_name, type(evt_src))) self._src = evt_src self._name = evt_name self._value = evt_value @property def src(self): return self._src @property def name(self): return self._name @property def value(self): return self._value def __repr__(self): return '' % (self.src, self.name, self.value) def __str__(self): return ('ConfEvent(src=%s, name=%s, value=%s)' % (self.src, self.name, self.value)) def __lt__(self, other): return ((self.src, self.name, self.value) < (other.src, other.name, other.value)) def __eq__(self, other): return ((self.src, self.name, self.value) == (other.src, other.name, other.value)) # ============================================================================= # Runtime configuration setting validators and their registry. # ============================================================================= @validate(name=ConfWithId.ID) def validate_conf_id(identifier): if not isinstance(identifier, str): raise ConfigTypeError(conf_name=ConfWithId.ID, conf_value=identifier) if len(identifier) > 128: raise ConfigValueError(conf_name=ConfWithId.ID, conf_value=identifier) return identifier @validate(name=ConfWithId.NAME) def validate_conf_name(name): if not isinstance(name, str): raise ConfigTypeError(conf_name=ConfWithId.NAME, conf_value=name) if len(name) > 128: raise ConfigValueError(conf_name=ConfWithId.NAME, conf_value=name) return name @validate(name=ConfWithId.DESCRIPTION) def validate_conf_desc(description): if not isinstance(description, str): raise ConfigTypeError(conf_name=ConfWithId.DESCRIPTION, conf_value=description) return description @validate(name=ConfWithStats.STATS_LOG_ENABLED) def validate_stats_log_enabled(stats_log_enabled): if not isinstance(stats_log_enabled, bool): raise ConfigTypeError(desc='Statistics log enabled settings can only' ' be boolean type.') return stats_log_enabled @validate(name=ConfWithStats.STATS_TIME) def validate_stats_time(stats_time): if not isinstance(stats_time, numbers.Integral): raise ConfigTypeError(desc='Statistics log timer value has to be of ' 'integral type but got: %r' % stats_time) if stats_time < 10: raise ConfigValueError(desc='Statistics log timer cannot be set to ' 'less then 10 sec, given timer value %s.' % stats_time) return stats_time @validate(name=CAP_REFRESH) def validate_cap_refresh(crefresh): if not isinstance(crefresh, bool): raise ConfigTypeError(desc='Invalid Refresh capability settings: %s. ' 'Boolean value expected' % crefresh) return crefresh @validate(name=CAP_ENHANCED_REFRESH) def validate_cap_enhanced_refresh(cer): if not isinstance(cer, bool): raise ConfigTypeError(desc='Invalid Enhanced Refresh capability ' 'settings: %s. Boolean value expected' % cer) return cer @validate(name=CAP_FOUR_OCTET_AS_NUMBER) def validate_cap_four_octet_as_number(cfoan): if not isinstance(cfoan, bool): raise ConfigTypeError(desc='Invalid Four-Octet AS Number capability ' 'settings: %s boolean value expected' % cfoan) return cfoan @validate(name=CAP_MBGP_IPV4) def validate_cap_mbgp_ipv4(cmv4): if not isinstance(cmv4, bool): raise ConfigTypeError(desc='Invalid MP-BGP IPv4 capability ' 'settings: %s. Boolean value expected' % cmv4) return cmv4 @validate(name=CAP_MBGP_IPV6) def validate_cap_mbgp_ipv6(cmv6): if not isinstance(cmv6, bool): raise ConfigTypeError(desc='Invalid MP-BGP IPv6 capability ' 'settings: %s. Boolean value expected' % cmv6) return cmv6 @validate(name=CAP_MBGP_VPNV4) def validate_cap_mbgp_vpnv4(cmv4): if not isinstance(cmv4, bool): raise ConfigTypeError(desc='Invalid MP-BGP VPNv4 capability ' 'settings: %s. Boolean value expected' % cmv4) return cmv4 @validate(name=CAP_MBGP_VPNV6) def validate_cap_mbgp_vpnv6(cmv6): if not isinstance(cmv6, bool): raise ConfigTypeError(desc='Invalid MP-BGP VPNv6 capability ' 'settings: %s. Boolean value expected' % cmv6) return cmv6 @validate(name=CAP_MBGP_EVPN) def validate_cap_mbgp_evpn(cmevpn): if not isinstance(cmevpn, bool): raise ConfigTypeError(desc='Invalid Ethernet VPN capability ' 'settings: %s. Boolean value expected' % cmevpn) return cmevpn @validate(name=CAP_MBGP_IPV4FS) def validate_cap_mbgp_ipv4fs(cmv4fs): if not isinstance(cmv4fs, bool): raise ConfigTypeError(desc='Invalid MP-BGP ' 'IPv4 Flow Specification capability ' 'settings: %s. Boolean value expected' % cmv4fs) return cmv4fs @validate(name=CAP_MBGP_IPV6FS) def validate_cap_mbgp_ipv6fs(cmv6fs): if not isinstance(cmv6fs, bool): raise ConfigTypeError(desc='Invalid MP-BGP ' 'IPv6 Flow Specification capability ' 'settings: %s. Boolean value expected' % cmv6fs) return cmv6fs @validate(name=CAP_MBGP_VPNV4FS) def validate_cap_mbgp_vpnv4fs(cmv4fs): if not isinstance(cmv4fs, bool): raise ConfigTypeError(desc='Invalid MP-BGP ' 'VPNv4 Flow Specification capability ' 'settings: %s. Boolean value expected' % cmv4fs) return cmv4fs @validate(name=CAP_MBGP_VPNV6FS) def validate_cap_mbgp_vpnv66fs(cmv6fs): if not isinstance(cmv6fs, bool): raise ConfigTypeError(desc='Invalid MP-BGP ' 'VPNv6 Flow Specification capability ' 'settings: %s. Boolean value expected' % cmv6fs) return cmv6fs @validate(name=CAP_MBGP_L2VPNFS) def validate_cap_mbgp_l2vpnfs(cml2fs): if not isinstance(cml2fs, bool): raise ConfigTypeError(desc='Invalid MP-BGP ' 'L2VPN Flow Specification capability ' 'settings: %s. Boolean value expected' % cml2fs) return cml2fs @validate(name=CAP_RTC) def validate_cap_rtc(cap_rtc): if not isinstance(cap_rtc, bool): raise ConfigTypeError(desc='Invalid type for specifying RTC ' 'capability. Expected boolean got: %s' % type(cap_rtc)) return cap_rtc @validate(name=RTC_AS) def validate_cap_rtc_as(rtc_as): if not is_valid_asn(rtc_as): raise ConfigValueError(desc='Invalid RTC AS configuration value: %s' % rtc_as) return rtc_as @validate(name=HOLD_TIME) def validate_hold_time(hold_time): if ((hold_time is None) or (not isinstance(hold_time, int)) or hold_time < 10): raise ConfigValueError(desc='Invalid hold_time configuration value %s' % hold_time) return hold_time @validate(name=MULTI_EXIT_DISC) def validate_med(med): if med is not None and not validation.is_valid_med(med): raise ConfigValueError(desc='Invalid multi-exit-discriminatory (med)' ' value: %s.' % med) return med @validate(name=SITE_OF_ORIGINS) def validate_soo_list(soo_list): if not isinstance(soo_list, list): raise ConfigTypeError(conf_name=SITE_OF_ORIGINS, conf_value=soo_list) if len(soo_list) > MAX_NUM_SOO: raise ConfigValueError(desc='Max. SOO is limited to %s' % MAX_NUM_SOO) if not all(validation.is_valid_ext_comm_attr(attr) for attr in soo_list): raise ConfigValueError(conf_name=SITE_OF_ORIGINS, conf_value=soo_list) # Check if we have duplicates unique_rts = set(soo_list) if len(unique_rts) != len(soo_list): raise ConfigValueError(desc='Duplicate value provided in %s' % soo_list) return soo_list @validate(name=MAX_PREFIXES) def validate_max_prefixes(max_prefixes): if not isinstance(max_prefixes, int): raise ConfigTypeError(desc='Max. prefixes value should be of type ' 'int or long but found %s' % type(max_prefixes)) if max_prefixes < 0: raise ConfigValueError(desc='Invalid max. prefixes value: %s' % max_prefixes) return max_prefixes @validate(name=ADVERTISE_PEER_AS) def validate_advertise_peer_as(advertise_peer_as): if not isinstance(advertise_peer_as, bool): raise ConfigTypeError(desc='Invalid type for advertise-peer-as, ' 'expected bool got %s' % type(advertise_peer_as)) return advertise_peer_as # ============================================================================= # Other utils. # ============================================================================= def compute_optional_conf(conf_name, default_value, **all_config): """Returns *conf_name* settings if provided in *all_config*, else returns *default_value*. Validates *conf_name* value if provided. """ conf_value = all_config.get(conf_name) if conf_value is not None: # Validate configuration value. conf_value = get_validator(conf_name)(conf_value) else: conf_value = default_value return conf_value ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/rtconf/common.py0000664000175000017500000003640200000000000024050 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone 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. """ Runtime configuration that applies to all bgp sessions, i.e. global settings. """ import logging import numbers from os_ken.lib import ip from os_ken.services.protocols.bgp.utils.validation import is_valid_ipv4 from os_ken.services.protocols.bgp.utils.validation import is_valid_asn from os_ken.services.protocols.bgp import rtconf from os_ken.services.protocols.bgp.rtconf.base import BaseConf from os_ken.services.protocols.bgp.rtconf.base import BaseConfListener from os_ken.services.protocols.bgp.rtconf.base import compute_optional_conf from os_ken.services.protocols.bgp.rtconf.base import ConfigTypeError from os_ken.services.protocols.bgp.rtconf.base import ConfigValueError from os_ken.services.protocols.bgp.rtconf.base import MissingRequiredConf from os_ken.services.protocols.bgp.rtconf.base import validate LOG = logging.getLogger('bgpspeaker.rtconf.common') # Global configuration settings. LOCAL_AS = 'local_as' ROUTER_ID = 'router_id' CLUSTER_ID = 'cluster_id' LABEL_RANGE = 'label_range' LABEL_RANGE_MAX = 'max' LABEL_RANGE_MIN = 'min' LOCAL_PREF = 'local_pref' # Similar to Cisco command 'allowas-in'. Allows the local ASN in the path. # Facilitates auto rd, auto rt import/export # ("rd auto/route-target both auto") and simplified spine/leaf architectures, # sharing an ASN between e.g. leafs. ALLOW_LOCAL_AS_IN_COUNT = 'allow_local_as_in_count' # Configuration that can be set at global level as well as per context # (session/vrf) level # Nested configuration override global or higher level configuration as they # are more granular. # TODO(apgw-dev) Nested configuration overriding higher level configuration is # currently low priority # Similar to Cisco command 'bgp refresh stalepath-time'. To cause the router to # remove stale routes from the BGP table even if the router does not receive a # Route-Refresh EOR message The bgp refresh stalepath-time command is not # needed under normal circumstances. # TODO(PH): Support this feature (currently low priority) REFRESH_STALEPATH_TIME = 'refresh_stalepath_time' # Similar to Cisco command 'bgp refresh max-eor-time'. The bgp refresh max-eor- # time command is not needed under normal circumstances. You might configure # the bgp refresh max-eor-time command in the event of continuous route # flapping, when the router is unable to generate a Route- Refresh EOR message, # in which case a Route-Refresh EOR is generated after the timer expires. # TODO(PH): Support this feature (currently low priority) REFRESH_MAX_EOR_TIME = 'refresh_max_eor_time' BGP_CONN_RETRY_TIME = 'bgp_conn_retry_time' BGP_SERVER_HOSTS = 'bgp_server_hosts' BGP_SERVER_PORT = 'bgp_server_port' TCP_CONN_TIMEOUT = 'tcp_conn_timeout' MAX_PATH_EXT_RTFILTER_ALL = 'maximum_paths_external_rtfilter_all' # Valid default values of some settings. DEFAULT_LABEL_RANGE = (100, 100000) DEFAULT_REFRESH_STALEPATH_TIME = 0 DEFAULT_REFRESH_MAX_EOR_TIME = 0 DEFAULT_BGP_SERVER_HOSTS = ('0.0.0.0', '::') DEFAULT_BGP_SERVER_PORT = 179 DEFAULT_TCP_CONN_TIMEOUT = 30 DEFAULT_BGP_CONN_RETRY_TIME = 30 DEFAULT_MED = 0 DEFAULT_MAX_PATH_EXT_RTFILTER_ALL = True DEFAULT_LOCAL_PREF = 100 @validate(name=ALLOW_LOCAL_AS_IN_COUNT) def validate_allow_local_as_in_count(count): if not isinstance(count, numbers.Integral): raise ConfigTypeError(desc=('Configuration value for %s has to be ' 'integral type' % ALLOW_LOCAL_AS_IN_COUNT)) if count < 0: raise ConfigValueError(desc='Invalid local AS count %s' % count) return count @validate(name=LOCAL_AS) def validate_local_as(asn): if asn is None: raise MissingRequiredConf(conf_name=LOCAL_AS) if not is_valid_asn(asn): raise ConfigValueError(desc='Invalid local_as configuration value: %s' % asn) return asn @validate(name=ROUTER_ID) def validate_router_id(router_id): if not router_id: raise MissingRequiredConf(conf_name=ROUTER_ID) if not isinstance(router_id, str): raise ConfigTypeError(conf_name=ROUTER_ID) if not is_valid_ipv4(router_id): raise ConfigValueError(desc='Invalid router id %s' % router_id) return router_id @validate(name=CLUSTER_ID) def validate_router_id(cluster_id): if not isinstance(cluster_id, str): raise ConfigTypeError(conf_name=CLUSTER_ID) if not is_valid_ipv4(cluster_id): raise ConfigValueError(desc='Invalid cluster id %s' % cluster_id) return cluster_id @validate(name=REFRESH_STALEPATH_TIME) def validate_refresh_stalepath_time(rst): if not isinstance(rst, numbers.Integral): raise ConfigTypeError(desc=('Configuration value for %s has to be ' 'integral type' % REFRESH_STALEPATH_TIME)) if rst < 0: raise ConfigValueError(desc='Invalid refresh stalepath time %s' % rst) return rst @validate(name=REFRESH_MAX_EOR_TIME) def validate_refresh_max_eor_time(rmet): if not isinstance(rmet, numbers.Integral): raise ConfigTypeError(desc=('Configuration value for %s has to be of ' 'integral type ' % REFRESH_MAX_EOR_TIME)) if rmet < 0: raise ConfigValueError(desc='Invalid refresh stalepath time %s' % rmet) return rmet @validate(name=LABEL_RANGE) def validate_label_range(label_range): min_label, max_label = label_range if (not min_label or not max_label or not isinstance(min_label, numbers.Integral) or not isinstance(max_label, numbers.Integral) or min_label < 17 or min_label >= max_label): raise ConfigValueError(desc=('Invalid label_range configuration value:' ' (%s).' % label_range)) return label_range @validate(name=BGP_SERVER_HOSTS) def validate_bgp_server_hosts(hosts): for host in hosts: if not ip.valid_ipv4(host) and not ip.valid_ipv6(host): raise ConfigTypeError(desc=('Invalid bgp sever hosts ' 'configuration value %s' % hosts)) return hosts @validate(name=BGP_SERVER_PORT) def validate_bgp_server_port(server_port): if not isinstance(server_port, numbers.Integral): raise ConfigTypeError(desc=('Invalid bgp sever port configuration ' 'value %s' % server_port)) if server_port < 0 or server_port > 65535: raise ConfigValueError(desc='Invalid server port %s' % server_port) return server_port @validate(name=TCP_CONN_TIMEOUT) def validate_tcp_conn_timeout(tcp_conn_timeout): # TODO(apgw-dev) made-up some valid values for this settings, check if we # have a standard value in any routers if not isinstance(tcp_conn_timeout, numbers.Integral): raise ConfigTypeError(desc=('Invalid tcp connection timeout ' 'configuration value %s' % tcp_conn_timeout)) if tcp_conn_timeout < 10: raise ConfigValueError(desc=('Invalid tcp connection timeout' ' configuration value %s' % tcp_conn_timeout)) return tcp_conn_timeout @validate(name=BGP_CONN_RETRY_TIME) def validate_bgp_conn_retry_time(bgp_conn_retry_time): if not isinstance(bgp_conn_retry_time, numbers.Integral): raise ConfigTypeError(desc=('Invalid bgp conn. retry time ' 'configuration value %s' % bgp_conn_retry_time)) if bgp_conn_retry_time < 10: raise ConfigValueError(desc=('Invalid bgp connection retry time' ' configuration value %s' % bgp_conn_retry_time)) return bgp_conn_retry_time @validate(name=MAX_PATH_EXT_RTFILTER_ALL) def validate_max_path_ext_rtfilter_all(max_path_ext_rtfilter_all): if not isinstance(max_path_ext_rtfilter_all, bool): raise ConfigTypeError(desc=('Invalid max_path_ext_rtfilter_all' ' configuration value %s' % max_path_ext_rtfilter_all)) return max_path_ext_rtfilter_all @validate(name=LOCAL_PREF) def validate_local_pref(local_pref): if not isinstance(local_pref, numbers.Integral): raise ConfigTypeError(desc=('Invalid local_pref' ' configuration value %s' % local_pref)) return local_pref class CommonConf(BaseConf): """Encapsulates configurations applicable to all peer sessions. Currently if any of these configurations change, it is assumed that current active peer session will be bought down and restarted. """ CONF_CHANGED_EVT = 1 VALID_EVT = frozenset([CONF_CHANGED_EVT]) REQUIRED_SETTINGS = frozenset([ROUTER_ID, LOCAL_AS]) OPTIONAL_SETTINGS = frozenset([REFRESH_STALEPATH_TIME, REFRESH_MAX_EOR_TIME, LABEL_RANGE, BGP_SERVER_HOSTS, BGP_SERVER_PORT, TCP_CONN_TIMEOUT, BGP_CONN_RETRY_TIME, MAX_PATH_EXT_RTFILTER_ALL, ALLOW_LOCAL_AS_IN_COUNT, CLUSTER_ID, LOCAL_PREF]) def __init__(self, **kwargs): super(CommonConf, self).__init__(**kwargs) def _init_opt_settings(self, **kwargs): super(CommonConf, self)._init_opt_settings(**kwargs) self._settings[ALLOW_LOCAL_AS_IN_COUNT] = compute_optional_conf( ALLOW_LOCAL_AS_IN_COUNT, 0, **kwargs) self._settings[LABEL_RANGE] = compute_optional_conf( LABEL_RANGE, DEFAULT_LABEL_RANGE, **kwargs) self._settings[REFRESH_STALEPATH_TIME] = compute_optional_conf( REFRESH_STALEPATH_TIME, DEFAULT_REFRESH_STALEPATH_TIME, **kwargs) self._settings[REFRESH_MAX_EOR_TIME] = compute_optional_conf( REFRESH_MAX_EOR_TIME, DEFAULT_REFRESH_MAX_EOR_TIME, **kwargs) self._settings[BGP_SERVER_HOSTS] = compute_optional_conf( BGP_SERVER_HOSTS, DEFAULT_BGP_SERVER_HOSTS, **kwargs) self._settings[BGP_SERVER_PORT] = compute_optional_conf( BGP_SERVER_PORT, DEFAULT_BGP_SERVER_PORT, **kwargs) self._settings[TCP_CONN_TIMEOUT] = compute_optional_conf( TCP_CONN_TIMEOUT, DEFAULT_TCP_CONN_TIMEOUT, **kwargs) self._settings[BGP_CONN_RETRY_TIME] = compute_optional_conf( BGP_CONN_RETRY_TIME, DEFAULT_BGP_CONN_RETRY_TIME, **kwargs) self._settings[MAX_PATH_EXT_RTFILTER_ALL] = compute_optional_conf( MAX_PATH_EXT_RTFILTER_ALL, DEFAULT_MAX_PATH_EXT_RTFILTER_ALL, **kwargs) self._settings[CLUSTER_ID] = compute_optional_conf( CLUSTER_ID, kwargs[ROUTER_ID], **kwargs) self._settings[LOCAL_PREF] = compute_optional_conf( LOCAL_PREF, DEFAULT_LOCAL_PREF, **kwargs) # ========================================================================= # Required attributes # ========================================================================= @property def local_as(self): return self._settings[LOCAL_AS] @property def router_id(self): return self._settings[ROUTER_ID] # ========================================================================= # Optional attributes with valid defaults. # ========================================================================= @property def cluster_id(self): return self._settings[CLUSTER_ID] @property def allow_local_as_in_count(self): return self._settings[ALLOW_LOCAL_AS_IN_COUNT] @property def bgp_conn_retry_time(self): return self._settings[BGP_CONN_RETRY_TIME] @property def tcp_conn_timeout(self): return self._settings[TCP_CONN_TIMEOUT] @property def refresh_stalepath_time(self): return self._settings[REFRESH_STALEPATH_TIME] @property def refresh_max_eor_time(self): return self._settings[REFRESH_MAX_EOR_TIME] @property def label_range(self): return self._settings[LABEL_RANGE] @property def bgp_server_hosts(self): return self._settings[BGP_SERVER_HOSTS] @property def bgp_server_port(self): return self._settings[BGP_SERVER_PORT] @property def max_path_ext_rtfilter_all(self): return self._settings[MAX_PATH_EXT_RTFILTER_ALL] @property def local_pref(self): return self._settings[LOCAL_PREF] @classmethod def get_opt_settings(self): self_confs = super(CommonConf, self).get_opt_settings() self_confs.update(CommonConf.OPTIONAL_SETTINGS) return self_confs @classmethod def get_req_settings(self): self_confs = super(CommonConf, self).get_req_settings() self_confs.update(CommonConf.REQUIRED_SETTINGS) return self_confs @classmethod def get_valid_evts(self): self_valid_evts = super(CommonConf, self).get_valid_evts() self_valid_evts.update(CommonConf.VALID_EVT) return self_valid_evts def update(self, **kwargs): """Updates global configuration settings with given values. First checks if given configuration values differ from current values. If any of the configuration values changed, generates a change event. Currently we generate change event for any configuration change. Note: This method is idempotent. """ # Update inherited configurations super(CommonConf, self).update(**kwargs) conf_changed = False # Validate given configurations and check if value changed for conf_name, conf_value in kwargs.items(): rtconf.base.get_validator(conf_name)(conf_value) item1 = self._settings.get(conf_name, None) item2 = kwargs.get(conf_name, None) if item1 != item2: conf_changed = True # If any configuration changed, we update configuration value and # notify listeners if conf_changed: for conf_name, conf_value in kwargs.items(): # Since all new values are already validated, we can use them self._settings[conf_name] = conf_value self._notify_listeners(CommonConf.CONF_CHANGED_EVT, self) class CommonConfListener(BaseConfListener): """Base listener for various changes to common configurations.""" def __init__(self, global_conf): super(CommonConfListener, self).__init__(global_conf) global_conf.add_listener(CommonConf.CONF_CHANGED_EVT, self.on_update_common_conf) def on_update_common_conf(self, evt): raise NotImplementedError('This method should be overridden.') ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/rtconf/neighbors.py0000664000175000017500000007641500000000000024550 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone 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. """ Running or runtime configuration related to bgp peers/neighbors. """ from abc import abstractmethod import logging import numbers import netaddr from os_ken.lib import ip from os_ken.lib.packet.bgp import RF_IPv4_UC from os_ken.lib.packet.bgp import RF_IPv6_UC from os_ken.lib.packet.bgp import RF_IPv4_VPN from os_ken.lib.packet.bgp import RF_IPv6_VPN from os_ken.lib.packet.bgp import RF_L2_EVPN from os_ken.lib.packet.bgp import RF_IPv4_FLOWSPEC from os_ken.lib.packet.bgp import RF_IPv6_FLOWSPEC from os_ken.lib.packet.bgp import RF_VPNv4_FLOWSPEC from os_ken.lib.packet.bgp import RF_VPNv6_FLOWSPEC from os_ken.lib.packet.bgp import RF_L2VPN_FLOWSPEC from os_ken.lib.packet.bgp import RF_RTC_UC from os_ken.lib.packet.bgp import BGPOptParamCapabilityFourOctetAsNumber from os_ken.lib.packet.bgp import BGPOptParamCapabilityEnhancedRouteRefresh from os_ken.lib.packet.bgp import BGPOptParamCapabilityMultiprotocol from os_ken.lib.packet.bgp import BGPOptParamCapabilityRouteRefresh from os_ken.lib.packet.bgp import BGP_CAP_FOUR_OCTET_AS_NUMBER from os_ken.lib.packet.bgp import BGP_CAP_ENHANCED_ROUTE_REFRESH from os_ken.lib.packet.bgp import BGP_CAP_MULTIPROTOCOL from os_ken.lib.packet.bgp import BGP_CAP_ROUTE_REFRESH from os_ken.services.protocols.bgp.base import OrderedDict from os_ken.services.protocols.bgp.constants import STD_BGP_SERVER_PORT_NUM from os_ken.services.protocols.bgp.rtconf.base import ADVERTISE_PEER_AS from os_ken.services.protocols.bgp.rtconf.base import BaseConf from os_ken.services.protocols.bgp.rtconf.base import BaseConfListener from os_ken.services.protocols.bgp.rtconf.base import CAP_ENHANCED_REFRESH from os_ken.services.protocols.bgp.rtconf.base import CAP_FOUR_OCTET_AS_NUMBER from os_ken.services.protocols.bgp.rtconf.base import CAP_MBGP_IPV4 from os_ken.services.protocols.bgp.rtconf.base import CAP_MBGP_IPV6 from os_ken.services.protocols.bgp.rtconf.base import CAP_MBGP_VPNV4 from os_ken.services.protocols.bgp.rtconf.base import CAP_MBGP_VPNV6 from os_ken.services.protocols.bgp.rtconf.base import CAP_MBGP_EVPN from os_ken.services.protocols.bgp.rtconf.base import CAP_MBGP_IPV4FS from os_ken.services.protocols.bgp.rtconf.base import CAP_MBGP_IPV6FS from os_ken.services.protocols.bgp.rtconf.base import CAP_MBGP_VPNV4FS from os_ken.services.protocols.bgp.rtconf.base import CAP_MBGP_VPNV6FS from os_ken.services.protocols.bgp.rtconf.base import CAP_MBGP_L2VPNFS from os_ken.services.protocols.bgp.rtconf.base import CAP_REFRESH from os_ken.services.protocols.bgp.rtconf.base import CAP_RTC from os_ken.services.protocols.bgp.rtconf.base import compute_optional_conf from os_ken.services.protocols.bgp.rtconf.base import ConfigTypeError from os_ken.services.protocols.bgp.rtconf.base import ConfigValueError from os_ken.services.protocols.bgp.rtconf.base import ConfWithId from os_ken.services.protocols.bgp.rtconf.base import ConfWithIdListener from os_ken.services.protocols.bgp.rtconf.base import ConfWithStats from os_ken.services.protocols.bgp.rtconf.base import ConfWithStatsListener from os_ken.services.protocols.bgp.rtconf.base import HOLD_TIME from os_ken.services.protocols.bgp.rtconf.base import MAX_PREFIXES from os_ken.services.protocols.bgp.rtconf.base import MULTI_EXIT_DISC from os_ken.services.protocols.bgp.rtconf.base import RTC_AS from os_ken.services.protocols.bgp.rtconf.base import RuntimeConfigError from os_ken.services.protocols.bgp.rtconf.base import SITE_OF_ORIGINS from os_ken.services.protocols.bgp.rtconf.base import validate from os_ken.services.protocols.bgp.rtconf.base import validate_med from os_ken.services.protocols.bgp.rtconf.base import validate_soo_list from os_ken.services.protocols.bgp.utils.validation import is_valid_asn from os_ken.services.protocols.bgp.info_base.base import Filter from os_ken.services.protocols.bgp.info_base.base import PrefixFilter from os_ken.services.protocols.bgp.info_base.base import AttributeMap LOG = logging.getLogger('bgpspeaker.rtconf.neighbor') # Various neighbor settings. REMOTE_AS = 'remote_as' IP_ADDRESS = 'ip_address' REMOTE_PORT = 'remote_port' ENABLED = 'enabled' CHANGES = 'changes' LOCAL_ADDRESS = 'local_address' LOCAL_PORT = 'local_port' LOCAL_AS = 'local_as' PEER_NEXT_HOP = 'peer_next_hop' PASSWORD = 'password' IN_FILTER = 'in_filter' OUT_FILTER = 'out_filter' IS_ROUTE_SERVER_CLIENT = 'is_route_server_client' IS_ROUTE_REFLECTOR_CLIENT = 'is_route_reflector_client' CHECK_FIRST_AS = 'check_first_as' ATTRIBUTE_MAP = 'attribute_map' IS_NEXT_HOP_SELF = 'is_next_hop_self' CONNECT_MODE = 'connect_mode' CONNECT_MODE_ACTIVE = 'active' CONNECT_MODE_PASSIVE = 'passive' CONNECT_MODE_BOTH = 'both' # Default value constants. DEFAULT_BGP_PORT = STD_BGP_SERVER_PORT_NUM DEFAULT_CAP_GR_NULL = True DEFAULT_CAP_REFRESH = True DEFAULT_CAP_ENHANCED_REFRESH = False DEFAULT_CAP_FOUR_OCTET_AS_NUMBER = True DEFAULT_CAP_MBGP_IPV4 = True DEFAULT_CAP_MBGP_IPV6 = False DEFAULT_CAP_MBGP_VPNV4 = False DEFAULT_CAP_MBGP_VPNV6 = False DEFAULT_CAP_MBGP_EVPN = False DEFAULT_CAP_MBGP_IPV4FS = False DEFAULT_CAP_MBGP_IPV6FS = False DEFAULT_CAP_MBGP_VPNV4FS = False DEFAULT_CAP_MBGP_VPNV6FS = False DEFAULT_CAP_MBGP_L2VPNFS = False DEFAULT_HOLD_TIME = 40 DEFAULT_ENABLED = True DEFAULT_CAP_RTC = False DEFAULT_IN_FILTER = [] DEFAULT_OUT_FILTER = [] DEFAULT_IS_ROUTE_SERVER_CLIENT = False DEFAULT_IS_ROUTE_REFLECTOR_CLIENT = False DEFAULT_CHECK_FIRST_AS = False DEFAULT_IS_NEXT_HOP_SELF = False DEFAULT_CONNECT_MODE = CONNECT_MODE_BOTH # Default value for *MAX_PREFIXES* setting is set to 0. DEFAULT_MAX_PREFIXES = 0 DEFAULT_ADVERTISE_PEER_AS = False @validate(name=ENABLED) def validate_enabled(enabled): if not isinstance(enabled, bool): raise ConfigValueError(desc='Enable property is not an instance of ' 'boolean') return enabled @validate(name=CHANGES) def validate_changes(changes): for k, v in changes.items(): if k not in (MULTI_EXIT_DISC, ENABLED, CONNECT_MODE): raise ConfigValueError(desc="Unknown field to change: %s" % k) if k == MULTI_EXIT_DISC: validate_med(v) elif k == ENABLED: validate_enabled(v) elif k == CONNECT_MODE: validate_connect_mode(v) return changes def valid_ip_address(addr): if not ip.valid_ipv4(addr) and not ip.valid_ipv6(addr): return False return True @validate(name=IP_ADDRESS) def validate_ip_address(ip_address): if not valid_ip_address(ip_address): raise ConfigValueError(desc='Invalid neighbor ip_address: %s' % ip_address) return str(netaddr.IPAddress(ip_address)) @validate(name=LOCAL_ADDRESS) def validate_local_address(ip_address): if not valid_ip_address(ip_address): raise ConfigValueError(desc='Invalid local ip_address: %s' % ip_address) return str(netaddr.IPAddress(ip_address)) @validate(name=PEER_NEXT_HOP) def validate_next_hop(ip_address): if not valid_ip_address(ip_address): raise ConfigValueError(desc='Invalid next_hop ip_address: %s' % ip_address) return str(netaddr.IPAddress(ip_address)) @validate(name=PASSWORD) def validate_password(password): return password @validate(name=LOCAL_PORT) def validate_local_port(port): if not isinstance(port, numbers.Integral): raise ConfigTypeError(desc='Invalid local port: %s' % port) if port < 1025 or port > 65535: raise ConfigValueError(desc='Invalid local port value: %s, has to be' ' between 1025 and 65535' % port) return port @validate(name=REMOTE_AS) def validate_remote_as(asn): if not is_valid_asn(asn): raise ConfigValueError(desc='Invalid remote as value %s' % asn) return asn @validate(name=REMOTE_PORT) def validate_remote_port(port): if not isinstance(port, numbers.Integral): raise ConfigTypeError(desc='Invalid remote port: %s' % port) return port def valid_prefix_filter(filter_): policy = filter_.get('policy', None) if policy == 'permit': policy = PrefixFilter.POLICY_PERMIT else: policy = PrefixFilter.POLICY_DENY prefix = filter_['prefix'] ge = filter_.get('ge', None) le = filter_.get('le', None) return PrefixFilter(prefix, policy, ge=ge, le=le) PREFIX_FILTER = 'prefix_filter' SUPPORTED_FILTER_VALIDATORS = { PREFIX_FILTER: valid_prefix_filter } def valid_filter(filter_): if isinstance(filter_, Filter): return filter_ if not isinstance(filter_, dict): raise ConfigTypeError(desc='Invalid filter: %s' % filter_) if 'type' not in filter_: raise ConfigTypeError(desc='Invalid filter: %s, needs \'type\' field' % filter_) if not filter_['type'] in SUPPORTED_FILTER_VALIDATORS: raise ConfigTypeError(desc='Invalid filter type: %s, supported filter' ' types are %s' % (filter_['type'], list(SUPPORTED_FILTER_VALIDATORS.keys()))) return SUPPORTED_FILTER_VALIDATORS[filter_['type']](filter_) def valid_attribute_map(attribute_map): if not isinstance(attribute_map, AttributeMap): raise ConfigTypeError(desc='Invalid AttributeMap: %s' % attribute_map) else: return attribute_map @validate(name=IN_FILTER) def validate_in_filters(filters): return [valid_filter(filter_) for filter_ in filters] @validate(name=OUT_FILTER) def validate_out_filters(filters): return [valid_filter(filter_) for filter_ in filters] @validate(name=ATTRIBUTE_MAP) def validate_attribute_maps(attribute_maps): return [valid_attribute_map(attribute_map) for attribute_map in attribute_maps] @validate(name=IS_ROUTE_SERVER_CLIENT) def validate_is_route_server_client(is_route_server_client): if not isinstance(is_route_server_client, bool): raise ConfigValueError(desc='Invalid is_route_server_client(%s)' % is_route_server_client) return is_route_server_client @validate(name=IS_ROUTE_REFLECTOR_CLIENT) def validate_is_route_reflector_client(is_route_reflector_client): if not isinstance(is_route_reflector_client, bool): raise ConfigValueError(desc='Invalid is_route_reflector_client(%s)' % is_route_reflector_client) return is_route_reflector_client @validate(name=CHECK_FIRST_AS) def validate_check_first_as(check_first_as): if not isinstance(check_first_as, bool): raise ConfigValueError(desc='Invalid check_first_as(%s)' % check_first_as) return check_first_as @validate(name=IS_NEXT_HOP_SELF) def validate_is_next_hop_self(is_next_hop_self): if not isinstance(is_next_hop_self, bool): raise ConfigValueError(desc='Invalid is_next_hop_self(%s)' % is_next_hop_self) return is_next_hop_self @validate(name=CONNECT_MODE) def validate_connect_mode(mode): if mode not in (CONNECT_MODE_ACTIVE, CONNECT_MODE_PASSIVE, CONNECT_MODE_BOTH): raise ConfigValueError(desc='Invalid connect_mode(%s)' % mode) return mode class NeighborConf(ConfWithId, ConfWithStats): """Class that encapsulates one neighbors' configuration.""" UPDATE_ENABLED_EVT = 'update_enabled_evt' UPDATE_MED_EVT = 'update_med_evt' UPDATE_CONNECT_MODE_EVT = 'update_connect_mode_evt' VALID_EVT = frozenset([UPDATE_ENABLED_EVT, UPDATE_MED_EVT, UPDATE_CONNECT_MODE_EVT]) REQUIRED_SETTINGS = frozenset([REMOTE_AS, IP_ADDRESS]) OPTIONAL_SETTINGS = frozenset([CAP_REFRESH, CAP_ENHANCED_REFRESH, CAP_FOUR_OCTET_AS_NUMBER, CAP_MBGP_IPV4, CAP_MBGP_IPV6, CAP_MBGP_VPNV4, CAP_MBGP_VPNV6, CAP_RTC, CAP_MBGP_EVPN, CAP_MBGP_IPV4FS, CAP_MBGP_VPNV4FS, CAP_MBGP_IPV6FS, CAP_MBGP_VPNV6FS, CAP_MBGP_L2VPNFS, RTC_AS, HOLD_TIME, REMOTE_PORT, ENABLED, MULTI_EXIT_DISC, MAX_PREFIXES, ADVERTISE_PEER_AS, SITE_OF_ORIGINS, LOCAL_ADDRESS, LOCAL_PORT, LOCAL_AS, PEER_NEXT_HOP, PASSWORD, IN_FILTER, OUT_FILTER, IS_ROUTE_SERVER_CLIENT, IS_ROUTE_REFLECTOR_CLIENT, CHECK_FIRST_AS, IS_NEXT_HOP_SELF, CONNECT_MODE]) def __init__(self, **kwargs): super(NeighborConf, self).__init__(**kwargs) def _init_opt_settings(self, **kwargs): self._settings[CAP_REFRESH] = compute_optional_conf( CAP_REFRESH, DEFAULT_CAP_REFRESH, **kwargs) self._settings[CAP_ENHANCED_REFRESH] = compute_optional_conf( CAP_ENHANCED_REFRESH, DEFAULT_CAP_ENHANCED_REFRESH, **kwargs) self._settings[CAP_FOUR_OCTET_AS_NUMBER] = compute_optional_conf( CAP_FOUR_OCTET_AS_NUMBER, DEFAULT_CAP_FOUR_OCTET_AS_NUMBER, **kwargs) self._settings[CAP_MBGP_IPV4] = compute_optional_conf( CAP_MBGP_IPV4, DEFAULT_CAP_MBGP_IPV4, **kwargs) self._settings[CAP_MBGP_IPV6] = compute_optional_conf( CAP_MBGP_IPV6, DEFAULT_CAP_MBGP_IPV6, **kwargs) self._settings[CAP_MBGP_VPNV4] = compute_optional_conf( CAP_MBGP_VPNV4, DEFAULT_CAP_MBGP_VPNV4, **kwargs) self._settings[CAP_MBGP_EVPN] = compute_optional_conf( CAP_MBGP_EVPN, DEFAULT_CAP_MBGP_EVPN, **kwargs) self._settings[CAP_MBGP_VPNV6] = compute_optional_conf( CAP_MBGP_VPNV6, DEFAULT_CAP_MBGP_VPNV6, **kwargs) self._settings[CAP_MBGP_IPV4FS] = compute_optional_conf( CAP_MBGP_IPV4FS, DEFAULT_CAP_MBGP_IPV4FS, **kwargs) self._settings[CAP_MBGP_IPV6FS] = compute_optional_conf( CAP_MBGP_IPV6FS, DEFAULT_CAP_MBGP_IPV6FS, **kwargs) self._settings[CAP_MBGP_VPNV4FS] = compute_optional_conf( CAP_MBGP_VPNV4FS, DEFAULT_CAP_MBGP_VPNV4FS, **kwargs) self._settings[CAP_MBGP_VPNV6FS] = compute_optional_conf( CAP_MBGP_VPNV6FS, DEFAULT_CAP_MBGP_VPNV6FS, **kwargs) self._settings[CAP_MBGP_L2VPNFS] = compute_optional_conf( CAP_MBGP_L2VPNFS, DEFAULT_CAP_MBGP_L2VPNFS, **kwargs) self._settings[HOLD_TIME] = compute_optional_conf( HOLD_TIME, DEFAULT_HOLD_TIME, **kwargs) self._settings[ENABLED] = compute_optional_conf( ENABLED, DEFAULT_ENABLED, **kwargs) self._settings[MAX_PREFIXES] = compute_optional_conf( MAX_PREFIXES, DEFAULT_MAX_PREFIXES, **kwargs) self._settings[ADVERTISE_PEER_AS] = compute_optional_conf( ADVERTISE_PEER_AS, DEFAULT_ADVERTISE_PEER_AS, **kwargs) self._settings[IN_FILTER] = compute_optional_conf( IN_FILTER, DEFAULT_IN_FILTER, **kwargs) self._settings[OUT_FILTER] = compute_optional_conf( OUT_FILTER, DEFAULT_OUT_FILTER, **kwargs) self._settings[IS_ROUTE_SERVER_CLIENT] = compute_optional_conf( IS_ROUTE_SERVER_CLIENT, DEFAULT_IS_ROUTE_SERVER_CLIENT, **kwargs) self._settings[IS_ROUTE_REFLECTOR_CLIENT] = compute_optional_conf( IS_ROUTE_REFLECTOR_CLIENT, DEFAULT_IS_ROUTE_REFLECTOR_CLIENT, **kwargs) self._settings[CHECK_FIRST_AS] = compute_optional_conf( CHECK_FIRST_AS, DEFAULT_CHECK_FIRST_AS, **kwargs) self._settings[IS_NEXT_HOP_SELF] = compute_optional_conf( IS_NEXT_HOP_SELF, DEFAULT_IS_NEXT_HOP_SELF, **kwargs) self._settings[CONNECT_MODE] = compute_optional_conf( CONNECT_MODE, DEFAULT_CONNECT_MODE, **kwargs) self._settings[REMOTE_PORT] = compute_optional_conf( REMOTE_PORT, DEFAULT_BGP_PORT, **kwargs) # We do not have valid default MED value. # If no MED attribute is provided then we do not have to use MED. # If MED attribute is provided we have to validate it and use it. med = kwargs.pop(MULTI_EXIT_DISC, None) if med and validate_med(med): self._settings[MULTI_EXIT_DISC] = med # We do not have valid default SOO value. # If no SOO attribute is provided then we do not have to use SOO. # If SOO attribute is provided we have to validate it and use it. soos = kwargs.pop(SITE_OF_ORIGINS, None) if soos and validate_soo_list(soos): self._settings[SITE_OF_ORIGINS] = soos # We do not have valid default LOCAL_ADDRESS and LOCAL_PORT value. # If no LOCAL_ADDRESS/PORT is provided then we will bind to system # default. self._settings[LOCAL_ADDRESS] = compute_optional_conf( LOCAL_ADDRESS, None, **kwargs) self._settings[LOCAL_PORT] = compute_optional_conf( LOCAL_PORT, None, **kwargs) # We use the global defined local (router) AS as the default # local AS. from os_ken.services.protocols.bgp.core_manager import CORE_MANAGER g_local_as = CORE_MANAGER.common_conf.local_as self._settings[LOCAL_AS] = compute_optional_conf( LOCAL_AS, g_local_as, **kwargs) self._settings[PEER_NEXT_HOP] = compute_optional_conf( PEER_NEXT_HOP, None, **kwargs) self._settings[PASSWORD] = compute_optional_conf( PASSWORD, None, **kwargs) # RTC configurations. self._settings[CAP_RTC] = compute_optional_conf( CAP_RTC, DEFAULT_CAP_RTC, **kwargs) # Default RTC_AS is local (router) AS. self._settings[RTC_AS] = compute_optional_conf( RTC_AS, g_local_as, **kwargs) # Since ConfWithId' default values use str(self) and repr(self), we # call super method after we have initialized other settings. super(NeighborConf, self)._init_opt_settings(**kwargs) @classmethod def get_opt_settings(cls): self_confs = super(NeighborConf, cls).get_opt_settings() self_confs.update(NeighborConf.OPTIONAL_SETTINGS) return self_confs @classmethod def get_req_settings(cls): self_confs = super(NeighborConf, cls).get_req_settings() self_confs.update(NeighborConf.REQUIRED_SETTINGS) return self_confs @classmethod def get_valid_evts(cls): self_valid_evts = super(NeighborConf, cls).get_valid_evts() self_valid_evts.update(NeighborConf.VALID_EVT) return self_valid_evts # ========================================================================= # Required attributes # ========================================================================= @property def remote_as(self): return self._settings[REMOTE_AS] @property def ip_address(self): return self._settings[IP_ADDRESS] @property def port(self): return self._settings[REMOTE_PORT] @property def host_bind_ip(self): return self._settings[LOCAL_ADDRESS] @property def host_bind_port(self): return self._settings[LOCAL_PORT] @property def next_hop(self): return self._settings[PEER_NEXT_HOP] @property def password(self): return self._settings[PASSWORD] # ========================================================================= # Optional attributes with valid defaults. # ========================================================================= @property def local_as(self): return self._settings[LOCAL_AS] @property def hold_time(self): return self._settings[HOLD_TIME] @property def cap_refresh(self): return self._settings[CAP_REFRESH] @property def cap_enhanced_refresh(self): return self._settings[CAP_ENHANCED_REFRESH] @property def cap_four_octet_as_number(self): return self._settings[CAP_FOUR_OCTET_AS_NUMBER] @cap_four_octet_as_number.setter def cap_four_octet_as_number(self, cap): kwargs = {CAP_FOUR_OCTET_AS_NUMBER: cap} self._settings[CAP_FOUR_OCTET_AS_NUMBER] = compute_optional_conf( CAP_FOUR_OCTET_AS_NUMBER, DEFAULT_CAP_FOUR_OCTET_AS_NUMBER, **kwargs) @property def cap_mbgp_ipv4(self): return self._settings[CAP_MBGP_IPV4] @property def cap_mbgp_ipv6(self): return self._settings[CAP_MBGP_IPV6] @property def cap_mbgp_vpnv4(self): return self._settings[CAP_MBGP_VPNV4] @property def cap_mbgp_vpnv6(self): return self._settings[CAP_MBGP_VPNV6] @property def cap_mbgp_evpn(self): return self._settings[CAP_MBGP_EVPN] @property def cap_mbgp_ipv4fs(self): return self._settings[CAP_MBGP_IPV4FS] @property def cap_mbgp_ipv6fs(self): return self._settings[CAP_MBGP_IPV6FS] @property def cap_mbgp_vpnv4fs(self): return self._settings[CAP_MBGP_VPNV4FS] @property def cap_mbgp_vpnv6fs(self): return self._settings[CAP_MBGP_VPNV6FS] @property def cap_mbgp_l2vpnfs(self): return self._settings[CAP_MBGP_L2VPNFS] @property def cap_rtc(self): return self._settings[CAP_RTC] @property def enabled(self): return self._settings[ENABLED] @enabled.setter def enabled(self, enable): # Update enabled flag and notify listeners. if self._settings[ENABLED] != enable: self._settings[ENABLED] = enable self._notify_listeners(NeighborConf.UPDATE_ENABLED_EVT, enable) # ========================================================================= # Optional attributes with no valid defaults. # ========================================================================= @property def multi_exit_disc(self): # This property does not have any valid default. Hence if not set we # return None. return self._settings.get(MULTI_EXIT_DISC) @multi_exit_disc.setter def multi_exit_disc(self, value): if self._settings.get(MULTI_EXIT_DISC) != value: self._settings[MULTI_EXIT_DISC] = value self._notify_listeners(NeighborConf.UPDATE_MED_EVT, value) @property def soo_list(self): soos = self._settings.get(SITE_OF_ORIGINS) if soos: soos = list(soos) else: soos = [] return soos @property def rtc_as(self): return self._settings[RTC_AS] @property def in_filter(self): return self._settings[IN_FILTER] @property def out_filter(self): return self._settings[OUT_FILTER] @property def is_route_server_client(self): return self._settings[IS_ROUTE_SERVER_CLIENT] @property def is_route_reflector_client(self): return self._settings[IS_ROUTE_REFLECTOR_CLIENT] @property def check_first_as(self): return self._settings[CHECK_FIRST_AS] @property def is_next_hop_self(self): return self._settings[IS_NEXT_HOP_SELF] @property def connect_mode(self): return self._settings[CONNECT_MODE] @connect_mode.setter def connect_mode(self, mode): self._settings[CONNECT_MODE] = mode self._notify_listeners(NeighborConf.UPDATE_CONNECT_MODE_EVT, mode) def exceeds_max_prefix_allowed(self, prefix_count): allowed_max = self._settings[MAX_PREFIXES] does_exceed = False # Check if allowed max. is unlimited. if allowed_max != 0: # If max. prefix is limited, check if given exceeds this limit. if prefix_count > allowed_max: does_exceed = True return does_exceed def get_configured_capabilities(self): """Returns configured capabilities.""" capabilities = OrderedDict() mbgp_caps = [] if self.cap_mbgp_ipv4: mbgp_caps.append( BGPOptParamCapabilityMultiprotocol( RF_IPv4_UC.afi, RF_IPv4_UC.safi)) if self.cap_mbgp_ipv6: mbgp_caps.append( BGPOptParamCapabilityMultiprotocol( RF_IPv6_UC.afi, RF_IPv6_UC.safi)) if self.cap_mbgp_vpnv4: mbgp_caps.append( BGPOptParamCapabilityMultiprotocol( RF_IPv4_VPN.afi, RF_IPv4_VPN.safi)) if self.cap_mbgp_vpnv6: mbgp_caps.append( BGPOptParamCapabilityMultiprotocol( RF_IPv6_VPN.afi, RF_IPv6_VPN.safi)) if self.cap_rtc: mbgp_caps.append( BGPOptParamCapabilityMultiprotocol( RF_RTC_UC.afi, RF_RTC_UC.safi)) if self.cap_mbgp_evpn: mbgp_caps.append( BGPOptParamCapabilityMultiprotocol( RF_L2_EVPN.afi, RF_L2_EVPN.safi)) if self.cap_mbgp_ipv4fs: mbgp_caps.append( BGPOptParamCapabilityMultiprotocol( RF_IPv4_FLOWSPEC.afi, RF_IPv4_FLOWSPEC.safi)) if self.cap_mbgp_ipv6fs: mbgp_caps.append( BGPOptParamCapabilityMultiprotocol( RF_IPv6_FLOWSPEC.afi, RF_IPv6_FLOWSPEC.safi)) if self.cap_mbgp_vpnv4fs: mbgp_caps.append( BGPOptParamCapabilityMultiprotocol( RF_VPNv4_FLOWSPEC.afi, RF_VPNv4_FLOWSPEC.safi)) if self.cap_mbgp_vpnv6fs: mbgp_caps.append( BGPOptParamCapabilityMultiprotocol( RF_VPNv6_FLOWSPEC.afi, RF_VPNv6_FLOWSPEC.safi)) if self.cap_mbgp_l2vpnfs: mbgp_caps.append( BGPOptParamCapabilityMultiprotocol( RF_L2VPN_FLOWSPEC.afi, RF_L2VPN_FLOWSPEC.safi)) if mbgp_caps: capabilities[BGP_CAP_MULTIPROTOCOL] = mbgp_caps if self.cap_refresh: capabilities[BGP_CAP_ROUTE_REFRESH] = [ BGPOptParamCapabilityRouteRefresh()] if self.cap_enhanced_refresh: capabilities[BGP_CAP_ENHANCED_ROUTE_REFRESH] = [ BGPOptParamCapabilityEnhancedRouteRefresh()] if self.cap_four_octet_as_number: capabilities[BGP_CAP_FOUR_OCTET_AS_NUMBER] = [ BGPOptParamCapabilityFourOctetAsNumber(self.local_as)] return capabilities def __repr__(self): return '<%s(%r, %r, %r)>' % (self.__class__.__name__, self.remote_as, self.ip_address, self.enabled) def __str__(self): return 'Neighbor: %s' % self.ip_address class NeighborsConf(BaseConf): """Container of all neighbor configurations.""" ADD_NEIGH_CONF_EVT = 'add_neigh_conf_evt' REMOVE_NEIGH_CONF_EVT = 'remove_neigh_conf_evt' VALID_EVT = frozenset([ADD_NEIGH_CONF_EVT, REMOVE_NEIGH_CONF_EVT]) def __init__(self): super(NeighborsConf, self).__init__() self._neighbors = {} def _init_opt_settings(self, **kwargs): pass def update(self, **kwargs): raise NotImplementedError('Use either add/remove_neighbor_conf' ' methods instead.') @property def rtc_as_set(self): """Returns current RTC AS configured for current neighbors. """ rtc_as_set = set() for neigh in self._neighbors.values(): rtc_as_set.add(neigh.rtc_as) return rtc_as_set @classmethod def get_valid_evts(cls): self_valid_evts = super(NeighborsConf, cls).get_valid_evts() self_valid_evts.update(NeighborsConf.VALID_EVT) return self_valid_evts def add_neighbor_conf(self, neigh_conf): # Check if we already know this neighbor if neigh_conf.ip_address in self._neighbors.keys(): message = 'Neighbor with given ip address already exists' raise RuntimeConfigError(desc=message) # Add this neighbor to known configured neighbors and generate update # event self._neighbors[neigh_conf.ip_address] = neigh_conf self._notify_listeners(NeighborsConf.ADD_NEIGH_CONF_EVT, neigh_conf) def remove_neighbor_conf(self, neigh_ip_address): neigh_conf = self._neighbors.pop(neigh_ip_address, None) if not neigh_conf: raise RuntimeConfigError(desc='Tried to remove a neighbor that ' 'does not exists') else: self._notify_listeners(NeighborsConf.REMOVE_NEIGH_CONF_EVT, neigh_conf) return neigh_conf def get_neighbor_conf(self, neigh_ip_address): return self._neighbors.get(neigh_ip_address, None) def __repr__(self): return '<%s(%r)>' % (self.__class__.__name__, self._neighbors) def __str__(self): return '\'Neighbors\': %s' % self._neighbors @property def settings(self): return [neighbor.settings for _, neighbor in self._neighbors.items()] class NeighborConfListener(ConfWithIdListener, ConfWithStatsListener): """Base listener for change events to a specific neighbors' configurations. """ def __init__(self, neigh_conf): super(NeighborConfListener, self).__init__(neigh_conf) neigh_conf.add_listener(NeighborConf.UPDATE_ENABLED_EVT, self.on_update_enabled) neigh_conf.add_listener(NeighborConf.UPDATE_MED_EVT, self.on_update_med) neigh_conf.add_listener(NeighborConf.UPDATE_CONNECT_MODE_EVT, self.on_update_connect_mode) @abstractmethod def on_update_enabled(self, evt): raise NotImplementedError('This method should be overridden.') @abstractmethod def on_update_med(self, evt): raise NotImplementedError('This method should be overridden.') @abstractmethod def on_update_connect_mode(self, evt): raise NotImplementedError('This method should be overridden.') class NeighborsConfListener(BaseConfListener): """Base listener for change events to neighbor configuration container.""" def __init__(self, neighbors_conf): super(NeighborsConfListener, self).__init__(neighbors_conf) neighbors_conf.add_listener(NeighborsConf.ADD_NEIGH_CONF_EVT, self.on_add_neighbor_conf) neighbors_conf.add_listener(NeighborsConf.REMOVE_NEIGH_CONF_EVT, self.on_remove_neighbor_conf) @abstractmethod def on_add_neighbor_conf(self, evt): raise NotImplementedError('This method should be overridden.') @abstractmethod def on_remove_neighbor_conf(self, evt): raise NotImplementedError('This method should be overridden.') ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/rtconf/vrfs.py0000664000175000017500000005065200000000000023543 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone 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. """ Running or runtime configuration related to Virtual Routing and Forwarding tables (VRFs). """ import abc import logging from os_ken.lib.packet.bgp import RF_IPv4_UC from os_ken.lib.packet.bgp import RF_IPv6_UC from os_ken.lib.packet.bgp import RF_L2_EVPN from os_ken.lib.packet.bgp import RF_IPv4_FLOWSPEC from os_ken.lib.packet.bgp import RF_IPv6_FLOWSPEC from os_ken.lib.packet.bgp import RF_L2VPN_FLOWSPEC from os_ken.services.protocols.bgp.utils import validation from os_ken.services.protocols.bgp.base import get_validator from os_ken.services.protocols.bgp.rtconf.base import BaseConf from os_ken.services.protocols.bgp.rtconf.base import BaseConfListener from os_ken.services.protocols.bgp.rtconf.base import ConfigTypeError from os_ken.services.protocols.bgp.rtconf.base import ConfigValueError from os_ken.services.protocols.bgp.rtconf.base import ConfWithId from os_ken.services.protocols.bgp.rtconf.base import ConfWithIdListener from os_ken.services.protocols.bgp.rtconf.base import ConfWithStats from os_ken.services.protocols.bgp.rtconf.base import ConfWithStatsListener from os_ken.services.protocols.bgp.rtconf.base import MAX_NUM_EXPORT_RT from os_ken.services.protocols.bgp.rtconf.base import MAX_NUM_IMPORT_RT from os_ken.services.protocols.bgp.rtconf.base import MULTI_EXIT_DISC from os_ken.services.protocols.bgp.rtconf.base import RuntimeConfigError from os_ken.services.protocols.bgp.rtconf.base import SITE_OF_ORIGINS from os_ken.services.protocols.bgp.rtconf.base import validate from os_ken.services.protocols.bgp.rtconf.base import validate_med from os_ken.services.protocols.bgp.rtconf.base import validate_soo_list LOG = logging.getLogger('bgpspeaker.rtconf.vrfs') # Configuration setting names. ROUTE_DISTINGUISHER = 'route_dist' IMPORT_RTS = 'import_rts' EXPORT_RTS = 'export_rts' VRF_NAME = 'vrf_name' VRF_DESC = 'vrf_desc' VRF_RF = 'route_family' IMPORT_MAPS = 'import_maps' # Supported VRF route-families VRF_RF_IPV4 = 'ipv4' VRF_RF_IPV6 = 'ipv6' VRF_RF_L2_EVPN = 'evpn' VRF_RF_IPV4_FLOWSPEC = 'ipv4fs' VRF_RF_IPV6_FLOWSPEC = 'ipv6fs' VRF_RF_L2VPN_FLOWSPEC = 'l2vpnfs' SUPPORTED_VRF_RF = ( VRF_RF_IPV4, VRF_RF_IPV6, VRF_RF_L2_EVPN, VRF_RF_IPV4_FLOWSPEC, VRF_RF_IPV6_FLOWSPEC, VRF_RF_L2VPN_FLOWSPEC, ) # Default configuration values. DEFAULT_VRF_NAME = 'no-vrf-name' DEFAULT_VRF_DESC = 'no-vrf-desc' @validate(name=IMPORT_RTS) def validate_import_rts(import_rts): if not isinstance(import_rts, list): raise ConfigTypeError(conf_name=IMPORT_RTS, conf_value=import_rts) if not (len(import_rts) <= MAX_NUM_IMPORT_RT): raise ConfigValueError(desc='Max. import RT is limited to %s' % MAX_NUM_IMPORT_RT) if not all(validation.is_valid_ext_comm_attr(rt) for rt in import_rts): raise ConfigValueError(conf_name=IMPORT_RTS, conf_value=import_rts) # Check if we have duplicates unique_rts = set(import_rts) if len(unique_rts) != len(import_rts): raise ConfigValueError(desc='Duplicate value provided %s' % import_rts) return import_rts @validate(name=EXPORT_RTS) def validate_export_rts(export_rts): if not isinstance(export_rts, list): raise ConfigTypeError(conf_name=EXPORT_RTS, conf_value=export_rts) if not (len(export_rts) <= MAX_NUM_EXPORT_RT): raise ConfigValueError(desc='Max. import RT is limited to %s' % MAX_NUM_EXPORT_RT) if not all(validation.is_valid_ext_comm_attr(rt) for rt in export_rts): raise ConfigValueError(conf_name=EXPORT_RTS, conf_value=export_rts) # Check if we have duplicates unique_rts = set(export_rts) if len(unique_rts) != len(export_rts): raise ConfigValueError(desc='Duplicate value provided in %s' % export_rts) return export_rts @validate(name=ROUTE_DISTINGUISHER) def validate_rd(route_dist): if not validation.is_valid_route_dist(route_dist): raise ConfigValueError(conf_name=ROUTE_DISTINGUISHER, conf_value=route_dist) return route_dist @validate(name=VRF_RF) def validate_vrf_rf(vrf_rf): if vrf_rf not in SUPPORTED_VRF_RF: raise ConfigValueError(desc='Give VRF route family %s is not ' 'supported.' % vrf_rf) return vrf_rf class VrfConf(ConfWithId, ConfWithStats): """Class that encapsulates configurations for one VRF.""" VRF_CHG_EVT = 'vrf_chg_evt' VALID_EVT = frozenset([VRF_CHG_EVT]) REQUIRED_SETTINGS = frozenset([ROUTE_DISTINGUISHER, IMPORT_RTS, EXPORT_RTS]) OPTIONAL_SETTINGS = frozenset( [VRF_NAME, MULTI_EXIT_DISC, SITE_OF_ORIGINS, VRF_RF, IMPORT_MAPS] ) def __init__(self, **kwargs): """Create an instance of VRF runtime configuration.""" super(VrfConf, self).__init__(**kwargs) def _init_opt_settings(self, **kwargs): super(VrfConf, self)._init_opt_settings(**kwargs) # We do not have valid default MED value. # If no MED attribute is provided then we do not have to use MED. # If MED attribute is provided we have to validate it and use it. med = kwargs.pop(MULTI_EXIT_DISC, None) if med and validate_med(med): self._settings[MULTI_EXIT_DISC] = med # We do not have valid default SOO value. # If no SOO attribute is provided then we do not have to use SOO. # If SOO attribute is provided we have to validate it and use it. soos = kwargs.pop(SITE_OF_ORIGINS, None) if soos and validate_soo_list(soos): self._settings[SITE_OF_ORIGINS] = soos # Current we we only support VRF for IPv4 and IPv6 with default IPv4 vrf_rf = kwargs.pop(VRF_RF, VRF_RF_IPV4) if vrf_rf and validate_vrf_rf(vrf_rf): self._settings[VRF_RF] = vrf_rf import_maps = kwargs.pop(IMPORT_MAPS, []) self._settings[IMPORT_MAPS] = import_maps # ========================================================================= # Required attributes # ========================================================================= @property def route_dist(self): return self._settings[ROUTE_DISTINGUISHER] # ========================================================================= # Optional attributes with valid defaults. # ========================================================================= @property def import_rts(self): return list(self._settings[IMPORT_RTS]) @property def export_rts(self): return list(self._settings[EXPORT_RTS]) @property def soo_list(self): soos = self._settings.get(SITE_OF_ORIGINS) if soos: soos = list(soos) else: soos = [] return soos @property def multi_exit_disc(self): """Returns configured value of MED, else None. This configuration does not have default value. """ return self._settings.get(MULTI_EXIT_DISC) @property def route_family(self): """Returns configured route family for this VRF This configuration does not change. """ return self._settings.get(VRF_RF) @property def rd_rf_id(self): return VrfConf.create_rd_rf_id(self.route_dist, self.route_family) @property def import_maps(self): return self._settings.get(IMPORT_MAPS) @staticmethod def create_rd_rf_id(route_dist, route_family): return route_dist, route_family @staticmethod def vrf_rf_2_rf(vrf_rf): if vrf_rf == VRF_RF_IPV4: return RF_IPv4_UC elif vrf_rf == VRF_RF_IPV6: return RF_IPv6_UC elif vrf_rf == VRF_RF_L2_EVPN: return RF_L2_EVPN elif vrf_rf == VRF_RF_IPV4_FLOWSPEC: return RF_IPv4_FLOWSPEC elif vrf_rf == VRF_RF_IPV6_FLOWSPEC: return RF_IPv6_FLOWSPEC elif vrf_rf == VRF_RF_L2VPN_FLOWSPEC: return RF_L2VPN_FLOWSPEC else: raise ValueError('Unsupported VRF route family given %s' % vrf_rf) @staticmethod def rf_2_vrf_rf(route_family): if route_family == RF_IPv4_UC: return VRF_RF_IPV4 elif route_family == RF_IPv6_UC: return VRF_RF_IPV6 elif route_family == RF_L2_EVPN: return VRF_RF_L2_EVPN elif route_family == RF_IPv4_FLOWSPEC: return VRF_RF_IPV4_FLOWSPEC elif route_family == RF_IPv6_FLOWSPEC: return VRF_RF_IPV6_FLOWSPEC elif route_family == RF_L2VPN_FLOWSPEC: return VRF_RF_L2VPN_FLOWSPEC else: raise ValueError('No supported mapping for route family ' 'to vrf_route_family exists for %s' % route_family) @property def settings(self): """Returns a copy of current settings. As some of the attributes are themselves containers, we clone the settings to provide clones for those containers as well. """ # Shallow copy first cloned_setting = self._settings.copy() # Don't want clone to link to same RT containers cloned_setting[IMPORT_RTS] = self.import_rts cloned_setting[EXPORT_RTS] = self.export_rts cloned_setting[SITE_OF_ORIGINS] = self.soo_list return cloned_setting @classmethod def get_opt_settings(cls): self_confs = super(VrfConf, cls).get_opt_settings() self_confs.update(VrfConf.OPTIONAL_SETTINGS) return self_confs @classmethod def get_req_settings(cls): self_confs = super(VrfConf, cls).get_req_settings() self_confs.update(VrfConf.REQUIRED_SETTINGS) return self_confs @classmethod def get_valid_evts(cls): self_valid_evts = super(VrfConf, cls).get_valid_evts() self_valid_evts.update(VrfConf.VALID_EVT) return self_valid_evts def update(self, **kwargs): """Updates this `VrfConf` settings. Notifies listeners if any settings changed. Returns `True` if update was successful. This vrfs' route family, id and route dist settings cannot be updated/changed. """ # Update inherited configurations super(VrfConf, self).update(**kwargs) vrf_id = kwargs.get(ConfWithId.ID) vrf_rd = kwargs.get(ROUTE_DISTINGUISHER) vrf_rf = kwargs.get(VRF_RF) if (vrf_id != self.id or vrf_rd != self.route_dist or vrf_rf != self.route_family): raise ConfigValueError(desc='id/route-distinguisher/route-family' ' do not match configured value.') # Validate and update individual settings new_imp_rts, old_imp_rts = \ self._update_import_rts(**kwargs) export_rts_changed = self._update_export_rts(**kwargs) soos_list_changed = self._update_soo_list(**kwargs) med_changed = self._update_med(**kwargs) re_export_needed = (export_rts_changed or soos_list_changed or med_changed) import_maps = kwargs.get(IMPORT_MAPS, []) re_import_needed = self._update_importmaps(import_maps) # If we did have any change in value of any settings, we notify # listeners if (new_imp_rts is not None or old_imp_rts is not None or re_export_needed or re_import_needed): evt_value = ( new_imp_rts, old_imp_rts, import_maps, re_export_needed, re_import_needed ) self._notify_listeners(VrfConf.VRF_CHG_EVT, evt_value) return True def _update_import_rts(self, **kwargs): import_rts = kwargs.get(IMPORT_RTS) get_validator(IMPORT_RTS)(import_rts) curr_import_rts = set(self._settings[IMPORT_RTS]) import_rts = set(import_rts) if not import_rts.symmetric_difference(curr_import_rts): return None, None # Get the difference between current and new RTs new_import_rts = import_rts - curr_import_rts old_import_rts = curr_import_rts - import_rts # Update current RTs and notify listeners. self._settings[IMPORT_RTS] = import_rts return new_import_rts, old_import_rts def _update_export_rts(self, **kwargs): export_rts = kwargs.get(EXPORT_RTS) get_validator(EXPORT_RTS)(export_rts) curr_export_rts = set(self._settings[EXPORT_RTS]) if curr_export_rts.symmetric_difference(export_rts): # Update current RTs and notify listeners. self._settings[EXPORT_RTS] = list(export_rts) return True return False def _update_soo_list(self, **kwargs): soo_list = kwargs.get(SITE_OF_ORIGINS, []) get_validator(SITE_OF_ORIGINS)(soo_list) curr_soos = set(self.soo_list) # If given list is different from existing settings, we update it if curr_soos.symmetric_difference(soo_list): self._settings[SITE_OF_ORIGINS] = soo_list[:] return True return False def _update_med(self, **kwargs): multi_exit_disc = kwargs.get(MULTI_EXIT_DISC, None) if multi_exit_disc: get_validator(MULTI_EXIT_DISC)(multi_exit_disc) if multi_exit_disc != self.multi_exit_disc: self._settings[MULTI_EXIT_DISC] = multi_exit_disc return True return False def _update_importmaps(self, import_maps): if set(self._settings[IMPORT_MAPS]).symmetric_difference(import_maps): self._settings[IMPORT_MAPS] = import_maps return True return False def __repr__(self): return ('<%s(route_dist: %r, import_rts: %r, export_rts: %r, ' 'soo_list: %r)>' % (self.__class__.__name__, self.route_dist, self.import_rts, self.export_rts, self.soo_list)) def __str__(self): return 'VrfConf-%s' % self.route_dist class VrfsConf(BaseConf): """Container for all VRF configurations.""" ADD_VRF_CONF_EVT, REMOVE_VRF_CONF_EVT = range(2) VALID_EVT = frozenset([ADD_VRF_CONF_EVT, REMOVE_VRF_CONF_EVT]) def __init__(self): super(VrfsConf, self).__init__() self._vrfs_by_rd_rf = {} self._vrfs_by_id = {} def _init_opt_settings(self, **kwargs): pass @property def vrf_confs(self): """Returns a list of configured `VrfConf`s """ return list(self._vrfs_by_rd_rf.values()) @property def vrf_interested_rts(self): interested_rts = set() for vrf_conf in self._vrfs_by_id.values(): interested_rts.update(vrf_conf.import_rts) return interested_rts def update(self, **kwargs): raise NotImplementedError('Use either add/remove_vrf_conf' ' methods instead.') def add_vrf_conf(self, vrf_conf): if vrf_conf.rd_rf_id in self._vrfs_by_rd_rf.keys(): raise RuntimeConfigError( desc='VrfConf with rd_rf %s already exists' % str(vrf_conf.rd_rf_id) ) if vrf_conf.id in self._vrfs_by_id: raise RuntimeConfigError( desc='VrfConf with id %s already exists' % str(vrf_conf.id) ) self._vrfs_by_rd_rf[vrf_conf.rd_rf_id] = vrf_conf self._vrfs_by_id[vrf_conf.id] = vrf_conf self._notify_listeners(VrfsConf.ADD_VRF_CONF_EVT, vrf_conf) def remove_vrf_conf(self, route_dist=None, vrf_id=None, vrf_rf=None): """Removes any matching `VrfConf` for given `route_dist` or `vrf_id` Parameters: - `route_dist`: (str) route distinguisher of a configured VRF - `vrf_id`: (str) vrf ID - `vrf_rf`: (str) route family of the VRF configuration If only `route_dist` is given, removes `VrfConf`s for all supported address families for this `route_dist`. If `vrf_rf` is given, than only removes `VrfConf` for that specific route family. If only `vrf_id` is given, matching `VrfConf` will be removed. """ if route_dist is None and vrf_id is None: raise RuntimeConfigError(desc='To delete supply route_dist or id.') # By default we remove all VRFs for given Id or RD vrf_rfs = SUPPORTED_VRF_RF # If asked to delete specific route family vrf conf. if vrf_rf: vrf_rfs = vrf_rf # For all vrf route family asked to be deleted, we collect all deleted # VrfConfs removed_vrf_confs = [] for route_family in vrf_rfs: if route_dist is not None: rd_rf_id = VrfConf.create_rd_rf_id(route_dist, route_family) vrf_conf = self._vrfs_by_rd_rf.pop(rd_rf_id, None) if vrf_conf: self._vrfs_by_id.pop(vrf_conf.id, None) removed_vrf_confs.append(vrf_conf) else: vrf_conf = self._vrfs_by_id.pop(vrf_id, None) if vrf_conf: self._vrfs_by_rd_rf.pop(vrf_conf.rd_rd_id, None) removed_vrf_confs.append(vrf_conf) # We do not raise any exception if we cannot find asked VRF. for vrf_conf in removed_vrf_confs: self._notify_listeners(VrfsConf.REMOVE_VRF_CONF_EVT, vrf_conf) return removed_vrf_confs def get_vrf_conf(self, route_dist, vrf_rf, vrf_id=None): if route_dist is None and vrf_id is None: raise RuntimeConfigError(desc='To get VRF supply route_dist ' 'or vrf_id.') if route_dist is not None and vrf_id is not None: vrf1 = self._vrfs_by_id.get(vrf_id) rd_rf_id = VrfConf.create_rd_rf_id(route_dist, vrf_rf) vrf2 = self._vrfs_by_rd_rf.get(rd_rf_id) if vrf1 is not vrf2: raise RuntimeConfigError(desc='Given VRF ID (%s) and RD (%s)' ' are not of same VRF.' % (vrf_id, route_dist)) vrf = vrf1 elif route_dist is not None: rd_rf_id = VrfConf.create_rd_rf_id(route_dist, vrf_rf) vrf = self._vrfs_by_rd_rf.get(rd_rf_id) else: vrf = self._vrfs_by_id.get(vrf_id) return vrf @property def vrfs_by_rd_rf_id(self): return dict(self._vrfs_by_rd_rf) @classmethod def get_valid_evts(cls): self_valid_evts = super(VrfsConf, cls).get_valid_evts() self_valid_evts.update(VrfsConf.VALID_EVT) return self_valid_evts def __repr__(self): return '<%s(%r)>' % (self.__class__.__name__, self._vrfs_by_id) @property def settings(self): return [vrf.settings for vrf in self._vrfs_by_id.values()] class VrfConfListener(ConfWithIdListener, ConfWithStatsListener): """Base listener for various VRF configuration change event.""" def __init__(self, vrf_conf): super(VrfConfListener, self).__init__(vrf_conf) vrf_conf.add_listener(VrfConf.VRF_CHG_EVT, self.on_chg_vrf_conf) def on_chg_vrf_conf(self, evt): raise NotImplementedError('This method should be overridden') class VrfsConfListener(BaseConfListener): """Base listener for VRF container change events.""" def __init__(self, vrfs_conf): super(VrfsConfListener, self).__init__(vrfs_conf) vrfs_conf.add_listener(VrfsConf.ADD_VRF_CONF_EVT, self.on_add_vrf_conf) vrfs_conf.add_listener(VrfsConf.REMOVE_VRF_CONF_EVT, self.on_remove_vrf_conf) @abc.abstractmethod def on_add_vrf_conf(self, evt): raise NotImplementedError('This method should be overridden') @abc.abstractmethod def on_remove_vrf_conf(self, evt): raise NotImplementedError('This method should be overridden') ././@PaxHeader0000000000000000000000000000003300000000000011451 xustar000000000000000027 mtime=1724334546.114106 os-ken-2.10.0/os_ken/services/protocols/bgp/signals/0000775000175000017500000000000000000000000022346 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/signals/__init__.py0000664000175000017500000000015300000000000024456 0ustar00zuulzuul00000000000000from os_ken.services.protocols.bgp.signals.base import SignalBus __all__ = [SignalBus] __author__ = 'yak' ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/signals/base.py0000664000175000017500000000201000000000000023623 0ustar00zuulzuul00000000000000import logging LOG = logging.getLogger('bgpspeaker.signals.base') class SignalBus(object): def __init__(self): self._listeners = {} def emit_signal(self, identifier, data): identifier = _to_tuple(identifier) LOG.debug('SIGNAL: %s emitted with data: %s ', identifier, data) for func, filter_func in self._listeners.get(identifier, []): if not filter_func or filter_func(data): func(identifier, data) def register_listener(self, identifier, func, filter_func=None): identifier = _to_tuple(identifier) substrings = (identifier[:i] for i in range(1, len(identifier) + 1)) for partial_id in substrings: self._listeners.setdefault( partial_id, [] ).append((func, filter_func)) def unregister_all(self): self._listeners = {} def _to_tuple(tuple_or_not): if not isinstance(tuple_or_not, tuple): return (tuple_or_not, ) else: return tuple_or_not ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/signals/emit.py0000664000175000017500000000513400000000000023661 0ustar00zuulzuul00000000000000from os_ken.services.protocols.bgp.signals import SignalBus class BgpSignalBus(SignalBus): BGP_ERROR = ('error', 'bgp') BGP_DEST_CHANGED = ('core', 'dest', 'changed') BGP_VRF_REMOVED = ('core', 'vrf', 'removed') BGP_VRF_ADDED = ('core', 'vrf', 'added') BGP_NOTIFICATION_RECEIVED = ('bgp', 'notification_received') BGP_NOTIFICATION_SENT = ('bgp', 'notification_sent') BGP_VRF_STATS_CONFIG_CHANGED = ( 'core', 'vrf', 'config', 'stats', 'changed' ) BGP_BEST_PATH_CHANGED = ('core', 'best', 'changed') BGP_ADJ_RIB_IN_CHANGED = ('core', 'adj', 'rib', 'in', 'changed') BGP_ADJ_RIB_OUT_CHANGED = ('core', 'adj', 'rib', 'out', 'changed') BGP_ADJ_UP = ('core', 'adj', 'up') BGP_ADJ_DOWN = ('core', 'adj', 'down') def bgp_error(self, peer, code, subcode, reason): return self.emit_signal( self.BGP_ERROR + (peer, ), {'code': code, 'subcode': subcode, 'reason': reason, 'peer': peer} ) def bgp_notification_received(self, peer, notification): return self.emit_signal( self.BGP_NOTIFICATION_RECEIVED + (peer,), notification ) def bgp_notification_sent(self, peer, notification): return self.emit_signal( self.BGP_NOTIFICATION_SENT + (peer,), notification ) def dest_changed(self, dest): return self.emit_signal( self.BGP_DEST_CHANGED, dest ) def vrf_removed(self, route_dist): return self.emit_signal( self.BGP_VRF_REMOVED, route_dist ) def vrf_added(self, vrf_conf): return self.emit_signal( self.BGP_VRF_ADDED, vrf_conf ) def stats_config_changed(self, vrf_conf): return self.emit_signal( self.BGP_VRF_STATS_CONFIG_CHANGED, vrf_conf ) def best_path_changed(self, path, is_withdraw): return self.emit_signal( self.BGP_BEST_PATH_CHANGED, {'path': path, 'is_withdraw': is_withdraw}) def adj_rib_in_changed(self, peer, received_route): return self.emit_signal( self.BGP_ADJ_RIB_IN_CHANGED, {'peer': peer, 'received_route': received_route}) def adj_rib_out_changed(self, peer, sent_route): return self.emit_signal( self.BGP_ADJ_RIB_OUT_CHANGED, {'peer': peer, 'sent_route': sent_route}) def adj_up(self, peer): return self.emit_signal(self.BGP_ADJ_UP, {'peer': peer}) def adj_down(self, peer): return self.emit_signal(self.BGP_ADJ_DOWN, {'peer': peer}) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/speaker.py0000664000175000017500000005575300000000000022731 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone 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. """ BGP protocol implementation. """ import logging import socket import struct import traceback from socket import IPPROTO_TCP, TCP_NODELAY from eventlet import semaphore from os_ken.lib.packet import bgp from os_ken.lib.packet.bgp import AS_TRANS from os_ken.lib.packet.bgp import BGPMessage from os_ken.lib.packet.bgp import BGPOpen from os_ken.lib.packet.bgp import BGPUpdate from os_ken.lib.packet.bgp import BGPKeepAlive from os_ken.lib.packet.bgp import BGPNotification from os_ken.lib.packet.bgp import BGP_MSG_OPEN from os_ken.lib.packet.bgp import BGP_MSG_UPDATE from os_ken.lib.packet.bgp import BGP_MSG_KEEPALIVE from os_ken.lib.packet.bgp import BGP_MSG_NOTIFICATION from os_ken.lib.packet.bgp import BGP_MSG_ROUTE_REFRESH from os_ken.lib.packet.bgp import BGP_CAP_FOUR_OCTET_AS_NUMBER from os_ken.lib.packet.bgp import BGP_CAP_ENHANCED_ROUTE_REFRESH from os_ken.lib.packet.bgp import BGP_CAP_MULTIPROTOCOL from os_ken.lib.packet.bgp import BGP_ERROR_HOLD_TIMER_EXPIRED from os_ken.lib.packet.bgp import BGP_ERROR_SUB_HOLD_TIMER_EXPIRED from os_ken.lib.packet.bgp import get_rf from os_ken.services.protocols.bgp.base import Activity from os_ken.services.protocols.bgp.base import add_bgp_error_metadata from os_ken.services.protocols.bgp.base import BGPSException from os_ken.services.protocols.bgp.base import CORE_ERROR_CODE from os_ken.services.protocols.bgp.constants import BGP_FSM_CONNECT from os_ken.services.protocols.bgp.constants import BGP_FSM_OPEN_CONFIRM from os_ken.services.protocols.bgp.constants import BGP_FSM_OPEN_SENT from os_ken.services.protocols.bgp.constants import BGP_VERSION_NUM from os_ken.services.protocols.bgp.protocol import Protocol LOG = logging.getLogger('bgpspeaker.speaker') # BGP min. and max. message lengths as per RFC. BGP_MIN_MSG_LEN = 19 BGP_MAX_MSG_LEN = 4096 # Keep-alive singleton. _KEEP_ALIVE = BGPKeepAlive() @add_bgp_error_metadata(code=CORE_ERROR_CODE, sub_code=2, def_desc='Unknown error occurred related to Speaker.') class BgpProtocolException(BGPSException): """Base exception related to peer connection management. """ pass def notification_factory(code, subcode): """Returns a `Notification` message corresponding to given codes. Parameters: - `code`: (int) BGP error code - `subcode`: (int) BGP error sub-code """ notification = BGPNotification(code, subcode) if not notification.reason: raise ValueError('Invalid code/sub-code.') return notification class BgpProtocol(Protocol, Activity): """Protocol that handles BGP messages. """ MESSAGE_MARKER = (b'\xff\xff\xff\xff\xff\xff\xff\xff' b'\xff\xff\xff\xff\xff\xff\xff\xff') def __init__(self, socket, signal_bus, is_reactive_conn=False): # Validate input. if socket is None: raise ValueError('Invalid arguments passed.') self._remotename = self.get_remotename(socket) self._localname = self.get_localname(socket) activity_name = ('BgpProtocol %s, %s, %s' % (is_reactive_conn, self._remotename, self._localname)) Activity.__init__(self, name=activity_name) # Initialize instance variables. self._peer = None self._recv_buff = b'' self._socket = socket self._socket.setsockopt(IPPROTO_TCP, TCP_NODELAY, 1) self._sendlock = semaphore.Semaphore() self._signal_bus = signal_bus self._holdtime = None self._keepalive = None self._expiry = None # Add socket to Activity's socket container for managing it. if is_reactive_conn: self._asso_socket_map['passive_conn'] = self._socket else: self._asso_socket_map['active_conn'] = self._socket self._open_msg = None self.state = BGP_FSM_CONNECT self._is_reactive = is_reactive_conn self.sent_open_msg = None self.recv_open_msg = None self._is_bound = False self.cap_four_octet_as_number = False @property def is_reactive(self): return self._is_reactive @property def holdtime(self): return self._holdtime @property def keepalive(self): return self._keepalive def is_colliding(self, other_protocol): if not isinstance(other_protocol, BgpProtocol): raise ValueError('Currently only support comparing with ' '`BgpProtocol`') # Compare protocol connection end point's addresses if (self._remotename[0] == other_protocol._remotename[0] and self._localname[0] == other_protocol._localname[0]): return True return False def is_local_router_id_greater(self): """Compares *True* if local router id is greater when compared to peer bgp id. Should only be called after protocol has reached OpenConfirm state. """ from os_ken.services.protocols.bgp.utils.bgp import from_inet_ptoi if not self.state == BGP_FSM_OPEN_CONFIRM: raise BgpProtocolException(desc='Can access remote router id only' ' after open message is received') remote_id = self.recv_open_msg.bgp_identifier local_id = self.sent_open_msg.bgp_identifier return from_inet_ptoi(local_id) > from_inet_ptoi(remote_id) def is_enhanced_rr_cap_valid(self): """Checks is enhanced route refresh capability is enabled/valid. Checks sent and received `Open` messages to see if this session with peer is capable of enhanced route refresh capability. """ if not self.recv_open_msg: raise ValueError('Did not yet receive peers open message.') err_cap_enabled = False local_caps = self.sent_open_msg.opt_param peer_caps = self.recv_open_msg.opt_param local_cap = [cap for cap in local_caps if cap.cap_code == BGP_CAP_ENHANCED_ROUTE_REFRESH] peer_cap = [cap for cap in peer_caps if cap.cap_code == BGP_CAP_ENHANCED_ROUTE_REFRESH] # Both local and peer should advertise ERR capability for it to be # enabled. if local_cap and peer_cap: err_cap_enabled = True return err_cap_enabled def _check_route_fmly_adv(self, open_msg, route_family): match_found = False local_caps = open_msg.opt_param for cap in local_caps: # Check MP_BGP capability was advertised. if cap.cap_code == BGP_CAP_MULTIPROTOCOL: # Iterate over all advertised mp_bgp caps to find a match. if (route_family.afi == cap.afi and route_family.safi == cap.safi): match_found = True return match_found def is_route_family_adv(self, route_family): """Checks if `route_family` was advertised to peer as per MP_BGP cap. Returns: - True: if given address family was advertised. - False: if given address family was not advertised. """ return self._check_route_fmly_adv(self.sent_open_msg, route_family) def is_route_family_adv_recv(self, route_family): """Checks if `route_family` was advertised by peer as per MP_BGP cap. Returns: - True: if given address family was advertised. - False: if given address family was not advertised. """ return self._check_route_fmly_adv(self.recv_open_msg, route_family) @property def negotiated_afs(self): local_caps = self.sent_open_msg.opt_param remote_caps = self.recv_open_msg.opt_param local_mbgp_cap = [cap for cap in local_caps if cap.cap_code == BGP_CAP_MULTIPROTOCOL] remote_mbgp_cap = [cap for cap in remote_caps if cap.cap_code == BGP_CAP_MULTIPROTOCOL] # Check MP_BGP capabilities were advertised. if local_mbgp_cap and remote_mbgp_cap: local_families = set([ (peer_cap.afi, peer_cap.safi) for peer_cap in local_mbgp_cap ]) remote_families = set([ (peer_cap.afi, peer_cap.safi) for peer_cap in remote_mbgp_cap ]) afi_safi = local_families.intersection(remote_families) else: afi_safi = set() afs = [] for afi, safi in afi_safi: afs.append(get_rf(afi, safi)) return afs def is_mbgp_cap_valid(self, route_family): """Returns True if both sides of this protocol have advertise capability for this address family. """ return (self.is_route_family_adv(route_family) and self.is_route_family_adv_recv(route_family)) def is_four_octet_as_number_cap_valid(self): """Returns True if both sides of this protocol have Four-Octet AS number capability.""" return (self.cap_four_octet_as_number and self._peer.cap_four_octet_as_number) def _run(self, peer): """Sends open message to peer and handles received messages. Parameters: - `peer`: the peer to which this protocol instance is connected to. """ # We know the peer we are connected to, we send open message. self._peer = peer self.connection_made() # We wait for peer to send messages. self._recv_loop() def data_received(self, next_bytes): try: self._data_received(next_bytes) except bgp.BgpExc as exc: LOG.error( "BGPExc Exception while receiving data: " "%s \n Traceback %s \n" % (str(exc), traceback.format_exc()) ) if exc.SEND_ERROR: self.send_notification(exc.CODE, exc.SUB_CODE) else: self._socket.close() raise exc @staticmethod def parse_msg_header(buff): """Parses given `buff` into bgp message header format. Returns a tuple of marker, length, type of bgp message. """ return struct.unpack('!16sHB', buff) def _data_received(self, next_bytes): """Maintains buffer of bytes received from peer and extracts bgp message from this buffer if enough data is received. Validates bgp message marker, length, type and data and constructs appropriate bgp message instance and calls handler. :Parameters: - `next_bytes`: next set of bytes received from peer. """ # Append buffer with received bytes. self._recv_buff += next_bytes while True: # If current buffer size is less then minimum bgp message size, we # return as we do not have a complete bgp message to work with. if len(self._recv_buff) < BGP_MIN_MSG_LEN: return # Parse message header into elements. auth, length, ptype = BgpProtocol.parse_msg_header( self._recv_buff[:BGP_MIN_MSG_LEN]) # Check if we have valid bgp message marker. # We should get default marker since we are not supporting any # authentication. if (auth != BgpProtocol.MESSAGE_MARKER): LOG.error('Invalid message marker received: %s', auth) raise bgp.NotSync() # Check if we have valid bgp message length. check = (length < BGP_MIN_MSG_LEN or length > BGP_MAX_MSG_LEN) # RFC says: The minimum length of the OPEN message is 29 # octets (including the message header). check2 = (ptype == BGP_MSG_OPEN and length < BGPOpen._MIN_LEN) # RFC says: A KEEPALIVE message consists of only the # message header and has a length of 19 octets. check3 = (ptype == BGP_MSG_KEEPALIVE and length != BGPKeepAlive._MIN_LEN) # RFC says: The minimum length of the UPDATE message is 23 # octets. check4 = (ptype == BGP_MSG_UPDATE and length < BGPUpdate._MIN_LEN) if any((check, check2, check3, check4)): raise bgp.BadLen(ptype, length) # If we have partial message we wait for rest of the message. if len(self._recv_buff) < length: return msg, _, rest = BGPMessage.parser(self._recv_buff) self._recv_buff = rest # If we have a valid bgp message we call message handler. self._handle_msg(msg) def send_notification(self, code, subcode): """Utility to send notification message. Closes the socket after sending the message. :Parameters: - `socket`: (socket) - socket over which to send notification message. - `code`: (int) - BGP Notification code - `subcode`: (int) - BGP Notification sub-code RFC ref: http://tools.ietf.org/html/rfc4486 http://www.iana.org/assignments/bgp-parameters/bgp-parameters.xhtml """ notification = BGPNotification(code, subcode) reason = notification.reason self._send_with_lock(notification) self._signal_bus.bgp_error(self._peer, code, subcode, reason) if len(self._localname): LOG.error('Sent notification to %r >> %s', self._localname, notification) self._socket.close() def _send_with_lock(self, msg): self._sendlock.acquire() try: self._socket.sendall(msg.serialize()) except socket.error: self.connection_lost('failed to write to socket') finally: self._sendlock.release() def send(self, msg): if not self.started: raise BgpProtocolException('Tried to send message to peer when ' 'this protocol instance is not started' ' or is no longer is started state.') self._send_with_lock(msg) if msg.type == BGP_MSG_NOTIFICATION: LOG.error('Sent notification to %s >> %s', self._remotename, msg) self._signal_bus.bgp_notification_sent(self._peer, msg) else: LOG.debug('Sent msg to %s >> %s', self._remotename, msg) def stop(self): Activity.stop(self) def _validate_open_msg(self, open_msg): """Validates BGP OPEN message according from application context. Parsing modules takes care of validating OPEN message that need no context. But here we validate it according to current application settings. RTC or RR/ERR are MUST capability if peer does not support either one of them we have to end session. """ assert open_msg.type == BGP_MSG_OPEN opt_param_cap_map = open_msg.opt_param_cap_map # Validate remote AS number. remote_as = open_msg.my_as # Try to get AS number from Four-Octet AS number capability. cap4as = opt_param_cap_map.get(BGP_CAP_FOUR_OCTET_AS_NUMBER, None) if cap4as is None: if remote_as == AS_TRANS: # Raise Bad Peer AS error message, if my_as is AS_TRANS # and without Four-Octet AS number capability. raise bgp.BadPeerAs() self.cap_four_octet_as_number = False else: # Note: Even if the peer has Four-Octet AS number capability, # keep the local capability setting remote_as = cap4as.as_number self.cap_four_octet_as_number = True # Validate remote AS number with local setting. if remote_as != self._peer.remote_as: raise bgp.BadPeerAs() # Validate bgp version number. if open_msg.version != BGP_VERSION_NUM: raise bgp.UnsupportedVersion(BGP_VERSION_NUM) def _handle_msg(self, msg): """When a BGP message is received, send it to peer. Open messages are validated here. Peer handler is called to handle each message except for *Open* and *Notification* message. On receiving *Notification* message we close connection with peer. """ LOG.debug('Received msg from %s << %s', self._remotename, msg) # If we receive open message we try to bind to protocol if msg.type == BGP_MSG_OPEN: if self.state == BGP_FSM_OPEN_SENT: # Validate open message. self._validate_open_msg(msg) self.recv_open_msg = msg self.state = BGP_FSM_OPEN_CONFIRM self._peer.state.bgp_state = self.state # Try to bind this protocol to peer. self._is_bound = self._peer.bind_protocol(self) # If this protocol failed to bind to peer. if not self._is_bound: # Failure to bind to peer indicates connection collision # resolution choose different instance of protocol and this # instance has to close. Before closing it sends # appropriate notification msg. to peer. raise bgp.CollisionResolution() # If peer sends Hold Time as zero, then according to RFC we do # not set Hold Time and Keep Alive timer. if msg.hold_time == 0: LOG.info('The Hold Time sent by the peer is zero, hence ' 'not setting any Hold Time and Keep Alive' ' timers.') else: # Start Keep Alive timer considering Hold Time preference # of the peer. self._start_timers(msg.hold_time) self._send_keepalive() # Peer does not see open message. return else: # If we receive a Open message out of order LOG.error('Open message received when current state is not ' 'OpenSent') # Received out-of-order open message # We raise Finite state machine error raise bgp.FiniteStateMachineError() elif msg.type == BGP_MSG_NOTIFICATION: if self._peer: self._signal_bus.bgp_notification_received(self._peer, msg) # If we receive notification message LOG.error('Received notification message, hence closing ' 'connection %s', msg) self._socket.close() return # If we receive keepalive or update message, we reset expire timer. if (msg.type == BGP_MSG_KEEPALIVE or msg.type == BGP_MSG_UPDATE): if self._expiry: self._expiry.reset() # Call peer message handler for appropriate messages. if (msg.type in (BGP_MSG_UPDATE, BGP_MSG_KEEPALIVE, BGP_MSG_ROUTE_REFRESH)): self._peer.handle_msg(msg) # We give chance to other threads to run. self.pause(0) def _start_timers(self, peer_holdtime): """Starts keepalive and expire timers. Hold time is set to min. of peer and configured/default hold time. Starts keep alive timer and expire timer based on this value. """ neg_timer = min(self._holdtime, peer_holdtime) if neg_timer < self._holdtime: LOG.info('Negotiated hold time (%s) is lower then ' 'configured/default (%s).', neg_timer, self._holdtime) # We use negotiated timer value. self._holdtime = neg_timer self._keepalive = self._create_timer('Keepalive Timer', self._send_keepalive) interval = self._holdtime // 3 self._keepalive.start(interval, now=False) # Setup the expire timer. self._expiry = self._create_timer('Holdtime Timer', self._expired) self._expiry.start(self._holdtime, now=False) LOG.debug('Started keep-alive and expire timer for negotiated hold' 'time %s', self._holdtime) def _expired(self): """Hold timer expired event handler. """ LOG.info('Negotiated hold time %s expired.', self._holdtime) code = BGP_ERROR_HOLD_TIMER_EXPIRED subcode = BGP_ERROR_SUB_HOLD_TIMER_EXPIRED self.send_notification(code, subcode) self.connection_lost('Negotiated hold time %s expired.' % self._holdtime) self.stop() def _send_keepalive(self): self.send(_KEEP_ALIVE) def _recv_loop(self): """Sits in tight loop collecting data received from peer and processing it. """ required_len = BGP_MIN_MSG_LEN conn_lost_reason = "Connection lost as protocol is no longer active" try: while True: next_bytes = self._socket.recv(required_len) if len(next_bytes) == 0: conn_lost_reason = 'Peer closed connection' break self.data_received(next_bytes) except socket.error as err: conn_lost_reason = 'Connection to peer lost: %s.' % err except bgp.BgpExc as ex: conn_lost_reason = 'Connection to peer lost, reason: %s.' % ex except Exception as e: LOG.debug(traceback.format_exc()) conn_lost_reason = str(e) finally: self.connection_lost(conn_lost_reason) def connection_made(self): """Connection to peer handler. We send bgp open message to peer and initialize related attributes. """ assert self.state == BGP_FSM_CONNECT # We have a connection with peer we send open message. open_msg = self._peer.create_open_msg() self._holdtime = open_msg.hold_time self.state = BGP_FSM_OPEN_SENT if not self.is_reactive: self._peer.state.bgp_state = self.state self.sent_open_msg = open_msg self.send(open_msg) self._peer.connection_made() def connection_lost(self, reason): """Stops all timers and notifies peer that connection is lost. """ if self._peer: state = self._peer.state.bgp_state if self._is_bound or state == BGP_FSM_OPEN_SENT: self._peer.connection_lost(reason) self._peer = None if reason: LOG.info(reason) else: LOG.info('Connection to peer closed for unknown reasons.') ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.1181061 os-ken-2.10.0/os_ken/services/protocols/bgp/utils/0000775000175000017500000000000000000000000022046 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/utils/__init__.py0000664000175000017500000000000000000000000024145 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/utils/bgp.py0000664000175000017500000002476500000000000023206 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone 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. """ Utilities related to bgp data types and models. """ import logging import netaddr from os_ken.lib import ip from os_ken.lib.packet.bgp import ( BGPUpdate, RF_IPv4_UC, RF_IPv6_UC, RF_IPv4_VPN, RF_IPv6_VPN, RF_L2_EVPN, RF_IPv4_FLOWSPEC, RF_IPv6_FLOWSPEC, RF_VPNv4_FLOWSPEC, RF_VPNv6_FLOWSPEC, RF_L2VPN_FLOWSPEC, RF_RTC_UC, RouteTargetMembershipNLRI, BGP_ATTR_TYPE_MULTI_EXIT_DISC, BGPPathAttributeMultiExitDisc, BGPPathAttributeMpUnreachNLRI, BGPPathAttributeAs4Path, BGPPathAttributeAs4Aggregator, BGPPathAttributeUnknown, BGP_ATTR_FLAG_OPTIONAL, BGP_ATTR_FLAG_TRANSITIVE, BGPTwoOctetAsSpecificExtendedCommunity, BGPIPv4AddressSpecificExtendedCommunity, BGPFourOctetAsSpecificExtendedCommunity, BGPFlowSpecTrafficRateCommunity, BGPFlowSpecTrafficActionCommunity, BGPFlowSpecRedirectCommunity, BGPFlowSpecTrafficMarkingCommunity, BGPFlowSpecVlanActionCommunity, BGPFlowSpecTPIDActionCommunity, ) from os_ken.services.protocols.bgp.info_base.rtc import RtcPath from os_ken.services.protocols.bgp.info_base.ipv4 import Ipv4Path from os_ken.services.protocols.bgp.info_base.ipv6 import Ipv6Path from os_ken.services.protocols.bgp.info_base.vpnv4 import Vpnv4Path from os_ken.services.protocols.bgp.info_base.vpnv6 import Vpnv6Path from os_ken.services.protocols.bgp.info_base.evpn import EvpnPath from os_ken.services.protocols.bgp.info_base.ipv4fs import IPv4FlowSpecPath from os_ken.services.protocols.bgp.info_base.ipv6fs import IPv6FlowSpecPath from os_ken.services.protocols.bgp.info_base.vpnv4fs import VPNv4FlowSpecPath from os_ken.services.protocols.bgp.info_base.vpnv6fs import VPNv6FlowSpecPath from os_ken.services.protocols.bgp.info_base.l2vpnfs import L2VPNFlowSpecPath LOG = logging.getLogger('utils.bgp') # RouteFamily to path sub-class mapping. _ROUTE_FAMILY_TO_PATH_MAP = {RF_IPv4_UC: Ipv4Path, RF_IPv6_UC: Ipv6Path, RF_IPv4_VPN: Vpnv4Path, RF_IPv6_VPN: Vpnv6Path, RF_L2_EVPN: EvpnPath, RF_IPv4_FLOWSPEC: IPv4FlowSpecPath, RF_IPv6_FLOWSPEC: IPv6FlowSpecPath, RF_VPNv4_FLOWSPEC: VPNv4FlowSpecPath, RF_VPNv6_FLOWSPEC: VPNv6FlowSpecPath, RF_L2VPN_FLOWSPEC: L2VPNFlowSpecPath, RF_RTC_UC: RtcPath} def create_path(src_peer, nlri, **kwargs): route_family = nlri.ROUTE_FAMILY assert route_family in _ROUTE_FAMILY_TO_PATH_MAP.keys() path_cls = _ROUTE_FAMILY_TO_PATH_MAP.get(route_family) return path_cls(src_peer, nlri, src_peer.version_num, **kwargs) def clone_path_and_update_med_for_target_neighbor(path, med): assert path and med route_family = path.route_family if route_family not in _ROUTE_FAMILY_TO_PATH_MAP.keys(): raise ValueError('Clone is not supported for address-family %s' % route_family) path_cls = _ROUTE_FAMILY_TO_PATH_MAP.get(route_family) pattrs = path.pathattr_map pattrs[BGP_ATTR_TYPE_MULTI_EXIT_DISC] = BGPPathAttributeMultiExitDisc(med) return path_cls( path.source, path.nlri, path.source_version_num, pattrs=pattrs, nexthop=path.nexthop, is_withdraw=path.is_withdraw, med_set_by_target_neighbor=True ) def clone_rtcpath_update_rt_as(path, new_rt_as): """Clones given RT NLRI `path`, and updates it with new RT_NLRI AS. Parameters: - `path`: (Path) RT_NLRI path - `new_rt_as`: AS value of cloned paths' RT_NLRI """ assert path and new_rt_as if not path or path.route_family != RF_RTC_UC: raise ValueError('Expected RT_NLRI path') old_nlri = path.nlri new_rt_nlri = RouteTargetMembershipNLRI(new_rt_as, old_nlri.route_target) return RtcPath(path.source, new_rt_nlri, path.source_version_num, pattrs=path.pathattr_map, nexthop=path.nexthop, is_withdraw=path.is_withdraw) def from_inet_ptoi(bgp_id): """Convert an IPv4 address string format to a four byte long. """ four_byte_id = None try: four_byte_id = ip.ipv4_to_int(bgp_id) except ValueError: LOG.debug('Invalid bgp id given for conversion to integer value %s', bgp_id) return four_byte_id def get_unknown_opttrans_attr(path): """Utility method that gives a `dict` of unknown and unsupported optional transitive path attributes of `path`. Returns dict: - attribute type code, - unknown path-attr. """ path_attrs = path.pathattr_map unknown_opt_tran_attrs = {} for _, attr in path_attrs.items(): if (isinstance(attr, BGPPathAttributeUnknown) and attr.flags & (BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANSITIVE)) or \ isinstance(attr, BGPPathAttributeAs4Path) or \ isinstance(attr, BGPPathAttributeAs4Aggregator): unknown_opt_tran_attrs[attr.type] = attr return unknown_opt_tran_attrs def create_end_of_rib_update(): """Construct end-of-rib (EOR) Update instance.""" mpunreach_attr = BGPPathAttributeMpUnreachNLRI(RF_IPv4_VPN.afi, RF_IPv4_VPN.safi, []) eor = BGPUpdate(path_attributes=[mpunreach_attr]) return eor # Bgp update message instance that can used as End of RIB marker. UPDATE_EOR = create_end_of_rib_update() def create_rt_extended_community(value, subtype=2): """ Creates an instance of the BGP Route Target Community (if "subtype=2") or Route Origin Community ("subtype=3"). :param value: String of Route Target or Route Origin value. :param subtype: Subtype of Extended Community. :return: An instance of Route Target or Route Origin Community. """ global_admin, local_admin = value.split(':') local_admin = int(local_admin) if global_admin.isdigit() and 0 <= int(global_admin) <= 0xffff: ext_com = BGPTwoOctetAsSpecificExtendedCommunity( subtype=subtype, as_number=int(global_admin), local_administrator=local_admin) elif global_admin.isdigit() and 0xffff < int(global_admin) <= 0xffffffff: ext_com = BGPFourOctetAsSpecificExtendedCommunity( subtype=subtype, as_number=int(global_admin), local_administrator=local_admin) elif ip.valid_ipv4(global_admin): ext_com = BGPIPv4AddressSpecificExtendedCommunity( subtype=subtype, ipv4_address=global_admin, local_administrator=local_admin) else: raise ValueError( 'Invalid Route Target or Route Origin value: %s' % value) return ext_com def create_v4flowspec_actions(actions=None): """ Create list of traffic filtering actions for Ipv4 Flow Specification and VPNv4 Flow Specification. `` actions`` specifies Traffic Filtering Actions of Flow Specification as a dictionary type value. Returns a list of extended community values. """ from os_ken.services.protocols.bgp.api.prefix import ( FLOWSPEC_ACTION_TRAFFIC_RATE, FLOWSPEC_ACTION_TRAFFIC_ACTION, FLOWSPEC_ACTION_REDIRECT, FLOWSPEC_ACTION_TRAFFIC_MARKING, ) # Supported action type for IPv4 and VPNv4. action_types = { FLOWSPEC_ACTION_TRAFFIC_RATE: BGPFlowSpecTrafficRateCommunity, FLOWSPEC_ACTION_TRAFFIC_ACTION: BGPFlowSpecTrafficActionCommunity, FLOWSPEC_ACTION_REDIRECT: BGPFlowSpecRedirectCommunity, FLOWSPEC_ACTION_TRAFFIC_MARKING: BGPFlowSpecTrafficMarkingCommunity, } return _create_actions(actions, action_types) def create_v6flowspec_actions(actions=None): """ Create list of traffic filtering actions for Ipv6 Flow Specification and VPNv6 Flow Specification. "FLOWSPEC_ACTION_REDIRECT_IPV6" is not implemented yet. """ from os_ken.services.protocols.bgp.api.prefix import ( FLOWSPEC_ACTION_TRAFFIC_RATE, FLOWSPEC_ACTION_TRAFFIC_ACTION, FLOWSPEC_ACTION_REDIRECT, FLOWSPEC_ACTION_TRAFFIC_MARKING, ) # Supported action type for IPv6 and VPNv6. action_types = { FLOWSPEC_ACTION_TRAFFIC_RATE: BGPFlowSpecTrafficRateCommunity, FLOWSPEC_ACTION_TRAFFIC_ACTION: BGPFlowSpecTrafficActionCommunity, FLOWSPEC_ACTION_REDIRECT: BGPFlowSpecRedirectCommunity, FLOWSPEC_ACTION_TRAFFIC_MARKING: BGPFlowSpecTrafficMarkingCommunity, } return _create_actions(actions, action_types) def create_l2vpnflowspec_actions(actions=None): """ Create list of traffic filtering actions for L2VPN Flow Specification. """ from os_ken.services.protocols.bgp.api.prefix import ( FLOWSPEC_ACTION_TRAFFIC_RATE, FLOWSPEC_ACTION_TRAFFIC_ACTION, FLOWSPEC_ACTION_REDIRECT, FLOWSPEC_ACTION_TRAFFIC_MARKING, FLOWSPEC_ACTION_VLAN, FLOWSPEC_ACTION_TPID, ) # Supported action type for L2VPN. action_types = { FLOWSPEC_ACTION_TRAFFIC_RATE: BGPFlowSpecTrafficRateCommunity, FLOWSPEC_ACTION_TRAFFIC_ACTION: BGPFlowSpecTrafficActionCommunity, FLOWSPEC_ACTION_REDIRECT: BGPFlowSpecRedirectCommunity, FLOWSPEC_ACTION_TRAFFIC_MARKING: BGPFlowSpecTrafficMarkingCommunity, FLOWSPEC_ACTION_VLAN: BGPFlowSpecVlanActionCommunity, FLOWSPEC_ACTION_TPID: BGPFlowSpecTPIDActionCommunity, } return _create_actions(actions, action_types) def _create_actions(actions, action_types): communities = [] if actions is None: return communities for name, action in actions.items(): cls_ = action_types.get(name, None) if cls_: communities.append(cls_(**action)) else: raise ValueError( 'Unsupported flowspec action %s' % name) return communities ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/utils/circlist.py0000664000175000017500000002006500000000000024237 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone 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. from sys import intern class CircularListType(object): """Instances of this class represent a specific type of list. Nodes are linked in a circular fashion, using attributes on the nodes themselves. Example: ItemList = CircularListType(next_attr='_next', prev_attr='_prev') l = ItemList() l.prepend(item) The created list has the following properties: - A node can be inserted O(1) time at the head, tail, or after/before another specified node. - A node can be removed in O(1) time from any list it may be on, without providing a reference to the list. - The current node in an iteration can be deleted safely. """ class List(object): """An object that represents a list. This class is not expected to be used directly by clients. Rather, they would use the 'create' method of a CircularListType object to create an instance. """ # Define the set of valid attributes so as to make the list # head lightweight. # # We override __getattr__ and __setattr__ so as to store the # the next and previous references on the list head in # _next_slot_ and _prev_slot_ respectively. __slots__ = ["list_type", "head", "_next_slot_", "_prev_slot_"] def __init__(self, list_type): self.list_type = list_type # Save memory by using the List object itself as the head. self.head = self self.list_type.node_init(self.head) def __getattr__(self, name): if(name == self.list_type.next_name): return self._next_slot_ if(name == self.list_type.prev_name): return self._prev_slot_ raise AttributeError(name) def __setattr__(self, name, value): if(name in CircularListType.List.__slots__): object.__setattr__(self, name, value) return if(name == self.list_type.next_name): self._next_slot_ = value return if(name == self.list_type.prev_name): self._prev_slot_ = value return raise AttributeError(name) def is_empty(self): return not self.list_type.node_is_on_list(self.head) def clear(self): """Remove all items from the list.""" # Make sure that all items are unlinked. for node in self: self.remove(node) def is_on_list(self, node): return self.list_type.node_is_on_list(node) def append(self, node): self.list_type.node_insert_before(self.head, node) def prepend(self, node): self.list_type.node_insert_after(self.head, node) def __iter__(self): return self.generator() def remove(self, node): """List the given node from the list. Note that this does not verify that the node is on this list. It could even be on a different list. """ self.list_type.node_unlink(node) self.list_type.node_del_attrs(node) def pop_first(self): """Remove the first item in the list and return it.""" node = self.list_type.node_next(self.head) if(node is self.head): return None self.remove(node) return node def generator(self): """Enables iteration over the list. The current item can safely be removed from the list during iteration. """ # Keep a pointer to the next node when returning the # current node. This allows the caller to remove the # current node safely. node = self.list_type.node_next(self.head) next = self.list_type.node_next(node) while(node is not self.head): yield node node = next next = self.list_type.node_next(node) # # CircularListType methods # def __init__(self, next_attr_name=None, prev_attr_name=None): """Initializes this list. next_attr_name: The name of the attribute that holds a reference to the next item in the list. prev_attr_name: the name of the attribute that holds a reference to the previous item in the list. """ # Keep an interned version of the attribute names. This should # speed up the process of looking up the attributes. self.next_name = intern(next_attr_name) self.prev_name = intern(prev_attr_name) def create(self): return CircularListType.List(self) def __call__(self): """Make a CircularListType instance look like a class by creating a list object. """ return self.create() def node_init(self, node): assert(not self.node_is_on_list(node)) # Set the node to point to itself as the previous and next # entries. self.node_set_next(node, node) self.node_set_prev(node, node) def node_next(self, node): try: return getattr(node, self.next_name) except AttributeError: return None def node_set_next(self, node, next): setattr(node, self.next_name, next) def node_prev(self, node): try: return getattr(node, self.prev_name) except AttributeError: return None def node_set_prev(self, node, prev): setattr(node, self.prev_name, prev) def node_del_attrs(self, node): """Remove all attributes that are used for putting this node on this type of list. """ try: delattr(node, self.next_name) delattr(node, self.prev_name) except AttributeError: pass def node_is_on_list(self, node): """Returns True if this node is on *some* list. A node is not on any list if it is linked to itself, or if it does not have the next and/prev attributes at all. """ next = self.node_next(node) if next == node or next is None: assert(self.node_prev(node) is next) return False return True def node_insert_after(self, node, new_node): """Insert the new node after node.""" assert(not self.node_is_on_list(new_node)) assert(node is not new_node) next = self.node_next(node) assert(next is not None) self.node_set_next(node, new_node) self.node_set_prev(new_node, node) self.node_set_next(new_node, next) self.node_set_prev(next, new_node) def node_insert_before(self, node, new_node): """Insert the new node before node.""" assert(not self.node_is_on_list(new_node)) assert(node is not new_node) prev = self.node_prev(node) assert(prev is not None) self.node_set_prev(node, new_node) self.node_set_next(new_node, node) self.node_set_prev(new_node, prev) self.node_set_next(prev, new_node) def node_unlink(self, node): if not self.node_is_on_list(node): return prev = self.node_prev(node) next = self.node_next(node) self.node_set_next(prev, next) self.node_set_prev(next, prev) self.node_set_next(node, node) self.node_set_prev(node, node) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/utils/evtlet.py0000664000175000017500000000544500000000000023733 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone 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. """ Concurrent networking library - Eventlet, based utilities classes. """ from os_ken.lib import hub import logging LOG = logging.getLogger('utils.evtlet') class EventletIOFactory(object): @staticmethod def create_custom_event(): LOG.debug('Create CustomEvent called') return hub.Event() @staticmethod def create_looping_call(funct, *args, **kwargs): LOG.debug('create_looping_call called') return LoopingCall(funct, *args, **kwargs) # TODO: improve Timer service and move it into framework class LoopingCall(object): """Call a function repeatedly. """ def __init__(self, funct, *args, **kwargs): self._funct = funct self._args = args self._kwargs = kwargs self._running = False self._interval = 0 self._self_thread = None @property def running(self): return self._running @property def interval(self): return self._interval def __call__(self): if self._running: # Schedule next iteration of the call. self._self_thread = hub.spawn_after(self._interval, self) self._funct(*self._args, **self._kwargs) def start(self, interval, now=True): """Start running pre-set function every interval seconds. """ if interval < 0: raise ValueError('interval must be >= 0') if self._running: self.stop() self._running = True self._interval = interval if now: self._self_thread = hub.spawn_after(0, self) else: self._self_thread = hub.spawn_after(self._interval, self) def stop(self): """Stop running scheduled function. """ self._running = False if self._self_thread is not None: self._self_thread.cancel() self._self_thread = None def reset(self): """Skip the next iteration and reset timer. """ if self._self_thread is not None: # Cancel currently scheduled call self._self_thread.cancel() self._self_thread = None # Schedule a new call self._self_thread = hub.spawn_after(self._interval, self) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/utils/rtfilter.py0000664000175000017500000002243700000000000024263 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone 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. """ Module for RT Filter related functionality. """ import logging from os_ken.lib.packet.bgp import RF_RTC_UC from os_ken.lib.packet.bgp import RouteTargetMembershipNLRI from os_ken.lib.packet.bgp import BGP_ATTR_TYPE_AS_PATH from os_ken.lib.packet.bgp import BGP_ATTR_TYPE_ORIGIN from os_ken.lib.packet.bgp import BGPPathAttributeAsPath from os_ken.lib.packet.bgp import BGPPathAttributeOrigin from os_ken.services.protocols.bgp.base import OrderedDict from os_ken.services.protocols.bgp.info_base.rtc import RtcPath LOG = logging.getLogger('bgpspeaker.util.rtfilter') class RouteTargetManager(object): def __init__(self, core_service, neighbors_conf, vrfs_conf): self._core_service = core_service # TODO(PH): Consider extending VrfsConfListener and # NeighborsConfListener self._neighbors_conf = neighbors_conf self._vrfs_conf = vrfs_conf # Peer to its current RT filter map # /value = / self._peer_to_rtfilter_map = {} # Collection of import RTs of all configured VRFs self._all_vrfs_import_rts_set = set() # Collection of current RTC AS for all configured Neighbors self._all_rtc_as_set = set() # Interested RTs according to current entries in RTC global table self._global_interested_rts = set() @property def peer_to_rtfilter_map(self): return self._peer_to_rtfilter_map.copy() @peer_to_rtfilter_map.setter def peer_to_rtfilter_map(self, new_map): self._peer_to_rtfilter_map = new_map.copy() @property def global_interested_rts(self): return set(self._global_interested_rts) def add_rt_nlri(self, route_target, is_withdraw=False): assert route_target # Since we allow RTC AS setting for each neighbor, we collect all we # collect allRTC AS settings and add a RT NLRI using each AS number rtc_as_set = set() # Add RT NLRI with local AS rtc_as_set.add(self._core_service.asn) # Collect RTC AS from neighbor settings rtc_as_set.update(self._neighbors_conf.rtc_as_set) # Add RT NLRI path (withdraw) for each RTC AS for rtc_as in rtc_as_set: self._add_rt_nlri_for_as(rtc_as, route_target, is_withdraw) def _add_rt_nlri_for_as(self, rtc_as, route_target, is_withdraw=False): from os_ken.services.protocols.bgp.core import EXPECTED_ORIGIN rt_nlri = RouteTargetMembershipNLRI(rtc_as, route_target) # Create a dictionary for path-attrs. pattrs = OrderedDict() if not is_withdraw: # MpReachNlri and/or MpUnReachNlri attribute info. is contained # in the path. Hence we do not add these attributes here. pattrs[BGP_ATTR_TYPE_ORIGIN] = BGPPathAttributeOrigin( EXPECTED_ORIGIN) pattrs[BGP_ATTR_TYPE_AS_PATH] = BGPPathAttributeAsPath([]) # Create Path instance and initialize appropriately. path = RtcPath(None, rt_nlri, 0, is_withdraw=is_withdraw, pattrs=pattrs) tm = self._core_service.table_manager tm.learn_path(path) def update_rtc_as_set(self): """Syncs RT NLRIs for new and removed RTC_ASes. This method should be called when a neighbor is added or removed. """ # Compute the diffs in RTC_ASes curr_rtc_as_set = self._neighbors_conf.rtc_as_set # Always add local AS to RTC AS set curr_rtc_as_set.add(self._core_service.asn) removed_rtc_as_set = self._all_rtc_as_set - curr_rtc_as_set new_rtc_as_set = curr_rtc_as_set - self._all_rtc_as_set # Update to new RTC_AS set self._all_rtc_as_set = curr_rtc_as_set # Sync RT NLRI by adding/withdrawing as appropriate for new_rtc_as in new_rtc_as_set: for import_rt in self._all_vrfs_import_rts_set: self._add_rt_nlri_for_as(new_rtc_as, import_rt) for removed_rtc_as in removed_rtc_as_set: for import_rt in self._all_vrfs_import_rts_set: self._add_rt_nlri_for_as(removed_rtc_as, import_rt, is_withdraw=True) def update_local_rt_nlris(self): """Does book-keeping of local RT NLRIs based on all configured VRFs. Syncs all import RTs and RT NLRIs. The method should be called when any VRFs are added/removed/changed. """ current_conf_import_rts = set() for vrf in self._vrfs_conf.vrf_confs: current_conf_import_rts.update(vrf.import_rts) removed_rts = self._all_vrfs_import_rts_set - current_conf_import_rts new_rts = current_conf_import_rts - self._all_vrfs_import_rts_set self._all_vrfs_import_rts_set = current_conf_import_rts # Add new and withdraw removed local RtNlris for new_rt in new_rts: self.add_rt_nlri(new_rt) for removed_rt in removed_rts: self.add_rt_nlri(removed_rt, is_withdraw=True) def on_rt_filter_chg_sync_peer(self, peer, new_rts, old_rts, table): LOG.debug('RT Filter changed for peer %s, new_rts %s, old_rts %s ', peer, new_rts, old_rts) for dest in table.values(): # If this destination does not have best path, we ignore it if not dest.best_path: continue desired_rts = set(dest.best_path.get_rts()) # If this path was sent to peer and if all path RTs are now not of # interest, we need to send withdraw for this path to this peer if dest.was_sent_to(peer): if not (desired_rts - old_rts): dest.withdraw_if_sent_to(peer) else: # New RT could be Default RT, which means we need to share this # path desired_rts.add(RouteTargetMembershipNLRI.DEFAULT_RT) # If we have RT filter has new RTs that are common with path # RTs, then we send this path to peer if desired_rts.intersection(new_rts): peer.communicate_path(dest.best_path) def _compute_global_interested_rts(self): """Computes current global interested RTs for global tables. Computes interested RTs based on current RT filters for peers. This filter should be used to check if for RTs on a path that is installed in any global table (expect RT Table). """ interested_rts = set() for rtfilter in self._peer_to_rtfilter_map.values(): interested_rts.update(rtfilter) interested_rts.update(self._vrfs_conf.vrf_interested_rts) # Remove default RT as it is not a valid RT for paths # TODO(PH): Check if we have better alternative than add and remove interested_rts.add(RouteTargetMembershipNLRI.DEFAULT_RT) interested_rts.remove(RouteTargetMembershipNLRI.DEFAULT_RT) return interested_rts def update_interested_rts(self): """Updates interested RT list. Check if interested RTs have changes from previous check. Takes appropriate action for new interesting RTs and removal of un- interesting RTs. """ prev_global_rts = self._global_interested_rts curr_global_rts = self._compute_global_interested_rts() new_global_rts = curr_global_rts - prev_global_rts removed_global_rts = prev_global_rts - curr_global_rts # Update current interested RTs for next iteration self._global_interested_rts = curr_global_rts LOG.debug('Global Interested RT changed, new RTs %s, removed RTs %s', new_global_rts, removed_global_rts) tm = self._core_service.table_manager tm.on_interesting_rts_change(new_global_rts, removed_global_rts) def filter_by_origin_as(self, new_best_path, qualified_peers): path_rf = new_best_path.route_family # We need not filter any peer if this is not a RT NLRI path or if # source of this path is remote peer (i.e. if this is not a local path) if path_rf != RF_RTC_UC or new_best_path.source is not None: return qualified_peers else: filtered_qualified_peers = [] rt_origin_as = new_best_path.nlri.origin_as # Collect peers whose RTC_AS setting match paths RT Origin AS for qualified_peer in qualified_peers: neigh_conf = \ self._neighbors_conf.get_neighbor_conf( qualified_peer.ip_address) if neigh_conf.rtc_as == rt_origin_as: filtered_qualified_peers.append(qualified_peer) # Update qualified peers to include only filtered peers return filtered_qualified_peers ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/utils/stats.py0000664000175000017500000000615100000000000023561 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone 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. """ Module for stats related classes and utilities. """ import datetime import json import logging import time from os_ken.services.protocols.bgp.rtconf.base import ConfWithId _STATS_LOGGER = logging.getLogger('stats') # Various stats related constants. DEFAULT_LOG_LEVEL = logging.INFO RESOURCE_ID = 'resource_id' RESOURCE_NAME = 'resource_name' TIMESTAMP = 'timestamp' LOG_LEVEL = 'log_level' STATS_RESOURCE = 'stats_resource' STATS_SOURCE = 'stats_source' # VRF related stat constants REMOTE_ROUTES = 'remote_routes' LOCAL_ROUTES = 'local_routes' # Peer related stat constant. UPDATE_MSG_IN = 'update_message_in' UPDATE_MSG_OUT = 'update_message_out' TOTAL_MSG_IN = 'total_message_in' TOTAL_MSG_OUT = 'total_message_out' FMS_EST_TRANS = 'fsm_established_transitions' UPTIME = 'uptime' def log(stats_resource=None, stats_source=None, log_level=DEFAULT_LOG_LEVEL, **kwargs): """Utility to log given stats to *stats* logger. Stats to log are given by `stats_source` and in its absence we log `kwargs`. *stats* logger is configured independently from any logger. Only stats should be logged to this logger. Will add current timestamp to the logged stats if not given. Parameters: - `stats_resource`: any object that complies with `id` and `name` attrs. - `stats_source`: any callable that give a `dict` that will be logged to *stats* logger. - `log_level`: str representing level at which to log this stats message. - `**kwargs`: if `stats_source` is not given, we log this `dict`. """ # Get stats from source if given. if stats_source is not None: kwargs = stats_source() if stats_resource is None: if RESOURCE_ID not in kwargs or RESOURCE_NAME not in kwargs: raise ValueError('Missing required stats labels.') else: if not (hasattr(stats_resource, ConfWithId.ID) and hasattr(stats_resource, ConfWithId.NAME)): raise ValueError('Given stats source is missing id or name' ' attributes.') kwargs[RESOURCE_ID] = stats_resource.id kwargs[RESOURCE_NAME] = stats_resource.name if TIMESTAMP not in kwargs: kwargs[TIMESTAMP] = datetime.datetime.utcfromtimestamp( time.time()).strftime("%Y-%m-%dT%H:%M:%S.%fZ") _STATS_LOGGER.log(log_level, json.dumps(kwargs)) def logd(**kwargs): log(log_level=logging.DEBUG, **kwargs) def logi(**kwargs): log(log_level=logging.INFO, **kwargs) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/bgp/utils/validation.py0000664000175000017500000001667500000000000024571 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone 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. """ Module provides utilities for validation. """ import numbers import re import socket from os_ken.lib import ip def is_valid_mac(mac): """Returns True if the given MAC address is valid. The given MAC address should be a colon hexadecimal notation string. Samples: - valid address: aa:bb:cc:dd:ee:ff, 11:22:33:44:55:66 - invalid address: aa:bb:cc:dd, 11-22-33-44-55-66, etc. """ return bool(re.match(r'^' + r'[\:\-]'.join([r'([0-9a-f]{2})'] * 6) + r'$', mac.lower())) def is_valid_ip_prefix(prefix, bits): """Returns True if *prefix* is a valid IPv4 or IPv6 address prefix. *prefix* should be a number between 0 to *bits* length. """ try: # Prefix should be a number prefix = int(prefix) except ValueError: return False # Prefix should be a number between 0 to *bits* return 0 <= prefix <= bits def is_valid_ipv4(ipv4): """Returns True if given is a valid ipv4 address. Given value should be a dot-decimal notation string. Samples: - valid address: 10.0.0.1, 192.168.0.1 - invalid address: 11.0.0, 192:168:0:1, etc. """ return ip.valid_ipv4(ipv4) def is_valid_ipv4_prefix(ipv4_prefix): """Returns True if *ipv4_prefix* is a valid prefix with mask. Samples: - valid prefix: 1.1.1.0/32, 244.244.244.1/10 - invalid prefix: 255.2.2.2/2, 2.2.2/22, etc. """ if not isinstance(ipv4_prefix, str): return False tokens = ipv4_prefix.split('/') if len(tokens) != 2: return False # Validate address/mask and return return is_valid_ipv4(tokens[0]) and is_valid_ip_prefix(tokens[1], 32) def is_valid_ipv6(ipv6): """Returns True if given `ipv6` is a valid IPv6 address """ return ip.valid_ipv6(ipv6) def is_valid_ipv6_prefix(ipv6_prefix): """Returns True if given `ipv6_prefix` is a valid IPv6 prefix.""" # Validate input type if not isinstance(ipv6_prefix, str): return False tokens = ipv6_prefix.split('/') if len(tokens) != 2: return False # Validate address/mask and return return is_valid_ipv6(tokens[0]) and is_valid_ip_prefix(tokens[1], 128) def is_valid_old_asn(asn): """Returns True if the given AS number is Two Octet.""" return isinstance(asn, numbers.Integral) and 0 <= asn <= 0xffff def is_valid_asn(asn): """Returns True if the given AS number is Two or Four Octet.""" return isinstance(asn, numbers.Integral) and 0 <= asn <= 0xffffffff def is_valid_vpnv4_prefix(prefix): """Returns True if given prefix is a string represent vpnv4 prefix. Vpnv4 prefix is made up of RD:Ipv4, where RD is represents route distinguisher and Ipv4 represents valid dot-decimal ipv4 notation string. """ if not isinstance(prefix, str): return False # Split the prefix into route distinguisher and IP tokens = prefix.split(':', 2) if len(tokens) != 3: return False # Validate route distinguisher if not is_valid_route_dist(':'.join([tokens[0], tokens[1]])): return False # Validate IPv4 prefix and return return is_valid_ipv4_prefix(tokens[2]) def is_valid_vpnv6_prefix(prefix): """Returns True if given prefix is a string represent vpnv6 prefix. Vpnv6 prefix is made up of RD:Ipv6, where RD is represents route distinguisher and Ipv6 represents valid colon hexadecimal notation string. """ if not isinstance(prefix, str): return False # Split the prefix into route distinguisher and IP tokens = prefix.split(':', 2) if len(tokens) != 3: return False # Validate route distinguisher if not is_valid_route_dist(':'.join([tokens[0], tokens[1]])): return False # Validate IPv6 prefix and return return is_valid_ipv6_prefix(tokens[2]) def is_valid_med(med): """Returns True if value of *med* is valid as per RFC. According to RFC MED is a four octet non-negative integer and value '((2 ** 32) - 1) = 0xffffffff' denotes an "infinity" metric. """ return isinstance(med, numbers.Integral) and 0 <= med <= 0xffffffff def is_valid_mpls_label(label): """Validates `label` according to MPLS label rules RFC says: This 20-bit field. A value of 0 represents the "IPv4 Explicit NULL Label". A value of 1 represents the "Router Alert Label". A value of 2 represents the "IPv6 Explicit NULL Label". A value of 3 represents the "Implicit NULL Label". Values 4-15 are reserved. """ if (not isinstance(label, numbers.Integral) or (4 <= label <= 15) or (label < 0 or label > 2 ** 20)): return False return True def is_valid_mpls_labels(labels): """Returns True if the given value is a list of valid MPLS labels. """ if not isinstance(labels, (list, tuple)): return False for label in labels: if not is_valid_mpls_label(label): return False return True def is_valid_route_dist(route_dist): """Validates *route_dist* as string representation of route distinguisher. Returns True if *route_dist* is as per our convention of RD, else False. Our convention is to represent RD as a string in format: *admin_sub_field:assigned_num_field* and *admin_sub_field* can be valid IPv4 string representation. Valid examples: '65000:222', '1.2.3.4:4432'. Invalid examples: '1.11.1: 333' """ # TODO(PH): Provide complete implementation. return is_valid_ext_comm_attr(route_dist) def is_valid_ext_comm_attr(attr): """Validates *attr* as string representation of RT or SOO. Returns True if *attr* is as per our convention of RT or SOO, else False. Our convention is to represent RT/SOO is a string with format: *global_admin_part:local_admin_path* """ if not isinstance(attr, str): return False tokens = attr.rsplit(':', 1) if len(tokens) != 2: return False try: if '.' in tokens[0]: if not is_valid_ipv4(tokens[0]): return False else: int(tokens[0]) int(tokens[1]) except (ValueError, socket.error): return False return True def is_valid_esi(esi): """Returns True if the given EVPN Ethernet SegmentEthernet ID is valid.""" if isinstance(esi, numbers.Integral): return 0 <= esi <= 0xffffffffffffffffff return isinstance(esi, dict) def is_valid_ethernet_tag_id(etag_id): """Returns True if the given EVPN Ethernet Tag ID is valid. Ethernet Tag ID should be a 32-bit field number. """ return isinstance(etag_id, numbers.Integral) and 0 <= etag_id <= 0xffffffff def is_valid_vni(vni): """Returns True if the given Virtual Network Identifier for VXLAN is valid. Virtual Network Identifier should be a 24-bit field number. """ return isinstance(vni, numbers.Integral) and 0 <= vni <= 0xffffff ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.1181061 os-ken-2.10.0/os_ken/services/protocols/ovsdb/0000775000175000017500000000000000000000000021253 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/ovsdb/__init__.py0000664000175000017500000000111200000000000023357 0ustar00zuulzuul00000000000000# Copyright (c) 2014 Rackspace Hosting # # 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. ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/ovsdb/api.py0000664000175000017500000003131600000000000022402 0ustar00zuulzuul00000000000000# Copyright (c) 2014 Rackspace Hosting # # 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. import uuid from os_ken.lib import dpid as dpidlib from os_ken.services.protocols.ovsdb import event as ovsdb_event def _get_table_row(table, attr_name, attr_value, tables): sentinel = object() for row in tables[table].rows.values(): if getattr(row, attr_name, sentinel) == attr_value: return row def _get_controller(tables, attr_val, attr_name='target'): return _get_table_row('Controller', attr_name, attr_val, tables=tables) def _get_bridge(tables, attr_val, attr_name='name'): return _get_table_row('Bridge', attr_name, attr_val, tables=tables) def _get_port(tables, attr_val, attr_name='name'): return _get_table_row('Port', attr_name, attr_val, tables=tables) def _get_iface(tables, attr_val, attr_name='name'): return _get_table_row('Interface', attr_name, attr_val, tables=tables) def match_row(manager, system_id, table, fn): def _match_row(tables): return next((r for r in tables[table].rows.values() if fn(r)), None) request_to_get_tables = ovsdb_event.EventReadRequest(system_id, _match_row) reply_to_get_tables = manager.send_request(request_to_get_tables) return reply_to_get_tables.result def match_rows(manager, system_id, table, fn): def _match_rows(tables): return (r for r in tables[table].rows.values() if fn(r)) request = ovsdb_event.EventReadRequest(system_id, _match_rows) reply = manager.send_request(request) return reply.result def row_by_name(manager, system_id, name, table='Bridge', fn=None): matched_row = match_row(manager, system_id, table, lambda row: row.name == name) if fn is not None: return fn(matched_row) return matched_row def rows_by_external_id(manager, system_id, key, value, table='Bridge', fn=None): matched_rows = match_rows(manager, system_id, table, lambda r: (key in r.external_ids and r.external_ids.get(key) == value)) if matched_rows and fn is not None: return [fn(row) for row in matched_rows] return matched_rows def rows_by_other_config(manager, system_id, key, value, table='Bridge', fn=None): matched_rows = match_rows(manager, system_id, table, lambda r: (key in r.other_config and r.other_config.get(key) == value)) if matched_rows and fn is not None: return [fn(row) for row in matched_rows] return matched_rows def get_column_value(manager, table, record, column): """ Example : To get datapath_id from Bridge table get_column_value('Bridge', , 'datapath_id').strip('"') """ row = row_by_name(manager, record, table) value = getattr(row, column, "") if isinstance(value, list) and len(value) == 1: value = value[0] return str(value) def get_iface_by_name(manager, system_id, name, fn=None): iface = row_by_name(manager, system_id, name, 'Interface') if fn is not None: return fn(iface) return iface def get_ifaces_by_external_id(manager, system_id, key, value, fn=None): return rows_by_external_id(manager, system_id, key, value, 'Interface', fn) def get_ifaces_by_other_config(manager, system_id, key, value, fn=None): return rows_by_other_config(manager, system_id, key, value, 'Interface', fn) def get_port_by_name(manager, system_id, name, fn=None): port = row_by_name(manager, system_id, name, 'Port') if fn is not None: return fn(port) return port def get_bridge_for_iface_name(manager, system_id, iface_name, fn=None): iface = row_by_name(manager, system_id, iface_name, 'Interface') port = match_row(manager, system_id, 'Port', lambda x: iface in x.interfaces) bridge = match_row(manager, system_id, 'Bridge', lambda x: port in x.ports) if fn is not None: return fn(bridge) return bridge def get_table(manager, system_id, name): def _get_table(tables): return tables[name] request_to_get_tables = ovsdb_event.EventReadRequest(system_id, _get_table) reply_to_get_tables = manager.send_request(request_to_get_tables) return reply_to_get_tables.result def get_bridge_by_datapath_id(manager, system_id, datapath_id, fn=None): def _match_fn(row): row_dpid = dpidlib.str_to_dpid(str(row.datapath_id[0])) return row_dpid == datapath_id bridge = match_row(manager, system_id, 'Bridge', _match_fn) if fn is not None: return fn(bridge) return bridge def get_datapath_ids_for_systemd_id(manager, system_id): def _get_dp_ids(tables): dp_ids = [] bridges = tables.get('Bridge') if not bridges: return dp_ids for bridge in bridges.rows.values(): datapath_ids = bridge.datapath_id dp_ids.extend(dpidlib.str_to_dpid(dp_id) for dp_id in datapath_ids) return dp_ids request = ovsdb_event.EventReadRequest(system_id, _get_dp_ids) reply = manager.send_request(request) return reply.result def get_system_id_for_datapath_id(manager, datapath_id): def _get_dp_ids(tables): bridges = tables.get('Bridge') if not bridges: return None for bridge in bridges.rows.values(): datapath_ids = [dpidlib.str_to_dpid(dp_id) for dp_id in bridge.datapath_id] if datapath_id in datapath_ids: openvswitch = tables['Open_vSwitch'].rows if openvswitch: row = openvswitch.get(list(openvswitch.keys())[0]) return row.external_ids.get('system-id') return None request = ovsdb_event.EventReadRequest(None, _get_dp_ids) reply = manager.send_request(request) # NOTE(jkoelker) Bulk reads return a tuple of (system_id, result) for result in reply.result: if result[1]: return result[0] return None def get_bridges_by_system_id(manager, system_id, fn=None): bridges = get_table(manager, system_id, 'Bridge').rows.values() if fn is not None: return fn(bridges) return bridges def bridge_exists(manager, system_id, bridge_name): return bool(row_by_name(manager, system_id, bridge_name)) def port_exists(manager, system_id, port_name): return bool(row_by_name(manager, system_id, port_name, 'Port')) def set_external_id(manager, system_id, key, val, fn): val = str(val) def _set_iface_external_id(tables, *_): row = fn(tables) if not row: return None external_ids = row.external_ids external_ids[key] = val row.external_ids = external_ids req = ovsdb_event.EventModifyRequest(system_id, _set_iface_external_id) return manager.send_request(req) def set_iface_external_id(manager, system_id, iface_name, key, val): return set_external_id(manager, system_id, key, val, lambda tables: _get_iface(tables, iface_name)) def set_other_config(manager, system_id, key, val, fn): val = str(val) def _set_iface_other_config(tables, *_): row = fn(tables) if not row: return None other_config = row.other_config other_config[key] = val row.other_config = other_config req = ovsdb_event.EventModifyRequest(system_id, _set_iface_other_config) return manager.send_request(req) def set_iface_other_config(manager, system_id, iface_name, key, val): return set_other_config(manager, system_id, key, val, lambda tables: _get_iface(tables, iface_name)) def del_external_id(manager, system_id, key, fn): def _del_iface_external_id(tables, *_): row = fn(tables) if not row: return None external_ids = row.external_ids if key in external_ids: external_ids.pop(key) row.external_ids = external_ids req = ovsdb_event.EventModifyRequest(system_id, _del_iface_external_id) return manager.send_request(req) def del_iface_external_id(manager, system_id, iface_name, key): return del_external_id(manager, system_id, key, lambda tables: _get_iface(tables, iface_name)) def del_other_config(manager, system_id, key, fn): def _del_iface_other_config(tables, *_): row = fn(tables) if not row: return None other_config = row.other_config if key in other_config: other_config.pop(key) row.other_config = other_config req = ovsdb_event.EventModifyRequest(system_id, _del_iface_other_config) return manager.send_request(req) def del_iface_other_config(manager, system_id, iface_name, key): return del_other_config(manager, system_id, key, lambda tables: _get_iface(tables, iface_name)) def del_port(manager, system_id, bridge_name, fn): def _delete_port(tables, *_): bridge = _get_bridge(tables, bridge_name) if not bridge: return port = fn(tables) if not port: return ports = bridge.ports ports.remove(port) bridge.ports = ports req = ovsdb_event.EventModifyRequest(system_id, _delete_port) return manager.send_request(req) def del_port_by_uuid(manager, system_id, bridge_name, port_uuid): return del_port(manager, system_id, bridge_name, lambda tables: _get_port(tables, port_uuid, attr_name='uuid')) def del_port_by_name(manager, system_id, bridge_name, port_name): return del_port(manager, system_id, bridge_name, lambda tables: _get_port(tables, port_name)) def set_controller(manager, system_id, bridge_name, target, controller_info=None): controller_info = controller_info or {} def _set_controller(tables, insert): bridge = _get_bridge(tables, bridge_name) controller = _get_controller(tables, target) _uuid = None if not controller: _uuid = controller_info.get('uuid', uuid.uuid4()) controller = insert(tables['Controller'], _uuid) controller.target = target controller.connection_mode = ['out-of-band'] elif 'out-of-band' not in controller.connection_mode: controller.connection_mode = ['out-of-band'] if controller_info: for key, val in controller_info.items(): setattr(controller, key, val) bridge.controller = [controller] return _uuid req = ovsdb_event.EventModifyRequest(system_id, _set_controller) return manager.send_request(req) def create_port(manager, system_id, bridge_name, port_info, iface_info=None, port_insert_uuid=None, iface_insert_uuid=None): if iface_info is None: iface_info = {} if not port_insert_uuid: port_insert_uuid = uuid.uuid4() if not iface_insert_uuid: iface_insert_uuid = uuid.uuid4() def _create_port(tables, insert): bridge = _get_bridge(tables, bridge_name) if not bridge: return default_port_name = 'port' + str(port_insert_uuid) if 'name' not in iface_info: iface_info['name'] = port_info.get('name', default_port_name) if 'type' not in iface_info: iface_info['type'] = 'internal' if 'name' not in port_info: port_info['name'] = default_port_name iface = insert(tables['Interface'], iface_insert_uuid) for key, val in iface_info.items(): setattr(iface, key, val) port = insert(tables['Port'], port_insert_uuid) for key, val in port_info.items(): setattr(port, key, val) port.interfaces = [iface] bridge.ports = bridge.ports + [port] return port_insert_uuid, iface_insert_uuid req = ovsdb_event.EventModifyRequest(system_id, _create_port) return manager.send_request(req) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/ovsdb/client.py0000664000175000017500000003441500000000000023112 0ustar00zuulzuul00000000000000# Copyright (c) 2014 Rackspace Hosting # # 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. import collections import errno import uuid from ovs import jsonrpc from ovs import poller from ovs import reconnect from ovs import stream from ovs import timeval from ovs.db import idl from os_ken.base import app_manager from os_ken.lib import hub from os_ken.services.protocols.ovsdb import event from os_ken.services.protocols.ovsdb import model now = timeval.msec def _uuid_to_row(atom, base): if base.ref_table: value = base.ref_table.rows.get(atom) else: value = atom if isinstance(value, idl.Row): value = str(value.uuid) return value def dictify(row): if row is None: return result = {} for key, value in row._data.items(): result[key] = value.to_python(_uuid_to_row) hub.sleep(0) return result def transact_block(request, connection): """Emulate jsonrpc.Connection.transact_block without blocking eventlet. """ error = connection.send(request) reply = None if error: return error, reply ovs_poller = poller.Poller() while not error: ovs_poller.immediate_wake() error, reply = connection.recv() if error != errno.EAGAIN: break if (reply and reply.id == request.id and reply.type in (jsonrpc.Message.T_REPLY, jsonrpc.Message.T_ERROR)): break connection.run() connection.wait(ovs_poller) connection.recv_wait(ovs_poller) ovs_poller.block() hub.sleep(0) return error, reply def discover_schemas(connection): # NOTE(jkoelker) currently only the Open_vSwitch schema # is supported. # TODO(jkoelker) support arbitrary schemas req = jsonrpc.Message.create_request('list_dbs', []) error, reply = transact_block(req, connection) if error or reply.error: return schemas = [] for db in reply.result: if db != 'Open_vSwitch': continue req = jsonrpc.Message.create_request('get_schema', [db]) error, reply = transact_block(req, connection) if error or reply.error: # TODO(jkoelker) Error handling continue schemas.append(reply.result) return schemas def discover_system_id(idl): system_id = None while system_id is None and idl._session.is_connected(): idl.run() openvswitch = idl.tables['Open_vSwitch'].rows if openvswitch: row = openvswitch.get(list(openvswitch.keys())[0]) system_id = row.external_ids.get('system-id') return system_id def _filter_schemas(schemas, schema_tables, exclude_table_columns): """Wrapper method for _filter_schema to filter multiple schemas.""" return [_filter_schema(s, schema_tables, exclude_table_columns) for s in schemas] def _filter_schema(schema, schema_tables, exclude_table_columns): """Filters a schema to only include the specified tables in the schema_tables parameter. This will also filter out any colums for included tables that reference tables that are not included in the schema_tables parameter :param schema: Schema dict to be filtered :param schema_tables: List of table names to filter on. EX: ['Bridge', 'Controller', 'Interface'] NOTE: This list is case sensitive. :return: Schema dict: filtered if the schema_table parameter contains table names, else the original schema dict """ tables = {} for tbl_name, tbl_data in schema['tables'].items(): if not schema_tables or tbl_name in schema_tables: columns = {} exclude_columns = exclude_table_columns.get(tbl_name, []) for col_name, col_data in tbl_data['columns'].items(): if col_name in exclude_columns: continue # NOTE(Alan Quillin) Needs to check and remove # and columns that have references to tables that # are not to be configured type_ = col_data.get('type') if type_: if type_ and isinstance(type_, dict): key = type_.get('key') if key and isinstance(key, dict): ref_tbl = key.get('refTable') if ref_tbl and isinstance(ref_tbl, str): if ref_tbl not in schema_tables: continue value = type_.get('value') if value and isinstance(value, dict): ref_tbl = value.get('refTable') if ref_tbl and isinstance(ref_tbl, str): if ref_tbl not in schema_tables: continue columns[col_name] = col_data tbl_data['columns'] = columns tables[tbl_name] = tbl_data schema['tables'] = tables return schema # NOTE(jkoelker) Wrap ovs's Idl to accept an existing session, and # trigger callbacks on changes class Idl(idl.Idl): def __init__(self, session, schema): if not isinstance(schema, idl.SchemaHelper): schema = idl.SchemaHelper(schema_json=schema) schema.register_all() schema = schema.get_idl_schema() # NOTE(jkoelker) event buffer self._events = [] self.tables = schema.tables self.readonly = schema.readonly self._db = schema self._session = session self._monitor_request_id = None self._last_seqno = None self.change_seqno = 0 self.uuid = uuid.uuid1() self.state = self.IDL_S_INITIAL # Database locking. self.lock_name = None # Name of lock we need, None if none. self.has_lock = False # Has db server said we have the lock? self.is_lock_contended = False # Has db server said we can't get lock? self._lock_request_id = None # JSON-RPC ID of in-flight lock request. # Transaction support. self.txn = None self._outstanding_txns = {} for table in schema.tables.values(): for column in table.columns.values(): if not hasattr(column, 'alert'): column.alert = True table.need_table = False table.rows = {} table.idl = self table.condition = [] table.cond_changed = False @property def events(self): events = self._events self._events = [] return events def __process_update(self, table, uuid, old, new): old_row = table.rows.get(uuid) if old_row is not None: old_row = model.Row(dictify(old_row)) old_row['_uuid'] = uuid changed = idl.Idl.__process_update(self, table, uuid, old, new) if changed: if not new: ev = (event.EventRowDelete, (table.name, old_row)) elif not old: new_row = model.Row(dictify(table.rows.get(uuid))) new_row['_uuid'] = uuid ev = (event.EventRowInsert, (table.name, new_row)) else: new_row = model.Row(dictify(table.rows.get(uuid))) new_row['_uuid'] = uuid ev = (event.EventRowUpdate, (table.name, old_row, new_row)) self._events.append(ev) return changed class RemoteOvsdb(app_manager.OSKenApp): _EVENTS = [event.EventRowUpdate, event.EventRowDelete, event.EventRowInsert, event.EventInterfaceDeleted, event.EventInterfaceInserted, event.EventInterfaceUpdated, event.EventPortDeleted, event.EventPortInserted, event.EventPortUpdated] @classmethod def factory(cls, sock, address, probe_interval=None, min_backoff=None, max_backoff=None, schema_tables=None, schema_exclude_columns=None, *args, **kwargs): schema_exclude_columns = schema_exclude_columns or {} ovs_stream = stream.Stream(sock, None, None) connection = jsonrpc.Connection(ovs_stream) schemas = discover_schemas(connection) if not schemas: return if schema_tables or schema_exclude_columns: schemas = _filter_schemas(schemas, schema_tables, schema_exclude_columns) fsm = reconnect.Reconnect(now()) fsm.set_name('%s:%s' % address[:2]) fsm.enable(now()) fsm.set_passive(True, now()) fsm.set_max_tries(-1) if probe_interval is not None: fsm.set_probe_interval(probe_interval) if min_backoff is None: min_backoff = fsm.get_min_backoff() if max_backoff is None: max_backoff = fsm.get_max_backoff() if min_backoff and max_backoff: fsm.set_backoff(min_backoff, max_backoff) fsm.connected(now()) session = jsonrpc.Session(fsm, connection, fsm.get_name()) idl = Idl(session, schemas[0]) system_id = discover_system_id(idl) if not system_id: return None name = cls.instance_name(system_id) ovs_stream.name = name connection.name = name fsm.set_name(name) kwargs = kwargs.copy() kwargs['socket'] = sock kwargs['address'] = address kwargs['idl'] = idl kwargs['name'] = name kwargs['system_id'] = system_id app_mgr = app_manager.AppManager.get_instance() old_app = app_manager.lookup_service_brick(name) old_events = None if old_app: old_events = old_app.events app_mgr.uninstantiate(name) app = app_mgr.instantiate(cls, *args, **kwargs) if old_events: app.events = old_events return app @classmethod def instance_name(cls, system_id): return '%s-%s' % (cls.__name__, system_id) def __init__(self, *args, **kwargs): super(RemoteOvsdb, self).__init__(*args, **kwargs) self.socket = kwargs['socket'] self.address = kwargs['address'] self._idl = kwargs['idl'] self.system_id = kwargs['system_id'] self.name = kwargs['name'] self._txn_q = collections.deque() def _event_proxy_loop(self): while self.is_active: events = self._idl.events if not events: hub.sleep(0.1) continue for e in events: ev = e[0] args = e[1] self._submit_event(ev(self.system_id, *args)) hub.sleep(0) def _submit_event(self, ev): self.send_event_to_observers(ev) try: ev_cls_name = 'Event' + ev.table + ev.event_type proxy_ev_cls = getattr(event, ev_cls_name, None) if proxy_ev_cls: self.send_event_to_observers(proxy_ev_cls(ev)) except Exception: self.logger.exception( 'Error submitting specific event for OVSDB %s', self.system_id) def _idl_loop(self): while self.is_active: try: self._idl.run() self._transactions() except Exception: self.logger.exception('Error running IDL for system_id %s' % self.system_id) raise hub.sleep(0) def _run_thread(self, func, *args, **kwargs): try: func(*args, **kwargs) except: self.stop() def _transactions(self): if not self._txn_q: return # NOTE(jkoelker) possibly run multiple transactions per loop? self._transaction() def _transaction(self): req = self._txn_q.popleft() txn = idl.Transaction(self._idl) uuids = req.func(self._idl.tables, txn.insert) status = txn.commit_block() insert_uuids = {} err_msg = None if status in (idl.Transaction.SUCCESS, idl.Transaction.UNCHANGED): if uuids: if isinstance(uuids, uuid.UUID): insert_uuids[uuids] = txn.get_insert_uuid(uuids) else: insert_uuids = dict((uuid, txn.get_insert_uuid(uuid)) for uuid in uuids) else: err_msg = txn.get_error() rep = event.EventModifyReply(self.system_id, status, insert_uuids, err_msg) self.reply_to_request(req, rep) def modify_request_handler(self, ev): self._txn_q.append(ev) def read_request_handler(self, ev, bulk=False): result = ev.func(self._idl.tables) # NOTE(jkoelker) If this was a bulk request, the parent OVSDB app is # responsible for the reply if bulk: return (self.system_id, result) rep = event.EventReadReply(self.system_id, result) self.reply_to_request(ev, rep) def start(self): super(RemoteOvsdb, self).start() t = hub.spawn(self._run_thread, self._idl_loop) self.threads.append(t) t = hub.spawn(self._run_thread, self._event_proxy_loop) self.threads.append(t) def stop(self): # NOTE(jkoelker) Stop the idl and event_proxy threads first # letting them finish their current loop. self.is_active = False hub.joinall(self.threads) self._idl.close() super(RemoteOvsdb, self).stop() ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/ovsdb/event.py0000664000175000017500000001400000000000000022741 0ustar00zuulzuul00000000000000# Copyright (c) 2014 Rackspace Hosting # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. from os_ken.controller import event as os_ken_event from os_ken.controller import handler class EventRowBase(os_ken_event.EventBase): def __init__(self, system_id, table, row, event_type): super(EventRowBase, self).__init__() self.system_id = system_id self.table = table self.row = row self.event_type = event_type def __str__(self): return '%s' % (self.__class__.__name__, self.system_id, self.table, self.row['_uuid']) class EventRowDelete(EventRowBase): def __init__(self, system_id, table, row): super(EventRowDelete, self).__init__(system_id, table, row, 'Deleted') class EventRowInsert(EventRowBase): def __init__(self, system_id, table, row): super(EventRowInsert, self).__init__(system_id, table, row, 'Inserted') class EventRowUpdate(os_ken_event.EventBase): def __init__(self, system_id, table, old, new): super(EventRowUpdate, self).__init__() self.system_id = system_id self.table = table self.old = old self.new = new self.event_type = 'Updated' def __str__(self): return '%s' % (self.__class__.__name__, self.system_id, self.table, self.old['_uuid']) class EventModifyRequest(os_ken_event.EventRequestBase): """ Dispatch a modify function to OVSDB `func` must be a callable that accepts an insert fucntion and the IDL.tables object. It can then modify the tables as needed. For inserts, specify a UUID for each insert, and return a tuple of the temporary UUID's. The execution of `func` will be wrapped in a single transaction and the reply will include a dict of temporary UUID to real UUID mappings. e.g. new_port_uuid = uuid.uuid4() def modify(tables, insert): bridges = tables['Bridge'].rows bridge = None for b in bridges: if b.name == 'my-bridge': bridge = b if not bridge: return port = insert('Port', new_port_uuid) bridge.ports = bridge.ports + [port] return (new_port_uuid, ) request = EventModifyRequest(system_id, modify) reply = send_request(request) port_uuid = reply.insert_uuids[new_port_uuid] """ def __init__(self, system_id, func): super(EventModifyRequest, self).__init__() self.dst = 'OVSDB' self.system_id = system_id self.func = func def __str__(self): return '%s' % (self.__class__.__name__, self.system_id) class EventModifyReply(os_ken_event.EventReplyBase): def __init__(self, system_id, status, insert_uuids, err_msg): self.system_id = system_id self.status = status self.insert_uuids = insert_uuids self.err_msg = err_msg def __str__(self): return ('%s' % (self.__class__.__name__, self.system_id, self.status, self.insert_uuids, self.err_msg)) class EventNewOVSDBConnection(os_ken_event.EventBase): def __init__(self, client): super(EventNewOVSDBConnection, self).__init__() self.client = client def __str__(self): return '%s' % (self.__class__.__name__, self.client.system_id) @property def system_id(self): return self.client.system_id class EventReadRequest(os_ken_event.EventRequestBase): def __init__(self, system_id, func): self.system_id = system_id self.func = func self.dst = 'OVSDB' class EventReadReply(os_ken_event.EventReplyBase): def __init__(self, system_id, result, err_msg=''): self.system_id = system_id self.result = result self.err_msg = err_msg class EventRowInsertedBase(EventRowInsert): def __init__(self, ev): super(EventRowInsertedBase, self).__init__(ev.system_id, ev.table, ev.row) class EventRowDeletedBase(EventRowDelete): def __init__(self, ev): super(EventRowDeletedBase, self).__init__(ev.system_id, ev.table, ev.row) class EventRowUpdatedBase(EventRowUpdate): def __init__(self, ev): super(EventRowUpdatedBase, self).__init__(ev.system_id, ev.table, ev.old, ev.new) class EventPortInserted(EventRowInsertedBase): pass class EventPortDeleted(EventRowDeletedBase): pass class EventPortUpdated(EventRowUpdatedBase): pass class EventInterfaceInserted(EventRowInsertedBase): pass class EventInterfaceDeleted(EventRowDeletedBase): pass class EventInterfaceUpdated(EventRowUpdatedBase): pass handler.register_service('os_ken.services.protocols.ovsdb.manager') ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/ovsdb/manager.py0000664000175000017500000002145500000000000023246 0ustar00zuulzuul00000000000000# Copyright (c) 2014 Rackspace Hosting # # 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. import ssl import socket from os_ken import cfg from os_ken.base import app_manager from os_ken.lib import hub from os_ken.lib import ip from os_ken.services.protocols.ovsdb import client from os_ken.services.protocols.ovsdb import event from os_ken.controller import handler opts = (cfg.StrOpt('address', default='0.0.0.0', help='OVSDB address'), cfg.IntOpt('port', default=6640, help='OVSDB port'), cfg.IntOpt('probe-interval', help='OVSDB reconnect probe interval'), cfg.IntOpt('min-backoff', help=('OVSDB reconnect minimum milliseconds between ' 'connection attemps')), cfg.IntOpt('max-backoff', help=('OVSDB reconnect maximum milliseconds between ' 'connection attemps')), cfg.StrOpt('mngr-privkey', default=None, help='manager private key'), cfg.StrOpt('mngr-cert', default=None, help='manager certificate'), cfg.ListOpt('whitelist', default=[], help='Whitelist of address to allow to connect'), cfg.ListOpt('schema-tables', default=[], help='Tables in the OVSDB schema to configure'), cfg.ListOpt('schema-exclude-columns', default=[], help='Table columns in the OVSDB schema to filter out. ' 'Values should be in the format: ..' 'Ex: Bridge.netflow,Interface.statistics') ) cfg.CONF.register_opts(opts, 'ovsdb') class OVSDB(app_manager.OSKenApp): _EVENTS = [event.EventNewOVSDBConnection, event.EventModifyRequest, event.EventReadRequest] def __init__(self, *args, **kwargs): super(OVSDB, self).__init__(*args, **kwargs) self._address = self.CONF.ovsdb.address self._port = self.CONF.ovsdb.port self._probe_interval = self.CONF.ovsdb.probe_interval self._min_backoff = self.CONF.ovsdb.min_backoff self._max_backoff = self.CONF.ovsdb.max_backoff self._clients = {} def _accept(self, server): if self.CONF.ovsdb.whitelist: def check(address): if address in self.CONF.ovsdb.whitelist: return True self.logger.debug('Connection from non-whitelist client ' '(%s:%s)' % address) return False else: def check(address): return True while self.is_active: try: # TODO(jkoelker) SSL Certificate Fingerprint check sock, client_address = server.accept() except: if self.is_active: self.logger.exception('Error accepting connection') continue if not check(client_address[0]): sock.shutdown(socket.SHUT_RDWR) sock.close() continue if ip.valid_ipv6(client_address[0]): self.logger.debug( 'New connection from [%s]:%s' % client_address[:2]) else: self.logger.debug( 'New connection from %s:%s' % client_address[:2]) t = hub.spawn(self._start_remote, sock, client_address) self.threads.append(t) def _bulk_read_handler(self, ev): results = [] def done(gt, *args, **kwargs): if gt in self.threads: self.threads.remove(gt) results.append(gt.wait()) threads = [] for c in self._clients.values(): gt = hub.spawn(c.read_request_handler, ev, bulk=True) threads.append(gt) self.threads.append(gt) gt.link(done) hub.joinall(threads) rep = event.EventReadReply(None, results) self.reply_to_request(ev, rep) def _proxy_event(self, ev): system_id = ev.system_id client_name = client.RemoteOvsdb.instance_name(system_id) if client_name not in self._clients: self.logger.info('Unknown remote system_id %s' % system_id) return return self.send_event(client_name, ev) def _start_remote(self, sock, client_address): schema_tables = cfg.CONF.ovsdb.schema_tables schema_ex_col = {} if cfg.CONF.ovsdb.schema_exclude_columns: for c in cfg.CONF.ovsdb.schema_exclude_columns: tbl, col = c.split('.') if tbl in schema_ex_col: schema_ex_col[tbl].append(col) else: schema_ex_col[tbl] = [col] app = client.RemoteOvsdb.factory(sock, client_address, probe_interval=self._probe_interval, min_backoff=self._min_backoff, max_backoff=self._max_backoff, schema_tables=schema_tables, schema_exclude_columns=schema_ex_col) if app: self._clients[app.name] = app app.start() ev = event.EventNewOVSDBConnection(app) self.send_event_to_observers(ev) else: try: sock.shutdown(socket.SHUT_RDWR) except: pass sock.close() def start(self): if ip.valid_ipv6(self._address): server = hub.listen( (self._address, self._port), family=socket.AF_INET6) else: server = hub.listen((self._address, self._port)) key = self.CONF.ovsdb.mngr_privkey or self.CONF.ctl_privkey cert = self.CONF.ovsdb.mngr_cert or self.CONF.ctl_cert if key is not None and cert is not None: ssl_kwargs = dict(keyfile=key, certfile=cert, server_side=True) if self.CONF.ca_certs is not None: ssl_kwargs['cert_reqs'] = ssl.CERT_REQUIRED ssl_kwargs['ca_certs'] = self.CONF.ca_certs server = ssl.wrap_socket(server, **ssl_kwargs) self._server = server if ip.valid_ipv6(self._address): self.logger.info( 'Listening on [%s]:%s for clients', self._address, self._port) else: self.logger.info( 'Listening on %s:%s for clients', self._address, self._port) t = hub.spawn(self._accept, self._server) super(OVSDB, self).start() return t def stop(self): # NOTE(jkoelker) Attempt to gracefully stop the accept loop self.is_active = False # NOTE(jkoelker) Forceably kill the loop and clear the main_thread if self.main_thread: hub.kill(self.main_thread) self.main_thread = None # NOTE(jkoelker) Stop all the clients for c in self._clients.values(): c.stop() # NOTE(jkoelker) super will only take care of the event and joining now super(OVSDB, self).stop() @handler.set_ev_cls(event.EventModifyRequest) def modify_request_handler(self, ev): system_id = ev.system_id client_name = client.RemoteOvsdb.instance_name(system_id) remote = self._clients.get(client_name) if not remote: msg = 'Unknown remote system_id %s' % system_id self.logger.info(msg) rep = event.EventModifyReply(system_id, None, None, msg) return self.reply_to_request(ev, rep) return remote.modify_request_handler(ev) @handler.set_ev_cls(event.EventReadRequest) def read_request_handler(self, ev): system_id = ev.system_id if system_id is None: def done(gt, *args, **kwargs): if gt in self.threads: self.threads.remove(gt) thread = hub.spawn(self._bulk_read_handler, ev) self.threads.append(thread) return thread.link(done) client_name = client.RemoteOvsdb.instance_name(system_id) remote = self._clients.get(client_name) if not remote: msg = 'Unknown remote system_id %s' % system_id self.logger.info(msg) rep = event.EventReadReply(system_id, None, msg) return self.reply_to_request(ev, rep) return remote.read_request_handler(ev) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/ovsdb/model.py0000664000175000017500000000217200000000000022727 0ustar00zuulzuul00000000000000# Copyright (c) 2014 Rackspace Hosting # # 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. import uuid class _UUIDDict(dict): def _uuidize(self): if '_uuid' not in self or self['_uuid'] is None: self['_uuid'] = uuid.uuid4() @property def uuid(self): self._uuidize() return self['_uuid'] @uuid.setter def uuid(self, value): self['_uuid'] = value class Row(_UUIDDict): @property def delete(self): if '_delete' in self and self['_delete']: return True return False @delete.setter def delete(self, value): self['_delete'] = value ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.1221063 os-ken-2.10.0/os_ken/services/protocols/vrrp/0000775000175000017500000000000000000000000021127 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/vrrp/__init__.py0000664000175000017500000000142600000000000023243 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013 Isaku Yamahata # # 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. import os_ken.services.protocols.vrrp.monitor_linux import os_ken.services.protocols.vrrp.monitor_openflow ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/vrrp/api.py0000664000175000017500000000471200000000000022256 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013 Isaku Yamahata # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. from os_ken.base import app_manager from os_ken.services.protocols.vrrp import event as vrrp_event def vrrp_config(app, interface, config): """create an instance. returns EventVRRPConfigReply(instance.name, interface, config) on success. returns EventVRRPConfigReply(None, interface, config) on failure. """ config_request = vrrp_event.EventVRRPConfigRequest(interface, config) config_request.sync = True return app.send_request(config_request) def vrrp_shutdown(app, instance_name): """shutdown the instance. """ shutdown_request = vrrp_event.EventVRRPShutdownRequest(instance_name) app.send_event(vrrp_event.VRRP_MANAGER_NAME, shutdown_request) def vrrp_transmit(app, monitor_name, data): """transmit a packet from the switch. this is internal use only. data is str-like, a packet to send. """ transmit_request = vrrp_event.EventVRRPTransmitRequest(data) app.send_event(monitor_name, transmit_request) def vrrp_list(app, instance_name=None): """list instances. returns EventVRRPListReply([VRRPInstance]). """ list_request = vrrp_event.EventVRRPListRequest(instance_name) list_request.dst = vrrp_event.VRRP_MANAGER_NAME return app.send_request(list_request) def vrrp_config_change(app, instance_name, priority=None, advertisement_interval=None, preempt_mode=None, accept_mode=None): """change configuration of an instance. None means no change. """ config_change = vrrp_event.EventVRRPConfigChangeRequest( instance_name, priority, advertisement_interval, preempt_mode, accept_mode) return app.send_event(vrrp_event.VRRP_MANAGER_NAME, config_change) app_manager.require_app('os_ken.services.protocols.vrrp.manager', api_style=True) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/vrrp/dumper.py0000664000175000017500000001704700000000000023006 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013 Isaku Yamahata # # 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. """ VRRP event dumper This is also a template for router implementation that support VRRP """ from os_ken.base import app_manager from os_ken.controller import handler from os_ken.services.protocols.vrrp import event as vrrp_event class VRRPDumper(app_manager.OSKenApp): def __init__(self, *args, **kwargs): super(VRRPDumper, self).__init__(*args, **kwargs) @handler.set_ev_cls(vrrp_event.EventVRRPStateChanged) def vrrp_state_changed_handler(self, ev): old_state = ev.old_state new_state = ev.new_state self.logger.info('state change %s: %s -> %s', ev.instance_name, old_state, new_state) if new_state == vrrp_event.VRRP_STATE_MASTER: self.logger.info('becomes master') if old_state is None: # RFC3768 6.4.1 # o Broadcast a gratuitous ARP request containing the virtual # router MAC address for each IP address associated with the # virtual router. # # or # # RFC 5795 6.4.1 # (115)+ If the protected IPvX address is an IPv4 address, # then: # (120) * Broadcast a gratuitous ARP request containing the # virtual router MAC address for each IP address associated # with the virtual router. # (125) + else // IPv6 # (130) * For each IPv6 address associated with the virtual # router, send an unsolicited ND Neighbor Advertisement with # the Router Flag (R) set, the Solicited Flag (S) unset, the # Override flag (O) set, the target address set to the IPv6 # address of the virtual router, and the target link-layer # address set to the virtual router MAC address. # pass elif old_state == vrrp_event.VRRP_STATE_BACKUP: # RFC3768 6.4.2 # o Broadcast a gratuitous ARP request containing the virtual # router MAC address for each IP address associated with the # virtual router # # or # # RFC 5795 6.4.2 # (375)+ If the protected IPvX address is an IPv4 address, # then: # (380)* Broadcast a gratuitous ARP request on that interface # containing the virtual router MAC address for each IPv4 # address associated with the virtual router. # (385) + else // ipv6 # (390) * Compute and join the Solicited-Node multicast # address [RFC4291] for the IPv6 address(es) associated with # the virtual router. # (395) * For each IPv6 address associated with the virtual # router, send an unsolicited ND Neighbor Advertisement with # the Router Flag (R) set, the Solicited Flag (S) unset, the # Override flag (O) set, the target address set to the IPv6 # address of the virtual router, and the target link-layer # address set to the virtual router MAC address. pass # RFC 3768 6.4.3 # - MUST respond to ARP requests for the IP address(es) associated # with the virtual router. # - MUST forward packets with a destination link layer MAC address # equal to the virtual router MAC address. # - MUST NOT accept packets addressed to the IP address(es) # associated with the virtual router if it is not the IP address # owner. # - MUST accept packets addressed to the IP address(es) associated # with the virtual router if it is the IP address owner. # # or # # RFC5798 6.4.3 # (605) - If the protected IPvX address is an IPv4 address, then: # (610) + MUST respond to ARP requests for the IPv4 address(es) # associated with the virtual router. # (615) - else // ipv6 # (620) + MUST be a member of the Solicited-Node multicast # address for the IPv6 address(es) associated with the virtual # router. # (625) + MUST respond to ND Neighbor Solicitation message for # the IPv6 address(es) associated with the virtual router. # (630) ++ MUST send ND Router Advertisements for the virtual # router. # (635) ++ If Accept_Mode is False: MUST NOT drop IPv6 Neighbor # Solicitations and Neighbor Advertisements. # (640) +-endif // ipv4? # (645) - MUST forward packets with a destination link-layer MAC # address equal to the virtual router MAC address. # (650) - MUST accept packets addressed to the IPvX address(es) # associated with the virtual router if it is the IPvX address # owner or if Accept_Mode is True. Otherwise, MUST NOT accept # these packets. elif new_state == vrrp_event.VRRP_STATE_BACKUP: self.logger.info('becomes backup') # RFC 3768 6.4.2 Backup # - MUST NOT respond to ARP requests for the IP address(s) # associated with the virtual router. # - MUST discard packets with a destination link layer MAC address # equal to the virtual router MAC address. # - MUST NOT accept packets addressed to the IP address(es) # associated with the virtual router. # # or # # RFC 5798 6.4.2 Backup # (305) - If the protected IPvX address is an IPv4 address, then: # (310) + MUST NOT respond to ARP requests for the IPv4 # address(es) associated with the virtual router. # (315) - else // protected addr is IPv6 # (320) + MUST NOT respond to ND Neighbor Solicitation messages # for the IPv6 address(es) associated with the virtual router. # (325) + MUST NOT send ND Router Advertisement messages for the # virtual router. # (330) -endif // was protected addr IPv4? # (335) - MUST discard packets with a destination link-layer MAC # address equal to the virtual router MAC address. # (340) - MUST NOT accept packets addressed to the IPvX address(es) # associated with the virtual router. elif new_state == vrrp_event.VRRP_STATE_INITIALIZE: if old_state is None: self.logger.info('initialized') else: self.logger.info('shutdowned') else: raise ValueError('invalid vrrp state %s' % new_state) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/vrrp/event.py0000664000175000017500000002267300000000000022634 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013 Isaku Yamahata # # 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. """ Events for VRRP """ from os_ken.controller import handler from os_ken.controller import event from os_ken.lib import dpid as dpid_lib from os_ken.lib import mac as mac_lib from os_ken.lib.packet import vrrp from os_ken.lib import addrconv # When an instance is created, state transition is None -> Initialize VRRP_STATE_INITIALIZE = 'Initialize' VRRP_STATE_MASTER = 'Master' VRRP_STATE_BACKUP = 'Backup' VRRP_MANAGER_NAME = 'VRRPManager' class VRRPInterfaceBase(object): """ interface on which VRRP router works vlan_id = None means no vlan. NOTE: multiple virtual router can be configured on single port See RFC 5798 4.2 Sample Configuration 2 """ def __init__(self, mac_address, primary_ip_address, vlan_id=None): super(VRRPInterfaceBase, self).__init__() self.mac_address = mac_address self.primary_ip_address = primary_ip_address self.vlan_id = vlan_id def __eq__(self, other): return (self.__class__ == other.__class__ and self.mac_address == other.mac_address and self.primary_ip_address == other.primary_ip_address and self.vlan_id == other.vlan_id) def __hash__(self): return hash(( addrconv.mac.text_to_bin(self.mac_address), vrrp.ip_text_to_bin(self.primary_ip_address), self.vlan_id)) class VRRPInterfaceNetworkDevice(VRRPInterfaceBase): def __init__(self, mac_address, primary_ip_address, vlan_id, device_name): super(VRRPInterfaceNetworkDevice, self).__init__( mac_address, primary_ip_address, vlan_id) self.device_name = device_name def __str__(self): return '%s<%s, %s, %s, %s>' % ( self.__class__.__name__, self.mac_address, self.primary_ip_address, self.vlan_id, self.device_name) def __eq__(self, other): return (super(VRRPInterfaceNetworkDevice, self).__eq__(other) and self.device_name == other.device_name) def __hash__(self): return hash(( addrconv.mac.text_to_bin(self.mac_address), vrrp.ip_text_to_bin(self.primary_ip_address), self.vlan_id, self.device_name)) class VRRPInterfaceOpenFlow(VRRPInterfaceBase): def __init__(self, mac_address, primary_ip_address, vlan_id, dpid, port_no): super(VRRPInterfaceOpenFlow, self).__init__( mac_address, primary_ip_address, vlan_id) self.dpid = dpid self.port_no = port_no def __str__(self): return '%s<%s, %s, %s, %s, %d>' % ( self.__class__.__name__, self.mac_address, self.primary_ip_address, self.vlan_id, dpid_lib.dpid_to_str(self.dpid), self.port_no) def __eq__(self, other): return (super(VRRPInterfaceOpenFlow, self).__eq__(other) and self.dpid == other.dpid and self.port_no == other.port_no) def __hash__(self): return hash(( addrconv.mac.text_to_bin(self.mac_address), vrrp.ip_text_to_bin(self.primary_ip_address), self.vlan_id, self.dpid, self.port_no)) class VRRPConfig(object): """ advertmisement_interval is in seconds as float. (Not in centiseconds) """ def __init__(self, version=vrrp.VRRP_VERSION_V3, vrid=None, admin_state=True, priority=vrrp.VRRP_PRIORITY_BACKUP_DEFAULT, ip_addresses=None, advertisement_interval=vrrp.VRRP_MAX_ADVER_INT_DEFAULT_IN_SEC, preempt_mode=True, preempt_delay=0, accept_mode=False, statistics_interval=30, resource_id=None): # To allow version and priority default assert vrid is not None assert ip_addresses is not None super(VRRPConfig, self).__init__() self.version = version self.admin_state = admin_state self.vrid = vrid self.priority = priority self.ip_addresses = ip_addresses self.advertisement_interval = advertisement_interval self.preempt_mode = preempt_mode self.preempt_delay = preempt_delay self.accept_mode = accept_mode self.is_ipv6 = vrrp.is_ipv6(ip_addresses[0]) self.statistics_interval = statistics_interval self.resource_id = resource_id @property def address_owner(self): return self.priority == vrrp.VRRP_PRIORITY_ADDRESS_OWNER def __eq__(self, other): return (self.version == other.version and self.vrid == other.vrid and self.priority == other.priority and self.ip_addresses == other.ip_addresses and self.advertisement_interval == other.advertisement_interval and self.preempt_mode == other.preempt_mode and self.preempt_delay == other.preempt_delay and self.accept_mode == other.accept_mode and self.is_ipv6 == other.is_ipv6) def __hash__(self): hash((self.version, self.vrid, self.priority, list(map(vrrp.ip_text_to_bin, self.ip_addresses)), self.advertisement_interval, self.preempt_mode, self.preempt_delay, self.accept_mode, self.is_ipv6)) class EventVRRPConfigRequest(event.EventRequestBase): """ Request from management layer to VRRP manager to initialize VRRP Router. """ def __init__(self, interface, config): super(EventVRRPConfigRequest, self).__init__() self.dst = VRRP_MANAGER_NAME self.interface = interface self.config = config class EventVRRPConfigReply(event.EventReplyBase): def __init__(self, instance_name, interface, config): # dst = None. dst is filled by app_base.OSKenApp#reply_to_request() super(EventVRRPConfigReply, self).__init__(None) self.instance_name = instance_name # None means failure self.interface = interface self.config = config class EventVRRPShutdownRequest(event.EventRequestBase): """ Request from management layer to VRRP to shutdown VRRP Router. """ def __init__(self, instance_name): super(EventVRRPShutdownRequest, self).__init__() self.instance_name = instance_name class EventVRRPStateChanged(event.EventBase): """ Event that this VRRP Router changed its state. """ def __init__(self, instance_name, monitor_name, interface, config, old_state, new_state): super(EventVRRPStateChanged, self).__init__() self.instance_name = instance_name self.monitor_name = monitor_name self.interface = interface self.config = config self.old_state = old_state self.new_state = new_state class VRRPInstance(object): def __init__(self, instance_name, monitor_name, config, interface, state): super(VRRPInstance, self).__init__() self.instance_name = instance_name self.monitor_name = monitor_name self.config = config self.interface = interface self.state = state class EventVRRPListRequest(event.EventRequestBase): """ Event that requests list of configured VRRP router instance_name=None means all instances. """ def __init__(self, instance_name=None): super(EventVRRPListRequest, self).__init__() self.instance_name = instance_name class EventVRRPListReply(event.EventReplyBase): def __init__(self, instance_list): super(EventVRRPListReply, self).__init__(None) self.instance_list = instance_list class EventVRRPConfigChangeRequest(event.EventRequestBase): """ Event that requests to change configuration of a given VRRP router. None means no-change. """ def __init__(self, instance_name, priority=None, advertisement_interval=None, preempt_mode=None, preempt_delay=None, accept_mode=None): super(EventVRRPConfigChangeRequest, self).__init__() self.instance_name = instance_name self.priority = priority self.advertisement_interval = advertisement_interval self.preempt_mode = preempt_mode self.preempt_delay = preempt_delay self.accept_mode = accept_mode # Following classes are internally used by VRRP class EventVRRPReceived(event.EventBase): """ Event that port manager received valid VRRP packet. Usually handed by VRRP Router. """ def __init__(self, interface, packet): super(EventVRRPReceived, self).__init__() self.interface = interface self.packet = packet class EventVRRPTransmitRequest(event.EventRequestBase): """ Request from VRRP router to port manager to transmit VRRP packet. """ def __init__(self, data): super(EventVRRPTransmitRequest, self).__init__() self.data = data handler.register_service('os_ken.services.protocols.vrrp.manager') ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/vrrp/manager.py0000664000175000017500000001741000000000000023116 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013 Isaku Yamahata # # 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. """ VRRP manager that manages VRRP router instances VRRPManager creates/deletes VRRPRouter, VRRPInterfaceMonitor dynamically as requested. Usage example osken-manager --verbose \ os_ken.services.protocols.vrrp.manager \ os_ken.services.protocols.vrrp.dumper """ import time from os_ken.base import app_manager from os_ken.controller import handler from os_ken.lib import hub from os_ken.services.protocols.vrrp import event as vrrp_event from os_ken.services.protocols.vrrp import monitor as vrrp_monitor from os_ken.services.protocols.vrrp import router as vrrp_router class VRRPInstance(object): def __init__(self, name, monitor_name, config, interface): super(VRRPInstance, self).__init__() self.name = name # vrrp_router.name self.monitor_name = monitor_name # interface_monitor.name self.config = config self.interface = interface self.state = None def state_changed(self, new_state): self.state = new_state class VRRPManager(app_manager.OSKenApp): @staticmethod def _instance_name(interface, vrid, is_ipv6): ip_version = 'ipv6' if is_ipv6 else 'ipv4' return 'VRRP-Router-%s-%d-%s' % (str(interface), vrid, ip_version) def __init__(self, *args, **kwargs): super(VRRPManager, self).__init__(*args, **kwargs) self._args = args self._kwargs = kwargs self.name = vrrp_event.VRRP_MANAGER_NAME self._instances = {} # name -> VRRPInstance self.shutdown = hub.Queue() def start(self): t = hub.spawn(self._shutdown_loop) super(VRRPManager, self).start() return t @handler.set_ev_cls(vrrp_event.EventVRRPConfigRequest) def config_request_handler(self, ev): config = ev.config interface = ev.interface name = self._instance_name(interface, config.vrid, config.is_ipv6) if name in self._instances: rep = vrrp_event.EventVRRPConfigReply(None, interface, config) self.reply_to_request(ev, rep) return statistics = VRRPStatistics(name, config.resource_id, config.statistics_interval) monitor = vrrp_monitor.VRRPInterfaceMonitor.factory( interface, config, name, statistics, *self._args, **self._kwargs) router = vrrp_router.VRRPRouter.factory(name, monitor.name, interface, config, statistics, *self._args, **self._kwargs) # Event piping # vrrp_router -> vrrp_manager # EventVRRPStateChanged to vrrp_manager is handled by framework # vrrp_manager -> vrrp_rouer self.register_observer(vrrp_event.EventVRRPShutdownRequest, router.name) # vrrp_router -> vrrp_monitor router.register_observer(vrrp_event.EventVRRPStateChanged, monitor.name) router.register_observer(vrrp_event.EventVRRPTransmitRequest, monitor.name) # vrrp_interface_monitor -> vrrp_router monitor.register_observer(vrrp_event.EventVRRPReceived, router.name) instance = VRRPInstance(name, monitor.name, config, interface) self._instances[name] = instance # self.logger.debug('report_bricks') # app_manager.AppManager.get_instance().report_bricks() # debug monitor.start() router.start() rep = vrrp_event.EventVRRPConfigReply(instance.name, interface, config) self.reply_to_request(ev, rep) def _proxy_event(self, ev): name = ev.instance_name instance = self._instances.get(name, None) if not instance: self.logger.info('unknown vrrp router %s', name) return self.send_event(instance.name, ev) @handler.set_ev_cls(vrrp_event.EventVRRPShutdownRequest) def shutdown_request_handler(self, ev): self._proxy_event(ev) @handler.set_ev_cls(vrrp_event.EventVRRPConfigChangeRequest) def config_change_request_handler(self, ev): self._proxy_event(ev) @handler.set_ev_cls(vrrp_event.EventVRRPStateChanged) def state_change_handler(self, ev): instance = self._instances.get(ev.instance_name, None) assert instance is not None instance.state_changed(ev.new_state) if ev.old_state and ev.new_state == vrrp_event.VRRP_STATE_INITIALIZE: self.shutdown.put(instance) def _shutdown_loop(self): app_mgr = app_manager.AppManager.get_instance() while self.is_active or not self.shutdown.empty(): instance = self.shutdown.get() app_mgr.uninstantiate(instance.name) app_mgr.uninstantiate(instance.monitor_name) del self._instances[instance.name] @handler.set_ev_cls(vrrp_event.EventVRRPListRequest) def list_request_handler(self, ev): instance_name = ev.instance_name if instance_name is None: instance_list = [vrrp_event.VRRPInstance( instance.name, instance.monitor_name, instance.config, instance.interface, instance.state) for instance in self._instances.values()] else: instance = self._instances.get(instance_name, None) if instance is None: instance_list = [] else: instance_list = [vrrp_event.VRRPInstance( instance_name, instance.monitor_name, instance.config, instance.interface, instance.state)] vrrp_list = vrrp_event.EventVRRPListReply(instance_list) self.reply_to_request(ev, vrrp_list) class VRRPStatistics(object): def __init__(self, name, resource_id, statistics_interval): self.name = name self.resource_id = resource_id self.statistics_interval = statistics_interval self.tx_vrrp_packets = 0 self.rx_vrrp_packets = 0 self.rx_vrrp_zero_prio_packets = 0 self.tx_vrrp_zero_prio_packets = 0 self.rx_vrrp_invalid_packets = 0 self.rx_vrrp_bad_auth = 0 self.idle_to_master_transitions = 0 self.idle_to_backup_transitions = 0 self.backup_to_master_transitions = 0 self.master_to_backup_transitions = 0 def get_stats(self): ts = time.strftime("%Y-%m-%dT%H:%M:%S") stats_dict = dict( timestamp=ts, resource_id=self.resource_id, tx_vrrp_packets=self.tx_vrrp_packets, rx_vrrp_packets=self.rx_vrrp_packets, rx_vrrp_zero_prio_packets=self.rx_vrrp_zero_prio_packets, tx_vrrp_zero_prio_packets=self.tx_vrrp_zero_prio_packets, rx_vrrp_invalid_packets=self.rx_vrrp_invalid_packets, rx_vrrp_bad_auth=self.rx_vrrp_bad_auth, idle_to_master_transitions=self.idle_to_master_transitions, idle_to_backup_transitions=self.idle_to_backup_transitions, backup_to_master_transitions=self.backup_to_master_transitions, master_to_backup_transitions=self.master_to_backup_transitions ) return stats_dict ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/vrrp/monitor.py0000664000175000017500000001471600000000000023201 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013 Isaku Yamahata # # 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 monitor. Watching packet received on this interface and parse VRRP packet. VRRPManager creates/deletes instances of interface monitor dynamically. """ from os_ken.base import app_manager from os_ken.controller import handler from os_ken.lib.packet import packet from os_ken.lib.packet import vlan from os_ken.lib.packet import vrrp from os_ken.services.protocols.vrrp import event as vrrp_event class VRRPInterfaceMonitor(app_manager.OSKenApp): # subclass of VRRPInterfaceBase -> subclass of VRRPInterfaceMonitor _CONSTRUCTORS = {} @staticmethod def register(interface_cls): def _register(cls): VRRPInterfaceMonitor._CONSTRUCTORS[interface_cls] = cls return cls return _register @staticmethod def factory(interface, config, router_name, statistics, *args, **kwargs): cls = VRRPInterfaceMonitor._CONSTRUCTORS[interface.__class__] app_mgr = app_manager.AppManager.get_instance() kwargs = kwargs.copy() kwargs['router_name'] = router_name kwargs['vrrp_config'] = config kwargs['vrrp_interface'] = interface kwargs['vrrp_statistics'] = statistics app = app_mgr.instantiate(cls, *args, **kwargs) return app @classmethod def instance_name(cls, interface, vrid): return '%s-%s-%d' % (cls.__name__, str(interface), vrid) def __init__(self, *args, **kwargs): super(VRRPInterfaceMonitor, self).__init__(*args, **kwargs) self.config = kwargs['vrrp_config'] self.interface = kwargs['vrrp_interface'] self.router_name = kwargs['router_name'] self.statistics = kwargs['vrrp_statistics'] self.name = self.instance_name(self.interface, self.config.vrid) def _parse_received_packet(self, packet_data): # OF doesn't support VRRP packet matching, so we have to parse # it ourselvs. packet_ = packet.Packet(packet_data) protocols = packet_.protocols # we expect either of # [ether, vlan, ip, vrrp{, padding}] # or # [ether, ip, vrrp{, padding}] if len(protocols) < 2: self.logger.debug('len(protocols) %d', len(protocols)) return vlan_vid = self.interface.vlan_id may_vlan = protocols[1] if (vlan_vid is not None) != isinstance(may_vlan, vlan.vlan): self.logger.debug('vlan_vid: %s %s', vlan_vid, type(may_vlan)) return if vlan_vid is not None and vlan_vid != may_vlan.vid: self.logger.debug('vlan_vid: %s vlan %s', vlan_vid, type(may_vlan)) return # self.logger.debug('%s %s', packet_, packet_.protocols) may_ip, may_vrrp = vrrp.vrrp.get_payload(packet_) if not may_ip or not may_vrrp: # self.logger.debug('may_ip %s may_vrrp %s', may_ip, may_vrrp) return if not vrrp.vrrp.is_valid_ttl(may_ip): self.logger.debug('valid_ttl') return if may_vrrp.version != self.config.version: self.logger.debug('vrrp version %d %d', may_vrrp.version, self.config.version) return if not may_vrrp.is_valid(): self.logger.debug('valid vrrp') return offset = 0 for proto in packet_.protocols: if proto == may_vrrp: break offset += len(proto) if not may_vrrp.checksum_ok( may_ip, packet_.data[offset:offset + len(may_vrrp)]): self.logger.debug('bad checksum') return if may_vrrp.vrid != self.config.vrid: self.logger.debug('vrid %d %d', may_vrrp.vrid, self.config.vrid) return if may_vrrp.is_ipv6 != self.config.is_ipv6: self.logger.debug('is_ipv6 %s %s', may_vrrp.is_ipv6, self.config.is_ipv6) return # TODO: Optional check rfc5798 7.1 # may_vrrp.ip_addresses equals to self.config.ip_addresses if may_vrrp.priority == 0: self.statistics.rx_vrrp_zero_prio_packets += 1 vrrp_received = vrrp_event.EventVRRPReceived(self.interface, packet_) self.send_event(self.router_name, vrrp_received) return True def _send_vrrp_packet_received(self, packet_data): valid = self._parse_received_packet(packet_data) if valid is True: self.statistics.rx_vrrp_packets += 1 else: self.statistics.rx_vrrp_invalid_packets += 1 @handler.set_ev_handler(vrrp_event.EventVRRPTransmitRequest) def vrrp_transmit_request_handler(self, ev): raise NotImplementedError() def _initialize(self): raise NotImplementedError() def _shutdown(self): raise NotImplementedError() @handler.set_ev_handler(vrrp_event.EventVRRPStateChanged) def vrrp_state_changed_handler(self, ev): assert ev.interface == self.interface if ev.new_state == vrrp_event.VRRP_STATE_INITIALIZE: # add/del packet in rule if ev.old_state: self._shutdown() else: self._initialize() elif ev.new_state in [vrrp_event.VRRP_STATE_BACKUP, vrrp_event.VRRP_STATE_MASTER]: if ev.old_state == vrrp_event.VRRP_STATE_INITIALIZE: if ev.new_state == vrrp_event.VRRP_STATE_MASTER: self.statistics.idle_to_master_transitions += 1 else: self.statistics.idle_to_backup_transitions += 1 elif ev.old_state == vrrp_event.VRRP_STATE_MASTER: self.statistics.master_to_backup_transitions += 1 else: self.statistics.backup_to_master_transitions += 1 else: raise RuntimeError('unknown vrrp state %s' % ev.new_state) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/vrrp/monitor_linux.py0000664000175000017500000002035700000000000024416 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013 Isaku Yamahata # # 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. import contextlib import socket import struct from os_ken.controller import handler from os_ken.ofproto import ether from os_ken.ofproto import inet from os_ken.lib import addrconv from os_ken.lib import hub from os_ken.lib.packet import arp from os_ken.lib.packet import vrrp from os_ken.services.protocols.vrrp import monitor from os_ken.services.protocols.vrrp import event as vrrp_event from os_ken.services.protocols.vrrp import utils # Those are not defined in socket module SS_MAXSIZE = 128 MCAST_JOIN_GROUP = 42 MCAST_LEAVE_GROUP = 45 PACKET_ADD_MEMBERSHIP = 1 PACKET_DROP_MEMBERSHIP = 2 PACKET_MR_MULTICAST = 0 SOL_PACKET = 263 def if_nametoindex(ifname): filename = '/sys/class/net/' + ifname + '/ifindex' with contextlib.closing(open(filename)) as f: for line in f: return int(line) @monitor.VRRPInterfaceMonitor.register(vrrp_event.VRRPInterfaceNetworkDevice) class VRRPInterfaceMonitorNetworkDevice(monitor.VRRPInterfaceMonitor): """ This module uses raw socket so that privilege(CAP_NET_ADMIN capability) is required. """ def __init__(self, *args, **kwargs): super(VRRPInterfaceMonitorNetworkDevice, self).__init__(*args, **kwargs) self.__is_active = True config = self.config if config.is_ipv6: family = socket.AF_INET6 ether_type = ether.ETH_TYPE_IPV6 mac_address = vrrp.vrrp_ipv6_src_mac_address(config.vrid) else: family = socket.AF_INET ether_type = ether.ETH_TYPE_IP mac_address = vrrp.vrrp_ipv4_src_mac_address(config.vrid) # socket module doesn't define IPPROTO_VRRP self.ip_socket = socket.socket(family, socket.SOCK_RAW, inet.IPPROTO_VRRP) self.packet_socket = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(ether_type)) self.packet_socket.bind((self.interface.device_name, ether_type, socket.PACKET_MULTICAST, arp.ARP_HW_TYPE_ETHERNET, addrconv.mac.text_to_bin(mac_address))) self.ifindex = if_nametoindex(self.interface.device_name) def start(self): # discard received packets before joining multicast membership packet_socket = self.packet_socket packet_socket.setblocking(0) with hub.Timeout(0.1, False): while True: try: packet_socket.recv(1500) except socket.error: break packet_socket.setblocking(1) self._join_multicast_membership(True) self._join_vrrp_group(True) super(VRRPInterfaceMonitorNetworkDevice, self).start() self.threads.append(hub.spawn(self._recv_loop)) def stop(self): self.__is_active = False super(VRRPInterfaceMonitorNetworkDevice, self).stop() # we assume that the structures in the following two functions for # multicast are aligned in the same way on all the archtectures. def _join_multicast_membership(self, join_leave): config = self.config if config.is_ipv6: mac_address = vrrp.vrrp_ipv6_src_mac_address(config.vrid) else: mac_address = vrrp.vrrp_ipv4_src_mac_address(config.vrid) if join_leave: add_drop = PACKET_ADD_MEMBERSHIP else: add_drop = PACKET_DROP_MEMBERSHIP # struct packet_mreq { # int mr_ifindex; # unsigned short mr_type; # unsigned short mr_alen; # unsigned char mr_mr_address[8]; # }; packet_mreq = struct.pack('IHH8s', self.ifindex, PACKET_MR_MULTICAST, 6, addrconv.mac.text_to_bin(mac_address)) self.packet_socket.setsockopt(SOL_PACKET, add_drop, packet_mreq) def _join_vrrp_group(self, join_leave): if join_leave: join_leave = MCAST_JOIN_GROUP else: join_leave = MCAST_LEAVE_GROUP # struct group_req { # __u32 gr_interface; /* interface index */ # struct __kernel_sockaddr_storage gr_group; /* group address */ # }; group_req = struct.pack('I', self.ifindex) # padding to gr_group. This is environment dependent group_req += b'\x00' * (struct.calcsize('P') - struct.calcsize('I')) if self.config.is_ipv6: # struct sockaddr_in6 { # sa_family_t sin6_family; /* AF_INET6 */ # in_port_t sin6_port; /* port number */ # uint32_t sin6_flowinfo; /* IPv6 flow information */ # struct in6_addr sin6_addr; /* IPv6 address */ # uint32_t sin6_scope_id; /* Scope ID (new in 2.4) */ # }; # struct in6_addr { # unsigned char s6_addr[16]; /* IPv6 address */ # }; family = socket.IPPROTO_IPV6 sockaddr = struct.pack('H', socket.AF_INET6) sockaddr += struct.pack('!H', 0) sockaddr += struct.pack('!I', 0) sockaddr += addrconv.ipv6.text_to_bin(vrrp.VRRP_IPV6_DST_ADDRESS) sockaddr += struct.pack('I', 0) else: # #define __SOCK_SIZE__ 16 /* sizeof(struct sockaddr) */ # struct sockaddr_in { # __kernel_sa_family_t sin_family; /* Address family */ # __be16 sin_port; /* Port number */ # struct in_addr sin_addr; /* Internet address */ # /* Pad to size of `struct sockaddr'. */ # unsigned char __pad[__SOCK_SIZE__ - sizeof(short int) - # sizeof(unsigned short int) - sizeof(struct in_addr)]; # }; # struct in_addr { # __be32 s_addr; # }; family = socket.IPPROTO_IP sockaddr = struct.pack('H', socket.AF_INET) sockaddr += struct.pack('!H', 0) sockaddr += addrconv.ipv4.text_to_bin(vrrp.VRRP_IPV4_DST_ADDRESS) sockaddr += b'\x00' * (SS_MAXSIZE - len(sockaddr)) group_req += sockaddr self.ip_socket.setsockopt(family, join_leave, group_req) return def _recv_loop(self): packet_socket = self.packet_socket packet_socket.settimeout(1.3) # to check activeness periodically try: while self.__is_active: try: buf = packet_socket.recv(128) except socket.timeout: self.logger.debug('timeout') continue except: self.logger.error('recv failed') continue if len(buf) == 0: self.__is_active = False break self.logger.debug('recv buf') self._send_vrrp_packet_received(buf) finally: self._join_vrrp_group(False) self._join_multicast_membership(False) @handler.set_ev_handler(vrrp_event.EventVRRPTransmitRequest) def vrrp_transmit_request_handler(self, ev): self.logger.debug('send') try: self.packet_socket.sendto(ev.data, (self.interface.device_name, 0)) except: self.logger.error('send failed') def _initialize(self): # nothing pass def _shutdown(self): self.__is_active = False ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/vrrp/monitor_openflow.py0000664000175000017500000001254500000000000025110 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013 Isaku Yamahata # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. from os_ken.controller import handler from os_ken.controller import ofp_event from os_ken.lib import dpid as dpid_lib from os_ken.lib.packet import vrrp from os_ken.ofproto import ether from os_ken.ofproto import inet from os_ken.ofproto import ofproto_v1_2 from os_ken.ofproto import ofproto_v1_3 from os_ken.services.protocols.vrrp import monitor from os_ken.services.protocols.vrrp import event as vrrp_event from os_ken.services.protocols.vrrp import utils @monitor.VRRPInterfaceMonitor.register(vrrp_event.VRRPInterfaceOpenFlow) class VRRPInterfaceMonitorOpenFlow(monitor.VRRPInterfaceMonitor): # OF1.2 OFP_VERSIONS = [ofproto_v1_2.OFP_VERSION, ofproto_v1_3.OFP_VERSION] # probably work with OF1.3 _TABLE = 0 # generate packet-in in this table _PRIORITY = 0x8000 # default priority def __init__(self, *args, **kwargs): super(VRRPInterfaceMonitorOpenFlow, self).__init__(*args, **kwargs) table = kwargs.get('vrrp_imof_table', None) if table is not None: self._TABLE = int(table) priority = kwargs.get('vrrp_imof_priority', None) if priority is not None: self._PRIORITY = int(priority) @handler.set_ev_cls(ofp_event.EventOFPPacketIn, handler.MAIN_DISPATCHER) def packet_in_handler(self, ev): self.logger.debug('packet_in_handler') msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto # TODO: subscribe only the designated datapath dpid = datapath.id if dpid != self.interface.dpid: self.logger.debug('packet_in_handler dpid %s %s', dpid_lib.dpid_to_str(dpid), dpid_lib.dpid_to_str(self.interface.dpid)) return in_port = None for field in msg.match.fields: if field.header == ofproto.OXM_OF_IN_PORT: in_port = field.value break if in_port != self.interface.port_no: self.logger.debug('packet_in_handler in_port %s %s', in_port, self.interface.port_no) return self._send_vrrp_packet_received(msg.data) def _get_dp(self): return utils.get_dp(self, self.interface.dpid) @handler.set_ev_handler(vrrp_event.EventVRRPTransmitRequest) def vrrp_transmit_request_handler(self, ev): dp = self._get_dp() if not dp: return utils.dp_packet_out(dp, self.interface.port_no, ev.data) def _ofp_match(self, ofproto_parser): is_ipv6 = vrrp.is_ipv6(self.config.ip_addresses[0]) kwargs = {} kwargs['in_port'] = self.interface.port_no if is_ipv6: kwargs['eth_dst'] = vrrp.VRRP_IPV6_DST_MAC_ADDRESS kwargs['eth_src'] = \ vrrp.vrrp_ipv6_src_mac_address(self.config.vrid) kwargs['eth_type'] = ether.ETH_TYPE_IPV6 kwargs['ipv6_dst'] = vrrp.VRRP_IPV6_DST_ADDRESS else: kwargs['eth_dst'] = vrrp.VRRP_IPV4_DST_MAC_ADDRESS kwargs['eth_src'] = \ vrrp.vrrp_ipv4_src_mac_address(self.config.vrid) kwargs['eth_type'] = ether.ETH_TYPE_IP kwargs['ipv4_dst'] = vrrp.VRRP_IPV4_DST_ADDRESS if self.interface.vlan_id is not None: kwargs['vlan_vid'] = self.interface.vlan_id kwargs['ip_proto'] = inet.IPPROTO_VRRP # OF1.2 doesn't support TTL match. # It needs to be checked by packet in handler return ofproto_parser.OFPMatch(**kwargs) def _initialize(self): dp = self._get_dp() if not dp: return ofproto = dp.ofproto ofproto_parser = dp.ofproto_parser match = self._ofp_match(ofproto_parser) utils.dp_flow_mod(dp, self._TABLE, ofproto.OFPFC_DELETE_STRICT, self._PRIORITY, match, [], out_port=ofproto.OFPP_CONTROLLER) match = self._ofp_match(ofproto_parser) actions = [ofproto_parser.OFPActionOutput(ofproto.OFPP_CONTROLLER, ofproto.OFPCML_NO_BUFFER)] instructions = [ofproto_parser.OFPInstructionActions( ofproto.OFPIT_APPLY_ACTIONS, actions)] utils.dp_flow_mod(dp, self._TABLE, ofproto.OFPFC_ADD, self._PRIORITY, match, instructions) def _shutdown(self): dp = self._get_dp() if not dp: return ofproto = dp.ofproto match = self._ofp_match(dp.ofproto_parser) utils.dp_flow_mod(dp, self._TABLE, ofproto.OFPFC_DELETE_STRICT, self._PRIORITY, match, [], out_port=ofproto.OFPP_CONTROLLER) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/vrrp/router.py0000664000175000017500000006566100000000000023037 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013 Isaku Yamahata # # 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. """ VRRP state machine implementation VRRPManager creates/deletes VRRPRounter instances dynamically. """ import abc from os_ken.base import app_manager from os_ken.controller import event from os_ken.controller import handler from os_ken.lib import hub from os_ken.lib.packet import vrrp from os_ken.services.protocols.vrrp import event as vrrp_event from os_ken.services.protocols.vrrp import api as vrrp_api # TODO: improve Timer service and move it into framework class Timer(object): def __init__(self, handler_): assert callable(handler_) super(Timer, self).__init__() self._handler = handler_ self._event = hub.Event() self._thread = None def start(self, interval): """interval is in seconds""" if self._thread: self.cancel() self._event.clear() self._thread = hub.spawn(self._timer, interval) def cancel(self): if self._thread is None: return self._event.set() hub.joinall([self._thread]) self._thread = None def is_running(self): return self._thread is not None def _timer(self, interval): # Avoid cancellation during execution of self._callable() cancel = self._event.wait(interval) if cancel: return self._handler() class TimerEventSender(Timer): # timeout handler is called by timer thread context. # So in order to actual execution context to application's event thread, # post the event to the application def __init__(self, app, ev_cls): super(TimerEventSender, self).__init__(self._timeout) self._app = app self._ev_cls = ev_cls def _timeout(self): self._app.send_event(self._app.name, self._ev_cls()) class VRRPParams(object): def __init__(self, config): self.config = config self.master_adver_interval = None # In seconds @property def skew_time(self): # In seconds config = self.config version = config.version priority = config.priority if config.version == vrrp.VRRP_VERSION_V2: return (256.0 - priority) / 256.0 if config.version == vrrp.VRRP_VERSION_V3: return (((256.0 - priority) * self.master_adver_interval) / 256.0) raise ValueError('unknown vrrp version %d' % version) @property def master_down_interval(self): # In seconds return (3.0 * self.master_adver_interval) + self.skew_time class VRRPState(object, metaclass=abc.ABCMeta): def __init__(self, vrrp_router): super(VRRPState, self).__init__() self.vrrp_router = vrrp_router @abc.abstractmethod def master_down(self, ev): pass @abc.abstractmethod def adver(self, ev): pass @abc.abstractmethod def preempt_delay(self, ev): pass @abc.abstractmethod def vrrp_received(self, ev): pass @abc.abstractmethod def vrrp_shutdown_request(self, ev): pass @abc.abstractmethod def vrrp_config_change_request(self, ev): pass class VRRPRouter(app_manager.OSKenApp): _EVENTS = [vrrp_event.EventVRRPStateChanged] _CONSTRUCTORS = {} _STATE_MAP = {} # should be overrided by concrete class @staticmethod def register(version): def _register(cls): VRRPRouter._CONSTRUCTORS[version] = cls return cls return _register @staticmethod def factory(name, monitor_name, interface, config, statistics, *args, **kwargs): cls = VRRPRouter._CONSTRUCTORS[config.version] app_mgr = app_manager.AppManager.get_instance() kwargs = kwargs.copy() kwargs['name'] = name kwargs['monitor_name'] = monitor_name kwargs['vrrp_interface'] = interface kwargs['vrrp_config'] = config kwargs['vrrp_statistics'] = statistics return app_mgr.instantiate(cls, *args, **kwargs) class _EventMasterDown(event.EventBase): pass class _EventAdver(event.EventBase): pass class _EventPreemptDelay(event.EventBase): pass class _EventStatisticsOut(event.EventBase): pass def __init__(self, *args, **kwargs): super(VRRPRouter, self).__init__(*args, **kwargs) self.name = kwargs['name'] self.monitor_name = kwargs['monitor_name'] self.interface = kwargs['vrrp_interface'] self.config = kwargs['vrrp_config'] self.statistics = kwargs['vrrp_statistics'] self.params = VRRPParams(self.config) self.state = None self.state_impl = None self.vrrp = None self.master_down_timer = TimerEventSender(self, self._EventMasterDown) self.adver_timer = TimerEventSender(self, self._EventAdver) self.preempt_delay_timer = TimerEventSender(self, self._EventPreemptDelay) self.register_observer(self._EventMasterDown, self.name) self.register_observer(self._EventAdver, self.name) self.stats_out_timer = TimerEventSender(self, self._EventStatisticsOut) self.register_observer(self._EventStatisticsOut, self.name) def send_advertisement(self, release=False): if self.vrrp is None: config = self.config max_adver_int = vrrp.vrrp.sec_to_max_adver_int( config.version, config.advertisement_interval) self.vrrp = vrrp.vrrp.create_version( config.version, vrrp.VRRP_TYPE_ADVERTISEMENT, config.vrid, config.priority, max_adver_int, config.ip_addresses) vrrp_ = self.vrrp if release: vrrp_ = vrrp_.create(vrrp_.type, vrrp_.vrid, vrrp.VRRP_PRIORITY_RELEASE_RESPONSIBILITY, vrrp_.max_adver_int, vrrp_.ip_addresses) if self.vrrp.priority == 0: self.statistics.tx_vrrp_zero_prio_packets += 1 # create packet frame each time to generate new ip identity interface = self.interface packet_ = vrrp_.create_packet(interface.primary_ip_address, interface.vlan_id) packet_.serialize() vrrp_api.vrrp_transmit(self, self.monitor_name, packet_.data) self.statistics.tx_vrrp_packets += 1 def state_change(self, new_state): old_state = self.state self.state = new_state self.state_impl = self._STATE_MAP[new_state](self) state_changed = vrrp_event.EventVRRPStateChanged( self.name, self.monitor_name, self.interface, self.config, old_state, new_state) self.send_event_to_observers(state_changed) @handler.set_ev_handler(_EventMasterDown) def master_down_handler(self, ev): self.state_impl.master_down(ev) @handler.set_ev_handler(_EventAdver) def adver_handler(self, ev): self.state_impl.adver(ev) @handler.set_ev_handler(_EventPreemptDelay) def preempt_delay_handler(self, ev): self.state_impl.preempt_delay(ev) @handler.set_ev_handler(vrrp_event.EventVRRPReceived) def vrrp_received_handler(self, ev): self.state_impl.vrrp_received(ev) @handler.set_ev_handler(vrrp_event.EventVRRPShutdownRequest) def vrrp_shutdown_request_handler(self, ev): assert ev.instance_name == self.name self.state_impl.vrrp_shutdown_request(ev) @handler.set_ev_handler(vrrp_event.EventVRRPConfigChangeRequest) def vrrp_config_change_request_handler(self, ev): config = self.config if ev.priority is not None: config.priority = ev.priority if ev.advertisement_interval is not None: config.advertisement_interval = ev.advertisement_interval if ev.preempt_mode is not None: config.preempt_mode = ev.preempt_mode if ev.preempt_delay is not None: config.preempt_delay = ev.preempt_delay if ev.accept_mode is not None: config.accept_mode = ev.accept_mode # force to recreate cached vrrp packet self.vrrp = None self.state_impl.vrrp_config_change_request(ev) @handler.set_ev_handler(_EventStatisticsOut) def statistics_handler(self, ev): # sends stats to somewhere here # print self.statistics.get_stats() self.stats_out_timer.start(self.statistics.statistics_interval) # RFC defines that start timer, then change the state. # This causes the race between state change and event dispatching. # So our implementation does, state change, then start timer class VRRPV2StateInitialize(VRRPState): # In theory this shouldn't be called. def master_down(self, ev): self.vrrp_router.logger.warning('%s master_down', self.__class__.__name__) def adver(self, ev): self.vrrp_router.logger.warning('%s adver', self.__class__.__name__) def preempt_delay(self, ev): self.vrrp_router.logger.warning('%s preempt_delay', self.__class__.__name__) def vrrp_received(self, ev): self.vrrp_router.logger.warning('%s vrrp_received', self.__class__.__name__) def vrrp_shutdown_request(self, ev): self.vrrp_router.logger.warning('%s vrrp_shutdown_request', self.__class__.__name__) def vrrp_config_change_request(self, ev): self.vrrp_router.logger.warning('%s vrrp_config_change_request', self.__class__.__name__) class VRRPV2StateMaster(VRRPState): def master_down(self, ev): # should not reach here. # In fact this can be happned due to event scheduling vrrp_router = self.vrrp_router vrrp_router.logger.debug('%s master_down %s %s', self.__class__.__name__, ev.__class__.__name__, vrrp_router.state) def _adver(self): vrrp_router = self.vrrp_router vrrp_router.send_advertisement() vrrp_router.adver_timer.start( vrrp_router.config.advertisement_interval) def adver(self, ev): self.vrrp_router.logger.debug('%s adver', self.__class__.__name__) self._adver() def preempt_delay(self, ev): self.vrrp_router.logger.warning('%s preempt_delay', self.__class__.__name__) def vrrp_received(self, ev): vrrp_router = self.vrrp_router vrrp_router.logger.debug('%s vrrp_received', self.__class__.__name__) ip, vrrp_ = vrrp.vrrp.get_payload(ev.packet) config = vrrp_router.config if vrrp_.priority == 0: vrrp_router.send_advertisement() vrrp_router.adver_timer.start(config.advertisement_interval) else: params = vrrp_router.params if (config.priority < vrrp_.priority or (config.priority == vrrp_.priority and vrrp.ip_address_lt(vrrp_router.interface.primary_ip_address, ip.src))): vrrp_router.adver_timer.cancel() vrrp_router.state_change(vrrp_event.VRRP_STATE_BACKUP) vrrp_router.master_down_timer.start( params.master_down_interval) def vrrp_shutdown_request(self, ev): vrrp_router = self.vrrp_router vrrp_router.logger.debug('%s vrrp_shutdown_request', self.__class__.__name__) vrrp_router.adver_timer.cancel() vrrp_router.send_advertisement(True) vrrp_router.state_change(vrrp_event.VRRP_STATE_INITIALIZE) def vrrp_config_change_request(self, ev): vrrp_router = self.vrrp_router vrrp_router.logger.warning('%s vrrp_config_change_request', self.__class__.__name__) if ev.priority is not None or ev.advertisement_interval is not None: vrrp_router.adver_timer.cancel() self._adver() class VRRPV2StateBackup(VRRPState): def _master_down(self): vrrp_router = self.vrrp_router vrrp_router.send_advertisement() # This action should be done router on # EventVRRPStateChanged(VRRP_STATE_BACKUP->VRRP_STATE_MASTER) # # RFC3768 6.4.2 Backup # o Broadcast a gratuitous ARP request containing the virtual # router MAC address for each IP address associated with the # virtual router # RACE: actual router has the responsiblity to send garp. # so due to thread scheduling there is a race between # actual router sending GARP and VRRPRouter becoming # master/backup vrrp_router.preempt_delay_timer.cancel() vrrp_router.state_change(vrrp_event.VRRP_STATE_MASTER) vrrp_router.adver_timer.start( vrrp_router.config.advertisement_interval) def master_down(self, ev): self.vrrp_router.logger.debug('%s master_down', self.__class__.__name__) self._master_down() def adver(self, ev): # should not reach here # In fact this can be happned due to event scheduling vrrp_router = self.vrrp_router vrrp_router.logger.debug('%s adver %s %s', self.__class__.__name__, ev.__class__.__name__, vrrp_router.state) def preempt_delay(self, ev): self.vrrp_router.logger.warning('%s preempt_delay', self.__class__.__name__) self._master_down() def vrrp_received(self, ev): vrrp_router = self.vrrp_router vrrp_router.logger.debug('%s vrrp_received', self.__class__.__name__) _ip, vrrp_ = vrrp.vrrp.get_payload(ev.packet) if vrrp_.priority == 0: vrrp_router.master_down_timer.start(vrrp_router.params.skew_time) else: config = vrrp_router.config params = vrrp_router.params if (not config.preempt_mode or config.priority <= vrrp_.priority): vrrp_router.preempt_delay_timer.cancel() vrrp_router.master_down_timer.start( params.master_down_interval) elif (config.preempt_mode and config.preempt_delay > 0 and config.priority > vrrp_.priority): if not vrrp_router.preempt_delay_timer.is_running(): vrrp_router.preempt_delay_timer.start(config.preempt_delay) vrrp_router.master_down_timer.start( params.master_down_interval) def vrrp_shutdown_request(self, ev): vrrp_router = self.vrrp_router vrrp_router.logger.debug('%s vrrp_shutdown_request', self.__class__.__name__) vrrp_router.master_down_timer.cancel() vrrp_router.preempt_delay_timer.cancel() vrrp_router.state_change(vrrp_event.VRRP_STATE_INITIALIZE) def vrrp_config_change_request(self, ev): vrrp_router = self.vrrp_router vrrp_router.logger.warning('%s vrrp_config_change_request', self.__class__.__name__) if ev.priority is not None and vrrp_router.config.address_owner: vrrp_router.master_down_timer.cancel() self._master_down() if ev.preempt_mode is not None or ev.preempt_delay is not None: vrrp_router.preempt_delay_timer.cancel() @VRRPRouter.register(vrrp.VRRP_VERSION_V2) class VRRPRouterV2(VRRPRouter): _STATE_MAP = { vrrp_event.VRRP_STATE_INITIALIZE: VRRPV2StateInitialize, vrrp_event.VRRP_STATE_MASTER: VRRPV2StateMaster, vrrp_event.VRRP_STATE_BACKUP: VRRPV2StateBackup, } def __init__(self, *args, **kwargs): super(VRRPRouterV2, self).__init__(*args, **kwargs) def start(self): params = self.params params.master_adver_interval = self.config.advertisement_interval self.state_change(vrrp_event.VRRP_STATE_INITIALIZE) if self.config.address_owner: self.send_advertisement() # This action should be done router on # EventVRRPStateChanged(None->VRRP_STATE_MASTER) # # RFC3768 6.4.1 # o Broadcast a gratuitous ARP request containing the virtual # router MAC address for each IP address associated with the # virtual router. self.state_change(vrrp_event.VRRP_STATE_MASTER) self.adver_timer.start(self.config.advertisement_interval) else: self.state_change(vrrp_event.VRRP_STATE_BACKUP) self.master_down_timer.start(params.master_down_interval) super(VRRPRouterV2, self).start() class VRRPV3StateInitialize(VRRPState): # In theory this shouldn't be called. def master_down(self, ev): self.vrrp_router.logger.debug('%s master_down', self.__class__.__name__) def adver(self, ev): self.vrrp_router.logger.debug('%s adver', self.__class__.__name__) def preempt_delay(self, ev): self.vrrp_router.logger.warning('%s preempt_delay', self.__class__.__name__) def vrrp_received(self, ev): self.vrrp_router.logger.debug('%s vrrp_received', self.__class__.__name__) def vrrp_shutdown_request(self, ev): self.vrrp_router.logger.debug('%s vrrp_shutdown_request', self.__class__.__name__) def vrrp_config_change_request(self, ev): self.vrrp_router.logger.warning('%s vrrp_config_change_request', self.__class__.__name__) class VRRPV3StateMaster(VRRPState): def master_down(self, ev): # should not reach here # In fact this can be happned due to event scheduling vrrp_router = self.vrrp_router vrrp_router.logger.debug('%s master_down %s %s', self.__class__.__name__, ev.__class__.__name__, vrrp_router.state) def _adver(self): vrrp_router = self.vrrp_router vrrp_router.send_advertisement() vrrp_router.adver_timer.start( vrrp_router.config.advertisement_interval) def adver(self, ev): self.vrrp_router.logger.debug('%s adver', self.__class__.__name__) self._adver() def preempt_delay(self, ev): self.vrrp_router.logger.warning('%s preempt_delay', self.__class__.__name__) def vrrp_received(self, ev): vrrp_router = self.vrrp_router vrrp_router.logger.debug('%s vrrp_received', self.__class__.__name__) ip, vrrp_ = vrrp.vrrp.get_payload(ev.packet) config = vrrp_router.config if vrrp_.priority == 0: vrrp_router.send_advertisement() vrrp_router.adver_timer.start(config.advertisement_interval) else: params = vrrp_router.params if (config.priority < vrrp_.priority or (config.priority == vrrp_.priority and vrrp.ip_address_lt(vrrp_router.interface.primary_ip_address, ip.src))): vrrp_router.adver_timer.cancel() params.master_adver_interval = vrrp_.max_adver_int_in_sec vrrp_router.state_change(vrrp_event.VRRP_STATE_BACKUP) vrrp_router.master_down_timer.start( params.master_down_interval) def vrrp_shutdown_request(self, ev): vrrp_router = self.vrrp_router vrrp_router.logger.debug('%s vrrp_shutdown_request', self.__class__.__name__) vrrp_router.adver_timer.cancel() vrrp_router.send_advertisement(True) vrrp_router.state_change(vrrp_event.VRRP_STATE_INITIALIZE) def vrrp_config_change_request(self, ev): vrrp_router = self.vrrp_router vrrp_router.logger.warning('%s vrrp_config_change_request', self.__class__.__name__) if ev.priority is not None or ev.advertisement_interval is not None: vrrp_router.adver_timer.cancel() self._adver() class VRRPV3StateBackup(VRRPState): def _master_down(self): vrrp_router = self.vrrp_router vrrp_router.send_advertisement() # This action should be done by router on # EventStateChange(VRRP_SATE_BACKUP -> VRRP_STATE_MASTER) # # RFC 5795 6.4.2 # (375) + If the protected IPvX address is an IPv4 address, then: # (380) * Broadcast a gratuitous ARP request on that interface # containing the virtual router MAC address for each IPv4 # address associated with the virtual router. # (385) + else // ipv6 # (390) * Compute and join the Solicited-Node multicast # address [RFC4291] for the IPv6 address(es) associated with # the virtual router. # (395) * For each IPv6 address associated with the virtual # router, send an unsolicited ND Neighbor Advertisement with # the Router Flag (R) set, the Solicited Flag (S) unset, the # Override flag (O) set, the target address set to the IPv6 # address of the virtual router, and the target link-layer # address set to the virtual router MAC address. # RACE: actual router has the responsiblity to send garp. # so due to thread scheduling there is a race between # actual router sending GARP and VRRPRouter becoming # master/backup vrrp_router.preempt_delay_timer.cancel() vrrp_router.state_change(vrrp_event.VRRP_STATE_MASTER) vrrp_router.adver_timer.start( vrrp_router.config.advertisement_interval) def master_down(self, ev): self.vrrp_router.logger.debug('%s master_down', self.__class__.__name__) self._master_down() def adver(self, ev): # should not reach here # In fact this can be happned due to event scheduling vrrp_router = self.vrrp_router vrrp_router.logger.debug('adver %s %s %s', self.__class__.__name__, ev.__class__.__name__, vrrp_router.state) def preempt_delay(self, ev): self.vrrp_router.logger.warning('%s preempt_delay', self.__class__.__name__) self._master_down() def vrrp_received(self, ev): vrrp_router = self.vrrp_router vrrp_router.logger.debug('%s vrrp_received', self.__class__.__name__) _ip, vrrp_ = vrrp.vrrp.get_payload(ev.packet) if vrrp_.priority == 0: vrrp_router.master_down_timer.start(vrrp_router.params.skew_time) else: params = vrrp_router.params config = vrrp_router.config if (not config.preempt_mode or config.priority <= vrrp_.priority): params.master_adver_interval = vrrp_.max_adver_int_in_sec vrrp_router.master_down_timer.start( params.master_down_interval) elif (config.preempt_mode and config.preempt_delay > 0 and config.priority > vrrp_.priority): if not vrrp_router.preempt_delay_timer.is_running(): vrrp_router.preempt_delay_timer.start(config.preempt_delay) vrrp_router.master_down_timer.start( params.master_down_interval) def vrrp_shutdown_request(self, ev): vrrp_router = self.vrrp_router vrrp_router.logger.debug('%s vrrp_shutdown_request', self.__class__.__name__) vrrp_router.preempt_delay_timer.cancel() vrrp_router.master_down_timer.cancel() vrrp_router.state_change(vrrp_event.VRRP_STATE_INITIALIZE) def vrrp_config_change_request(self, ev): vrrp_router = self.vrrp_router vrrp_router.logger.warning('%s vrrp_config_change_request', self.__class__.__name__) if ev.priority is not None and vrrp_router.config.address_owner: vrrp_router.master_down_timer.cancel() self._master_down() if ev.preempt_mode is not None or ev.preempt_delay is not None: vrrp_router.preempt_delay_timer.cancel() @VRRPRouter.register(vrrp.VRRP_VERSION_V3) class VRRPRouterV3(VRRPRouter): _STATE_MAP = { vrrp_event.VRRP_STATE_INITIALIZE: VRRPV3StateInitialize, vrrp_event.VRRP_STATE_MASTER: VRRPV3StateMaster, vrrp_event.VRRP_STATE_BACKUP: VRRPV3StateBackup, } def __init__(self, *args, **kwargs): super(VRRPRouterV3, self).__init__(*args, **kwargs) def start(self): self.state_change(vrrp_event.VRRP_STATE_INITIALIZE) # Check role here and change accordingly # Check config.admin_state if self.config.address_owner or self.config.admin_state == 'master': self.send_advertisement() # This action should be done router on # EventVRRPStateChanged(None->VRRP_STATE_MASTER) # # RFC 5795 6.4.1 # (115) + If the protected IPvX address is an IPv4 address, then: # (120) * Broadcast a gratuitous ARP request containing the # virtual router MAC address for each IP address associated # with the virtual router. # (125) + else // IPv6 # (130) * For each IPv6 address associated with the virtual # router, send an unsolicited ND Neighbor Advertisement with # the Router Flag (R) set, the Solicited Flag (S) unset, the # Override flag (O) set, the target address set to the IPv6 # address of the virtual router, and the target link-layer # address set to the virtual router MAC address. self.state_change(vrrp_event.VRRP_STATE_MASTER) self.adver_timer.start(self.config.advertisement_interval) else: params = self.params params.master_adver_interval = self.config.advertisement_interval self.state_change(vrrp_event.VRRP_STATE_BACKUP) self.master_down_timer.start(params.master_down_interval) self.stats_out_timer.start(self.statistics.statistics_interval) super(VRRPRouterV3, self).start() ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/vrrp/rpc_manager.py0000664000175000017500000001645100000000000023766 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone 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. from os_ken import cfg import socket import netaddr from os_ken.base import app_manager from os_ken.controller import handler from os_ken.services.protocols.vrrp import event as vrrp_event from os_ken.services.protocols.vrrp import api as vrrp_api from os_ken.lib import rpc from os_ken.lib import hub from os_ken.lib import mac VRRP_RPC_PORT = 50004 # random class RPCError(Exception): pass class Peer(object): def __init__(self, queue): super(Peer, self).__init__() self.queue = queue def _handle_vrrp_request(self, data): self.queue.put((self, data)) class RpcVRRPManager(app_manager.OSKenApp): def __init__(self, *args, **kwargs): super(RpcVRRPManager, self).__init__(*args, **kwargs) self.CONF.register_opts([ cfg.IntOpt('vrrp-rpc-port', default=VRRP_RPC_PORT, help='port for vrrp rpc interface')]) self._args = args self._kwargs = kwargs self._peers = [] self._rpc_events = hub.Queue(128) self.server_thread = hub.spawn(self._peer_accept_thread) self.event_thread = hub.spawn(self._rpc_request_loop_thread) def _rpc_request_loop_thread(self): while True: (peer, data) = self._rpc_events.get() msgid, target_method, params = data error = None result = None try: if target_method == b'vrrp_config': result = self._config(msgid, params) elif target_method == b'vrrp_list': result = self._list(msgid, params) elif target_method == b'vrrp_config_change': result = self._config_change(msgid, params) else: error = 'Unknown method %s' % (target_method) except RPCError as e: error = str(e) peer._endpoint.send_response(msgid, error=error, result=result) def _peer_loop_thread(self, peer): peer._endpoint.serve() # the peer connection is closed self._peers.remove(peer) def peer_accept_handler(self, new_sock, addr): peer = Peer(self._rpc_events) table = { rpc.MessageType.REQUEST: peer._handle_vrrp_request, } peer._endpoint = rpc.EndPoint(new_sock, disp_table=table) self._peers.append(peer) hub.spawn(self._peer_loop_thread, peer) def _peer_accept_thread(self): server = hub.StreamServer(('', self.CONF.vrrp_rpc_port), self.peer_accept_handler) server.serve_forever() def _params_to_dict(self, params, keys): d = {} for k, v in params.items(): if k in keys: d[k] = v return d def _config(self, msgid, params): self.logger.debug('handle vrrp_config request') try: param_dict = params[0] except: raise RPCError('parameters are missing') if_params = self._params_to_dict(param_dict, ('primary_ip_address', 'device_name')) # drop vlan support later if_params['vlan_id'] = None if_params['mac_address'] = mac.DONTCARE_STR try: interface = vrrp_event.VRRPInterfaceNetworkDevice(**if_params) except: raise RPCError('parameters are invalid, %s' % (str(param_dict))) config_params = self._params_to_dict(param_dict, ('vrid', # mandatory 'ip_addresses', # mandatory 'version', 'admin_state', 'priority', 'advertisement_interval', 'preempt_mode', 'preempt_delay', 'statistics_interval')) try: ip_addr = config_params.pop('ip_addresses') config_params['ip_addresses'] = [ip_addr] config = vrrp_event.VRRPConfig(**config_params) except: raise RPCError('parameters are invalid, %s' % (str(param_dict))) config_result = vrrp_api.vrrp_config(self, interface, config) api_result = [ config_result.config.vrid, config_result.config.priority, str(netaddr.IPAddress(config_result.config.ip_addresses[0]))] return api_result def _lookup_instance(self, vrid): for instance in vrrp_api.vrrp_list(self).instance_list: if vrid == instance.config.vrid: return instance.instance_name return None def _config_change(self, msgid, params): self.logger.debug('handle vrrp_config_change request') try: config_values = params[0] except: raise RPCError('parameters are missing') vrid = config_values.get('vrid') instance_name = self._lookup_instance(vrid) if not instance_name: raise RPCError('vrid %d is not found' % (vrid)) priority = config_values.get('priority') interval = config_values.get('advertisement_interval') vrrp_api.vrrp_config_change(self, instance_name, priority=priority, advertisement_interval=interval) return {} def _list(self, msgid, params): self.logger.debug('handle vrrp_list request') result = vrrp_api.vrrp_list(self) instance_list = result.instance_list ret_list = [] for instance in instance_list: c = instance.config info_dict = { "instance_name": instance.instance_name, "vrid": c.vrid, "version": c.version, "advertisement_interval": c.advertisement_interval, "priority": c.priority, "virtual_ip_address": str(netaddr.IPAddress(c.ip_addresses[0])) } ret_list.append(info_dict) return ret_list @handler.set_ev_cls(vrrp_event.EventVRRPStateChanged) def vrrp_state_changed_handler(self, ev): self.logger.info('handle EventVRRPStateChanged') name = ev.instance_name old_state = ev.old_state new_state = ev.new_state vrid = ev.config.vrid self.logger.info('VRID:%s %s: %s -> %s', vrid, name, old_state, new_state) params = {'vrid': vrid, 'old_state': old_state, 'new_state': new_state} for peer in self._peers: peer._endpoint.send_notification("notify_status", [params]) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/vrrp/sample_manager.py0000664000175000017500000000707200000000000024462 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013 Isaku Yamahata # # 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. """ sample router manager. (un-)instantiate routers Usage example: osken-manager --verbose \ os_ken.services.protocols.vrrp.manager \ os_ken.services.protocols.vrrp.dumper \ os_ken.services.protocols.vrrp.sample_manager """ from os_ken.base import app_manager from os_ken.controller import handler from os_ken.services.protocols.vrrp import event as vrrp_event from os_ken.services.protocols.vrrp import sample_router class RouterManager(app_manager.OSKenApp): _ROUTER_CLASSES = { vrrp_event.VRRPInterfaceNetworkDevice: { 4: sample_router.RouterIPV4Linux, 6: sample_router.RouterIPV6Linux, }, vrrp_event.VRRPInterfaceOpenFlow: { 4: sample_router.RouterIPV4OpenFlow, 6: sample_router.RouterIPV6OpenFlow, }, } def __init__(self, *args, **kwargs): super(RouterManager, self).__init__(*args, **kwargs) self._args = args self._kwargs = kwargs self.routers = {} # instance name -> router name def _router_factory(self, instance_name, monitor_name, interface, config): cls = None for interface_cls, router_clses in self._ROUTER_CLASSES.items(): if isinstance(interface, interface_cls): if config.is_ipv6: cls = router_clses[6] else: cls = router_clses[4] break self.logger.debug('interface %s %s', type(interface), interface) self.logger.debug('cls %s', cls) if cls is None: raise ValueError('Unknown interface type %s %s' % (type(interface), interface)) kwargs = self._kwargs.copy() kwargs.update({ 'name': instance_name, 'monitor_name': monitor_name, 'config': config, 'interface': interface, }) app_mgr = app_manager.AppManager.get_instance() return app_mgr.instantiate(cls, *self._args, **kwargs) @handler.set_ev_cls(vrrp_event.EventVRRPStateChanged) def vrrp_state_changed_handler(self, ev): if ev.new_state == vrrp_event.VRRP_STATE_INITIALIZE: if ev.old_state: self._shutdown(ev) else: self._initialize(ev) return router_name = self.routers.get(ev.instance_name) self.send_event(router_name, ev) def _initialize(self, ev): router = self._router_factory(ev.instance_name, ev.monitor_name, ev.interface, ev.config) self.routers[ev.instance_name] = router.name self.send_event(router.name, ev) router.start() def _shutdown(self, ev): router_name = self.routers.pop(ev.instance_name) self.send_event(router_name, ev) app_mgr = app_manager.AppManager.get_instance() app_mgr.uninstantiate(router_name) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/vrrp/sample_router.py0000664000175000017500000005023200000000000024364 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013 Isaku Yamahata # # 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. """ router implementation base class a template for router implementation that support VRRP Those routers needs to be created by someone else. sample_manager.routerManager is an example. Usage example: osken-manager --verbose \ os_ken.services.protocols.vrrp.manager \ os_ken.services.protocols.vrrp.dumper \ os_ken.services.protocols.vrrp.sample_manager """ import contextlib import greenlet import socket from os_ken.base import app_manager from os_ken.controller import handler from os_ken.controller import ofp_event from os_ken.lib import hub from os_ken.lib import mac as mac_lib from os_ken.lib.packet import arp from os_ken.lib.packet import ethernet from os_ken.lib.packet import packet from os_ken.lib.packet import vlan from os_ken.lib.packet import vrrp from os_ken.ofproto import ether from os_ken.ofproto import ofproto_v1_2 from os_ken.services.protocols.vrrp import api as vrrp_api from os_ken.services.protocols.vrrp import event as vrrp_event from os_ken.services.protocols.vrrp import utils class RouterBase(app_manager.OSKenApp): def _router_name(self, config, interface): ip_version = 'ipv6' if config.is_ipv6 else 'ipv4' return '%s-%s-%d-%s' % (self.__class__.__name__, str(interface), config.vrid, ip_version) def __init__(self, *args, **kwargs): super(RouterBase, self).__init__(*args, **kwargs) self.instance_name = kwargs['name'] self.monitor_name = kwargs['monitor_name'] self.config = kwargs['config'] self.interface = kwargs['interface'] self.name = self._router_name(self.config, self.interface) def _transmit(self, data): vrrp_api.vrrp_transmit(self, self.monitor_name, data) def _initialized(self): self.logger.debug('initialized') def _initialized_to_master(self): self.logger.debug('initialized to master') # RFC3768 6.4.1 # o Broadcast a gratuitous ARP request containing the virtual # router MAC address for each IP address associated with the # virtual router. # # or # # RFC 5795 6.4.1 # (115)+ If the protected IPvX address is an IPv4 address, then: # (120) * Broadcast a gratuitous ARP request containing the # virtual router MAC address for each IP address associated # with the virtual router. # (125) + else // IPv6 # (130) * For each IPv6 address associated with the virtual # router, send an unsolicited ND Neighbor Advertisement with # the Router Flag (R) set, the Solicited Flag (S) unset, the # Override flag (O) set, the target address set to the IPv6 # address of the virtual router, and the target link-layer # address set to the virtual router MAC address. def _become_master(self): self.logger.debug('become master') # RFC3768 6.4.2 # o Broadcast a gratuitous ARP request containing the virtual # router MAC address for each IP address associated with the # virtual router # # or # # RFC 5795 6.4.2 # (375)+ If the protected IPvX address is an IPv4 address, then: # (380)* Broadcast a gratuitous ARP request on that interface # containing the virtual router MAC address for each IPv4 # address associated with the virtual router. # (385) + else // ipv6 # (390) * Compute and join the Solicited-Node multicast # address [RFC4291] for the IPv6 address(es) associated with # the virtual router. # (395) * For each IPv6 address associated with the virtual # router, send an unsolicited ND Neighbor Advertisement with # the Router Flag (R) set, the Solicited Flag (S) unset, the # Override flag (O) set, the target address set to the IPv6 # address of the virtual router, and the target link-layer # address set to the virtual router MAC address. def _become_backup(self): self.logger.debug('become backup') # RFC 3768 6.4.2 Backup # - MUST NOT respond to ARP requests for the IP address(s) # associated with the virtual router. # - MUST discard packets with a destination link layer MAC address # equal to the virtual router MAC address. # - MUST NOT accept packets addressed to the IP address(es) # associated with the virtual router. # # or # # RFC 5798 6.4.2 Backup # (305) - If the protected IPvX address is an IPv4 address, then: # (310) + MUST NOT respond to ARP requests for the IPv4 # address(es) associated with the virtual router. # (315) - else // protected addr is IPv6 # (320) + MUST NOT respond to ND Neighbor Solicitation messages # for the IPv6 address(es) associated with the virtual router. # (325) + MUST NOT send ND Router Advertisement messages for the # virtual router. # (330) -endif // was protected addr IPv4? # (335) - MUST discard packets with a destination link-layer MAC # address equal to the virtual router MAC address. # (340) - MUST NOT accept packets addressed to the IPvX address(es) # associated with the virtual router. def _shutdowned(self): self.logger.debug('shutdowned') @handler.set_ev_handler(vrrp_event.EventVRRPStateChanged) def vrrp_state_changed_handler(self, ev): old_state = ev.old_state new_state = ev.new_state self.logger.debug('sample router %s -> %s', old_state, new_state) if new_state == vrrp_event.VRRP_STATE_MASTER: if old_state == vrrp_event.VRRP_STATE_INITIALIZE: self._initialized_to_master() elif old_state == vrrp_event.VRRP_STATE_BACKUP: self._become_master() # RFC 3768 6.4.3 # - MUST respond to ARP requests for the IP address(es) associated # with the virtual router. # - MUST forward packets with a destination link layer MAC address # equal to the virtual router MAC address. # - MUST NOT accept packets addressed to the IP address(es) # associated with the virtual router if it is not the IP address # owner. # - MUST accept packets addressed to the IP address(es) associated # with the virtual router if it is the IP address owner. # # or # # RFC5798 6.4.3 # (605) - If the protected IPvX address is an IPv4 address, then: # (610) + MUST respond to ARP requests for the IPv4 address(es) # associated with the virtual router. # (615) - else // ipv6 # (620) + MUST be a member of the Solicited-Node multicast # address for the IPv6 address(es) associated with the virtual # router. # (625) + MUST respond to ND Neighbor Solicitation message for # the IPv6 address(es) associated with the virtual router. # (630) ++ MUST send ND Router Advertisements for the virtual # router. # (635) ++ If Accept_Mode is False: MUST NOT drop IPv6 Neighbor # Solicitations and Neighbor Advertisements. # (640) +-endif // ipv4? # (645) - MUST forward packets with a destination link-layer MAC # address equal to the virtual router MAC address. # (650) - MUST accept packets addressed to the IPvX address(es) # associated with the virtual router if it is the IPvX address # owner or if Accept_Mode is True. Otherwise, MUST NOT accept # these packets. elif new_state == vrrp_event.VRRP_STATE_BACKUP: self._become_backup() elif new_state == vrrp_event.VRRP_STATE_INITIALIZE: if old_state is None: self._initialized() else: self._shutdowned() else: raise ValueError('invalid vrrp state %s' % new_state) class RouterIPV4(RouterBase): def _garp_packet(self, ip_address): # prepare garp packet src_mac = vrrp.vrrp_ipv4_src_mac_address(self.config.vrid) e = ethernet.ethernet(mac_lib.BROADCAST_STR, src_mac, ether.ETH_TYPE_ARP) a = arp.arp_ip(arp.ARP_REQUEST, src_mac, ip_address, mac_lib.DONTCARE_STR, ip_address) p = packet.Packet() p.add_protocol(e) utils.may_add_vlan(p, self.interface.vlan_id) p.add_protocol(a) p.serialize() return p def __init__(self, *args, **kwargs): super(RouterIPV4, self).__init__(*args, **kwargs) assert not self.config.is_ipv6 self.garp_packets = [self._garp_packet(ip_address) for ip_address in self.config.ip_addresses] def _send_garp(self): self.logger.debug('_send_garp') for garp_packet in self.garp_packets: self._transmit(garp_packet.data) def _arp_reply_packet(self, arp_req_sha, arp_req_spa, arp_req_tpa): if not (arp_req_tpa in self.config.ip_addresses or arp_req_tpa == self.config.primary_ip_address): return None src_mac = vrrp.vrrp_ipv4_src_mac_address(self.config.vrid) e = ethernet.ethernet(arp_req_sha, src_mac, ether.ETH_TYPE_ARP) a = arp.arp_ip(arp.ARP_REPLY, src_mac, arp_req_tpa, arp_req_sha, arp_req_spa) p = packet.Packet() p.add_protocol(e) utils.may_add_vlan(p, self.interface.vlan_id) p.add_protocol(a) p.serialize() self._transmit(p.data) def _arp_process(self, data): dst_mac = vrrp.vrrp_ipv4_src_mac_address(self.config.vrid) arp_sha = None arp_spa = None arp_tpa = None p = packet.Packet(data) for proto in p.protocols: if isinstance(proto, ethernet.ethernet): if proto.dst not in (mac_lib.BROADCAST_STR, dst_mac): return None ethertype = proto.ethertype if not ((self.interface.vlan_id is None and ethertype == ether.ETH_TYPE_ARP) or (self.interface.vlan_id is not None and ethertype == ether.ETH_TYPE_8021Q)): return None elif isinstance(proto, vlan.vlan): if (proto.vid != self.interface.vlan_id or proto.ethertype != ether.ETH_TYPE_ARP): return None elif isinstance(proto, arp.arp): if (proto.hwtype != arp.ARP_HW_TYPE_ETHERNET or proto.proto != ether.ETH_TYPE_IP or proto.hlen != 6 or proto.plen != 4 or proto.opcode != arp.ARP_REQUEST or proto.dst_mac != dst_mac): return None arp_sha = proto.src_mac arp_spa = proto.src_ip arp_tpa = proto.dst_ip break if arp_sha is None or arp_spa is None or arp_tpa is None: self.logger.debug('malformed arp request? arp_sha %s arp_spa %s', arp_sha, arp_spa) return None self._arp_reply_packet(arp_sha, arp_spa, arp_tpa) class RouterIPV4Linux(RouterIPV4): def __init__(self, *args, **kwargs): super(RouterIPV4Linux, self).__init__(*args, **kwargs) assert isinstance(self.interface, vrrp_event.VRRPInterfaceNetworkDevice) self.__is_master = False self._arp_thread = None def start(self): self._disable_router() super(RouterIPV4Linux, self).start() def _initialized_to_master(self): self.logger.debug('initialized to master') self._master() def _become_master(self): self.logger.debug('become master') self._master() def _master(self): self.__is_master = True self._enable_router() self._send_garp() def _become_backup(self): self.logger.debug('become backup') self.__is_master = False self._disable_router() def _shutdowned(self): # When VRRP functionality is disabled, what to do? # should we also exit? or continue to route packets? self._disable_router() def _arp_loop_socket(self, packet_socket): while True: try: buf = packet_socket.recv(1500) except socket.timeout: continue self._arp_process(buf) def _arp_loop(self): try: with contextlib.closing( socket.socket( socket.AF_PACKET, socket.SOCK_RAW, socket.htons(ether.ETH_TYPE_ARP))) as packet_socket: packet_socket.bind((self.interface.device_name, socket.htons(ether.ETH_TYPE_ARP), socket.PACKET_BROADCAST, arp.ARP_HW_TYPE_ETHERNET, mac_lib.BROADCAST)) self._arp_loop_socket(packet_socket) except greenlet.GreenletExit: # suppress thread.kill exception pass def _enable_router(self): if self._arp_thread is None: self._arp_thread = hub.spawn(self._arp_loop) # TODO: implement real routing logic self.logger.debug('TODO:_enable_router') def _disable_router(self): if self._arp_thread is not None: self._arp_thread.kill() hub.joinall([self._arp_thread]) self._arp_thread = None # TODO: implement real routing logic self.logger.debug('TODO:_disable_router') class RouterIPV4OpenFlow(RouterIPV4): OFP_VERSIONS = [ofproto_v1_2.OFP_VERSION] # it must be that # _DROP_PRIORITY < monitor.VRRPInterfaceMonitorOpenFlow._PRIORITY or # _DROP_TABLE > monitor.VRRPInterfaceMonitorOpenFlow._TABLE # to gurantee that VRRP packets are send to controller _DROP_TABLE = 0 _DROP_PRIORITY = 0x8000 / 2 # it must be that # _ARP_PRIORITY < _DROP_PRIORITY or # _ARP_TABLE > _DROP_TABLE # to gurantee that responding arp can be disabled _ARP_TABLE = 0 _ARP_PRIORITY = _DROP_PRIORITY // 2 # it must be that # _ROUTEING_TABLE < _ARP_TABLE or # _ROUTING_TABLE > _ARP_TABLE # to gurantee that routing can be disabled _ROUTING_TABLE = 0 _ROUTING_PRIORITY = _ARP_PRIORITY // 2 def __init__(self, *args, **kwargs): super(RouterIPV4OpenFlow, self).__init__(*args, **kwargs) assert isinstance(self.interface, vrrp_event.VRRPInterfaceOpenFlow) def _get_dp(self): return utils.get_dp(self, self.interface.dpid) def start(self): dp = self._get_dp() assert dp self._uninstall_route_rule(dp) self._uninstall_arp_rule(dp) self._uninstall_drop_rule(dp) self._install_drop_rule(dp) self._install_arp_rule(dp) self._install_route_rule(dp) super(RouterIPV4OpenFlow, self).start() def _initialized_to_master(self): self.logger.debug('initialized to master') self._master() def _become_master(self): self.logger.debug('become master') self._master() def _master(self): dp = self._get_dp() if dp is None: return self._uninstall_drop_rule(dp) self._send_garp(dp) def _become_backup(self): self.logger.debug('become backup') dp = self._get_dp() if dp is None: return self._install_drop_rule(dp) def _shutdowned(self): dp = self._get_dp() if dp is None: return # When VRRP functionality is disabled, what to do? # should we also exit? or continue to route packets? self._uninstall_route_rule(dp) self._uninstall_arp_rule(dp) self._uninstall_drop_rule(dp) @handler.set_ev_cls(ofp_event.EventOFPPacketIn, handler.MAIN_DISPATCHER) def packet_in_handler(self, ev): msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto # TODO: subscribe only the datapath that we route dpid = datapath.dpid if dpid != self.interface.dpid: return for field in msg.match.fields: header = field.header if header == ofproto.OXM_OF_IN_PORT: if field.value != self.interface.port_no: return break self._arp_process(msg.data) def _drop_match(self, dp): kwargs = {} kwargs['in_port'] = self.interface.port_no kwargs['eth_dst'] = vrrp.vrrp_ipv4_src_mac_address(self.config.vrid) if self.interface.vlan_id is not None: kwargs['vlan_vid'] = self.interface.vlan_id return dp.ofproto_parser.OFPMatch(**kwargs) def _install_drop_rule(self, dp): match = self._drop_match(dp) utils.dp_flow_mod(dp, self._DROP_TABLE, dp.ofproto.OFPFC_ADD, self._DROP_PRIORITY, match, []) def _uninstall_drop_rule(self, dp): match = self._drop_match(dp) utils.dp_flow_mod(dp, self._DROP_TABLE, dp.ofproto.OFPFC_DELETE_STRICT, self._DROP_PRIORITY, match, []) def _arp_match(self, dp): kwargs = {} kwargs['in_port'] = self.interface.port_no kwargs['eth_dst'] = mac_lib.BROADCAST_STR kwargs['eth_type'] = ether.ETH_TYPE_ARP if self.interface.vlan_id is not None: kwargs['vlan_vid'] = self.interface.vlan_id kwargs['arp_op'] = arp.ARP_REQUEST kwargs['arp_tpa'] = vrrp.vrrp_ipv4_src_mac_address(self.config.vrid) return dp.ofproto_parser.OFPMatch(**kwargs) def _install_arp_rule(self, dp): ofproto = dp.ofproto ofproto_parser = dp.ofproto_parser match = self._arp_match(dp) actions = [ofproto_parser.OFPActionOutput(ofproto.OFPP_CONTROLLER, ofproto.OFPCML_NO_BUFFER)] instructions = [ofproto_parser.OFPInstructionActions( ofproto.OFPIT_APPLY_ACTIONS, actions)] utils.dp_flow_mod(dp, self._ARP_TABLE, dp.fproto.OFPFC_ADD, self._ARP_PRIORITY, match, instructions) def _uninstall_arp_rule(self, dp): match = self._arp_match(dp) utils.dp_flow_mod(dp, self._ARP_TABLE, dp.fproto.OFPFC_DELETE_STRICT, self._ARP_PRIORITY, match, []) def _install_route_rule(self, dp): # TODO: implement real routing logic self.logger.debug('TODO:_install_router_rule') def _uninstall_route_rule(self, dp): # TODO: implement real routing logic self.logger.debug('TODO:_uninstall_router_rule') class RouterIPV6(RouterBase): def __init__(self, *args, **kwargs): super(RouterIPV6, self).__init__(*args, **kwargs) assert self.config.is_ipv6 class RouterIPV6Linux(RouterIPV6): def __init__(self, *args, **kwargs): super(RouterIPV6Linux, self).__init__(*args, **kwargs) assert isinstance(self.interface, vrrp_event.VRRPInterfaceNetworkDevice) # TODO: reader's home work pass class RouterIPV6OpenFlow(RouterIPV6): def __init__(self, *args, **kwargs): super(RouterIPV6OpenFlow, self).__init__(*args, **kwargs) assert isinstance(self.interface, vrrp_event.VRRPInterfaceOpenFlow) # TODO: reader's home work pass ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/vrrp/utils.py0000664000175000017500000000460400000000000022645 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013 Isaku Yamahata # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. from os_ken.lib.packet import ethernet from os_ken.lib.packet import vlan from os_ken.ofproto import ether from os_ken.topology import api as topo_api def may_add_vlan(packet, vlan_id): """ :type packet: os_ken.lib.packet.packet.Packet :param packet: :type vlan_id: int (0 <= vlan_id <= 4095) or None (= No VLAN) :param vlan_id: """ if vlan_id is None: return e = packet.protocols[0] assert isinstance(e, ethernet.ethernet) v = vlan.vlan(0, 0, vlan_id, e.ethertype) e.ethertype = ether.ETH_TYPE_8021Q packet.add_protocol(v) def get_dp(app, dpid): """ :type dpid: datapath id :param dpid: :rtype: os_ken.controller.controller.Datapath :returns: datapath corresponding to dpid """ switches = topo_api.get_switch(app, dpid) if not switches: return None assert len(switches) == 1 return switches[0].dp def dp_packet_out(dp, port_no, data): # OF 1.2 ofproto = dp.ofproto ofproto_parser = dp.ofproto_parser actions = [ofproto_parser.OFPActionOutput(port_no, ofproto.OFPCML_NO_BUFFER)] packet_out = ofproto_parser.OFPPacketOut( dp, 0xffffffff, ofproto.OFPP_CONTROLLER, actions, data) dp.send_msg(packet_out) def dp_flow_mod(dp, table, command, priority, match, instructions, out_port=None): # OF 1.2 ofproto = dp.ofproto ofproto_parser = dp.ofproto_parser if out_port is None: out_port = ofproto.OFPP_ANY flow_mod = ofproto_parser.OFPFlowMod( dp, 0, 0, table, command, 0, 0, priority, 0xffffffff, out_port, ofproto.OFPG_ANY, ofproto.OFPFF_CHECK_OVERLAP, match, instructions) dp.send_msg(flow_mod) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.1221063 os-ken-2.10.0/os_ken/services/protocols/zebra/0000775000175000017500000000000000000000000021241 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/zebra/__init__.py0000664000175000017500000000123000000000000023346 0ustar00zuulzuul00000000000000# Copyright (C) 2017 Nippon Telegraph and Telephone 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 for Zebra protocol service. """ ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.1221063 os-ken-2.10.0/os_ken/services/protocols/zebra/client/0000775000175000017500000000000000000000000022517 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/zebra/client/__init__.py0000664000175000017500000000135000000000000024627 0ustar00zuulzuul00000000000000# Copyright (C) 2017 Nippon Telegraph and Telephone 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. """ Client implementation for Zebra protocol service. This module provides the client side implementation for Zebra protocol. """ ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/zebra/client/event.py0000664000175000017500000000243500000000000024216 0ustar00zuulzuul00000000000000# Copyright (C) 2017 Nippon Telegraph and Telephone 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. """ Events generated by Zebra Client service. """ from os_ken.controller.event import EventBase class EventZClientBase(EventBase): """ The base class for the event generated by ZClient. """ class EventZServConnected(EventZClientBase): """ The event class for notifying the connection to Zebra server. """ def __init__(self, zserv): super(EventZServConnected, self).__init__() self.zserv = zserv class EventZServDisconnected(EventZClientBase): """ The event class for notifying the disconnection from Zebra server. """ def __init__(self, zserv): super(EventZServDisconnected, self).__init__() self.zserv = zserv ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/zebra/client/sample_dumper.py0000664000175000017500000000365000000000000025732 0ustar00zuulzuul00000000000000# Copyright (C) 2017 Nippon Telegraph and Telephone 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. """ Sample Zebra Client application dumping received events. """ from os_ken.controller.handler import set_ev_cls from os_ken.lib.packet import zebra from os_ken.services.protocols.zebra import event from os_ken.services.protocols.zebra.client.zclient import ZClient from os_ken.services.protocols.zebra.client import event as zclient_event class ZClientDumper(ZClient): @set_ev_cls(zclient_event.EventZServConnected) def _zserv_connected_handler(self, ev): self.logger.info( 'Zebra server connected to %s: %s', ev.zserv.sock.getpeername(), ev.zserv.sock) @set_ev_cls(event.EventZebraRouterIDUpdate) def _router_id_update_handler(self, ev): self.logger.info( 'ZEBRA_ROUTER_ID_UPDATE received: %s', ev.__dict__) @set_ev_cls(event.EventZebraInterfaceAdd) def _interface_add_handler(self, ev): self.logger.info( 'ZEBRA_INTERFACE_ADD received: %s', ev.__dict__) @set_ev_cls(event.EventZebraInterfaceAddressAdd) def _interface_address_add_handler(self, ev): self.logger.info( 'ZEBRA_INTERFACE_ADDRESS_ADD received: %s', ev.__dict__) @set_ev_cls(zclient_event.EventZServDisconnected) def _zserv_disconnected_handler(self, ev): self.logger.info( 'Zebra server disconnected: %s', ev.zserv.sock) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/zebra/client/zclient.py0000664000175000017500000002657300000000000024556 0ustar00zuulzuul00000000000000# Copyright (C) 2017 Nippon Telegraph and Telephone 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. """ Zebra Client corresponding to 'zclient' structure. """ import os import socket import struct from os_ken import cfg from os_ken.base.app_manager import OSKenApp from os_ken.lib import hub from os_ken.lib import ip from os_ken.lib.packet import zebra from os_ken.lib.packet import safi as packet_safi from os_ken.services.protocols.zebra import event from os_ken.services.protocols.zebra.client import event as zclient_event CONF = cfg.CONF['zapi'] GLOBAL_CONF = cfg.CONF def create_connection(address): """ Wrapper for socket.create_connection() function. If *address* (a 2-tuple ``(host, port)``) contains a valid IPv4/v6 address, passes *address* to socket.create_connection(). If *host* is valid path to Unix Domain socket, tries to connect to the server listening on the given socket. :param address: IP address or path to Unix Domain socket. :return: Socket instance. """ host, _port = address if ip.valid_ipv4(host) or ip.valid_ipv6(host): return socket.create_connection(address) elif os.path.exists(host): sock = None try: sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) sock.connect(host) except socket.error as e: if sock is not None: sock.close() raise e return sock else: raise ValueError('Invalid IP address or Unix Socket: %s' % host) def get_zebra_route_type_by_name(route_type='BGP'): """ Returns the constant value for Zebra route type named "ZEBRA_ROUTE_*" from its name. See "ZEBRA_ROUTE_*" constants in "os_ken.lib.packet.zebra" module. :param route_type: Route type name (e.g., Kernel, BGP). :return: Constant value for Zebra route type. """ return getattr(zebra, "ZEBRA_ROUTE_%s" % route_type.upper()) class ZServer(object): """ Zebra server class. """ def __init__(self, client): self.client = client self.logger = client.logger self.is_active = False self.sock = None # Client socket connecting to Zebra server self.threads = [] def start(self): self.is_active = True try: self.sock = create_connection(self.client.zserv_addr) except socket.error as e: self.logger.exception( 'Cannot connect to Zebra server%s: %s', self.client.zserv_addr, e) self.stop() return None self.sock.settimeout(GLOBAL_CONF.socket_timeout) self.threads.append(hub.spawn(self._send_loop)) self.threads.append(hub.spawn(self._recv_loop)) # Send the following messages at starting connection. # - ZEBRA_HELLO to register route_type # - ZEBRA_ROUTER_ID_ADD to get router_id # - ZEBRA_INTERFACE_ADD to get info for interfaces self.client.send_msg( zebra.ZebraMessage( version=self.client.zserv_ver, body=zebra.ZebraHello( route_type=self.client.route_type, instance=0))) self.client.send_msg( zebra.ZebraMessage( version=self.client.zserv_ver, body=zebra.ZebraRouterIDAdd())) self.client.send_msg( zebra.ZebraMessage( version=self.client.zserv_ver, body=zebra.ZebraInterfaceAdd())) self.client.send_event_to_observers( zclient_event.EventZServConnected(self)) hub.joinall(self.threads) self.client.send_event_to_observers( zclient_event.EventZServDisconnected(self)) def stop(self): self.is_active = False def _send_loop(self): try: while self.is_active: buf = self.client.send_q.get() self.sock.sendall(buf) except socket.error as e: self.logger.exception( 'Error while sending message to Zebra server%s: %s', self.client.zserv_addr, e) self.stop() def _recv_loop(self): buf = b'' min_len = recv_len = zebra.ZebraMessage.get_header_size( self.client.zserv_ver) try: while self.is_active: try: recv_buf = self.sock.recv(recv_len) except socket.timeout: continue if len(recv_buf) == 0: break buf += recv_buf while len(buf) >= min_len: (length,) = struct.unpack_from('!H', buf) if (length - len(buf)) > 0: # Need to receive remaining data recv_len = length - len(buf) break msg, _, buf = zebra._ZebraMessageFromZebra.parser(buf) ev = event.message_to_event(self.client, msg) if ev: self.client.send_event_to_observers(ev) except socket.error as e: self.logger.exception( 'Error while sending message to Zebra server%s: %s', self.client.zserv_addr, e) self.stop() class ZClient(OSKenApp): """ The base class for Zebra client application. """ _EVENTS = event.ZEBRA_EVENTS + [ zclient_event.EventZServConnected, zclient_event.EventZServDisconnected, ] def __init__(self, *args, **kwargs): super(ZClient, self).__init__(*args, **kwargs) self.zserv = None # ZServer instance self.zserv_addr = (CONF.server_host, CONF.server_port) self.zserv_ver = CONF.server_version self.send_q = hub.Queue(16) self.route_type = get_zebra_route_type_by_name( CONF.client_route_type) def start(self): super(ZClient, self).start() return hub.spawn(self._service_loop) def _service_loop(self): while self.is_active: self.zserv = ZServer(self) self.zserv.start() hub.sleep(CONF.retry_interval) self.close() def close(self): self.is_active = False self._send_event(self._event_stop, None) self.zserv.stop() def send_msg(self, msg): """ Sends Zebra message. :param msg: Instance of py:class: `os_ken.lib.packet.zebra.ZebraMessage`. :return: Serialized msg if succeeded, otherwise None. """ if not self.is_active: self.logger.debug( 'Cannot send message: Already deactivated: msg=%s', msg) return elif not self.send_q: self.logger.debug( 'Cannot send message: Send queue does not exist: msg=%s', msg) return elif self.zserv_ver != msg.version: self.logger.debug( 'Zebra protocol version mismatch:' 'server_version=%d, msg.version=%d', self.zserv_ver, msg.version) msg.version = self.zserv_ver # fixup self.send_q.put(msg.serialize()) def _send_ip_route_impl( self, prefix, nexthops=None, safi=packet_safi.UNICAST, flags=zebra.ZEBRA_FLAG_INTERNAL, distance=None, metric=None, mtu=None, tag=None, is_withdraw=False): if ip.valid_ipv4(prefix): if is_withdraw: msg_cls = zebra.ZebraIPv4RouteDelete else: msg_cls = zebra.ZebraIPv4RouteAdd elif ip.valid_ipv6(prefix): if is_withdraw: msg_cls = zebra.ZebraIPv6RouteDelete else: msg_cls = zebra.ZebraIPv6RouteAdd else: raise ValueError('Invalid prefix: %s' % prefix) nexthop_list = [] for nexthop in nexthops: if ip.valid_ipv4(nexthop): nexthop_list.append(zebra.NextHopIPv4(addr=nexthop)) elif ip.valid_ipv6(nexthop): nexthop_list.append(zebra.NextHopIPv6(addr=nexthop)) else: raise ValueError('Invalid nexthop: %s' % nexthop) msg = zebra.ZebraMessage( version=self.zserv_ver, body=msg_cls( route_type=self.route_type, flags=flags, message=0, safi=safi, prefix=prefix, nexthops=nexthop_list, distance=distance, metric=metric, mtu=mtu, tag=tag, instance=0)) self.send_msg(msg) return msg def send_ip_route_add( self, prefix, nexthops=None, safi=packet_safi.UNICAST, flags=zebra.ZEBRA_FLAG_INTERNAL, distance=None, metric=None, mtu=None, tag=None): """ Sends ZEBRA_IPV4/v6_ROUTE_ADD message to Zebra daemon. :param prefix: IPv4/v6 Prefix to advertise. :param nexthops: List of nexthop addresses. :param safi: SAFI to advertise. :param flags: Message flags to advertise. See "ZEBRA_FLAG_*". :param distance: (Optional) Distance to advertise. :param metric: (Optional) Metric to advertise. :param mtu: (Optional) MTU size to advertise. :param tag: (Optional) TAG information to advertise. :return: Zebra message instance to be sent. None if failed. """ try: return self._send_ip_route_impl( prefix=prefix, nexthops=nexthops, safi=safi, flags=flags, distance=distance, metric=metric, mtu=mtu, tag=tag, is_withdraw=False) except ValueError as e: self.logger.exception( 'Cannot send IP route add message: %s', e) return None def send_ip_route_delete( self, prefix, nexthops=None, safi=packet_safi.UNICAST, flags=zebra.ZEBRA_FLAG_INTERNAL, distance=None, metric=None, mtu=None, tag=None): """ Sends ZEBRA_IPV4/v6_ROUTE_DELETE message to Zebra daemon. :param prefix: IPv4/v6 Prefix to advertise. :param nexthops: List of nexthop addresses. :param safi: SAFI to advertise. :param flags: Message flags to advertise. See "ZEBRA_FLAG_*". :param distance: (Optional) Distance to advertise. :param metric: (Optional) Metric to advertise. :param mtu: (Optional) MTU size to advertise. :param tag: (Optional) TAG information to advertise. :return: Zebra message instance to be sent. None if failed. """ try: return self._send_ip_route_impl( prefix=prefix, nexthops=nexthops, safi=safi, flags=flags, distance=distance, metric=metric, mtu=mtu, tag=tag, is_withdraw=True) except ValueError as e: self.logger.exception( 'Cannot send IP route delete message: %s', e) return None ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.1261065 os-ken-2.10.0/os_ken/services/protocols/zebra/db/0000775000175000017500000000000000000000000021626 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/zebra/db/__init__.py0000664000175000017500000000212400000000000023736 0ustar00zuulzuul00000000000000# Copyright (C) 2017 Nippon Telegraph and Telephone 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. """ Database implementation for Zebra protocol service. """ from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker from os_ken import cfg # Configuration parameters for Zebra service CONF = cfg.CONF['zapi'] # Connect to database ENGINE = create_engine(CONF.db_url) Session = sessionmaker(bind=ENGINE) """ Session class connecting to database """ # Create all tables from . import base from . import interface from . import route base.Base.metadata.create_all(ENGINE) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/zebra/db/base.py0000664000175000017500000000405200000000000023113 0ustar00zuulzuul00000000000000# Copyright (C) 2017 Nippon Telegraph and Telephone 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. import functools import logging from sqlalchemy.ext.declarative import declarative_base LOG = logging.getLogger(__name__) Base = declarative_base() """ Base class for Zebra protocol database tables. """ def _repr(self): m = ', '.join( ['%s=%r' % (k, v) for k, v in self.__dict__.items() if not k.startswith('_')]) return "%s(%s)" % (self.__class__.__name__, m) Base.__repr__ = _repr def sql_function(func): """ Decorator for wrapping the given function in order to manipulate (CRUD) the records safely. For the adding/updating/deleting records function, this decorator invokes "Session.commit()" after the given function. If any exception while modifying records raised, this decorator invokes "Session.rollbacks()". """ @functools.wraps(func) def _wrapper(session, *args, **kwargs): ret = None try: ret = func(session, *args, **kwargs) if session.dirty: # If the given function has any update to records, # commits them. session.commit() except Exception as e: # If any exception raised, rollbacks the transaction. LOG.error('Error in %s: %s', func.__name__, e) if session.dirty: LOG.error('Do rolling back %s table', session.dirty[0].__tablename__) session.rollback() return ret return _wrapper ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/zebra/db/interface.py0000664000175000017500000001774000000000000024151 0ustar00zuulzuul00000000000000# Copyright (C) 2017 Nippon Telegraph and Telephone 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. import logging from sqlalchemy import Column from sqlalchemy import Integer from sqlalchemy import String from os_ken.lib import netdevice from os_ken.lib import ip from os_ken.lib.packet import zebra from . import base LOG = logging.getLogger(__name__) # Default value for ethernet interface DEFAULT_ETH_FLAGS = ( netdevice.IFF_UP | netdevice.IFF_BROADCAST | netdevice.IFF_RUNNING | netdevice.IFF_MULTICAST) DEFAULT_ETH_MTU = 1500 class Interface(base.Base): """ Interface table for Zebra protocol service. The default value for each fields suppose "Loopback" interface. ``ifindex``: Number of index. ``ifname``: Name of this interface. ``status``: A combination of flags "os_ken.lib.packet.zebra.ZEBRA_INTERFACE_*". The default value shows "active" and "link-detect". ``flags``: A combination of flags "os_ken.lib.netdevice.IFF_*". The default value show "up", "loopback" and "running". ``metric``: Metric of this interface. ``ifmtu``: IPv4 MTU of this interface. ``ifmtu6``: IPv6 MTU of this interface. ``bandwidth``: Bandwidth of this interface. ``ll_type``: Link Layer Type. One of "os_ken.lib.packet.zebra.ZEBRA_LLT_*" types. ``hw_addr``: Hardware address of this interface (mostly, MAC address). ``inet``: List of IPv4 addresses separated by a comma. (e.g., "192.168.1.100/24,192.168.2.100/24)". ``inet6``: List of IPv6 addresses separated by a comma. """ __tablename__ = 'interface' ifindex = Column(Integer, primary_key=True) ifname = Column(String, default="lo") status = Column( Integer, default=( zebra.ZEBRA_INTERFACE_ACTIVE | zebra.ZEBRA_INTERFACE_LINKDETECTION)) flags = Column( Integer, default=( netdevice.IFF_UP | netdevice.IFF_LOOPBACK | netdevice.IFF_RUNNING)) metric = Column(Integer, default=1) ifmtu = Column(Integer, default=0x10000) ifmtu6 = Column(Integer, default=0x10000) bandwidth = Column(Integer, default=0) ll_type = Column(Integer, default=zebra.ZEBRA_LLT_ETHER) hw_addr = Column(String, default='00:00:00:00:00:00') # Note: Only the PostgreSQL backend has support sqlalchemy.ARRAY, # we use the comma separated string as array instead. inet = Column(String, default='') inet6 = Column(String, default='') @base.sql_function def ip_link_show(session, **kwargs): """ Returns a first interface record matching the given filtering rules. The arguments for "kwargs" is the same with Interface class. :param session: Session instance connecting to database. :param kwargs: Filtering rules to query. :return: An instance of Interface record. """ return session.query(Interface).filter_by(**kwargs).first() @base.sql_function def ip_link_show_all(session, **kwargs): """ Returns all interface records matching the given filtering rules. The arguments for "kwargs" is the same with Interface class. :param session: Session instance connecting to database. :param kwargs: Filtering rules to query. :return: A list of Interface records. """ return session.query(Interface).filter_by(**kwargs).all() @base.sql_function def ip_link_add(session, name, type_='loopback', lladdr='00:00:00:00:00:00'): """ Adds an interface record into Zebra protocol service database. The arguments are similar to "ip link add" command of iproute2. :param session: Session instance connecting to database. :param name: Name of interface. :param type_: Type of interface. 'loopback' or 'ethernet'. :param lladdr: Link layer address. Mostly MAC address. :return: Instance of added record or already existing record. """ intf = ip_link_show(session, ifname=name) if intf: LOG.debug('Interface "%s" already exists: %s', intf.ifname, intf) return intf if type_ == 'ethernet': intf = Interface( ifname=name, flags=DEFAULT_ETH_FLAGS, ifmtu=DEFAULT_ETH_MTU, ifmtu6=DEFAULT_ETH_MTU, hw_addr=lladdr) else: # type_ == 'loopback': intf = Interface( ifname=name, inet='127.0.0.1/8', inet6='::1/128') session.add(intf) return intf @base.sql_function def ip_link_delete(session, name): """ Deletes an interface record from Zebra protocol service database. The arguments are similar to "ip link delete" command of iproute2. :param session: Session instance connecting to database. :param name: Name of interface. :return: Name of interface which was deleted. None if failed. """ intf = ip_link_show(session, ifname=name) if not intf: LOG.debug('Interface "%s" does not exist', name) return None session.delete(intf) return name # Currently, functions corresponding to "ip link show" and "ip address show" # have the same implementation. ip_address_show = ip_link_show ip_address_show_all = ip_link_show_all @base.sql_function def ip_address_add(session, ifname, ifaddr): """ Adds an IP address to interface record identified with the given "ifname". The arguments are similar to "ip address add" command of iproute2. :param session: Session instance connecting to database. :param ifname: Name of interface. :param ifaddr: IPv4 or IPv6 address. :return: Instance of record or "None" if failed. """ def _append_inet_addr(intf_inet, addr): addr_list = intf_inet.split(',') if addr in addr_list: LOG.debug( 'Interface "%s" has already "ifaddr": %s', intf.ifname, addr) return intf_inet else: addr_list.append(addr) return ','.join(addr_list) intf = ip_link_show(session, ifname=ifname) if not intf: LOG.debug('Interface "%s" does not exist', ifname) return None if ip.valid_ipv4(ifaddr): intf.inet = _append_inet_addr(intf.inet, ifaddr) elif ip.valid_ipv6(ifaddr): intf.inet6 = _append_inet_addr(intf.inet6, ifaddr) else: LOG.debug('Invalid IP address for "ifaddr": %s', ifaddr) return None return intf @base.sql_function def ip_address_delete(session, ifname, ifaddr): """ Deletes an IP address from interface record identified with the given "ifname". The arguments are similar to "ip address delete" command of iproute2. :param session: Session instance connecting to database. :param ifname: Name of interface. :param ifaddr: IPv4 or IPv6 address. :return: Instance of record or "None" if failed. """ def _remove_inet_addr(intf_inet, addr): addr_list = intf_inet.split(',') if addr not in addr_list: LOG.debug( 'Interface "%s" does not have "ifaddr": %s', intf.ifname, addr) return intf_inet else: addr_list.remove(addr) return ','.join(addr_list) intf = ip_link_show(session, ifname=ifname) if not intf: LOG.debug('Interface "%s" does not exist', ifname) return None if ip.valid_ipv4(ifaddr): intf.inet = _remove_inet_addr(intf.inet, ifaddr) elif ip.valid_ipv6(ifaddr): intf.inet6 = _remove_inet_addr(intf.inet6, ifaddr) else: LOG.debug('Invalid IP address for "ifaddr": %s', ifaddr) return None return intf ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/zebra/db/route.py0000664000175000017500000001453500000000000023346 0ustar00zuulzuul00000000000000# Copyright (C) 2017 Nippon Telegraph and Telephone 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. import logging import socket from sqlalchemy import Column from sqlalchemy import Boolean from sqlalchemy import Integer from sqlalchemy import String from os_ken.lib import ip from os_ken.lib.packet import safi as packet_safi from os_ken.lib.packet import zebra from . import base from . import interface LOG = logging.getLogger(__name__) class Route(base.Base): """ Route table (like routing table) for Zebra protocol service. ``id``: (Primary Key) ID of this route. ``family``: Address Family, not AFI (Address Family Identifiers). Mostly, "socket.AF_INET" or "socket.AF_INET6". ``safi``: Subsequent Address Family Identifiers. ``destination``: Destination prefix of this route. ``gateway``: Next hop address of this route. The default is "" (empty string). ``ifindex``: Index of interface to forward packets. ``source``: Source IP address of this route, which should be an address assigned to the local interface. ``route_type``: Route Type of this route. This type shows which daemon (or kernel) generated this route. ``is_selected``: Whether this route is selected for "destination". """ __tablename__ = 'route' id = Column(Integer, primary_key=True) family = Column(Integer, default=socket.AF_INET) safi = Column(Integer, default=packet_safi.UNICAST) destination = Column(String, default='0.0.0.0/0') gateway = Column(String, default='') ifindex = Column(Integer, default=0) source = Column(String, default='') route_type = Column(Integer, default=zebra.ZEBRA_ROUTE_KERNEL) is_selected = Column(Boolean, default=False) @base.sql_function def ip_route_show(session, destination, device, **kwargs): """ Returns a selected route record matching the given filtering rules. The arguments are similar to "ip route showdump" command of iproute2. :param session: Session instance connecting to database. :param destination: Destination prefix. :param device: Source device. :param kwargs: Filtering rules to query. :return: Instance of route record or "None" if failed. """ intf = interface.ip_link_show(session, ifname=device) if not intf: LOG.debug('Interface "%s" does not exist', device) return None return session.query(Route).filter_by( destination=destination, ifindex=intf.ifindex, **kwargs).first() @base.sql_function def ip_route_show_all(session, **kwargs): """ Returns a selected route record matching the given filtering rules. The arguments are similar to "ip route showdump" command of iproute2. If "is_selected=True", disables the existing selected route for the given destination. :param session: Session instance connecting to database. :param kwargs: Filtering rules to query. :return: A list of route records. """ return session.query(Route).filter_by(**kwargs).all() @base.sql_function def ip_route_add(session, destination, device=None, gateway='', source='', ifindex=0, route_type=zebra.ZEBRA_ROUTE_KERNEL, is_selected=True): """ Adds a route record into Zebra protocol service database. The arguments are similar to "ip route add" command of iproute2. If "is_selected=True", disables the existing selected route for the given destination. :param session: Session instance connecting to database. :param destination: Destination prefix. :param device: Source device. :param gateway: Gateway IP address. :param source: Source IP address. :param ifindex: Index of source device. :param route_type: Route type of daemon (or kernel). :param is_selected: If select the given route as "in use" or not. :return: Instance of record or "None" if failed. """ if device: intf = interface.ip_link_show(session, ifname=device) if not intf: LOG.debug('Interface "%s" does not exist', device) return None ifindex = ifindex or intf.ifindex route = ip_route_show(session, destination=destination, device=device) if route: LOG.debug( 'Route to "%s" already exists on "%s" device', destination, device) return route dest_addr, dest_prefix_num = destination.split('/') dest_prefix_num = int(dest_prefix_num) if ip.valid_ipv4(dest_addr) and 0 <= dest_prefix_num <= 32: family = socket.AF_INET elif ip.valid_ipv6(dest_addr) and 0 <= dest_prefix_num <= 128: family = socket.AF_INET6 else: LOG.debug('Invalid IP address for "prefix": %s', destination) return None safi = packet_safi.UNICAST if is_selected: old_routes = ip_route_show_all( session, destination=destination, is_selected=True) for old_route in old_routes: if old_route: LOG.debug('Set existing route to unselected: %s', old_route) old_route.is_selected = False new_route = Route( family=family, safi=safi, destination=destination, gateway=gateway, ifindex=ifindex, source=source, route_type=route_type, is_selected=is_selected) session.add(new_route) return new_route @base.sql_function def ip_route_delete(session, destination, **kwargs): """ Deletes route record(s) from Zebra protocol service database. The arguments are similar to "ip route delete" command of iproute2. :param session: Session instance connecting to database. :param destination: Destination prefix. :param kwargs: Filtering rules to query. :return: Records which are deleted. """ routes = ip_route_show_all(session, destination=destination, **kwargs) for route in routes: session.delete(route) return routes ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/zebra/event.py0000664000175000017500000000674200000000000022745 0ustar00zuulzuul00000000000000# Copyright (C) 2017 Nippon Telegraph and Telephone 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. """ Events for Zebra protocol service. """ import inspect import logging from os_ken import utils from os_ken.controller import event from os_ken.lib.packet import zebra LOG = logging.getLogger(__name__) MOD = utils.import_module(__name__) ZEBRA_EVENTS = [] class EventZebraBase(event.EventBase): """ The base class for Zebra protocol service event class. The subclasses have at least ``zclient`` and the same attributes with :py:class: `os_ken.lib.packet.zebra.ZebraMessage`. ``zclient`` is an instance of Zebra client class. See :py:class: `os_ken.services.protocols.zebra.client.zclient.ZClient` or :py:class: `os_ken.services.protocols.zebra.server.zserver.ZClient`. The subclasses are named as:: ``"Event" + `` For Example, if the service received ZEBRA_INTERFACE_ADD message, the body class should be :py:class: `os_ken.lib.packet.zebra.ZebraInterfaceAdd`, then the event class will be named as:: "Event" + "ZebraInterfaceAdd" = "EventZebraInterfaceAdd" ``msg`` argument must be an instance of :py:class: `os_ken.lib.packet.zebra.ZebraMessage` and used to extract the attributes for the event classes. """ def __init__(self, zclient, msg): super(EventZebraBase, self).__init__() assert isinstance(msg, zebra.ZebraMessage) self.__dict__ = msg.__dict__ self.zclient = zclient def __repr__(self): m = ', '.join( ['%s=%r' % (k, v) for k, v in self.__dict__.items() if not k.startswith('_')]) return "%s(%s)" % (self.__class__.__name__, m) __str__ = __repr__ def _event_name(body_cls): return 'Event%s' % body_cls.__name__ def message_to_event(zclient, msg): """ Converts Zebra protocol message instance to Zebra protocol service event instance. If corresponding event class is not defined, returns None. :param zclient: Zebra client instance. :param msg: Zebra protocol message. :return: Zebra protocol service event. """ if not isinstance(msg, zebra.ZebraMessage): return None body_cls = msg.get_body_class(msg.version, msg.command) ev_cls = getattr(MOD, _event_name(body_cls), None) if ev_cls is None: return None return ev_cls(zclient, msg) def _define_event_class(body_cls): name = _event_name(body_cls) event_cls = type(name, (EventZebraBase,), {}) globals()[name] = event_cls return event_cls def _generate_event_classes(): for zebra_cls in zebra.__dict__.values(): if (not inspect.isclass(zebra_cls) or not issubclass(zebra_cls, zebra._ZebraMessageBody) or zebra_cls.__name__.startswith('_')): continue ev = _define_event_class(zebra_cls) # LOG.debug('Generated Zebra event: %s' % ev) ZEBRA_EVENTS.append(ev) _generate_event_classes() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.1261065 os-ken-2.10.0/os_ken/services/protocols/zebra/server/0000775000175000017500000000000000000000000022547 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/zebra/server/__init__.py0000664000175000017500000000135000000000000024657 0ustar00zuulzuul00000000000000# Copyright (C) 2017 Nippon Telegraph and Telephone 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. """ Server implementation for Zebra protocol service. This module provides the server side implementation for Zebra protocol. """ ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/zebra/server/event.py0000664000175000017500000000246100000000000024245 0ustar00zuulzuul00000000000000# Copyright (C) 2017 Nippon Telegraph and Telephone 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. """ Events generated by Zebra Server service. """ from os_ken.controller.event import EventBase class EventZServerBase(EventBase): """ The base class for the event generated by ZServer. """ class EventZClientConnected(EventZServerBase): """ The event class for notifying the connection from Zebra client. """ def __init__(self, zclient): super(EventZClientConnected, self).__init__() self.zclient = zclient class EventZClientDisconnected(EventZServerBase): """ The event class for notifying the disconnection to Zebra client. """ def __init__(self, zclient): super(EventZClientDisconnected, self).__init__() self.zclient = zclient ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/zebra/server/sample_dumper.py0000664000175000017500000000375500000000000025770 0ustar00zuulzuul00000000000000# Copyright (C) 2017 Nippon Telegraph and Telephone 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. """ Sample Zebra Server application dumping received events. """ from os_ken.base.app_manager import OSKenApp from os_ken.controller.handler import set_ev_cls from os_ken.services.protocols.zebra import event from os_ken.services.protocols.zebra.server.zserver import ZServer from os_ken.services.protocols.zebra.server import event as zserver_event class ZServerDumper(OSKenApp): _CONTEXTS = { "zserver": ZServer, } def __init__(self, *args, **kwargs): super(ZServerDumper, self).__init__(*args, **kwargs) self.zserver = kwargs["zserver"] @set_ev_cls(zserver_event.EventZClientConnected) def _zclient_connected_handler(self, ev): self.logger.info('Zebra client connected: %s', ev.zclient.addr) @set_ev_cls(zserver_event.EventZClientDisconnected) def _zclient_disconnected_handler(self, ev): self.logger.info('Zebra client disconnected: %s', ev.zclient.addr) @set_ev_cls([event.EventZebraIPv4RouteAdd, event.EventZebraIPv6RouteAdd]) def _ip_route_add_handler(self, ev): self.logger.info( 'Client %s advertised IP route: %s', ev.zclient.addr, ev.body) @set_ev_cls([event.EventZebraIPv4RouteDelete, event.EventZebraIPv6RouteDelete]) def _ip_route_delete_handler(self, ev): self.logger.info( 'Client %s withdrew IP route: %s', ev.zclient.addr, ev.body) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/services/protocols/zebra/server/zserver.py0000664000175000017500000002567000000000000024633 0ustar00zuulzuul00000000000000# Copyright (C) 2017 Nippon Telegraph and Telephone 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. """ Zebra Server corresponding to 'zserv' structure. """ import contextlib import logging import os import socket import struct from os_ken import cfg from os_ken.base import app_manager from os_ken.base.app_manager import OSKenApp from os_ken.controller.handler import set_ev_cls from os_ken.lib import hub from os_ken.lib import ip from os_ken.lib.packet import zebra from os_ken.services.protocols.zebra import db from os_ken.services.protocols.zebra import event from os_ken.services.protocols.zebra.server import event as zserver_event LOG = logging.getLogger(__name__) CONF = cfg.CONF['zapi'] GLOBAL_CONF = cfg.CONF # Session to database of Zebra protocol service SESSION = db.Session() class ZClient(object): """ Zebra client class. """ def __init__(self, server, sock, addr): self.server = server self.sock = sock self.addr = addr self.logger = server.logger self.is_active = False self._threads = [] self.send_q = hub.Queue(16) # Zebra protocol version self.zserv_ver = CONF.server_version # Zebra route type distributed by client (not initialized yet) self.route_type = None def start(self): self.is_active = True self.sock.settimeout(GLOBAL_CONF.socket_timeout) self._threads.append(hub.spawn(self._send_loop)) self._threads.append(hub.spawn(self._recv_loop)) self.server.send_event_to_observers( zserver_event.EventZClientConnected(self)) hub.joinall(self._threads) self.server.send_event_to_observers( zserver_event.EventZClientDisconnected(self)) def stop(self): self.is_active = False def _send_loop(self): try: while self.is_active: buf = self.send_q.get() self.sock.sendall(buf) except socket.error as e: self.logger.exception( 'Error while sending message to Zebra client%s: %s', self.addr, e) self.stop() def _recv_loop(self): buf = b'' min_len = recv_len = zebra.ZebraMessage.get_header_size( self.zserv_ver) try: while self.is_active: try: recv_buf = self.sock.recv(recv_len) except socket.timeout: continue if len(recv_buf) == 0: break buf += recv_buf while len(buf) >= min_len: (length,) = struct.unpack_from('!H', buf) if (length - len(buf)) > 0: # Need to receive remaining data recv_len = length - len(buf) break msg, _, buf = zebra.ZebraMessage.parser(buf) ev = event.message_to_event(self, msg) if ev: self.logger.debug('Notify event: %s', ev) self.server.send_event_to_observers(ev) except socket.error as e: self.logger.exception( 'Error while sending message to Zebra client%s: %s', self.addr, e) self.stop() def send_msg(self, msg): """ Sends Zebra message. :param msg: Instance of py:class: `os_ken.lib.packet.zebra.ZebraMessage`. :return: Serialized msg if succeeded, otherwise None. """ if not self.is_active: self.logger.debug( 'Cannot send message: Already deactivated: msg=%s', msg) return elif not self.send_q: self.logger.debug( 'Cannot send message: Send queue does not exist: msg=%s', msg) return elif self.zserv_ver != msg.version: self.logger.debug( 'Zebra protocol version mismatch:' 'server_version=%d, msg.version=%d', self.zserv_ver, msg.version) msg.version = self.zserv_ver # fixup self.send_q.put(msg.serialize()) def zclient_connection_factory(sock, addr): LOG.debug('Connected from client: %s: %s', addr, sock) zserv = app_manager.lookup_service_brick(ZServer.__name__) with contextlib.closing(ZClient(zserv, sock, addr)) as zclient: try: zclient.start() except Exception as e: LOG.error('Error in client%s: %s', addr, e) raise e def detect_address_family(host): if ip.valid_ipv4(host): return socket.AF_INET elif ip.valid_ipv6(host): return socket.AF_INET6 elif os.path.isdir(os.path.dirname(host)): return socket.AF_UNIX else: return None class ZServer(OSKenApp): """ The base class for Zebra server application. """ _EVENTS = event.ZEBRA_EVENTS + [ zserver_event.EventZClientConnected, zserver_event.EventZClientDisconnected, ] def __init__(self, *args, **kwargs): super(ZServer, self).__init__(*args, **kwargs) self.zserv = None self.zserv_addr = (CONF.server_host, CONF.server_port) self.zapi_connection_family = detect_address_family(CONF.server_host) # Initial Router ID for Zebra server self.router_id = CONF.router_id def start(self): super(ZServer, self).start() if self.zapi_connection_family == socket.AF_UNIX: unix_sock_dir = os.path.dirname(CONF.server_host) # Makes sure the unix socket does not already exist if os.path.exists(CONF.server_host): os.remove(CONF.server_host) if not os.path.isdir(unix_sock_dir): os.mkdir(unix_sock_dir) os.chmod(unix_sock_dir, 0o777) try: self.zserv = hub.StreamServer( self.zserv_addr, zclient_connection_factory) except OSError as e: self.logger.error( 'Cannot start Zebra server%s: %s', self.zserv_addr, e) raise e if self.zapi_connection_family == socket.AF_UNIX: os.chmod(CONF.server_host, 0o777) self._add_lo_interface() return hub.spawn(self.zserv.serve_forever) def _add_lo_interface(self): intf = db.interface.ip_link_add(SESSION, 'lo') if intf: self.logger.debug('Added interface "%s": %s', intf.ifname, intf) route = db.route.ip_route_add( SESSION, destination='127.0.0.0/8', device='lo', source='127.0.0.1/8', route_type=zebra.ZEBRA_ROUTE_CONNECT) if route: self.logger.debug( 'Added route to "%s": %s', route.destination, route) @set_ev_cls(event.EventZebraHello) def _hello_handler(self, ev): if ev.body is None: self.logger.debug('Client %s says hello.', ev.zclient) return # Set distributed route_type to ZClient ev.zclient.route_type = ev.body.route_type self.logger.debug( 'Client %s says hello and bids fair to announce only %s routes', ev.zclient, ev.body.route_type) @set_ev_cls(event.EventZebraRouterIDAdd) def _router_id_add_handler(self, ev): self.logger.debug( 'Client %s requests router_id, server will response: router_id=%s', ev.zclient, self.router_id) # Send ZEBRA_ROUTER_ID_UPDATE for response msg = zebra.ZebraMessage( body=zebra.ZebraRouterIDUpdate( family=socket.AF_INET, prefix='%s/32' % self.router_id)) ev.zclient.send_msg(msg) @set_ev_cls(event.EventZebraInterfaceAdd) def _interface_add_handler(self, ev): self.logger.debug('Client %s requested all interfaces', ev.zclient) interfaces = db.interface.ip_address_show_all(SESSION) self.logger.debug('Server will response interfaces: %s', interfaces) for intf in interfaces: msg = zebra.ZebraMessage( body=zebra.ZebraInterfaceAdd( ifname=intf.ifname, ifindex=intf.ifindex, status=intf.status, if_flags=intf.flags, ptm_enable=zebra.ZEBRA_IF_PTM_ENABLE_OFF, ptm_status=zebra.ZEBRA_PTM_STATUS_UNKNOWN, metric=intf.metric, ifmtu=intf.ifmtu, ifmtu6=intf.ifmtu6, bandwidth=intf.bandwidth, ll_type=intf.ll_type, hw_addr=intf.hw_addr)) ev.zclient.send_msg(msg) routes = db.route.ip_route_show_all( SESSION, ifindex=intf.ifindex, is_selected=True) self.logger.debug('Server will response routes: %s', routes) for route in routes: dest, _ = route.destination.split('/') msg = zebra.ZebraMessage( body=zebra.ZebraInterfaceAddressAdd( ifindex=intf.ifindex, ifc_flags=0, family=None, prefix=route.source, dest=dest)) ev.zclient.send_msg(msg) @set_ev_cls([event.EventZebraIPv4RouteAdd, event.EventZebraIPv6RouteAdd]) def _ip_route_add_handler(self, ev): self.logger.debug( 'Client %s advertised IP route: %s', ev.zclient, ev.body) for nexthop in ev.body.nexthops: route = db.route.ip_route_add( SESSION, destination=ev.body.prefix, gateway=nexthop.addr, ifindex=nexthop.ifindex or 0, route_type=ev.body.route_type) if route: self.logger.debug( 'Added route to "%s": %s', route.destination, route) @set_ev_cls([event.EventZebraIPv4RouteDelete, event.EventZebraIPv6RouteDelete]) def _ip_route_delete_handler(self, ev): self.logger.debug( 'Client %s withdrew IP route: %s', ev.zclient, ev.body) for nexthop in ev.body.nexthops: routes = db.route.ip_route_delete( SESSION, destination=ev.body.prefix, gateway=nexthop.addr, route_type=ev.body.route_type) if routes: self.logger.debug( 'Deleted routes to "%s": %s', ev.body.prefix, routes) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.1261065 os-ken-2.10.0/os_ken/tests/0000775000175000017500000000000000000000000015431 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/__init__.py0000664000175000017500000000000000000000000017530 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003300000000000011451 xustar000000000000000027 mtime=1724334546.130107 os-ken-2.10.0/os_ken/tests/integrated/0000775000175000017500000000000000000000000017557 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/integrated/__init__.py0000664000175000017500000000000000000000000021656 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003300000000000011451 xustar000000000000000027 mtime=1724334546.130107 os-ken-2.10.0/os_ken/tests/integrated/bgp/0000775000175000017500000000000000000000000020327 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/integrated/bgp/__init__.py0000664000175000017500000000000000000000000022426 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/integrated/bgp/base.py0000664000175000017500000000621100000000000021613 0ustar00zuulzuul00000000000000# Copyright (C) 2016 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2016 Fumihiko Kakuma # # 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. import logging import sys import unittest from os_ken.tests.integrated.common import docker_base as ctn_base from os_ken.tests.integrated.common import oskenbgp from os_ken.tests.integrated.common import quagga LOG = logging.getLogger(__name__) class BgpSpeakerTestBase(unittest.TestCase): images = [] containers = [] bridges = [] checktime = 120 def setUp(self): self.skipTest('These tests require to have "docker" configured in the ' 'system. Regardless of if we move them to functional or ' 'fix them, now we need to disable them.') self.brdc1 = ctn_base.Bridge(name='brdc1', subnet='192.168.10.0/24') self.bridges.append(self.brdc1) self.dockerimg = ctn_base.DockerImage() image = 'python:%d.%d' % ( sys.version_info.major, sys.version_info.minor) self.r_img = self.dockerimg.create_os_ken(image=image, check_exist=True) self.images.append(self.r_img) self.q_img = 'osrg/quagga' self.images.append(self.q_img) self.r1 = oskenbgp.OSKenBGPContainer(name='r1', asn=64512, router_id='192.168.0.1', ctn_image_name=self.r_img) self.containers.append(self.r1) self.r1.add_route('10.10.0.0/28') self.r1.run(wait=True) self.r1_ip_cidr = self.brdc1.addif(self.r1) self.r1_ip = self.r1_ip_cidr.split('/')[0] self.q1 = quagga.QuaggaBGPContainer(name='q1', asn=64522, router_id='192.168.0.2', ctn_image_name=self.q_img) self.containers.append(self.q1) self.q1.add_route('192.168.160.0/24') self.q1.run(wait=True) self.q1_ip_cidr = self.brdc1.addif(self.q1) self.q1_ip = self.q1_ip_cidr.split('/')[0] self.r1.add_peer(self.q1, bridge=self.brdc1.name) self.q1.add_peer(self.r1, bridge=self.brdc1.name) super().setUp() @classmethod def tearDownClass(cls): for ctn in cls.containers: try: ctn.stop() except ctn_base.CommandError as e: LOG.exception('Exception when stopping containers: %s', e) ctn.remove() for br in cls.bridges: br.delete() super(BgpSpeakerTestBase, cls).tearDownClass() ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/integrated/bgp/base_ip6.py0000664000175000017500000000625100000000000022375 0ustar00zuulzuul00000000000000# Copyright (C) 2016 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2016 Fumihiko Kakuma # # 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. import logging import sys import unittest from os_ken.tests.integrated.common import docker_base as ctn_base from os_ken.tests.integrated.common import oskenbgp from os_ken.tests.integrated.common import quagga LOG = logging.getLogger(__name__) class BgpSpeakerTestBase(unittest.TestCase): images = [] containers = [] bridges = [] checktime = 120 def setUp(self): self.skipTest('These tests require to have "docker" configured in the ' 'system. Regardless of if we move them to functional or ' 'fix them, now we need to disable them.') self.brdc1 = ctn_base.Bridge(name='brip6dc1', subnet='2001:10::/32') self.bridges.append(self.brdc1) self.dockerimg = ctn_base.DockerImage() image = 'python:%d.%d' % ( sys.version_info.major, sys.version_info.minor) self.r_img = self.dockerimg.create_os_ken(image=image, check_exist=True) self.images.append(self.r_img) self.q_img = 'osrg/quagga' self.images.append(self.q_img) self.r1 = oskenbgp.OSKenBGPContainer(name='r1', asn=64512, router_id='192.168.0.1', ctn_image_name=self.r_img) self.containers.append(self.r1) self.r1.add_route('fc00:10::/64', route_info={'rf': 'ipv6'}) self.r1.run(wait=True) self.r1_ip_cidr = self.brdc1.addif(self.r1) self.r1_ip = self.r1_ip_cidr.split('/')[0] self.q1 = quagga.QuaggaBGPContainer(name='q1', asn=64522, router_id='192.168.0.2', ctn_image_name=self.q_img) self.containers.append(self.q1) self.q1.add_route('fc00:100::/64', route_info={'rf': 'ipv6'}) self.q1.run(wait=True) self.q1_ip_cidr = self.brdc1.addif(self.q1) self.q1_ip = self.q1_ip_cidr.split('/')[0] self.r1.add_peer(self.q1, bridge=self.brdc1.name, v6=True) self.q1.add_peer(self.r1, bridge=self.brdc1.name, v6=True) super().setUp() @classmethod def tearDownClass(cls): for ctn in cls.containers: try: ctn.stop() except ctn_base.CommandError as e: LOG.exception('Exception when stopping containers: %s', e) ctn.remove() for br in cls.bridges: br.delete() super(BgpSpeakerTestBase, cls).tearDownClass() ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/integrated/bgp/test_basic.py0000664000175000017500000000345600000000000023031 0ustar00zuulzuul00000000000000# Copyright (C) 2016 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2016 Fumihiko Kakuma # # 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. import time from os_ken.tests.integrated.common import docker_base as ctn_base from . import base class BgpSpeakerBasicTest(base.BgpSpeakerTestBase): def setUp(self): super().setUp() self.r1.stop_os_kenbgp(retry=True) self.r1.start_os_kenbgp(retry=True) def test_check_neighbor_established(self): neighbor_state = ctn_base.BGP_FSM_IDLE for _ in range(0, self.checktime): neighbor_state = self.q1.get_neighbor_state(self.r1) if neighbor_state == ctn_base.BGP_FSM_ESTABLISHED: break time.sleep(1) self.assertEqual(neighbor_state, ctn_base.BGP_FSM_ESTABLISHED) def test_check_rib_nexthop(self): neighbor_state = ctn_base.BGP_FSM_IDLE for _ in range(0, self.checktime): neighbor_state = self.q1.get_neighbor_state(self.r1) if neighbor_state == ctn_base.BGP_FSM_ESTABLISHED: break time.sleep(1) self.assertEqual(neighbor_state, ctn_base.BGP_FSM_ESTABLISHED) rib = self.q1.get_global_rib(prefix='10.10.0.0/28') self.assertEqual(self.r1_ip, rib[0]['nexthop']) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/integrated/bgp/test_ip6_basic.py0000664000175000017500000000350500000000000023602 0ustar00zuulzuul00000000000000# Copyright (C) 2016 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2016 Fumihiko Kakuma # # 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. import time from os_ken.tests.integrated.common import docker_base as ctn_base from . import base_ip6 as base class BgpSpeakerBasicTest(base.BgpSpeakerTestBase): def setUp(self): super().setUp() self.r1.stop_os_kenbgp(retry=True) self.r1.start_os_kenbgp(retry=True) def test_check_neighbor_established(self): neighbor_state = ctn_base.BGP_FSM_IDLE for _ in range(0, self.checktime): neighbor_state = self.q1.get_neighbor_state(self.r1) if neighbor_state == ctn_base.BGP_FSM_ESTABLISHED: break time.sleep(1) self.assertEqual(neighbor_state, ctn_base.BGP_FSM_ESTABLISHED) def test_check_rib_nexthop(self): neighbor_state = ctn_base.BGP_FSM_IDLE for _ in range(0, self.checktime): neighbor_state = self.q1.get_neighbor_state(self.r1) if neighbor_state == ctn_base.BGP_FSM_ESTABLISHED: break time.sleep(1) self.assertEqual(neighbor_state, ctn_base.BGP_FSM_ESTABLISHED) rib = self.q1.get_global_rib(prefix='fc00:10::/64', rf='ipv6') self.assertEqual(self.r1_ip, rib[0]['nexthop']) ././@PaxHeader0000000000000000000000000000003300000000000011451 xustar000000000000000027 mtime=1724334546.130107 os-ken-2.10.0/os_ken/tests/integrated/common/0000775000175000017500000000000000000000000021047 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/integrated/common/__init__.py0000664000175000017500000000000000000000000023146 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/integrated/common/docker_base.py0000664000175000017500000006665400000000000023703 0ustar00zuulzuul00000000000000# Copyright (C) 2015 Nippon Telegraph and Telephone Corporation. # # This is based on the following # https://github.com/osrg/gobgp/test/lib/base.py # # 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. import itertools import logging import os import re import subprocess import time import netaddr LOG = logging.getLogger(__name__) DEFAULT_TEST_PREFIX = '' DEFAULT_TEST_BASE_DIR = '/tmp/ctn_docker/bgp' TEST_PREFIX = DEFAULT_TEST_PREFIX TEST_BASE_DIR = DEFAULT_TEST_BASE_DIR BGP_FSM_IDLE = 'BGP_FSM_IDLE' BGP_FSM_ACTIVE = 'BGP_FSM_ACTIVE' BGP_FSM_ESTABLISHED = 'BGP_FSM_ESTABLISHED' BGP_ATTR_TYPE_ORIGIN = 1 BGP_ATTR_TYPE_AS_PATH = 2 BGP_ATTR_TYPE_NEXT_HOP = 3 BGP_ATTR_TYPE_MULTI_EXIT_DISC = 4 BGP_ATTR_TYPE_LOCAL_PREF = 5 BGP_ATTR_TYPE_COMMUNITIES = 8 BGP_ATTR_TYPE_ORIGINATOR_ID = 9 BGP_ATTR_TYPE_CLUSTER_LIST = 10 BGP_ATTR_TYPE_MP_REACH_NLRI = 14 BGP_ATTR_TYPE_EXTENDED_COMMUNITIES = 16 BRIDGE_TYPE_DOCKER = 'docker' BRIDGE_TYPE_BRCTL = 'brctl' BRIDGE_TYPE_OVS = 'ovs' class CommandError(Exception): def __init__(self, out): super(CommandError, self).__init__() self.out = out def try_several_times(f, t=3, s=1): e = RuntimeError() for _ in range(t): try: r = f() except RuntimeError as e: time.sleep(s) else: return r raise e class CmdBuffer(list): def __init__(self, delim='\n'): super(CmdBuffer, self).__init__() self.delim = delim def __lshift__(self, value): self.append(value) def __str__(self): return self.delim.join(self) class CommandOut(str): def __new__(cls, stdout, stderr, command, returncode, **kwargs): stdout = stdout or '' obj = super(CommandOut, cls).__new__(cls, stdout, **kwargs) obj.stderr = stderr or '' obj.command = command obj.returncode = returncode return obj class Command(object): def _execute(self, cmd, capture=False, executable=None): """Execute a command using subprocess.Popen() :Parameters: - out: stdout from subprocess.Popen() out has some attributes. out.returncode: returncode of subprocess.Popen() out.stderr: stderr from subprocess.Popen() """ if capture: p_stdout = subprocess.PIPE p_stderr = subprocess.PIPE else: p_stdout = None p_stderr = None pop = subprocess.Popen(cmd, shell=True, executable=executable, stdout=p_stdout, stderr=p_stderr) __stdout, __stderr = pop.communicate() _stdout = str(__stdout, 'utf-8') _stderr = str(__stderr, 'utf-8') out = CommandOut(_stdout, _stderr, cmd, pop.returncode) return out def execute(self, cmd, capture=True, try_times=1, interval=1): out = None for i in range(try_times): out = self._execute(cmd, capture=capture) LOG.info(out.command) if out.returncode == 0: return out LOG.error("stdout: %s", out) LOG.error("stderr: %s", out.stderr) if i + 1 >= try_times: break time.sleep(interval) raise CommandError(out) def sudo(self, cmd, capture=True, try_times=1, interval=1): cmd = 'sudo %s' % cmd return self.execute(cmd, capture=capture, try_times=try_times, interval=interval) class DockerImage(object): def __init__(self, baseimage='ubuntu:20.04'): self.baseimage = baseimage self.cmd = Command() def get_images(self): out = self.cmd.sudo('docker images') images = [] for line in out.splitlines()[1:]: images.append(line.split()[0]) return images def exist(self, name): return name in self.get_images() def build(self, tagname, dockerfile_dir): self.cmd.sudo( "docker build -t {0} {1}".format(tagname, dockerfile_dir), try_times=3) def remove(self, tagname, check_exist=False): if check_exist and not self.exist(tagname): return tagname self.cmd.sudo("docker rmi -f %s" % tagname, try_times=3) def create_quagga(self, tagname='quagga', image=None, check_exist=False): if check_exist and self.exist(tagname): return tagname workdir = os.path.join(TEST_BASE_DIR, tagname) pkges = ' '.join([ 'telnet', 'tcpdump', 'quagga-bgpd', ]) if image: use_image = image else: use_image = self.baseimage c = CmdBuffer() c << 'FROM %s' % use_image c << 'RUN apt-get update' c << 'RUN apt-get install -qy --no-install-recommends %s' % pkges c << 'RUN echo "#!/bin/sh" > /bgpd' c << 'RUN echo mkdir -p /run/quagga >> /bgpd' c << 'RUN echo chmod 755 /run/quagga >> /bgpd' c << 'RUN echo chown quagga:quagga /run/quagga >> /bgpd' c << 'RUN echo exec /usr/sbin/bgpd >> /bgpd' c << 'RUN chmod +x /bgpd' c << 'CMD /bgpd' self.cmd.sudo('rm -rf %s' % workdir) self.cmd.execute('mkdir -p %s' % workdir) self.cmd.execute("echo '%s' > %s/Dockerfile" % (str(c), workdir)) self.build(tagname, workdir) return tagname def create_os_ken(self, tagname='os_ken', image=None, check_exist=False): if check_exist and self.exist(tagname): return tagname workdir = os.path.join(TEST_BASE_DIR, tagname) workdir_ctn = '/root/osrg/os_ken' pkges = ' '.join([ 'tcpdump', 'iproute2', ]) if image: use_image = image else: use_image = self.baseimage c = CmdBuffer() c << 'FROM %s' % use_image c << 'ADD os_ken %s' % workdir_ctn install = ' '.join([ 'RUN apt-get update', '&& apt-get install -qy --no-install-recommends %s' % pkges, '&& cd %s' % workdir_ctn, # Note: Clean previous builds, because "python setup.py install" # might fail if the current directory contains the symlink to # Docker host file systems. '&& rm -rf *.egg-info/ build/ dist/ .tox/ *.log' '&& pip install -r requirements.txt -r test-requirements.txt', '&& pip install .', ]) c << install self.cmd.sudo('rm -rf %s' % workdir) self.cmd.execute('mkdir -p %s' % workdir) self.cmd.execute("echo '%s' > %s/Dockerfile" % (str(c), workdir)) self.cmd.execute('cp -r ../os_ken %s/' % workdir) self.build(tagname, workdir) return tagname class Bridge(object): def __init__(self, name, subnet='', start_ip=None, end_ip=None, with_ip=True, self_ip=False, fixed_ip=None, reuse=False, br_type='docker'): """Manage a bridge :Parameters: - name: bridge name - subnet: network cider to be used in this bridge - start_ip: start address of an ip to be used in the subnet - end_ip: end address of an ip to be used in the subnet - with_ip: specify if assign automatically an ip address - self_ip: specify if assign an ip address for the bridge - fixed_ip: an ip address to be assigned to the bridge - reuse: specify if use an existing bridge - br_type: One either in a 'docker', 'brctl' or 'ovs' """ self.cmd = Command() self.name = name if br_type not in (BRIDGE_TYPE_DOCKER, BRIDGE_TYPE_BRCTL, BRIDGE_TYPE_OVS): raise Exception("argument error br_type: %s" % br_type) self.br_type = br_type self.docker_nw = bool(self.br_type == BRIDGE_TYPE_DOCKER) if TEST_PREFIX != '': self.name = '{0}_{1}'.format(TEST_PREFIX, name) self.with_ip = with_ip if with_ip: self.subnet = netaddr.IPNetwork(subnet) if start_ip: self.start_ip = start_ip else: self.start_ip = netaddr.IPAddress(self.subnet.first) if end_ip: self.end_ip = end_ip else: self.end_ip = netaddr.IPAddress(self.subnet.last) def _ip_gen(): for host in netaddr.IPRange(self.start_ip, self.end_ip): yield host self._ip_generator = _ip_gen() # throw away first network address self.next_ip_address() self.self_ip = self_ip if fixed_ip: self.ip_addr = fixed_ip else: self.ip_addr = self.next_ip_address() if not reuse: def f(): if self.br_type == BRIDGE_TYPE_DOCKER: gw = "--gateway %s" % self.ip_addr.split('/')[0] v6 = '' if self.subnet.version == 6: v6 = '--ipv6' cmd = ("docker network create --driver bridge %s " "%s --subnet %s %s" % (v6, gw, subnet, self.name)) elif self.br_type == BRIDGE_TYPE_BRCTL: cmd = "ip link add {0} type bridge".format(self.name) elif self.br_type == BRIDGE_TYPE_OVS: cmd = "ovs-vsctl add-br {0}".format(self.name) else: raise ValueError('Unsupported br_type: %s' % self.br_type) self.delete() self.execute(cmd, sudo=True, retry=True) try_several_times(f) if not self.docker_nw: self.execute("ip link set up dev {0}".format(self.name), sudo=True, retry=True) if not self.docker_nw and self_ip: ips = self.check_br_addr(self.name) for key, ip in ips.items(): if self.subnet.version == key: self.execute( "ip addr del {0} dev {1}".format(ip, self.name), sudo=True, retry=True) self.execute( "ip addr add {0} dev {1}".format(self.ip_addr, self.name), sudo=True, retry=True) self.ctns = [] def get_bridges_dc(self): out = self.execute('docker network ls', sudo=True, retry=True) bridges = [] for line in out.splitlines()[1:]: bridges.append(line.split()[1]) return bridges def get_bridges_brctl(self): br_list = [] bridges = glob.glob('/sys/class/net/*/bridge/bridge_id') regex = re.compile(r"\/sys\/class\/net\/(.+)\/bridge\/bridge_id") for bridge in bridges: m = regex.match(bridge) br_list.append(m.group(1)) return br_list def get_bridges_ovs(self): out = self.execute('ovs-vsctl list-br', sudo=True, retry=True) return out.splitlines() def get_bridges(self): if self.br_type == BRIDGE_TYPE_DOCKER: return self.get_bridges_dc() elif self.br_type == BRIDGE_TYPE_BRCTL: return self.get_bridges_brctl() elif self.br_type == BRIDGE_TYPE_OVS: return self.get_bridges_ovs() def exist(self): return self.name in self.get_bridges() def execute(self, cmd, capture=True, sudo=False, retry=False): if sudo: m = self.cmd.sudo else: m = self.cmd.execute if retry: return m(cmd, capture=capture, try_times=3, interval=1) else: return m(cmd, capture=capture) def check_br_addr(self, br): ips = {} cmd = "ip a show dev %s" % br for line in self.execute(cmd, sudo=True).split('\n'): if line.strip().startswith("inet "): elems = [e.strip() for e in line.strip().split(' ')] ips[4] = elems[1] elif line.strip().startswith("inet6 "): elems = [e.strip() for e in line.strip().split(' ')] ips[6] = elems[1] return ips def next_ip_address(self): return "{0}/{1}".format(next(self._ip_generator), self.subnet.prefixlen) def addif(self, ctn): name = ctn.next_if_name() self.ctns.append(ctn) ip_address = None if self.docker_nw: ipv4 = None ipv6 = None ip_address = self.next_ip_address() ip_address_ip = ip_address.split('/')[0] version = 4 if netaddr.IPNetwork(ip_address).version == 6: version = 6 opt_ip = "--ip %s" % ip_address_ip if version == 4: ipv4 = ip_address else: opt_ip = "--ip6 %s" % ip_address_ip ipv6 = ip_address cmd = "docker network connect %s %s %s" % ( opt_ip, self.name, ctn.docker_name()) self.execute(cmd, sudo=True) ctn.set_addr_info(bridge=self.name, ipv4=ipv4, ipv6=ipv6, ifname=name) else: if self.with_ip: ip_address = self.next_ip_address() version = 4 if netaddr.IPNetwork(ip_address).version == 6: version = 6 ctn.pipework(self, ip_address, name, version=version) else: ctn.pipework(self, '0/0', name) return ip_address def delete(self, check_exist=True): if check_exist: if not self.exist(): return if self.br_type == BRIDGE_TYPE_DOCKER: self.execute("docker network rm %s" % self.name, sudo=True, retry=True) elif self.br_type == BRIDGE_TYPE_BRCTL: self.execute("ip link set down dev %s" % self.name, sudo=True, retry=True) self.execute( "ip link delete %s type bridge" % self.name, sudo=True, retry=True) elif self.br_type == BRIDGE_TYPE_OVS: self.execute( "ovs-vsctl del-br %s" % self.name, sudo=True, retry=True) class Container(object): def __init__(self, name, image=None): self.name = name self.image = image self.shared_volumes = [] self.ip_addrs = [] self.ip6_addrs = [] self.is_running = False self.eths = [] self.id = None self.cmd = Command() self.remove() def docker_name(self): if TEST_PREFIX == DEFAULT_TEST_PREFIX: return self.name return '{0}_{1}'.format(TEST_PREFIX, self.name) def get_docker_id(self): if self.id: return self.id else: return self.docker_name() def next_if_name(self): name = 'eth{0}'.format(len(self.eths) + 1) self.eths.append(name) return name def set_addr_info(self, bridge, ipv4=None, ipv6=None, ifname='eth0'): if ipv4: self.ip_addrs.append((ifname, ipv4, bridge)) if ipv6: self.ip6_addrs.append((ifname, ipv6, bridge)) def get_addr_info(self, bridge, ipv=4): addrinfo = {} if ipv == 4: ip_addrs = self.ip_addrs elif ipv == 6: ip_addrs = self.ip6_addrs else: return None for addr in ip_addrs: if addr[2] == bridge: addrinfo[addr[1]] = addr[0] return addrinfo def execute(self, cmd, capture=True, sudo=False, retry=False): if sudo: m = self.cmd.sudo else: m = self.cmd.execute if retry: return m(cmd, capture=capture, try_times=3, interval=1) else: return m(cmd, capture=capture) def dcexec(self, cmd, capture=True, retry=False): if retry: return self.cmd.sudo(cmd, capture=capture, try_times=3, interval=1) else: return self.cmd.sudo(cmd, capture=capture) def exec_on_ctn(self, cmd, capture=True, detach=False): name = self.docker_name() flag = '-d' if detach else '' return self.dcexec('docker exec {0} {1} {2}'.format( flag, name, cmd), capture=capture) def get_containers(self, allctn=False): cmd = 'docker ps --no-trunc=true' if allctn: cmd += ' --all=true' out = self.dcexec(cmd, retry=True) containers = [] for line in out.splitlines()[1:]: containers.append(line.split()[-1]) return containers def exist(self, allctn=False): return self.docker_name() in self.get_containers(allctn=allctn) def run(self): c = CmdBuffer(' ') c << "docker run --privileged=true" for sv in self.shared_volumes: c << "-v {0}:{1}".format(sv[0], sv[1]) c << "--name {0} --hostname {0} -id {1}".format(self.docker_name(), self.image) self.id = self.dcexec(str(c), retry=True) self.is_running = True self.exec_on_ctn("ip li set up dev lo") ipv4 = None ipv6 = None for line in self.exec_on_ctn("ip a show dev eth0").split('\n'): if line.strip().startswith("inet "): elems = [e.strip() for e in line.strip().split(' ')] ipv4 = elems[1] elif line.strip().startswith("inet6 "): elems = [e.strip() for e in line.strip().split(' ')] ipv6 = elems[1] self.set_addr_info(bridge='docker0', ipv4=ipv4, ipv6=ipv6, ifname='eth0') return 0 def stop(self, check_exist=True): if check_exist: if not self.exist(allctn=False): return ctn_id = self.get_docker_id() out = self.dcexec('docker stop -t 0 %s' % ctn_id, retry=True) self.is_running = False return out def remove(self, check_exist=True): if check_exist: if not self.exist(allctn=True): return ctn_id = self.get_docker_id() out = self.dcexec('docker rm -f %s' % ctn_id, retry=True) self.is_running = False return out def pipework(self, bridge, ip_addr, intf_name="", version=4): if not self.is_running: LOG.warning('Call run() before pipeworking') return c = CmdBuffer(' ') c << "pipework {0}".format(bridge.name) if intf_name != "": c << "-i {0}".format(intf_name) else: intf_name = "eth1" ipv4 = None ipv6 = None if version == 4: ipv4 = ip_addr else: c << '-a 6' ipv6 = ip_addr c << "{0} {1}".format(self.docker_name(), ip_addr) self.set_addr_info(bridge=bridge.name, ipv4=ipv4, ipv6=ipv6, ifname=intf_name) self.execute(str(c), sudo=True, retry=True) def get_pid(self): if self.is_running: cmd = "docker inspect -f '{{.State.Pid}}' %s" % self.docker_name() return int(self.dcexec(cmd)) return -1 def start_tcpdump(self, interface=None, filename=None): if not interface: interface = "eth0" if not filename: filename = "{0}/{1}.dump".format( self.shared_volumes[0][1], interface) self.exec_on_ctn( "tcpdump -i {0} -w {1}".format(interface, filename), detach=True) class BGPContainer(Container): WAIT_FOR_BOOT = 1 RETRY_INTERVAL = 5 DEFAULT_PEER_ARG = {'neigh_addr': '', 'passwd': None, 'vpn': False, 'flowspec': False, 'is_rs_client': False, 'is_rr_client': False, 'cluster_id': None, 'policies': None, 'passive': False, 'local_addr': '', 'as2': False, 'graceful_restart': None, 'local_as': None, 'prefix_limit': None} default_peer_keys = sorted(DEFAULT_PEER_ARG.keys()) DEFAULT_ROUTE_ARG = {'prefix': None, 'rf': 'ipv4', 'attr': None, 'next-hop': None, 'as-path': None, 'community': None, 'med': None, 'local-pref': None, 'extended-community': None, 'matchs': None, 'thens': None} default_route_keys = sorted(DEFAULT_ROUTE_ARG.keys()) def __init__(self, name, asn, router_id, ctn_image_name=None): self.config_dir = TEST_BASE_DIR if TEST_PREFIX: self.config_dir = os.path.join(self.config_dir, TEST_PREFIX) self.config_dir = os.path.join(self.config_dir, name) self.asn = asn self.router_id = router_id self.peers = {} self.routes = {} self.policies = {} super(BGPContainer, self).__init__(name, ctn_image_name) self.execute( 'rm -rf {0}'.format(self.config_dir), sudo=True) self.execute('mkdir -p {0}'.format(self.config_dir)) self.execute('chmod 777 {0}'.format(self.config_dir)) def __repr__(self): return str({'name': self.name, 'asn': self.asn, 'router_id': self.router_id}) def run(self, wait=False, w_time=WAIT_FOR_BOOT): self.create_config() super(BGPContainer, self).run() if wait: time.sleep(w_time) return w_time def add_peer(self, peer, bridge='', reload_config=True, v6=False, peer_info=None): peer_info = peer_info or {} self.peers[peer] = self.DEFAULT_PEER_ARG.copy() self.peers[peer].update(peer_info) peer_keys = sorted(self.peers[peer].keys()) if peer_keys != self.default_peer_keys: raise Exception("argument error peer_info: %s" % peer_info) neigh_addr = '' local_addr = '' it = itertools.product(self.ip_addrs, peer.ip_addrs) if v6: it = itertools.product(self.ip6_addrs, peer.ip6_addrs) for me, you in it: if bridge != '' and bridge != me[2]: continue if me[2] == you[2]: neigh_addr = you[1] local_addr = me[1] if v6: addr, mask = local_addr.split('/') local_addr = "{0}%{1}/{2}".format(addr, me[0], mask) break if neigh_addr == '': raise Exception('peer {0} seems not ip reachable'.format(peer)) if not self.peers[peer]['policies']: self.peers[peer]['policies'] = {} self.peers[peer]['neigh_addr'] = neigh_addr self.peers[peer]['local_addr'] = local_addr if self.is_running and reload_config: self.create_config() self.reload_config() def del_peer(self, peer, reload_config=True): del self.peers[peer] if self.is_running and reload_config: self.create_config() self.reload_config() def disable_peer(self, peer): raise NotImplementedError() def enable_peer(self, peer): raise NotImplementedError() def log(self): return self.execute('cat {0}/*.log'.format(self.config_dir)) def add_route(self, route, reload_config=True, route_info=None): route_info = route_info or {} self.routes[route] = self.DEFAULT_ROUTE_ARG.copy() self.routes[route].update(route_info) route_keys = sorted(self.routes[route].keys()) if route_keys != self.default_route_keys: raise Exception("argument error route_info: %s" % route_info) self.routes[route]['prefix'] = route if self.is_running and reload_config: self.create_config() self.reload_config() def add_policy(self, policy, peer, typ, default='accept', reload_config=True): self.set_default_policy(peer, typ, default) self.define_policy(policy) self.assign_policy(peer, policy, typ) if self.is_running and reload_config: self.create_config() self.reload_config() def set_default_policy(self, peer, typ, default): if (typ in ['in', 'out', 'import', 'export'] and default in ['reject', 'accept']): if 'default-policy' not in self.peers[peer]: self.peers[peer]['default-policy'] = {} self.peers[peer]['default-policy'][typ] = default else: raise Exception('wrong type or default') def define_policy(self, policy): self.policies[policy['name']] = policy def assign_policy(self, peer, policy, typ): if peer not in self.peers: raise Exception('peer {0} not found'.format(peer.name)) name = policy['name'] if name not in self.policies: raise Exception('policy {0} not found'.format(name)) self.peers[peer]['policies'][typ] = policy def get_local_rib(self, peer, rf): raise NotImplementedError() def get_global_rib(self, rf): raise NotImplementedError() def get_neighbor_state(self, peer_id): raise NotImplementedError() def get_reachablily(self, prefix, timeout=20): version = netaddr.IPNetwork(prefix).version addr = prefix.split('/')[0] if version == 4: ping_cmd = 'ping' elif version == 6: ping_cmd = 'ping6' else: raise Exception( 'unsupported route family: {0}'.format(version)) cmd = '/bin/bash -c "/bin/{0} -c 1 -w 1 {1} | xargs echo"'.format( ping_cmd, addr) interval = 1 count = 0 while True: res = self.exec_on_ctn(cmd) LOG.info(res) if '1 packets received' in res and '0% packet loss': break time.sleep(interval) count += interval if count >= timeout: raise Exception('timeout') return True def wait_for(self, expected_state, peer, timeout=120): interval = 1 count = 0 while True: state = self.get_neighbor_state(peer) LOG.info("%s's peer %s state: %s", self.router_id, peer.router_id, state) if state == expected_state: return time.sleep(interval) count += interval if count >= timeout: raise Exception('timeout') def add_static_route(self, network, next_hop): cmd = '/sbin/ip route add {0} via {1}'.format(network, next_hop) self.exec_on_ctn(cmd) def set_ipv6_forward(self): cmd = 'sysctl -w net.ipv6.conf.all.forwarding=1' self.exec_on_ctn(cmd) def create_config(self): raise NotImplementedError() def reload_config(self): raise NotImplementedError() ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/integrated/common/install_docker_test_pkg.sh0000664000175000017500000000221000000000000026273 0ustar00zuulzuul00000000000000#!/bin/bash set -ex OSKEN_PATH=`dirname $0` source ${OSKEN_PATH}/install_docker_test_pkg_common.sh function add_docker_aptline { sudo apt-get update if ! apt-cache search docker-engine | grep docker-engine; then VER=`lsb_release -r` if echo $VER | grep 12.04; then REL_NAME=precise elif echo $VER | grep 14.04; then REL_NAME=trusty elif echo $VER | grep 15.10; then REL_NAME=wily elif echo $VER | grep 16.04; then REL_NAME=xenial else retrun 1 fi RELEASE=ubuntu-$REL_NAME sudo apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D sudo sh -c "echo deb https://apt.dockerproject.org/repo $RELEASE main > /etc/apt/sources.list.d/docker.list" fi } init_variables process_options "$@" if [ $APTLINE_DOCKER -eq 1 ]; then add_docker_aptline fi sudo apt-get update if apt-cache search docker-engine | grep docker-engine; then DOCKER_PKG=docker-engine else DOCKER_PKG=docker.io fi sudo apt-get install -y $DOCKER_PKG install_depends_pkg ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/integrated/common/install_docker_test_pkg_common.sh0000664000175000017500000000144700000000000027656 0ustar00zuulzuul00000000000000#!/bin/bash set -ex function init_variables { APTLINE_DOCKER=0 DIR_BASE=/tmp } function process_options { local max local i max=$# i=1 while [ $i -le $max ]; do case "$1" in -a|--add-docker-aptline) APTLINE_DOCKER=1 ;; -d|--download-dir) shift; ((i++)) DIR_BASE=$1 ;; esac shift; ((i++)) done } function install_pipework { if ! which /usr/local/bin/pipework >/dev/null then sudo rm -rf $DIR_BASE/pipework git clone https://github.com/jpetazzo/pipework.git $DIR_BASE/pipework sudo install -m 0755 $DIR_BASE/pipework/pipework /usr/local/bin/pipework fi } function install_depends_pkg { install_pipework } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/integrated/common/install_docker_test_pkg_for_travis.sh0000664000175000017500000000026400000000000030540 0ustar00zuulzuul00000000000000#!/bin/bash set -ex OSKEN_PATH=`dirname $0` source ${OSKEN_PATH}/install_docker_test_pkg_common.sh init_variables process_options "$@" sudo apt-get update install_depends_pkg ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/integrated/common/oskenbgp.py0000664000175000017500000001526600000000000023243 0ustar00zuulzuul00000000000000# Copyright (C) 2016 Nippon Telegraph and Telephone 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. import logging import os import time from . import docker_base as base LOG = logging.getLogger(__name__) class OSKenBGPContainer(base.BGPContainer): WAIT_FOR_BOOT = 1 SHARED_VOLUME = '/etc/os_ken' def __init__(self, name, asn, router_id, ctn_image_name): super(OSKenBGPContainer, self).__init__(name, asn, router_id, ctn_image_name) self.OSKEN_CONF = os.path.join(self.config_dir, 'os_ken.conf') self.SHARED_OSKEN_CONF = os.path.join(self.SHARED_VOLUME, 'os_ken.conf') self.SHARED_BGP_CONF = os.path.join(self.SHARED_VOLUME, 'bgp_conf.py') self.shared_volumes.append((self.config_dir, self.SHARED_VOLUME)) def _create_config_os_ken(self): c = base.CmdBuffer() c << '[DEFAULT]' c << 'verbose=True' c << 'log_file=/etc/os_ken/manager.log' with open(self.OSKEN_CONF, 'w') as f: LOG.info("[%s's new config]" % self.name) LOG.info(str(c)) f.writelines(str(c)) def _create_config_os_ken_bgp(self): c = base.CmdBuffer() c << 'import os' c << '' c << 'BGP = {' c << " 'local_as': %s," % str(self.asn) c << " 'router_id': '%s'," % self.router_id c << " 'neighbors': [" c << " {" for peer, info in self.peers.items(): n_addr = info['neigh_addr'].split('/')[0] c << " 'address': '%s'," % n_addr c << " 'remote_as': %s," % str(peer.asn) c << " 'enable_ipv4': True," c << " 'enable_ipv6': True," c << " 'enable_vpnv4': True," c << " 'enable_vpnv6': True," c << ' },' c << ' ],' c << " 'routes': [" for route in self.routes.values(): c << " {" c << " 'prefix': '%s'," % route['prefix'] c << " }," c << " ]," c << "}" log_conf = """LOGGING = { # We use python logging package for logging. 'version': 1, 'disable_existing_loggers': False, 'formatters': { 'verbose': { 'format': '%(levelname)s %(asctime)s %(module)s ' + '[%(process)d %(thread)d] %(message)s' }, 'simple': { 'format': '%(levelname)s %(asctime)s %(module)s %(lineno)s ' + '%(message)s' }, 'stats': { 'format': '%(message)s' }, }, 'handlers': { # Outputs log to console. 'console': { 'level': 'DEBUG', 'class': 'logging.StreamHandler', 'formatter': 'simple' }, 'console_stats': { 'level': 'DEBUG', 'class': 'logging.StreamHandler', 'formatter': 'stats' }, # Rotates log file when its size reaches 10MB. 'log_file': { 'level': 'DEBUG', 'class': 'logging.handlers.RotatingFileHandler', 'filename': os.path.join('.', 'bgpspeaker.log'), 'maxBytes': '10000000', 'formatter': 'verbose' }, 'stats_file': { 'level': 'DEBUG', 'class': 'logging.handlers.RotatingFileHandler', 'filename': os.path.join('.', 'statistics_bgps.log'), 'maxBytes': '10000000', 'formatter': 'stats' }, }, # Fine-grained control of logging per instance. 'loggers': { 'bgpspeaker': { 'handlers': ['console', 'log_file'], 'handlers': ['console'], 'level': 'DEBUG', 'propagate': False, }, 'stats': { 'handlers': ['stats_file', 'console_stats'], 'level': 'INFO', 'propagate': False, 'formatter': 'stats', }, }, # Root loggers. 'root': { 'handlers': ['console', 'log_file'], 'level': 'DEBUG', 'propagate': True, }, }""" c << log_conf with open(os.path.join(self.config_dir, 'bgp_conf.py'), 'w') as f: LOG.info("[%s's new config]", self.name) LOG.info(str(c)) f.writelines(str(c)) def create_config(self): self._create_config_os_ken() self._create_config_os_ken_bgp() def is_running_os_ken(self): results = self.exec_on_ctn('ps ax') running = False for line in results.split('\n')[1:]: if 'osken-manager' in line: running = True return running def start_os_kenbgp(self, check_running=True, retry=False): if check_running: if self.is_running_os_ken(): return True result = False if retry: try_times = 3 else: try_times = 1 cmd = "osken-manager --verbose " cmd += "--config-file %s " % self.SHARED_OSKEN_CONF cmd += "--bgp-app-config-file %s " % self.SHARED_BGP_CONF cmd += "os_ken.services.protocols.bgp.application" for _ in range(try_times): self.exec_on_ctn(cmd, detach=True) if self.is_running_os_ken(): result = True break time.sleep(1) return result def stop_os_kenbgp(self, check_running=True, retry=False): if check_running: if not self.is_running_os_ken(): return True result = False if retry: try_times = 3 else: try_times = 1 for _ in range(try_times): cmd = '/usr/bin/pkill osken-manager -SIGTERM' self.exec_on_ctn(cmd) if not self.is_running_os_ken(): result = True break time.sleep(1) return result def run(self, wait=False, w_time=WAIT_FOR_BOOT): w_time = super(OSKenBGPContainer, self).run(wait=wait, w_time=self.WAIT_FOR_BOOT) return w_time def reload_config(self): self.stop_os_kenbgp(retry=True) self.start_os_kenbgp(retry=True) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/integrated/common/quagga.py0000664000175000017500000002676400000000000022705 0ustar00zuulzuul00000000000000# Copyright (C) 2015 Nippon Telegraph and Telephone Corporation. # # This is based on the following # https://github.com/osrg/gobgp/test/lib/quagga.py # # 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. import logging import os import netaddr from . import docker_base as base LOG = logging.getLogger(__name__) class QuaggaBGPContainer(base.BGPContainer): WAIT_FOR_BOOT = 1 SHARED_VOLUME = '/etc/quagga' def __init__(self, name, asn, router_id, ctn_image_name, zebra=False): super(QuaggaBGPContainer, self).__init__(name, asn, router_id, ctn_image_name) self.shared_volumes.append((self.config_dir, self.SHARED_VOLUME)) self.zebra = zebra self._create_config_debian() def run(self, wait=False, w_time=WAIT_FOR_BOOT): w_time = super(QuaggaBGPContainer, self).run(wait=wait, w_time=self.WAIT_FOR_BOOT) return w_time def get_global_rib(self, prefix='', rf='ipv4'): rib = [] if prefix != '': return self.get_global_rib_with_prefix(prefix, rf) out = self.vtysh('show bgp {0} unicast'.format(rf), config=False) if out.startswith('No BGP network exists'): return rib read_next = False for line in out.split('\n'): ibgp = False if line[:2] == '*>': line = line[2:] if line[0] == 'i': line = line[1:] ibgp = True elif not read_next: continue elems = line.split() if len(elems) == 1: read_next = True prefix = elems[0] continue elif read_next: nexthop = elems[0] else: prefix = elems[0] nexthop = elems[1] read_next = False rib.append({'prefix': prefix, 'nexthop': nexthop, 'ibgp': ibgp}) return rib def get_global_rib_with_prefix(self, prefix, rf): rib = [] lines = [line.strip() for line in self.vtysh( 'show bgp {0} unicast {1}'.format(rf, prefix), config=False).split('\n')] if lines[0] == '% Network not in table': return rib lines = lines[2:] if lines[0].startswith('Not advertised'): lines.pop(0) # another useless line elif lines[0].startswith('Advertised to non peer-group peers:'): lines = lines[2:] # other useless lines else: raise Exception('unknown output format {0}'.format(lines)) if lines[0] == 'Local': aspath = [] else: aspath = [int(asn) for asn in lines[0].split()] nexthop = lines[1].split()[0].strip() info = [s.strip(',') for s in lines[2].split()] attrs = [] if 'metric' in info: med = info[info.index('metric') + 1] attrs.append({'type': base.BGP_ATTR_TYPE_MULTI_EXIT_DISC, 'metric': int(med)}) if 'localpref' in info: localpref = info[info.index('localpref') + 1] attrs.append({'type': base.BGP_ATTR_TYPE_LOCAL_PREF, 'value': int(localpref)}) rib.append({'prefix': prefix, 'nexthop': nexthop, 'aspath': aspath, 'attrs': attrs}) return rib def get_neighbor_state(self, peer): if peer not in self.peers: raise Exception('not found peer {0}'.format(peer.router_id)) neigh_addr = self.peers[peer]['neigh_addr'].split('/')[0] info = [l.strip() for l in self.vtysh( 'show bgp neighbors {0}'.format(neigh_addr), config=False).split('\n')] if not info[0].startswith('BGP neighbor is'): raise Exception('unknown format') idx1 = info[0].index('BGP neighbor is ') idx2 = info[0].index(',') n_addr = info[0][idx1 + len('BGP neighbor is '):idx2] if n_addr == neigh_addr: idx1 = info[2].index('= ') state = info[2][idx1 + len('= '):] if state.startswith('Idle'): return base.BGP_FSM_IDLE elif state.startswith('Active'): return base.BGP_FSM_ACTIVE elif state.startswith('Established'): return base.BGP_FSM_ESTABLISHED else: return state raise Exception('not found peer {0}'.format(peer.router_id)) def send_route_refresh(self): self.vtysh('clear ip bgp * soft', config=False) def create_config(self): zebra = 'no' self._create_config_bgp() if self.zebra: zebra = 'yes' self._create_config_zebra() self._create_config_daemons(zebra) def _create_config_debian(self): c = base.CmdBuffer() c << 'vtysh_enable=yes' c << 'zebra_options=" --daemon -A 127.0.0.1"' c << 'bgpd_options=" --daemon -A 127.0.0.1"' c << 'ospfd_options=" --daemon -A 127.0.0.1"' c << 'ospf6d_options=" --daemon -A ::1"' c << 'ripd_options=" --daemon -A 127.0.0.1"' c << 'ripngd_options=" --daemon -A ::1"' c << 'isisd_options=" --daemon -A 127.0.0.1"' c << 'babeld_options=" --daemon -A 127.0.0.1"' c << 'watchquagga_enable=yes' c << 'watchquagga_options=(--daemon)' with open('{0}/debian.conf'.format(self.config_dir), 'w') as f: LOG.info("[%s's new config]", self.name) LOG.info(str(c)) f.writelines(str(c)) def _create_config_daemons(self, zebra='no'): c = base.CmdBuffer() c << 'zebra=%s' % zebra c << 'bgpd=yes' c << 'ospfd=no' c << 'ospf6d=no' c << 'ripd=no' c << 'ripngd=no' c << 'isisd=no' c << 'babeld=no' with open('{0}/daemons'.format(self.config_dir), 'w') as f: LOG.info("[%s's new config]", self.name) LOG.info(str(c)) f.writelines(str(c)) def _create_config_bgp(self): c = base.CmdBuffer() c << 'hostname bgpd' c << 'password zebra' c << 'router bgp {0}'.format(self.asn) c << 'bgp router-id {0}'.format(self.router_id) if any(info['graceful_restart'] for info in self.peers.values()): c << 'bgp graceful-restart' version = 4 for peer, info in self.peers.items(): version = netaddr.IPNetwork(info['neigh_addr']).version n_addr = info['neigh_addr'].split('/')[0] if version == 6: c << 'no bgp default ipv4-unicast' c << 'neighbor {0} remote-as {1}'.format(n_addr, peer.asn) if info['is_rs_client']: c << 'neighbor {0} route-server-client'.format(n_addr) for typ, p in info['policies'].items(): c << 'neighbor {0} route-map {1} {2}'.format(n_addr, p['name'], typ) if info['passwd']: c << 'neighbor {0} password {1}'.format(n_addr, info['passwd']) if info['passive']: c << 'neighbor {0} passive'.format(n_addr) if version == 6: c << 'address-family ipv6 unicast' c << 'neighbor {0} activate'.format(n_addr) c << 'exit-address-family' for route in self.routes.values(): if route['rf'] == 'ipv4': c << 'network {0}'.format(route['prefix']) elif route['rf'] == 'ipv6': c << 'address-family ipv6 unicast' c << 'network {0}'.format(route['prefix']) c << 'exit-address-family' else: raise Exception( 'unsupported route faily: {0}'.format(route['rf'])) if self.zebra: if version == 6: c << 'address-family ipv6 unicast' c << 'redistribute connected' c << 'exit-address-family' else: c << 'redistribute connected' for name, policy in self.policies.items(): c << 'access-list {0} {1} {2}'.format(name, policy['type'], policy['match']) c << 'route-map {0} permit 10'.format(name) c << 'match ip address {0}'.format(name) c << 'set metric {0}'.format(policy['med']) c << 'debug bgp as4' c << 'debug bgp fsm' c << 'debug bgp updates' c << 'debug bgp events' c << 'log file {0}/bgpd.log'.format(self.SHARED_VOLUME) with open('{0}/bgpd.conf'.format(self.config_dir), 'w') as f: LOG.info("[%s's new config]", self.name) LOG.info(str(c)) f.writelines(str(c)) def _create_config_zebra(self): c = base.CmdBuffer() c << 'hostname zebra' c << 'password zebra' c << 'log file {0}/zebra.log'.format(self.SHARED_VOLUME) c << 'debug zebra packet' c << 'debug zebra kernel' c << 'debug zebra rib' c << '' with open('{0}/zebra.conf'.format(self.config_dir), 'w') as f: LOG.info("[%s's new config]", self.name) LOG.info(str(c)) f.writelines(str(c)) def vtysh(self, cmd, config=True): if not isinstance(cmd, list): cmd = [cmd] cmd = ' '.join("-c '{0}'".format(c) for c in cmd) if config: return self.exec_on_ctn( "vtysh -d bgpd -c 'en' -c 'conf t' -c " "'router bgp {0}' {1}".format(self.asn, cmd), capture=True) else: return self.exec_on_ctn("vtysh -d bgpd {0}".format(cmd), capture=True) def reload_config(self): daemon = [] daemon.append('bgpd') if self.zebra: daemon.append('zebra') for d in daemon: cmd = '/usr/bin/pkill {0} -SIGHUP'.format(d) self.exec_on_ctn(cmd, capture=True) class RawQuaggaBGPContainer(QuaggaBGPContainer): def __init__(self, name, config, ctn_image_name, zebra=False): asn = None router_id = None for line in config.split('\n'): line = line.strip() if line.startswith('router bgp'): asn = int(line[len('router bgp'):].strip()) if line.startswith('bgp router-id'): router_id = line[len('bgp router-id'):].strip() if not asn: raise Exception('asn not in quagga config') if not router_id: raise Exception('router-id not in quagga config') self.config = config super(RawQuaggaBGPContainer, self).__init__(name, asn, router_id, ctn_image_name, zebra) def create_config(self): with open(os.path.join(self.config_dir, 'bgpd.conf'), 'w') as f: LOG.info("[%s's new config]", self.name) LOG.info(self.config) f.writelines(self.config) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/integrated/run_test.py0000664000175000017500000000330500000000000021775 0ustar00zuulzuul00000000000000# Copyright (C) 2016 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2016 Fumihiko Kakuma # # 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. import logging import os import sys import unittest from os_ken import log def load_tests(loader, tests, pattern): dirname = os.path.dirname(os.path.abspath(__file__)) base_path = os.path.abspath(dirname + '/../../..') suite = unittest.TestSuite() for test_dir in ['os_ken/tests/integrated/bgp']: if not pattern: suite.addTests(loader.discover(test_dir, top_level_dir=base_path)) else: suite.addTests(loader.discover(test_dir, pattern=pattern, top_level_dir=base_path)) return suite if __name__ == '__main__': log.early_init_log(logging.DEBUG) log.init_log() LOG = logging.getLogger(__name__) pattern = None if len(sys.argv) == 2: pattern = sys.argv[1] loader = unittest.defaultTestLoader suite = load_tests(loader, None, pattern) res = unittest.TextTestRunner(verbosity=2).run(suite) ret = 0 if res.errors or res.failures: ret = 1 sys.exit(ret) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/integrated/run_tests_with_ovs12.py0000775000175000017500000000616400000000000024256 0ustar00zuulzuul00000000000000#!/usr/bin/env python3 # Copyright (C) 2013 Nippon Telegraph and Telephone 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. import unittest from subprocess import Popen, PIPE, STDOUT import time from mininet.net import Mininet from mininet.node import RemoteController, OVSKernelSwitch TIMEOUT = 60 OSKEN_HOST = '127.0.0.1' OSKEN_PORT = 6633 PYTHON_BIN = '.venv/bin/python' OSKEN_MGR = 'osken-manager' class OVS12KernelSwitch(OVSKernelSwitch): """Set protocols parameter for OVS version 1.10""" def start(self, controllers): super(OVS12KernelSwitch, self).start(controllers) self.cmd('ovs-vsctl set Bridge', self, "protocols='[OpenFlow10, OpenFlow12]'") class TestWithOVS12(unittest.TestCase): @classmethod def setUpClass(cls): cls.mn = Mininet() c = cls.mn.addController(controller=RemoteController, ip=OSKEN_HOST, port=OSKEN_PORT) c.start() s1 = cls.mn.addSwitch('s1', cls=OVS12KernelSwitch) s1.start(cls.mn.controllers) h1 = cls.mn.addHost('h1', ip='0.0.0.0/0') link = cls.mn.addLink(h1, s1) s1.attach(link.intf2) @classmethod def tearDownClass(cls): cls.mn.stop() def test_add_flow_v10(self): app = 'os_ken/tests/integrated/test_add_flow_v10.py' self._run_os_ken_manager_and_check_output(app) def test_request_reply_v12(self): app = 'os_ken/tests/integrated/test_request_reply_v12.py' self._run_os_ken_manager_and_check_output(app) def test_add_flow_v12_actions(self): app = 'os_ken/tests/integrated/test_add_flow_v12_actions.py' self._run_os_ken_manager_and_check_output(app) def test_add_flow_v12_matches(self): app = 'os_ken/tests/integrated/test_add_flow_v12_matches.py' self._run_os_ken_manager_and_check_output(app) def test_of_config(self): self.skipTest('OVS 1.10 does not support of_config') def _run_os_ken_manager_and_check_output(self, app): cmd = [PYTHON_BIN, OSKEN_MGR, app] p = Popen(cmd, stdout=PIPE, stderr=STDOUT) while True: if p.poll() is not None: raise Exception('Another osken-manager already running?') line = p.stdout.readline().strip() if line == '': time.sleep(1) continue print("osken-manager: %s" % line) if line.find('TEST_FINISHED') != -1: self.assertTrue(line.find('Completed=[True]') != -1) p.terminate() p.communicate() # wait for subprocess is terminated break ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/integrated/test_add_flow_v10.py0000664000175000017500000002104200000000000023434 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone 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. # vim: tabstop=4 shiftwidth=4 softtabstop=4 import logging from os_ken.tests.integrated import tester from os_ken.ofproto import ofproto_v1_0 from os_ken.ofproto import ether from os_ken.ofproto import nx_match LOG = logging.getLogger(__name__) class RunTest(tester.TestFlowBase): """ Test case for add flows of1.0 """ OFP_VERSIONS = [ofproto_v1_0.OFP_VERSION] def __init__(self, *args, **kwargs): super(RunTest, self).__init__(*args, **kwargs) self._verify = [] def add_action(self, dp, action): rule = nx_match.ClsRule() self.send_flow_mod( dp, rule, 0, dp.ofproto.OFPFC_ADD, 0, 0, None, 0xffffffff, None, dp.ofproto.OFPFF_SEND_FLOW_REM, action) def add_rule(self, dp, rule): self.send_flow_mod( dp, rule, 0, dp.ofproto.OFPFC_ADD, 0, 0, None, 0xffffffff, None, dp.ofproto.OFPFF_SEND_FLOW_REM, []) def send_flow_mod(self, dp, rule, cookie, command, idle_timeout, hard_timeout, priority=None, buffer_id=0xffffffff, out_port=None, flags=0, actions=None): if priority is None: priority = dp.ofproto.OFP_DEFAULT_PRIORITY if out_port is None: out_port = dp.ofproto.OFPP_NONE match_tuple = rule.match_tuple() match = dp.ofproto_parser.OFPMatch(*match_tuple) m = dp.ofproto_parser.OFPFlowMod( dp, match, cookie, command, idle_timeout, hard_timeout, priority, buffer_id, out_port, flags, actions) dp.send_msg(m) def _verify_action(self, actions, type_, name, value): try: action = actions[0] if action.cls_action_type != type_: return "Action type error. send:%s, val:%s" \ % (type_, action.cls_action_type) except IndexError: return "Action is not setting." f_value = None if name: try: if isinstance(name, list): f_value = [getattr(action, n) for n in name] else: f_value = getattr(action, name) except AttributeError: pass if f_value != value: return "Value error. send:%s=%s val:%s" \ % (name, value, f_value) return True def _verify_rule(self, rule, name, value): f_value = getattr(rule, name) if f_value != value: return "Value error. send:%s=%s val:%s" \ % (name, value, f_value) return True def verify_default(self, dp, stats): verify = self._verify self._verify = [] match = stats[0].match actions = stats[0].actions if len(verify) == 2: return self._verify_rule(match, *verify) elif len(verify) == 3: return self._verify_action(actions, *verify) else: return "self._verify is invalid." # Test of Actions def test_action_output(self, dp): out_port = 2 self._verify = [dp.ofproto.OFPAT_OUTPUT, 'port', out_port] action = dp.ofproto_parser.OFPActionOutput(out_port) self.add_action(dp, [action, ]) def test_action_vlan_vid(self, dp): vlan_vid = 2 self._verify = [dp.ofproto.OFPAT_SET_VLAN_VID, 'vlan_vid', vlan_vid] action = dp.ofproto_parser.OFPActionVlanVid(vlan_vid) self.add_action(dp, [action, ]) def test_action_vlan_pcp(self, dp): vlan_pcp = 4 self._verify = [dp.ofproto.OFPAT_SET_VLAN_PCP, 'vlan_pcp', vlan_pcp] action = dp.ofproto_parser.OFPActionVlanPcp(vlan_pcp) self.add_action(dp, [action, ]) def test_action_strip_vlan(self, dp): vlan_pcp = 4 self._verify = [dp.ofproto.OFPAT_STRIP_VLAN, None, None] action = dp.ofproto_parser.OFPActionStripVlan() self.add_action(dp, [action, ]) def test_action_set_dl_src(self, dp): dl_src = '56:b3:42:04:b2:7a' dl_src_bin = self.haddr_to_bin(dl_src) self._verify = [dp.ofproto.OFPAT_SET_DL_SRC, 'dl_addr', dl_src_bin] action = dp.ofproto_parser.OFPActionSetDlSrc(dl_src_bin) self.add_action(dp, [action, ]) def test_action_set_dl_dst(self, dp): dl_dst = 'c2:93:a2:fb:d0:f4' dl_dst_bin = self.haddr_to_bin(dl_dst) self._verify = [dp.ofproto.OFPAT_SET_DL_DST, 'dl_addr', dl_dst_bin] action = dp.ofproto_parser.OFPActionSetDlDst(dl_dst_bin) self.add_action(dp, [action, ]) def test_action_set_nw_src(self, dp): nw_src = '216.132.81.105' nw_src_int = self.ipv4_to_int(nw_src) self._verify = [dp.ofproto.OFPAT_SET_NW_SRC, 'nw_addr', nw_src_int] action = dp.ofproto_parser.OFPActionSetNwSrc(nw_src_int) self.add_action(dp, [action, ]) def test_action_set_nw_dst(self, dp): nw_dst = '223.201.206.3' nw_dst_int = self.ipv4_to_int(nw_dst) self._verify = [dp.ofproto.OFPAT_SET_NW_DST, 'nw_addr', nw_dst_int] action = dp.ofproto_parser.OFPActionSetNwDst(nw_dst_int) self.add_action(dp, [action, ]) def test_action_set_nw_tos(self, dp): # lowest two bits must be zero nw_tos = 1 << 2 self._verify = [dp.ofproto.OFPAT_SET_NW_TOS, 'tos', nw_tos] action = dp.ofproto_parser.OFPActionSetNwTos(nw_tos) self.add_action(dp, [action, ]) def test_action_set_tp_src(self, dp): tp_src = 55420 self._verify = [dp.ofproto.OFPAT_SET_TP_SRC, 'tp', tp_src] action = dp.ofproto_parser.OFPActionSetTpSrc(tp_src) self.add_action(dp, [action, ]) def test_action_set_tp_dst(self, dp): tp_dst = 15430 self._verify = [dp.ofproto.OFPAT_SET_TP_DST, 'tp', tp_dst] action = dp.ofproto_parser.OFPActionSetTpDst(tp_dst) self.add_action(dp, [action, ]) def test_action_enqueue(self, dp): port = 207 queue_id = 4287508753 self._verify = [dp.ofproto.OFPAT_ENQUEUE, ['port', 'queue_id'], [port, queue_id]] action = dp.ofproto_parser.OFPActionEnqueue(port, queue_id) self.add_action(dp, [action, ]) # Test of Rules def test_rule_set_in_port(self, dp): in_port = 32 self._verify = ['in_port', in_port] rule = nx_match.ClsRule() rule.set_in_port(in_port) self.add_rule(dp, rule) def test_rule_set_dl_src(self, dp): dl_src = 'b8:a1:94:51:78:83' dl_src_bin = self.haddr_to_bin(dl_src) self._verify = ['dl_src', dl_src_bin] rule = nx_match.ClsRule() rule.set_dl_src(dl_src_bin) self.add_rule(dp, rule) def test_rule_set_dl_type_ip(self, dp): dl_type = ether.ETH_TYPE_IP self._verify = ['dl_type', dl_type] rule = nx_match.ClsRule() rule.set_dl_type(dl_type) self.add_rule(dp, rule) def test_rule_set_dl_type_arp(self, dp): dl_type = ether.ETH_TYPE_ARP self._verify = ['dl_type', dl_type] rule = nx_match.ClsRule() rule.set_dl_type(dl_type) self.add_rule(dp, rule) def test_rule_set_dl_type_vlan(self, dp): dl_type = ether.ETH_TYPE_8021Q self._verify = ['dl_type', dl_type] rule = nx_match.ClsRule() rule.set_dl_type(dl_type) self.add_rule(dp, rule) def test_rule_set_dl_type_ipv6(self, dp): dl_type = ether.ETH_TYPE_IPV6 self._verify = ['dl_type', dl_type] rule = nx_match.ClsRule() rule.set_dl_type(dl_type) self.add_rule(dp, rule) def test_rule_set_dl_type_lacp(self, dp): dl_type = ether.ETH_TYPE_SLOW self._verify = ['dl_type', dl_type] rule = nx_match.ClsRule() rule.set_dl_type(dl_type) self.add_rule(dp, rule) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/integrated/test_add_flow_v12_actions.py0000664000175000017500000004056100000000000025165 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone 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. # vim: tabstop=4 shiftwidth=4 softtabstop=4 import logging from os_ken.ofproto import ofproto_v1_2 from os_ken.ofproto import ether from os_ken.ofproto import inet from os_ken.tests.integrated import tester LOG = logging.getLogger(__name__) class RunTest(tester.TestFlowBase): """ Test case for add flows of Actions """ OFP_VERSIONS = [ofproto_v1_2.OFP_VERSION] def __init__(self, *args, **kwargs): super(RunTest, self).__init__(*args, **kwargs) self._verify = [] def add_apply_actions(self, dp, actions, match=None): inst = [dp.ofproto_parser.OFPInstructionActions( dp.ofproto.OFPIT_APPLY_ACTIONS, actions)] if match is None: match = dp.ofproto_parser.OFPMatch() m = dp.ofproto_parser.OFPFlowMod(dp, 0, 0, 0, dp.ofproto.OFPFC_ADD, 0, 0, 0xff, 0xffffffff, dp.ofproto.OFPP_ANY, dp.ofproto.OFPG_ANY, 0, match, inst) dp.send_msg(m) def add_set_field_action(self, dp, field, value, match=None): self._verify = [dp.ofproto.OFPAT_SET_FIELD, 'field', field, value] f = dp.ofproto_parser.OFPMatchField.make(field, value) actions = [dp.ofproto_parser.OFPActionSetField(f), ] self.add_apply_actions(dp, actions, match=match) def verify_default(self, dp, stats): verify = self._verify self._verify = [] type_ = name = field = value = None if len(verify) == 1: (type_, ) = verify elif len(verify) == 3: (type_, name, value) = verify elif len(verify) == 4: (type_, name, field, value) = verify else: return "self._verify is invalid." try: action = stats[0].instructions[0].actions[0] if action.cls_action_type != type_: return "Action type error. send:%s, val:%s" \ % (type_, action.cls_action_type) except IndexError: return "Action is not setting." s_val = None if name: try: s_val = getattr(action, name) except AttributeError: pass if name == 'field': if s_val.header != field: return "Field error. send:%s val:%s" \ % (field, s_val.header) s_val = s_val.value if name and s_val != value: return "Value error. send:%s=%s val:%s" \ % (name, value, s_val) return True def verify_action_drop(self, dp, stats): for s in stats: for i in s.instructions: if len(i.actions): return "has actions. %s" % (i.actions) return True # Test of General Actions def test_action_output(self, dp): out_port = 255 self._verify = [dp.ofproto.OFPAT_OUTPUT, 'port', out_port] actions = [dp.ofproto_parser.OFPActionOutput(out_port, 0), ] self.add_apply_actions(dp, actions) def test_action_drop(self, dp): self.add_apply_actions(dp, []) # Test of Push-Tag/Pop-Tag Actions def test_action_push_vlan(self, dp): ethertype = ether.ETH_TYPE_8021Q self._verify = [dp.ofproto.OFPAT_PUSH_VLAN, 'ethertype', ethertype] actions = [dp.ofproto_parser.OFPActionPushVlan(ethertype)] self.add_apply_actions(dp, actions) def test_action_pop_vlan(self, dp): self._verify = [dp.ofproto.OFPAT_POP_VLAN, ] actions = [dp.ofproto_parser.OFPActionPopVlan(), ] match = dp.ofproto_parser.OFPMatch() match.set_vlan_vid(1) self.add_apply_actions(dp, actions, match) def test_action_push_mpls(self, dp): ethertype = ether.ETH_TYPE_MPLS self._verify = [dp.ofproto.OFPAT_PUSH_MPLS, 'ethertype', ethertype] actions = [dp.ofproto_parser.OFPActionPushMpls(ethertype), ] self.add_apply_actions(dp, actions) def test_action_pop_mpls(self, dp): ethertype = ether.ETH_TYPE_8021Q self._verify = [dp.ofproto.OFPAT_POP_MPLS, 'ethertype', ethertype] actions = [dp.ofproto_parser.OFPActionPopMpls(ethertype), ] match = dp.ofproto_parser.OFPMatch() match.set_dl_type(ether.ETH_TYPE_MPLS) self.add_apply_actions(dp, actions, match) # Test of Set-Filed Actions def test_action_set_field_dl_dst(self, dp): field = dp.ofproto.OXM_OF_ETH_DST dl_dst = 'e2:7a:09:79:0b:0f' value = self.haddr_to_bin(dl_dst) self.add_set_field_action(dp, field, value) def test_action_set_field_dl_src(self, dp): field = dp.ofproto.OXM_OF_ETH_SRC dl_src = '08:82:63:b6:62:05' value = self.haddr_to_bin(dl_src) self.add_set_field_action(dp, field, value) def test_action_set_field_dl_type(self, dp): field = dp.ofproto.OXM_OF_ETH_TYPE value = ether.ETH_TYPE_IPV6 self.add_set_field_action(dp, field, value) def test_action_set_field_vlan_vid(self, dp): field = dp.ofproto.OXM_OF_VLAN_VID value = 0x1e4 match = dp.ofproto_parser.OFPMatch() match.set_vlan_vid(1) self.add_set_field_action(dp, field, value, match) def test_action_set_field_vlan_pcp(self, dp): field = dp.ofproto.OXM_OF_VLAN_PCP value = 3 match = dp.ofproto_parser.OFPMatch() match.set_vlan_vid(1) self.add_set_field_action(dp, field, value, match) def test_action_set_field_nw_dscp(self, dp): field = dp.ofproto.OXM_OF_IP_DSCP value = 32 match = dp.ofproto_parser.OFPMatch() match.set_dl_type(ether.ETH_TYPE_IP) self.add_set_field_action(dp, field, value, match) def test_action_set_field_nw_ecn(self, dp): field = dp.ofproto.OXM_OF_IP_ECN value = 1 match = dp.ofproto_parser.OFPMatch() match.set_dl_type(ether.ETH_TYPE_IP) self.add_set_field_action(dp, field, value, match) def test_action_set_field_ip_proto(self, dp): field = dp.ofproto.OXM_OF_IP_PROTO value = inet.IPPROTO_TCP match = dp.ofproto_parser.OFPMatch() match.set_dl_type(ether.ETH_TYPE_IP) self.add_set_field_action(dp, field, value, match) def test_action_set_field_ipv4_src(self, dp): field = dp.ofproto.OXM_OF_IPV4_SRC ipv4_src = '192.168.3.92' value = self.ipv4_to_int(ipv4_src) match = dp.ofproto_parser.OFPMatch() match.set_dl_type(ether.ETH_TYPE_IP) self.add_set_field_action(dp, field, value, match) def test_action_set_field_ipv4_dst(self, dp): field = dp.ofproto.OXM_OF_IPV4_DST ipv4_dst = '192.168.74.122' value = self.ipv4_to_int(ipv4_dst) match = dp.ofproto_parser.OFPMatch() match.set_dl_type(ether.ETH_TYPE_IP) self.add_set_field_action(dp, field, value, match) def test_action_set_field_tcp_src(self, dp): field = dp.ofproto.OXM_OF_TCP_SRC value = 105 match = dp.ofproto_parser.OFPMatch() match.set_dl_type(ether.ETH_TYPE_IP) match.set_ip_proto(inet.IPPROTO_TCP) self.add_set_field_action(dp, field, value, match) def test_action_set_field_tcp_dst(self, dp): field = dp.ofproto.OXM_OF_TCP_DST value = 75 match = dp.ofproto_parser.OFPMatch() match.set_dl_type(ether.ETH_TYPE_IP) match.set_ip_proto(inet.IPPROTO_TCP) self.add_set_field_action(dp, field, value, match) def test_action_set_field_udp_src(self, dp): field = dp.ofproto.OXM_OF_UDP_SRC value = 197 match = dp.ofproto_parser.OFPMatch() match.set_dl_type(ether.ETH_TYPE_IP) match.set_ip_proto(inet.IPPROTO_UDP) self.add_set_field_action(dp, field, value, match) def test_action_set_field_udp_dst(self, dp): field = dp.ofproto.OXM_OF_UDP_DST value = 17 match = dp.ofproto_parser.OFPMatch() match.set_dl_type(ether.ETH_TYPE_IP) match.set_ip_proto(inet.IPPROTO_UDP) self.add_set_field_action(dp, field, value, match) def test_action_set_field_icmpv4_type(self, dp): field = dp.ofproto.OXM_OF_ICMPV4_TYPE value = 8 match = dp.ofproto_parser.OFPMatch() match.set_ip_proto(inet.IPPROTO_ICMP) self.add_set_field_action(dp, field, value, match) def test_action_set_field_icmpv4_code(self, dp): field = dp.ofproto.OXM_OF_ICMPV4_CODE value = 2 match = dp.ofproto_parser.OFPMatch() match.set_ip_proto(inet.IPPROTO_ICMP) self.add_set_field_action(dp, field, value, match) def test_action_set_field_arp_op(self, dp): field = dp.ofproto.OXM_OF_ARP_OP value = 2 match = dp.ofproto_parser.OFPMatch() match.set_dl_type(ether.ETH_TYPE_ARP) self.add_set_field_action(dp, field, value, match) def test_action_set_field_arp_spa(self, dp): field = dp.ofproto.OXM_OF_ARP_SPA nw_src = '192.168.132.179' value = self.ipv4_to_int(nw_src) match = dp.ofproto_parser.OFPMatch() match.set_dl_type(ether.ETH_TYPE_ARP) self.add_set_field_action(dp, field, value, match) def test_action_set_field_arp_tpa(self, dp): field = dp.ofproto.OXM_OF_ARP_TPA nw_dst = '192.168.118.85' value = self.ipv4_to_int(nw_dst) match = dp.ofproto_parser.OFPMatch() match.set_dl_type(ether.ETH_TYPE_ARP) self.add_set_field_action(dp, field, value, match) def test_action_set_field_arp_sha(self, dp): field = dp.ofproto.OXM_OF_ARP_SHA arp_sha = '50:29:e7:7f:6c:7f' value = self.haddr_to_bin(arp_sha) match = dp.ofproto_parser.OFPMatch() match.set_dl_type(ether.ETH_TYPE_ARP) self.add_set_field_action(dp, field, value, match) def test_action_set_field_arp_tha(self, dp): field = dp.ofproto.OXM_OF_ARP_THA arp_tha = '71:c8:72:2f:47:fd' value = self.haddr_to_bin(arp_tha) match = dp.ofproto_parser.OFPMatch() match.set_dl_type(ether.ETH_TYPE_ARP) self.add_set_field_action(dp, field, value, match) def test_action_set_field_ipv6_src(self, dp): field = dp.ofproto.OXM_OF_IPV6_SRC ipv6_src = '7527:c798:c772:4a18:117a:14ff:c1b6:e4ef' value = self.ipv6_to_int(ipv6_src) match = dp.ofproto_parser.OFPMatch() match.set_dl_type(0x86dd) self.add_set_field_action(dp, field, value, match) def test_action_set_field_ipv6_dst(self, dp): field = dp.ofproto.OXM_OF_IPV6_DST ipv6_dst = '8893:65b3:6b49:3bdb:3d2:9401:866c:c96' value = self.ipv6_to_int(ipv6_dst) match = dp.ofproto_parser.OFPMatch() match.set_dl_type(0x86dd) self.add_set_field_action(dp, field, value, match) def test_action_set_field_ipv6_flabel(self, dp): field = dp.ofproto.OXM_OF_IPV6_FLABEL value = 0x2c12 self.add_set_field_action(dp, field, value) def test_action_set_field_icmpv6_type(self, dp): field = dp.ofproto.OXM_OF_ICMPV6_TYPE value = 129 self.add_set_field_action(dp, field, value) def test_action_set_field_icmpv6_code(self, dp): field = dp.ofproto.OXM_OF_ICMPV6_CODE value = 2 self.add_set_field_action(dp, field, value) def test_action_set_field_ipv6_nd_target(self, dp): field = dp.ofproto.OXM_OF_IPV6_ND_TARGET target = "5420:db3f:921b:3e33:2791:98f:dd7f:2e19" value = self.ipv6_to_int(target) self.add_set_field_action(dp, field, value) def test_action_set_field_ipv6_nd_sll(self, dp): field = dp.ofproto.OXM_OF_IPV6_ND_SLL sll = "54:db:3f:3e:27:19" value = self.haddr_to_bin(sll) self.add_set_field_action(dp, field, value) def test_action_set_field_ipv6_nd_tll(self, dp): field = dp.ofproto.OXM_OF_IPV6_ND_TLL tll = "83:13:48:1e:d0:b0" value = self.haddr_to_bin(tll) self.add_set_field_action(dp, field, value) def test_action_set_field_mpls_label(self, dp): field = dp.ofproto.OXM_OF_MPLS_LABEL value = 0x4c match = dp.ofproto_parser.OFPMatch() match.set_dl_type(ether.ETH_TYPE_MPLS) self.add_set_field_action(dp, field, value, match) def test_action_set_field_mpls_tc(self, dp): field = dp.ofproto.OXM_OF_MPLS_TC value = 0b101 match = dp.ofproto_parser.OFPMatch() match.set_dl_type(ether.ETH_TYPE_MPLS) self.add_set_field_action(dp, field, value, match) # Test of Change-TTL Actions def test_action_set_mpls_ttl(self, dp): mpls_ttl = 8 self._verify = [dp.ofproto.OFPAT_SET_MPLS_TTL, 'mpls_ttl', mpls_ttl] actions = [dp.ofproto_parser.OFPActionSetMplsTtl(mpls_ttl), ] match = dp.ofproto_parser.OFPMatch() match.set_dl_type(ether.ETH_TYPE_MPLS) self.add_apply_actions(dp, actions, match) def test_action_dec_mpls_ttl(self, dp): self._verify = [dp.ofproto.OFPAT_DEC_MPLS_TTL] actions = [dp.ofproto_parser.OFPActionDecMplsTtl(), ] match = dp.ofproto_parser.OFPMatch() match.set_dl_type(ether.ETH_TYPE_MPLS) self.add_apply_actions(dp, actions, match) def test_action_set_nw_ttl_ipv4(self, dp): nw_ttl = 64 self._verify = [dp.ofproto.OFPAT_SET_NW_TTL, 'nw_ttl', nw_ttl] actions = [dp.ofproto_parser.OFPActionSetNwTtl(nw_ttl), ] match = dp.ofproto_parser.OFPMatch() match.set_dl_type(0x0800) self.add_apply_actions(dp, actions, match) def test_action_set_nw_ttl_ipv6(self, dp): nw_ttl = 64 self._verify = [dp.ofproto.OFPAT_SET_NW_TTL, 'nw_ttl', nw_ttl] actions = [dp.ofproto_parser.OFPActionSetNwTtl(nw_ttl), ] match = dp.ofproto_parser.OFPMatch() match.set_dl_type(0x86dd) self.add_apply_actions(dp, actions, match) def test_action_dec_nw_ttl_ipv4(self, dp): self._verify = [dp.ofproto.OFPAT_DEC_NW_TTL] actions = [dp.ofproto_parser.OFPActionDecNwTtl(), ] match = dp.ofproto_parser.OFPMatch() match.set_dl_type(0x0800) self.add_apply_actions(dp, actions, match) def test_action_dec_nw_ttl_ipv6(self, dp): self._verify = [dp.ofproto.OFPAT_DEC_NW_TTL] actions = [dp.ofproto_parser.OFPActionDecNwTtl(), ] match = dp.ofproto_parser.OFPMatch() match.set_dl_type(0x86dd) self.add_apply_actions(dp, actions, match) def test_action_copy_ttl_out(self, dp): self._verify = [dp.ofproto.OFPAT_COPY_TTL_OUT] actions = [dp.ofproto_parser.OFPActionCopyTtlOut(), ] self.add_apply_actions(dp, actions) def test_action_copy_ttl_in(self, dp): self._verify = [dp.ofproto.OFPAT_COPY_TTL_IN] actions = [dp.ofproto_parser.OFPActionCopyTtlIn(), ] self.add_apply_actions(dp, actions) def is_supported(self, t): # Open vSwitch 1.10 does not support MPLS yet. unsupported = [ 'test_action_set_field_ip_proto', 'test_action_set_field_dl_type', 'test_action_set_field_icmp', 'test_action_set_field_icmpv6_code', 'test_action_set_field_icmpv6_type', 'test_action_set_field_ipv6_flabel', 'test_action_set_field_ipv6_nd_sll', 'test_action_set_field_ipv6_nd_target', 'test_action_set_field_ipv6_nd_tll', 'test_action_copy_ttl_in', 'test_action_copy_ttl_out' ] for u in unsupported: if t.find(u) != -1: return False return True ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/integrated/test_add_flow_v12_matches.py0000664000175000017500000011772300000000000025156 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone 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. # vim: tabstop=4 shiftwidth=4 softtabstop=4 import logging from os_ken.ofproto import ofproto_v1_2 from os_ken.ofproto import ether from os_ken.ofproto import inet from os_ken.tests.integrated import tester LOG = logging.getLogger(__name__) class RunTest(tester.TestFlowBase): """ Test case for add flows of Matches """ OFP_VERSIONS = [ofproto_v1_2.OFP_VERSION] def __init__(self, *args, **kwargs): super(RunTest, self).__init__(*args, **kwargs) self._verify = {} def add_matches(self, dp, match): m = dp.ofproto_parser.OFPFlowMod(dp, 0, 0, 0, dp.ofproto.OFPFC_ADD, 0, 0, 0, 0xffffffff, dp.ofproto.OFPP_ANY, 0xffffffff, 0, match, []) dp.send_msg(m) def _set_verify(self, headers, value, mask=None, all_bits_masked=False, type_='int'): self._verify = {} self._verify['headers'] = headers self._verify['value'] = value self._verify['mask'] = mask self._verify['all_bits_masked'] = all_bits_masked self._verify['type'] = type_ def verify_default(self, dp, stats): type_ = self._verify['type'] headers = self._verify['headers'] value = self._verify['value'] mask = self._verify['mask'] value_masked = self._masked(type_, value, mask) all_bits_masked = self._verify['all_bits_masked'] field = None for s in stats: for f in s.match.fields: if f.header in headers: field = f break if field is None: if self._is_all_zero_bit(type_, mask): return True return 'Field not found.' f_value = field.value if hasattr(field, 'mask'): f_mask = field.mask else: f_mask = None if (f_value == value) or (f_value == value_masked): if (f_mask == mask) or (all_bits_masked and f_mask is None): return True return "send: %s/%s, reply: %s/%s" \ % (self._cnv_to_str(type_, value, mask, f_value, f_mask)) def _masked(self, type_, value, mask): if mask is None: v = value elif type_ == 'int': v = value & mask elif type_ == 'mac': v = self.haddr_masked(value, mask) elif type_ == 'ipv4': v = self.ipv4_masked(value, mask) elif type_ == 'ipv6': v = self.ipv6_masked(value, mask) else: raise Exception('Unknown type') return v def _is_all_zero_bit(self, type_, val): if type_ == 'int' or type_ == 'ipv4': return val == 0 elif type_ == 'mac': for v in val: if v != b'\x00': return False return True elif type_ == 'ipv6': for v in val: if v != 0: return False return True else: raise Exception('Unknown type') def _cnv_to_str(self, type_, value, mask, f_value, f_mask): func = None if type_ == 'int': pass elif type_ == 'mac': func = self.haddr_to_str elif type_ == 'ipv4': func = self.ipv4_to_str elif type_ == 'ipv6': func = self.ipv6_to_str else: raise Exception('Unknown type') if func: value = func(value) f_value = func(f_value) if mask: mask = func(mask) if f_mask: f_mask = func(f_mask) return value, mask, f_value, f_mask def test_rule_set_dl_dst(self, dp): dl_dst = 'e2:7a:09:79:0b:0f' dl_dst_bin = self.haddr_to_bin(dl_dst) headers = [dp.ofproto.OXM_OF_ETH_DST, dp.ofproto.OXM_OF_ETH_DST_W] self._set_verify(headers, dl_dst_bin, type_='mac') match = dp.ofproto_parser.OFPMatch() match.set_dl_dst(dl_dst_bin) self.add_matches(dp, match) def test_rule_set_dl_dst_masked_ff(self, dp): dl_dst = 'd0:98:79:b4:75:b5' dl_dst_bin = self.haddr_to_bin(dl_dst) mask = 'ff:ff:ff:ff:ff:ff' mask_bin = self.haddr_to_bin(mask) headers = [dp.ofproto.OXM_OF_ETH_DST, dp.ofproto.OXM_OF_ETH_DST_W] self._set_verify(headers, dl_dst_bin, mask_bin, True, type_='mac') match = dp.ofproto_parser.OFPMatch() match.set_dl_dst_masked(dl_dst_bin, mask_bin) self.add_matches(dp, match) def test_rule_set_dl_dst_masked_f0(self, dp): dl_dst = 'e2:7a:09:79:0b:0f' dl_dst_bin = self.haddr_to_bin(dl_dst) mask = 'ff:ff:ff:ff:ff:00' mask_bin = self.haddr_to_bin(mask) headers = [dp.ofproto.OXM_OF_ETH_DST, dp.ofproto.OXM_OF_ETH_DST_W] self._set_verify(headers, dl_dst_bin, mask_bin, type_='mac') match = dp.ofproto_parser.OFPMatch() match.set_dl_dst_masked(dl_dst_bin, mask_bin) self.add_matches(dp, match) def test_rule_set_dl_dst_masked_00(self, dp): dl_dst = 'e2:7a:09:79:0b:0f' dl_dst_bin = self.haddr_to_bin(dl_dst) mask = '00:00:00:00:00:00' mask_bin = self.haddr_to_bin(mask) headers = [dp.ofproto.OXM_OF_ETH_DST, dp.ofproto.OXM_OF_ETH_DST_W] self._set_verify(headers, dl_dst_bin, mask_bin, type_='mac') match = dp.ofproto_parser.OFPMatch() match.set_dl_dst_masked(dl_dst_bin, mask_bin) self.add_matches(dp, match) def test_rule_set_dl_src(self, dp): dl_src = 'e2:7a:09:79:0b:0f' dl_src_bin = self.haddr_to_bin(dl_src) headers = [dp.ofproto.OXM_OF_ETH_SRC, dp.ofproto.OXM_OF_ETH_SRC_W] self._set_verify(headers, dl_src_bin, type_='mac') match = dp.ofproto_parser.OFPMatch() match.set_dl_src(dl_src_bin) self.add_matches(dp, match) def test_rule_set_dl_src_masked_ff(self, dp): dl_src = 'e2:7a:09:79:0b:0f' dl_src_bin = self.haddr_to_bin(dl_src) mask = 'ff:ff:ff:ff:ff:ff' mask_bin = self.haddr_to_bin(mask) headers = [dp.ofproto.OXM_OF_ETH_SRC, dp.ofproto.OXM_OF_ETH_SRC_W] self._set_verify(headers, dl_src_bin, mask_bin, True, type_='mac') match = dp.ofproto_parser.OFPMatch() match.set_dl_src_masked(dl_src_bin, mask_bin) self.add_matches(dp, match) def test_rule_set_dl_src_masked_f0(self, dp): dl_src = 'e2:7a:09:79:0b:0f' dl_src_bin = self.haddr_to_bin(dl_src) mask = 'ff:ff:ff:ff:ff:00' mask_bin = self.haddr_to_bin(mask) headers = [dp.ofproto.OXM_OF_ETH_SRC, dp.ofproto.OXM_OF_ETH_SRC_W] self._set_verify(headers, dl_src_bin, mask_bin, type_='mac') match = dp.ofproto_parser.OFPMatch() match.set_dl_src_masked(dl_src_bin, mask_bin) self.add_matches(dp, match) def test_rule_set_dl_src_masked_00(self, dp): dl_src = 'e2:7a:09:79:0b:0f' dl_src_bin = self.haddr_to_bin(dl_src) mask = '00:00:00:00:00:00' mask_bin = self.haddr_to_bin(mask) headers = [dp.ofproto.OXM_OF_ETH_SRC, dp.ofproto.OXM_OF_ETH_SRC_W] self._set_verify(headers, dl_src_bin, mask_bin, type_='mac') match = dp.ofproto_parser.OFPMatch() match.set_dl_src_masked(dl_src_bin, mask_bin) self.add_matches(dp, match) def test_rule_set_dl_type_ip(self, dp): dl_type = ether.ETH_TYPE_IP headers = [dp.ofproto.OXM_OF_ETH_TYPE] self._set_verify(headers, dl_type) match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) self.add_matches(dp, match) def test_rule_set_dl_type_arp(self, dp): dl_type = ether.ETH_TYPE_ARP headers = [dp.ofproto.OXM_OF_ETH_TYPE] self._set_verify(headers, dl_type) match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) self.add_matches(dp, match) def test_rule_set_dl_type_vlan(self, dp): dl_type = ether.ETH_TYPE_8021Q headers = [dp.ofproto.OXM_OF_ETH_TYPE] self._set_verify(headers, dl_type) match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) self.add_matches(dp, match) def test_rule_set_dl_type_ipv6(self, dp): dl_type = ether.ETH_TYPE_IPV6 headers = [dp.ofproto.OXM_OF_ETH_TYPE] self._set_verify(headers, dl_type) match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) self.add_matches(dp, match) def test_rule_set_dl_type_lacp(self, dp): dl_type = ether.ETH_TYPE_SLOW headers = [dp.ofproto.OXM_OF_ETH_TYPE] self._set_verify(headers, dl_type) match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) self.add_matches(dp, match) def test_rule_set_ip_dscp(self, dp): ip_dscp = 36 dl_type = ether.ETH_TYPE_IP headers = [dp.ofproto.OXM_OF_IP_DSCP] self._set_verify(headers, ip_dscp) match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_ip_dscp(ip_dscp) self.add_matches(dp, match) def test_rule_set_vlan_vid(self, dp): vlan_vid = 0x4ef headers = [dp.ofproto.OXM_OF_VLAN_VID, dp.ofproto.OXM_OF_VLAN_VID_W] self._set_verify(headers, vlan_vid) match = dp.ofproto_parser.OFPMatch() match.set_vlan_vid(vlan_vid) self.add_matches(dp, match) def test_rule_set_vlan_vid_masked_ff(self, dp): vlan_vid = 0x4ef mask = 0xfff headers = [dp.ofproto.OXM_OF_VLAN_VID, dp.ofproto.OXM_OF_VLAN_VID_W] self._set_verify(headers, vlan_vid, mask, True) match = dp.ofproto_parser.OFPMatch() match.set_vlan_vid_masked(vlan_vid, mask) self.add_matches(dp, match) def test_rule_set_vlan_vid_masked_f0(self, dp): vlan_vid = 0x4ef mask = 0xff0 headers = [dp.ofproto.OXM_OF_VLAN_VID, dp.ofproto.OXM_OF_VLAN_VID_W] self._set_verify(headers, vlan_vid, mask) match = dp.ofproto_parser.OFPMatch() match.set_vlan_vid_masked(vlan_vid, mask) self.add_matches(dp, match) def test_rule_set_vlan_vid_masked_00(self, dp): vlan_vid = 0x4ef mask = 0x000 headers = [dp.ofproto.OXM_OF_VLAN_VID, dp.ofproto.OXM_OF_VLAN_VID_W] self._set_verify(headers, vlan_vid, mask) match = dp.ofproto_parser.OFPMatch() match.set_vlan_vid_masked(vlan_vid, mask) self.add_matches(dp, match) def test_rule_set_vlan_pcp(self, dp): vlan_vid = 0x4ef vlan_pcp = 5 headers = [dp.ofproto.OXM_OF_VLAN_PCP] self._set_verify(headers, vlan_pcp) match = dp.ofproto_parser.OFPMatch() match.set_vlan_vid(vlan_vid) match.set_vlan_pcp(vlan_pcp) self.add_matches(dp, match) def test_rule_set_ip_ecn(self, dp): dl_type = ether.ETH_TYPE_IP ip_ecn = 3 headers = [dp.ofproto.OXM_OF_IP_ECN] self._set_verify(headers, ip_ecn) match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_ip_ecn(ip_ecn) self.add_matches(dp, match) def test_rule_set_ip_proto_icmp(self, dp): dl_type = ether.ETH_TYPE_IP ip_proto = inet.IPPROTO_ICMP headers = [dp.ofproto.OXM_OF_IP_PROTO] self._set_verify(headers, ip_proto) match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_ip_proto(ip_proto) self.add_matches(dp, match) def test_rule_set_ip_proto_tcp(self, dp): dl_type = ether.ETH_TYPE_IP ip_proto = inet.IPPROTO_TCP headers = [dp.ofproto.OXM_OF_IP_PROTO] self._set_verify(headers, ip_proto) match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_ip_proto(ip_proto) self.add_matches(dp, match) def test_rule_set_ip_proto_udp(self, dp): dl_type = ether.ETH_TYPE_IP ip_proto = inet.IPPROTO_UDP headers = [dp.ofproto.OXM_OF_IP_PROTO] self._set_verify(headers, ip_proto) match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_ip_proto(ip_proto) self.add_matches(dp, match) def test_rule_set_ip_proto_ipv6_route(self, dp): dl_type = ether.ETH_TYPE_IPV6 ip_proto = inet.IPPROTO_ROUTING headers = [dp.ofproto.OXM_OF_IP_PROTO] self._set_verify(headers, ip_proto) match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_ip_proto(ip_proto) self.add_matches(dp, match) def test_rule_set_ip_proto_ipv6_frag(self, dp): dl_type = ether.ETH_TYPE_IPV6 ip_proto = inet.IPPROTO_FRAGMENT headers = [dp.ofproto.OXM_OF_IP_PROTO] self._set_verify(headers, ip_proto) match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_ip_proto(ip_proto) self.add_matches(dp, match) def test_rule_set_ip_proto_ipv6_icmp(self, dp): dl_type = ether.ETH_TYPE_IPV6 ip_proto = inet.IPPROTO_ICMPV6 headers = [dp.ofproto.OXM_OF_IP_PROTO] self._set_verify(headers, ip_proto) match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_ip_proto(ip_proto) self.add_matches(dp, match) def test_rule_set_ip_proto_ipv6_none(self, dp): dl_type = ether.ETH_TYPE_IPV6 ip_proto = inet.IPPROTO_NONE headers = [dp.ofproto.OXM_OF_IP_PROTO] self._set_verify(headers, ip_proto) match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_ip_proto(ip_proto) self.add_matches(dp, match) def test_rule_set_ip_proto_ipv6_dstopts(self, dp): dl_type = ether.ETH_TYPE_IPV6 ip_proto = inet.IPPROTO_DSTOPTS headers = [dp.ofproto.OXM_OF_IP_PROTO] self._set_verify(headers, ip_proto) match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_ip_proto(ip_proto) self.add_matches(dp, match) def test_rule_set_ipv4_src(self, dp): dl_type = ether.ETH_TYPE_IP src = '192.168.196.250' src_int = self.ipv4_to_int(src) headers = [dp.ofproto.OXM_OF_IPV4_SRC, dp.ofproto.OXM_OF_IPV4_SRC_W] self._set_verify(headers, src_int, type_='ipv4') match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_ipv4_src(src_int) self.add_matches(dp, match) def test_rule_set_ipv4_src_masked_32(self, dp): dl_type = ether.ETH_TYPE_IP src = '192.168.196.250' src_int = self.ipv4_to_int(src) mask = '255.255.255.255' mask_int = self.ipv4_to_int(mask) headers = [dp.ofproto.OXM_OF_IPV4_SRC, dp.ofproto.OXM_OF_IPV4_SRC_W] self._set_verify(headers, src_int, mask_int, True, type_='ipv4') match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_ipv4_src_masked(src_int, mask_int) self.add_matches(dp, match) def test_rule_set_ipv4_src_masked_24(self, dp): dl_type = ether.ETH_TYPE_IP src = '192.168.196.250' src_int = self.ipv4_to_int(src) mask = '255.255.255.0' mask_int = self.ipv4_to_int(mask) headers = [dp.ofproto.OXM_OF_IPV4_SRC, dp.ofproto.OXM_OF_IPV4_SRC_W] self._set_verify(headers, src_int, mask_int, type_='ipv4') match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_ipv4_src_masked(src_int, mask_int) self.add_matches(dp, match) def test_rule_set_ipv4_src_masked_0(self, dp): dl_type = ether.ETH_TYPE_IP src = '192.168.196.250' src_int = self.ipv4_to_int(src) mask = '0.0.0.0' mask_int = self.ipv4_to_int(mask) headers = [dp.ofproto.OXM_OF_IPV4_SRC, dp.ofproto.OXM_OF_IPV4_SRC_W] self._set_verify(headers, src_int, mask_int, type_='ipv4') match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_ipv4_src_masked(src_int, mask_int) self.add_matches(dp, match) def test_rule_set_ipv4_dst(self, dp): dl_type = ether.ETH_TYPE_IP dst = '192.168.54.155' dst_int = self.ipv4_to_int(dst) headers = [dp.ofproto.OXM_OF_IPV4_DST, dp.ofproto.OXM_OF_IPV4_DST_W] self._set_verify(headers, dst_int, type_='ipv4') match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_ipv4_dst(dst_int) self.add_matches(dp, match) def test_rule_set_ipv4_dst_masked_32(self, dp): dl_type = ether.ETH_TYPE_IP dst = '192.168.54.155' dst_int = self.ipv4_to_int(dst) mask = '255.255.255.255' mask_int = self.ipv4_to_int(mask) headers = [dp.ofproto.OXM_OF_IPV4_DST, dp.ofproto.OXM_OF_IPV4_DST_W] self._set_verify(headers, dst_int, mask_int, True, type_='ipv4') match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_ipv4_dst_masked(dst_int, mask_int) self.add_matches(dp, match) def test_rule_set_ipv4_dst_masked_24(self, dp): dl_type = ether.ETH_TYPE_IP dst = '192.168.54.155' dst_int = self.ipv4_to_int(dst) mask = '255.255.255.0' mask_int = self.ipv4_to_int(mask) headers = [dp.ofproto.OXM_OF_IPV4_DST, dp.ofproto.OXM_OF_IPV4_DST_W] self._set_verify(headers, dst_int, mask_int, type_='ipv4') match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_ipv4_dst_masked(dst_int, mask_int) self.add_matches(dp, match) def test_rule_set_ipv4_dst_masked_0(self, dp): dl_type = ether.ETH_TYPE_IP dst = '192.168.54.155' dst_int = self.ipv4_to_int(dst) mask = '0.0.0.0' mask_int = self.ipv4_to_int(mask) headers = [dp.ofproto.OXM_OF_IPV4_DST, dp.ofproto.OXM_OF_IPV4_DST_W] self._set_verify(headers, dst_int, mask_int, type_='ipv4') match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_ipv4_dst_masked(dst_int, mask_int) self.add_matches(dp, match) def test_rule_set_tcp_src(self, dp): dl_type = ether.ETH_TYPE_IP ip_proto = inet.IPPROTO_TCP tp_src = 1103 headers = [dp.ofproto.OXM_OF_TCP_SRC] self._set_verify(headers, tp_src) match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_ip_proto(ip_proto) match.set_tcp_src(tp_src) self.add_matches(dp, match) def test_rule_set_tcp_dst(self, dp): dl_type = ether.ETH_TYPE_IP ip_proto = inet.IPPROTO_TCP tp_dst = 236 headers = [dp.ofproto.OXM_OF_TCP_DST] self._set_verify(headers, tp_dst) match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_ip_proto(ip_proto) match.set_tcp_dst(tp_dst) self.add_matches(dp, match) def test_rule_set_udp_src(self, dp): dl_type = ether.ETH_TYPE_IP ip_proto = inet.IPPROTO_UDP tp_src = 56617 headers = [dp.ofproto.OXM_OF_UDP_SRC] self._set_verify(headers, tp_src) match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_ip_proto(ip_proto) match.set_udp_src(tp_src) self.add_matches(dp, match) def test_rule_set_udp_dst(self, dp): dl_type = ether.ETH_TYPE_IP ip_proto = inet.IPPROTO_UDP tp_dst = 61278 headers = [dp.ofproto.OXM_OF_UDP_DST] self._set_verify(headers, tp_dst) match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_ip_proto(ip_proto) match.set_udp_dst(tp_dst) self.add_matches(dp, match) def test_rule_set_icmpv4_type(self, dp): dl_type = ether.ETH_TYPE_IP ip_proto = inet.IPPROTO_ICMP icmp_type = 8 headers = [dp.ofproto.OXM_OF_ICMPV4_TYPE] self._set_verify(headers, icmp_type) match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_ip_proto(ip_proto) match.set_icmpv4_type(icmp_type) self.add_matches(dp, match) def test_rule_set_icmpv4_code(self, dp): dl_type = ether.ETH_TYPE_IP ip_proto = inet.IPPROTO_ICMP icmp_type = 9 icmp_code = 16 headers = [dp.ofproto.OXM_OF_ICMPV4_CODE] self._set_verify(headers, icmp_code) match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_ip_proto(ip_proto) match.set_icmpv4_type(icmp_type) match.set_icmpv4_code(icmp_code) self.add_matches(dp, match) def test_rule_set_arp_opcode(self, dp): dl_type = ether.ETH_TYPE_ARP arp_op = 1 headers = [dp.ofproto.OXM_OF_ARP_OP] self._set_verify(headers, arp_op) match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_arp_opcode(arp_op) self.add_matches(dp, match) def test_rule_set_arp_spa(self, dp): dl_type = ether.ETH_TYPE_ARP nw_src = '192.168.222.57' nw_src_int = self.ipv4_to_int(nw_src) headers = [dp.ofproto.OXM_OF_ARP_SPA, dp.ofproto.OXM_OF_ARP_SPA_W] self._set_verify(headers, nw_src_int, type_='ipv4') match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_arp_spa(nw_src_int) self.add_matches(dp, match) def test_rule_set_arp_spa_masked_32(self, dp): dl_type = ether.ETH_TYPE_ARP nw_src = '192.168.222.57' nw_src_int = self.ipv4_to_int(nw_src) mask = '255.255.255.255' mask_int = self.ipv4_to_int(mask) headers = [dp.ofproto.OXM_OF_ARP_SPA, dp.ofproto.OXM_OF_ARP_SPA_W] self._set_verify(headers, nw_src_int, mask_int, True, type_='ipv4') match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_arp_spa_masked(nw_src_int, mask_int) self.add_matches(dp, match) def test_rule_set_arp_spa_masked_24(self, dp): dl_type = ether.ETH_TYPE_ARP nw_src = '192.168.222.57' nw_src_int = self.ipv4_to_int(nw_src) mask = '255.255.255.0' mask_int = self.ipv4_to_int(mask) headers = [dp.ofproto.OXM_OF_ARP_SPA, dp.ofproto.OXM_OF_ARP_SPA_W] self._set_verify(headers, nw_src_int, mask_int, type_='ipv4') match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_arp_spa_masked(nw_src_int, mask_int) self.add_matches(dp, match) def test_rule_set_arp_spa_masked_00(self, dp): dl_type = ether.ETH_TYPE_ARP nw_src = '192.168.222.57' nw_src_int = self.ipv4_to_int(nw_src) mask = '0.0.0.0' mask_int = self.ipv4_to_int(mask) headers = [dp.ofproto.OXM_OF_ARP_SPA, dp.ofproto.OXM_OF_ARP_SPA_W] self._set_verify(headers, nw_src_int, mask_int, type_='ipv4') match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_arp_spa_masked(nw_src_int, mask_int) self.add_matches(dp, match) def test_rule_set_arp_tpa(self, dp): dl_type = ether.ETH_TYPE_ARP nw_dst = '192.168.198.233' nw_dst_int = self.ipv4_to_int(nw_dst) headers = [dp.ofproto.OXM_OF_ARP_TPA, dp.ofproto.OXM_OF_ARP_TPA_W] self._set_verify(headers, nw_dst_int, type_='ipv4') match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_arp_tpa(nw_dst_int) self.add_matches(dp, match) def test_rule_set_arp_tpa_masked_32(self, dp): dl_type = ether.ETH_TYPE_ARP nw_dst = '192.168.198.233' nw_dst_int = self.ipv4_to_int(nw_dst) mask = '255.255.255.255' mask_int = self.ipv4_to_int(mask) headers = [dp.ofproto.OXM_OF_ARP_TPA, dp.ofproto.OXM_OF_ARP_TPA_W] self._set_verify(headers, nw_dst_int, mask_int, True, type_='ipv4') match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_arp_tpa_masked(nw_dst_int, mask_int) self.add_matches(dp, match) def test_rule_set_arp_tpa_masked_24(self, dp): dl_type = ether.ETH_TYPE_ARP nw_dst = '192.168.198.233' nw_dst_int = self.ipv4_to_int(nw_dst) mask = '255.255.255.0' mask_int = self.ipv4_to_int(mask) headers = [dp.ofproto.OXM_OF_ARP_TPA, dp.ofproto.OXM_OF_ARP_TPA_W] self._set_verify(headers, nw_dst_int, mask_int, type_='ipv4') match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_arp_tpa_masked(nw_dst_int, mask_int) self.add_matches(dp, match) def test_rule_set_arp_tpa_masked_00(self, dp): dl_type = ether.ETH_TYPE_ARP nw_dst = '192.168.198.233' nw_dst_int = self.ipv4_to_int(nw_dst) mask = '0.0.0.0' mask_int = self.ipv4_to_int(mask) headers = [dp.ofproto.OXM_OF_ARP_TPA, dp.ofproto.OXM_OF_ARP_TPA_W] self._set_verify(headers, nw_dst_int, mask_int, type_='ipv4') match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_arp_tpa_masked(nw_dst_int, mask_int) self.add_matches(dp, match) def test_rule_set_arp_sha(self, dp): dl_type = ether.ETH_TYPE_ARP arp_sha = '3e:ec:13:9b:f3:0b' arp_sha_bin = self.haddr_to_bin(arp_sha) headers = [dp.ofproto.OXM_OF_ARP_SHA, dp.ofproto.OXM_OF_ARP_SHA_W] self._set_verify(headers, arp_sha_bin, type_='mac') match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_arp_sha(arp_sha_bin) self.add_matches(dp, match) def test_rule_set_arp_sha_masked_ff(self, dp): dl_type = ether.ETH_TYPE_ARP arp_sha = '3e:ec:13:9b:f3:0b' arp_sha_bin = self.haddr_to_bin(arp_sha) mask = 'ff:ff:ff:ff:ff:ff' mask_bin = self.haddr_to_bin(mask) headers = [dp.ofproto.OXM_OF_ARP_SHA, dp.ofproto.OXM_OF_ARP_SHA_W] self._set_verify(headers, arp_sha_bin, mask_bin, True, type_='mac') match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_arp_sha_masked(arp_sha_bin, mask_bin) self.add_matches(dp, match) def test_rule_set_arp_sha_masked_f0(self, dp): dl_type = ether.ETH_TYPE_ARP arp_sha = '3e:ec:13:9b:f3:0b' arp_sha_bin = self.haddr_to_bin(arp_sha) mask = 'ff:ff:ff:ff:ff:00' mask_bin = self.haddr_to_bin(mask) headers = [dp.ofproto.OXM_OF_ARP_SHA, dp.ofproto.OXM_OF_ARP_SHA_W] self._set_verify(headers, arp_sha_bin, mask_bin, type_='mac') match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_arp_sha_masked(arp_sha_bin, mask_bin) self.add_matches(dp, match) def test_rule_set_arp_sha_masked_00(self, dp): dl_type = ether.ETH_TYPE_ARP arp_sha = '3e:ec:13:9b:f3:0b' arp_sha_bin = self.haddr_to_bin(arp_sha) mask = '00:00:00:00:00:00' mask_bin = self.haddr_to_bin(mask) headers = [dp.ofproto.OXM_OF_ARP_SHA, dp.ofproto.OXM_OF_ARP_SHA_W] self._set_verify(headers, arp_sha_bin, mask_bin, type_='mac') match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_arp_sha_masked(arp_sha_bin, mask_bin) self.add_matches(dp, match) def test_rule_set_arp_tha(self, dp): dl_type = ether.ETH_TYPE_ARP arp_tha = '83:6c:21:52:49:68' arp_tha_bin = self.haddr_to_bin(arp_tha) headers = [dp.ofproto.OXM_OF_ARP_THA, dp.ofproto.OXM_OF_ARP_THA_W] self._set_verify(headers, arp_tha_bin, type_='mac') match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_arp_tha(arp_tha_bin) self.add_matches(dp, match) def test_rule_set_arp_tha_masked_ff(self, dp): dl_type = ether.ETH_TYPE_ARP arp_tha = '83:6c:21:52:49:68' arp_tha_bin = self.haddr_to_bin(arp_tha) mask = 'ff:ff:ff:ff:ff:ff' mask_bin = self.haddr_to_bin(mask) headers = [dp.ofproto.OXM_OF_ARP_THA, dp.ofproto.OXM_OF_ARP_THA_W] self._set_verify(headers, arp_tha_bin, mask_bin, True, type_='mac') match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_arp_tha_masked(arp_tha_bin, mask_bin) self.add_matches(dp, match) def test_rule_set_arp_tha_masked_f0(self, dp): dl_type = ether.ETH_TYPE_ARP arp_tha = '83:6c:21:52:49:68' arp_tha_bin = self.haddr_to_bin(arp_tha) mask = 'ff:ff:ff:ff:ff:00' mask_bin = self.haddr_to_bin(mask) headers = [dp.ofproto.OXM_OF_ARP_THA, dp.ofproto.OXM_OF_ARP_THA_W] self._set_verify(headers, arp_tha_bin, mask_bin, type_='mac') match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_arp_tha_masked(arp_tha_bin, mask_bin) self.add_matches(dp, match) def test_rule_set_arp_tha_masked_00(self, dp): dl_type = ether.ETH_TYPE_ARP arp_tha = '83:6c:21:52:49:68' arp_tha_bin = self.haddr_to_bin(arp_tha) mask = '00:00:00:00:00:00' mask_bin = self.haddr_to_bin(mask) headers = [dp.ofproto.OXM_OF_ARP_THA, dp.ofproto.OXM_OF_ARP_THA_W] self._set_verify(headers, arp_tha_bin, mask_bin, type_='mac') match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_arp_tha_masked(arp_tha_bin, mask_bin) self.add_matches(dp, match) def test_rule_set_ipv6_src(self, dp): dl_type = ether.ETH_TYPE_IPV6 ipv6_src = '2001:db8:bd05:1d2:288a:1fc0:1:10ee' ipv6_src_int = self.ipv6_to_int(ipv6_src) headers = [dp.ofproto.OXM_OF_IPV6_SRC, dp.ofproto.OXM_OF_IPV6_SRC_W] self._set_verify(headers, ipv6_src_int, type_='ipv6') match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_ipv6_src(ipv6_src_int) self.add_matches(dp, match) def test_rule_set_ipv6_src_masked_ff(self, dp): dl_type = ether.ETH_TYPE_IPV6 ipv6_src = '2001:db8:bd05:1d2:288a:1fc0:1:10ee' ipv6_src_int = self.ipv6_to_int(ipv6_src) mask = 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff' mask_int = self.ipv6_to_int(mask) headers = [dp.ofproto.OXM_OF_IPV6_SRC, dp.ofproto.OXM_OF_IPV6_SRC_W] self._set_verify(headers, ipv6_src_int, mask_int, True, type_='ipv6') match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_ipv6_src_masked(ipv6_src_int, mask_int) self.add_matches(dp, match) def test_rule_set_ipv6_src_masked_f0(self, dp): dl_type = ether.ETH_TYPE_IPV6 ipv6_src = '2001:db8:bd05:1d2:288a:1fc0:1:10ee' ipv6_src_int = self.ipv6_to_int(ipv6_src) mask = 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:0' mask_int = self.ipv6_to_int(mask) headers = [dp.ofproto.OXM_OF_IPV6_SRC, dp.ofproto.OXM_OF_IPV6_SRC_W] self._set_verify(headers, ipv6_src_int, mask_int, type_='ipv6') match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_ipv6_src_masked(ipv6_src_int, mask_int) self.add_matches(dp, match) def test_rule_set_ipv6_src_masked_00(self, dp): dl_type = ether.ETH_TYPE_IPV6 ipv6_src = '2001:db8:bd05:1d2:288a:1fc0:1:10ee' ipv6_src_int = self.ipv6_to_int(ipv6_src) mask = '0:0:0:0:0:0:0:0' mask_int = self.ipv6_to_int(mask) headers = [dp.ofproto.OXM_OF_IPV6_SRC, dp.ofproto.OXM_OF_IPV6_SRC_W] self._set_verify(headers, ipv6_src_int, mask_int, type_='ipv6') match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_ipv6_src_masked(ipv6_src_int, mask_int) self.add_matches(dp, match) def test_rule_set_ipv6_dst(self, dp): dl_type = ether.ETH_TYPE_IPV6 ipv6_dst = 'e9e8:9ea5:7d67:82cc:ca54:1fc0:2d24:f038' ipv6_dst_int = self.ipv6_to_int(ipv6_dst) headers = [dp.ofproto.OXM_OF_IPV6_DST, dp.ofproto.OXM_OF_IPV6_DST_W] self._set_verify(headers, ipv6_dst_int, type_='ipv6') match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_ipv6_dst(ipv6_dst_int) self.add_matches(dp, match) def test_rule_set_ipv6_dst_masked_ff(self, dp): dl_type = ether.ETH_TYPE_IPV6 ipv6_dst = 'e9e8:9ea5:7d67:82cc:ca54:1fc0:2d24:f038' ipv6_dst_int = self.ipv6_to_int(ipv6_dst) mask = 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff' mask_int = self.ipv6_to_int(mask) headers = [dp.ofproto.OXM_OF_IPV6_DST, dp.ofproto.OXM_OF_IPV6_DST_W] self._set_verify(headers, ipv6_dst_int, mask_int, True, type_='ipv6') match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_ipv6_dst_masked(ipv6_dst_int, mask_int) self.add_matches(dp, match) def test_rule_set_ipv6_dst_masked_f0(self, dp): dl_type = ether.ETH_TYPE_IPV6 ipv6_dst = 'e9e8:9ea5:7d67:82cc:ca54:1fc0:2d24:f038' ipv6_dst_int = self.ipv6_to_int(ipv6_dst) mask = 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:0' mask_int = self.ipv6_to_int(mask) headers = [dp.ofproto.OXM_OF_IPV6_DST, dp.ofproto.OXM_OF_IPV6_DST_W] self._set_verify(headers, ipv6_dst_int, mask_int, type_='ipv6') match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_ipv6_dst_masked(ipv6_dst_int, mask_int) self.add_matches(dp, match) def test_rule_set_ipv6_dst_masked_00(self, dp): dl_type = ether.ETH_TYPE_IPV6 ipv6_dst = 'e9e8:9ea5:7d67:82cc:ca54:1fc0:2d24:f038' ipv6_dst_int = self.ipv6_to_int(ipv6_dst) mask = '0:0:0:0:0:0:0:0' mask_int = self.ipv6_to_int(mask) headers = [dp.ofproto.OXM_OF_IPV6_DST, dp.ofproto.OXM_OF_IPV6_DST_W] self._set_verify(headers, ipv6_dst_int, mask_int, type_='ipv6') match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_ipv6_dst_masked(ipv6_dst_int, mask_int) self.add_matches(dp, match) def test_rule_set_ipv6_flabel(self, dp): dl_type = ether.ETH_TYPE_IPV6 ipv6_label = 0xc5384 headers = [dp.ofproto.OXM_OF_IPV6_FLABEL, dp.ofproto.OXM_OF_IPV6_FLABEL_W] self._set_verify(headers, ipv6_label) match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_ipv6_flabel(ipv6_label) self.add_matches(dp, match) def test_rule_set_ipv6_flabel_masked_ff(self, dp): dl_type = ether.ETH_TYPE_IPV6 ipv6_label = 0xc5384 mask = 0xfffff headers = [dp.ofproto.OXM_OF_IPV6_FLABEL, dp.ofproto.OXM_OF_IPV6_FLABEL_W] self._set_verify(headers, ipv6_label, mask, True) match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_ipv6_flabel_masked(ipv6_label, mask) self.add_matches(dp, match) def test_rule_set_ipv6_flabel_masked_f0(self, dp): dl_type = ether.ETH_TYPE_IPV6 ipv6_label = 0xc5384 mask = 0xffff0 headers = [dp.ofproto.OXM_OF_IPV6_FLABEL, dp.ofproto.OXM_OF_IPV6_FLABEL_W] self._set_verify(headers, ipv6_label, mask) match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_ipv6_flabel_masked(ipv6_label, mask) self.add_matches(dp, match) def test_rule_set_ipv6_flabel_masked_00(self, dp): dl_type = ether.ETH_TYPE_IPV6 ipv6_label = 0xc5384 mask = 0x0 headers = [dp.ofproto.OXM_OF_IPV6_FLABEL, dp.ofproto.OXM_OF_IPV6_FLABEL_W] self._set_verify(headers, ipv6_label, mask) match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_ipv6_flabel_masked(ipv6_label, mask) self.add_matches(dp, match) def test_rule_set_icmpv6_type(self, dp): dl_type = ether.ETH_TYPE_IPV6 ip_proto = inet.IPPROTO_ICMPV6 icmp_type = 129 headers = [dp.ofproto.OXM_OF_ICMPV6_TYPE] self._set_verify(headers, icmp_type) match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_ip_proto(ip_proto) match.set_icmpv6_type(icmp_type) self.add_matches(dp, match) def test_rule_set_icmpv6_code(self, dp): dl_type = ether.ETH_TYPE_IPV6 ip_proto = inet.IPPROTO_ICMPV6 icmp_type = 138 icmp_code = 1 headers = [dp.ofproto.OXM_OF_ICMPV6_CODE] self._set_verify(headers, icmp_code) match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_ip_proto(ip_proto) match.set_icmpv6_type(icmp_type) match.set_icmpv6_code(icmp_code) self.add_matches(dp, match) def test_rule_set_ipv6_nd_target(self, dp): dl_type = ether.ETH_TYPE_IPV6 ip_proto = inet.IPPROTO_ICMPV6 icmp_type = 135 target = "5420:db3f:921b:3e33:2791:98f:dd7f:2e19" target_int = self.ipv6_to_int(target) headers = [dp.ofproto.OXM_OF_IPV6_ND_TARGET] self._set_verify(headers, target_int, type_='ipv6') match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_ip_proto(ip_proto) match.set_icmpv6_type(icmp_type) match.set_ipv6_nd_target(target_int) self.add_matches(dp, match) def test_rule_set_ipv6_nd_sll(self, dp): dl_type = ether.ETH_TYPE_IPV6 ip_proto = inet.IPPROTO_ICMPV6 icmp_type = 135 nd_sll = "93:6d:d0:d4:e8:36" nd_sll_bin = self.haddr_to_bin(nd_sll) headers = [dp.ofproto.OXM_OF_IPV6_ND_SLL] self._set_verify(headers, nd_sll_bin, type_='mac') match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_ip_proto(ip_proto) match.set_icmpv6_type(icmp_type) match.set_ipv6_nd_sll(nd_sll_bin) self.add_matches(dp, match) def test_rule_set_ipv6_nd_tll(self, dp): dl_type = ether.ETH_TYPE_IPV6 ip_proto = inet.IPPROTO_ICMPV6 icmp_type = 136 nd_tll = "18:f6:66:b6:f1:b3" nd_tll_bin = self.haddr_to_bin(nd_tll) headers = [dp.ofproto.OXM_OF_IPV6_ND_TLL] self._set_verify(headers, nd_tll_bin, type_='mac') match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_ip_proto(ip_proto) match.set_icmpv6_type(icmp_type) match.set_ipv6_nd_tll(nd_tll_bin) self.add_matches(dp, match) def test_rule_set_mpls_label(self, dp): dl_type = 0x8847 label = 2144 headers = [dp.ofproto.OXM_OF_MPLS_LABEL] self._set_verify(headers, label) match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_mpls_label(label) self.add_matches(dp, match) def test_rule_set_mpls_tc(self, dp): dl_type = 0x8847 tc = 3 headers = [dp.ofproto.OXM_OF_MPLS_TC] self._set_verify(headers, tc) match = dp.ofproto_parser.OFPMatch() match.set_dl_type(dl_type) match.set_mpls_tc(tc) self.add_matches(dp, match) def is_supported(self, t): # Open vSwitch 1.10 does not support MPLS yet. unsupported = [ 'test_rule_set_mpls_label', 'test_rule_set_mpls_tc', ] for u in unsupported: if t.find(u) != -1: return False return True ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/integrated/test_of_config.py0000664000175000017500000002337500000000000023133 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013 Isaku Yamahata # # 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. """ How to run this test edit linc config file. LINC-Switch/rel/linc/releases/1.0/sys.config You can find the sample config I used for the test below For this following config to work, the network interface linc-port and linc-port2 must be created before hand. (Or edit the port name depending on your environment) An easy way is to create them as follows # ip link add linc-port type veth peer name linc-port-peer # ip link set linc-port up # ip link add linc-port2 type veth peer name linc-port-peer2 # ip link set linc-port2 up Then run linc # rel/linc/bin/linc console Then run os_ken # osken-manager --verbose \ os_ken/tests/integrated/test_of_config.py Here is my sys.config used for this test. -->8-->8-->8-->8-->8-->8-->8-->8-->8-->8-->8-->8-->8--- [ {linc, [ {of_config, enabled}, {logical_switches, [ {switch, 0, [ {backend, linc_us4}, {controllers, [ {"Switch0-DefaultController", "localhost", 6633, tcp} ]}, {ports, [ {port, 1, [{interface, "linc-port"}]}, {port, 2, [{interface, "linc-port2"}]} ]}, {queues_status, disabled}, {queues, [ ]} ]} ]} ]}, {enetconf, [ {capabilities, [{base, {1, 1}}, {startup, {1, 0}}, {'writable-running', {1, 0}}]}, {callback_module, linc_ofconfig}, {sshd_ip, any}, {sshd_port, 1830}, {sshd_user_passwords, [ {"linc", "linc"} ]} ]}, {lager, [ {handlers, [ {lager_console_backend, info}, {lager_file_backend, [ {"log/error.log", error, 10485760, "$D0", 5}, {"log/console.log", info, 10485760, "$D0", 5} ]} ]} ]}, {sasl, [ {sasl_error_logger, {file, "log/sasl-error.log"}}, {errlog_type, error}, {error_logger_mf_dir, "log/sasl"}, % Log directory {error_logger_mf_maxbytes, 10485760}, % 10 MB max file size {error_logger_mf_maxfiles, 5} % 5 files max ]} ]. -->8-->8-->8-->8-->8-->8-->8-->8-->8-->8-->8-->8-->8-- """ import traceback import lxml.etree import ncclient from os_ken.base import app_manager from os_ken.lib.netconf import constants as nc_consts from os_ken.lib import hub from os_ken.lib import of_config from os_ken.lib.of_config import capable_switch from os_ken.lib.of_config import constants as ofc_consts # Change those depending on switch configuration HOST = '127.0.0.1' PORT = 1830 USERNAME = 'linc' PASSWORD = 'linc' CAPABLE_SWITCH_ID = 'CapableSwitch0' LOGICAL_SWITCH = 'LogicalSwitch0' PORT_ID = 'LogicalSwitch0-Port2' CONTROLLER_ID = 'Switch0-DefaultController' PORT_DICT = { 'capable_switch': CAPABLE_SWITCH_ID, 'port_id': PORT_ID, 'logical_switch': LOGICAL_SWITCH, 'controller_id': CONTROLLER_ID, 'ip': HOST, } SWITCH_PORT_DOWN = ''' %(capable_switch)s %(port_id)s down false false false ''' % PORT_DICT SWITCH_ADVERTISED = ''' %(capable_switch)s %(port_id)s 10Mb-FD true copper unsupported ''' % PORT_DICT SWITCH_CONTROLLER = ''' %(capable_switch)s %(logical_switch)s %(controller_id)s master %(ip)s 6633 tcp ''' % PORT_DICT def _get_schema(): # file_name = of_config.OF_CONFIG_1_0_XSD # file_name = of_config.OF_CONFIG_1_1_XSD file_name = of_config.OF_CONFIG_1_1_1_XSD return lxml.etree.XMLSchema(file=file_name) class OFConfigClient(app_manager.OSKenApp): def __init__(self, *args, **kwargs): super(OFConfigClient, self).__init__(*args, **kwargs) self.switch = capable_switch.OFCapableSwitch( host=HOST, port=PORT, username=USERNAME, password=PASSWORD, unknown_host_cb=lambda host, fingeprint: True) hub.spawn(self._do_of_config) def _validate(self, tree): xmlschema = _get_schema() try: xmlschema.assertValid(tree) except: traceback.print_exc() def _do_get(self): data_xml = self.switch.raw_get() tree = lxml.etree.fromstring(data_xml) # print(lxml.etree.tostring(tree, pretty_print=True)) self._validate(tree) name_spaces = set() for e in tree.iter(): name_spaces.add(capable_switch.get_ns_tag(e.tag)[0]) print(name_spaces) return tree def _do_get_config(self, source): print('source = %s' % source) config_xml = self.switch.raw_get_config(source) tree = lxml.etree.fromstring(config_xml) # print(lxml.etree.tostring(tree, pretty_print=True)) self._validate(tree) def _do_edit_config(self, config): tree = lxml.etree.fromstring(config) self._validate(tree) self.switch.raw_edit_config(target='running', config=config) def _print_ports(self, tree, ns): for port in tree.findall('{%s}%s/{%s}%s' % (ns, ofc_consts.RESOURCES, ns, ofc_consts.PORT)): print(lxml.etree.tostring(port, pretty_print=True)) def _set_ports_down(self): """try to set all ports down with etree operation""" tree = self._do_get() print(lxml.etree.tostring(tree, pretty_print=True)) qname = lxml.etree.QName(tree.tag) ns = qname.namespace self._print_ports(tree, ns) switch_id = tree.find('{%s}%s' % (ns, ofc_consts.ID)) resources = tree.find('{%s}%s' % (ns, ofc_consts.RESOURCES)) configuration = tree.find( '{%s}%s/{%s}%s/{%s}%s' % (ns, ofc_consts.RESOURCES, ns, ofc_consts.PORT, ns, ofc_consts.CONFIGURATION)) admin_state = tree.find( '{%s}%s/{%s}%s/{%s}%s/{%s}%s' % (ns, ofc_consts.RESOURCES, ns, ofc_consts.PORT, ns, ofc_consts.CONFIGURATION, ns, ofc_consts.ADMIN_STATE)) config_ = lxml.etree.Element( '{%s}%s' % (ncclient.xml_.BASE_NS_1_0, nc_consts.CONFIG)) capable_switch_ = lxml.etree.SubElement(config_, tree.tag) switch_id_ = lxml.etree.SubElement(capable_switch_, switch_id.tag) switch_id_.text = switch_id.text resources_ = lxml.etree.SubElement(capable_switch_, resources.tag) for port in tree.findall( '{%s}%s/{%s}%s' % (ns, ofc_consts.RESOURCES, ns, ofc_consts.PORT)): resource_id = port.find('{%s}%s' % (ns, ofc_consts.RESOURCE_ID)) port_ = lxml.etree.SubElement(resources_, port.tag) resource_id_ = lxml.etree.SubElement(port_, resource_id.tag) resource_id_.text = resource_id.text configuration_ = lxml.etree.SubElement(port_, configuration.tag) configuration_.set(ofc_consts.OPERATION, nc_consts.MERGE) admin_state_ = lxml.etree.SubElement(configuration_, admin_state.tag) admin_state_.text = ofc_consts.DOWN self._do_edit_config(lxml.etree.tostring(config_, pretty_print=True)) tree = self._do_get() self._print_ports(tree, ns) def _do_of_config(self): self._do_get() self._do_get_config('running') self._do_get_config('startup') # LINC doesn't support 'candidate' datastore try: self._do_get_config('candidate') except ncclient.NCClientError: traceback.print_exc() # use raw XML format self._do_edit_config(SWITCH_PORT_DOWN) self._do_edit_config(SWITCH_ADVERTISED) self._do_edit_config(SWITCH_CONTROLLER) self._set_ports_down() self.switch.close_session() ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/integrated/test_request_reply_v12.py0000664000175000017500000010413300000000000024565 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone 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. # vim: tabstop=4 shiftwidth=4 softtabstop=4 import time import logging from os_ken.controller import ofp_event from os_ken.controller.handler import MAIN_DISPATCHER from os_ken.controller.handler import set_ev_cls from os_ken.ofproto import ofproto_v1_2 from os_ken.tests.integrated import tester LOG = logging.getLogger(__name__) class RunTest(tester.TestFlowBase): """ Test case for Request-Reply messages. Some tests need attached port to switch. If use the OVS, can do it with the following commands. # ip link add type dummy # ovs-vsctl add-port """ OFP_VERSIONS = [ofproto_v1_2.OFP_VERSION] def __init__(self, *args, **kwargs): super(RunTest, self).__init__(*args, **kwargs) self._verify = None self.n_tables = ofproto_v1_2.OFPTT_MAX def start_next_test(self, dp): self._verify = None self.delete_all_flows(dp) dp.send_barrier() if len(self.pending): t = self.pending.pop() if self.is_supported(t): LOG.info(tester.LOG_TEST_START, t) self.current = t getattr(self, t)(dp) else: self.results[t] = 'SKIP (unsupported)' self.unclear -= 1 self.start_next_test(dp) else: self.print_results() def run_verify(self, ev): msg = ev.msg dp = msg.datapath verify_func = self.verify_default v = "verify" + self.current[4:] if v in dir(self): verify_func = getattr(self, v) result = verify_func(dp, msg) if result is True: self.unclear -= 1 self.results[self.current] = result self.start_next_test(dp) def verify_default(self, dp, msg): type_ = self._verify if msg.msg_type == dp.ofproto.OFPT_STATS_REPLY: return self.verify_stats(dp, msg.body, type_) elif msg.msg_type == type_: return True else: return 'Reply msg_type %s expected %s' \ % (msg.msg_type, type_) def verify_stats(self, dp, stats, type_): stats_types = dp.ofproto_parser.OFPStatsReply._STATS_TYPES expect = stats_types.get(type_).__name__ if isinstance(stats, list): for s in stats: if expect == s.__class__.__name__: return True else: if expect == stats.__class__.__name__: return True return 'Reply msg has not \'%s\' class.\n%s' % (expect, stats) def mod_flow(self, dp, cookie=0, cookie_mask=0, table_id=0, command=None, idle_timeout=0, hard_timeout=0, priority=0xff, buffer_id=0xffffffff, match=None, actions=None, inst_type=None, out_port=None, out_group=None, flags=0, inst=None): if command is None: command = dp.ofproto.OFPFC_ADD if inst is None: if inst_type is None: inst_type = dp.ofproto.OFPIT_APPLY_ACTIONS inst = [] if actions is not None: inst = [dp.ofproto_parser.OFPInstructionActions( inst_type, actions)] if match is None: match = dp.ofproto_parser.OFPMatch() if out_port is None: out_port = dp.ofproto.OFPP_ANY if out_group is None: out_group = dp.ofproto.OFPG_ANY m = dp.ofproto_parser.OFPFlowMod(dp, cookie, cookie_mask, table_id, command, idle_timeout, hard_timeout, priority, buffer_id, out_port, out_group, flags, match, inst) dp.send_msg(m) def get_port(self, dp): for port_no, port in dp.ports.items(): if port_no != dp.ofproto.OFPP_LOCAL: return port return None # Test for Reply message type def test_desc_stats_request(self, dp): self._verify = dp.ofproto.OFPST_DESC m = dp.ofproto_parser.OFPDescStatsRequest(dp) dp.send_msg(m) def test_flow_stats_request(self, dp): self._verify = dp.ofproto.OFPST_FLOW self.mod_flow(dp) self.send_flow_stats(dp) def test_aggregate_stats_request(self, dp): self._verify = dp.ofproto.OFPST_AGGREGATE match = dp.ofproto_parser.OFPMatch() m = dp.ofproto_parser.OFPAggregateStatsRequest( dp, dp.ofproto.OFPTT_ALL, dp.ofproto.OFPP_ANY, dp.ofproto.OFPG_ANY, 0, 0, match) dp.send_msg(m) def test_table_stats_request(self, dp): self._verify = dp.ofproto.OFPST_TABLE m = dp.ofproto_parser.OFPTableStatsRequest(dp) dp.send_msg(m) def test_port_stats_request(self, dp): self._verify = dp.ofproto.OFPST_PORT m = dp.ofproto_parser.OFPPortStatsRequest(dp, dp.ofproto.OFPP_ANY) dp.send_msg(m) def test_echo_request(self, dp): self._verify = dp.ofproto.OFPT_ECHO_REPLY m = dp.ofproto_parser.OFPEchoRequest(dp) dp.send_msg(m) def test_features_request(self, dp): self._verify = dp.ofproto.OFPT_FEATURES_REPLY m = dp.ofproto_parser.OFPFeaturesRequest(dp) dp.send_msg(m) def test_get_config_request(self, dp): self._verify = dp.ofproto.OFPT_GET_CONFIG_REPLY m = dp.ofproto_parser.OFPGetConfigRequest(dp) dp.send_msg(m) def test_barrier_request(self, dp): self._verify = dp.ofproto.OFPT_BARRIER_REPLY dp.send_barrier() def test_error_reply(self, dp): ports = [0] for p in dp.ports: if p != dp.ofproto.OFPP_LOCAL: ports.append(p) port_no = max(ports) + 1 self._verify = dp.ofproto.OFPT_ERROR m = dp.ofproto_parser.OFPPortMod( dp, port_no, 'ff:ff:ff:ff:ff:ff', 0, 0, 0) dp.send_msg(m) # Test for reply value def test_flow_stats_none(self, dp): self.send_flow_stats(dp) def verify_flow_stats_none(self, dp, msg): stats = msg.body if len(stats): return 'Reply msg has body. %s' % (stats, ) return True def test_flow_stats_reply_value(self, dp): self._verify = [] c = 0 while c < self.n_tables: # value = (talbe_id, cookie, idle_timeout, hard_timeout, priority) v = (c, c + 1, c + 2, c + 3, c + 4) self._verify.append(v) self.mod_flow(dp, table_id=v[0], cookie=v[1], idle_timeout=v[2], hard_timeout=v[3], priority=v[4]) c += 1 dp.send_barrier() self.send_flow_stats(dp) def verify_flow_stats_reply_value(self, dp, msg): c = 0 for f in msg.body: f_value = (f.table_id, f.cookie, f.idle_timeout, f.hard_timeout, f.priority, ) if f_value != self._verify[c]: return 'param is mismatched. verify=%s, reply=%s' \ % (self._verify[c], f_value,) c += 1 return len(msg.body) == self.n_tables def test_echo_request_has_data(self, dp): data = 'test' self._verify = data m = dp.ofproto_parser.OFPEchoRequest(dp) m.data = data dp.send_msg(m) def verify_echo_request_has_data(self, dp, msg): data = msg.data return self._verify == data def test_aggregate_stats_flow_count(self, dp): c = 0 while c < self.n_tables: self.mod_flow(dp, table_id=c) c += 1 dp.send_barrier() match = dp.ofproto_parser.OFPMatch() m = dp.ofproto_parser.OFPAggregateStatsRequest( dp, dp.ofproto.OFPTT_ALL, dp.ofproto.OFPP_ANY, dp.ofproto.OFPG_ANY, 0, 0, match) dp.send_msg(m) def verify_aggregate_stats_flow_count(self, dp, msg): stats = msg.body return stats.flow_count == self.n_tables def test_aggregate_stats_flow_count_out_port(self, dp): actions = [dp.ofproto_parser.OFPActionOutput(1, 1500)] self.mod_flow(dp, table_id=1, actions=actions) actions = [dp.ofproto_parser.OFPActionOutput(2, 1500)] self.mod_flow(dp, table_id=2, actions=actions) dp.send_barrier() out_port = 2 match = dp.ofproto_parser.OFPMatch() m = dp.ofproto_parser.OFPAggregateStatsRequest( dp, dp.ofproto.OFPTT_ALL, out_port, dp.ofproto.OFPG_ANY, 0, 0, match) dp.send_msg(m) def verify_aggregate_stats_flow_count_out_port(self, dp, msg): stats = msg.body return stats.flow_count == 1 def test_aggregate_stats_packet_count(self, dp): in_port = 1 data = 'test' self._verify = {'packet_count': 1, 'byte_count': len(data)} # add flow match = dp.ofproto_parser.OFPMatch() match.set_in_port(in_port) self.mod_flow(dp, table_id=0, match=match) # packet out output = dp.ofproto.OFPP_TABLE actions = [dp.ofproto_parser.OFPActionOutput(output, 0)] m = dp.ofproto_parser.OFPPacketOut(dp, 0xffffffff, in_port, actions, data) dp.send_msg(m) dp.send_barrier() match = dp.ofproto_parser.OFPMatch() m = dp.ofproto_parser.OFPAggregateStatsRequest( dp, dp.ofproto.OFPTT_ALL, dp.ofproto.OFPP_ANY, dp.ofproto.OFPG_ANY, 0, 0, match) dp.send_msg(m) def verify_aggregate_stats_packet_count(self, dp, msg): for name, val in self._verify.items(): r_val = getattr(msg.body, name) if val != r_val: return '%s is mismatched. verify=%s, reply=%s' \ % (name, val, r_val) return True def test_set_config_nomal(self, dp): flags = dp.ofproto.OFPC_FRAG_NORMAL self._verify = flags m = dp.ofproto_parser.OFPSetConfig(dp, flags, 0) dp.send_msg(m) dp.send_barrier() m = dp.ofproto_parser.OFPGetConfigRequest(dp) dp.send_msg(m) def verify_set_config_nomal(self, dp, msg): return self._verify == msg.flags def test_set_config_drop(self, dp): flags = dp.ofproto.OFPC_FRAG_DROP self._verify = flags m = dp.ofproto_parser.OFPSetConfig(dp, flags, 0) dp.send_msg(m) dp.send_barrier() m = dp.ofproto_parser.OFPGetConfigRequest(dp) dp.send_msg(m) def verify_set_config_drop(self, dp, msg): return self._verify == msg.flags def test_set_config_mask(self, dp): flags = dp.ofproto.OFPC_FRAG_MASK self._verify = flags m = dp.ofproto_parser.OFPSetConfig(dp, flags, 0) dp.send_msg(m) dp.send_barrier() m = dp.ofproto_parser.OFPGetConfigRequest(dp) dp.send_msg(m) def verify_set_config_mask(self, dp, msg): return self._verify == msg.flags def test_set_config_ttl_to_controller(self, dp): flags = dp.ofproto.OFPC_INVALID_TTL_TO_CONTROLLER self._verify = flags m = dp.ofproto_parser.OFPSetConfig(dp, flags, 0) dp.send_msg(m) dp.send_barrier() m = dp.ofproto_parser.OFPGetConfigRequest(dp) dp.send_msg(m) def verify_set_config_ttl_to_controller(self, dp, msg): return self._verify == msg.flags def test_set_config_miss_send_len(self, dp): flags = dp.ofproto.OFPC_FRAG_NORMAL ms_len = 256 self._verify = ms_len m = dp.ofproto_parser.OFPSetConfig(dp, flags, ms_len) dp.send_msg(m) dp.send_barrier() m = dp.ofproto_parser.OFPGetConfigRequest(dp) dp.send_msg(m) def verify_set_config_miss_send_len(self, dp, msg): return self._verify == msg.miss_send_len def test_set_config_miss_send_len_max(self, dp): flags = dp.ofproto.OFPC_FRAG_NORMAL ms_len = dp.ofproto.OFPCML_MAX self._verify = ms_len m = dp.ofproto_parser.OFPSetConfig(dp, flags, ms_len) dp.send_msg(m) dp.send_barrier() m = dp.ofproto_parser.OFPGetConfigRequest(dp) dp.send_msg(m) def verify_set_config_miss_send_len_max(self, dp, msg): return self._verify == msg.miss_send_len def test_set_config_no_buffer(self, dp): flags = dp.ofproto.OFPC_FRAG_NORMAL ms_len = dp.ofproto.OFPCML_NO_BUFFER self._verify = ms_len m = dp.ofproto_parser.OFPSetConfig(dp, flags, ms_len) dp.send_msg(m) dp.send_barrier() m = dp.ofproto_parser.OFPGetConfigRequest(dp) dp.send_msg(m) def verify_set_config_no_buffer(self, dp, msg): return self._verify == msg.miss_send_len def _verify_flow_inst_type(self, dp, msg): inst_type = self._verify stats = msg.body for s in stats: for i in s.instructions: if i.type == inst_type: return True return 'not found inst_type[%s]' % (inst_type, ) def test_flow_add_apply_actions(self, dp): inst_type = dp.ofproto.OFPIT_APPLY_ACTIONS self._verify = inst_type actions = [dp.ofproto_parser.OFPActionOutput(1, 1500)] self.mod_flow(dp, actions=actions, inst_type=inst_type) self.send_flow_stats(dp) def verify_flow_add_apply_actions(self, dp, msg): return self._verify_flow_inst_type(dp, msg) def test_flow_add_goto_table(self, dp): self._verify = dp.ofproto.OFPIT_GOTO_TABLE inst = [dp.ofproto_parser.OFPInstructionGotoTable(1), ] self.mod_flow(dp, inst=inst) self.send_flow_stats(dp) def verify_flow_add_goto_table(self, dp, msg): return self._verify_flow_inst_type(dp, msg) def _verify_flow_value(self, dp, msg): stats = msg.body verify = self._verify if len(verify) != len(stats): return 'flow_count is mismatched. verify=%s stats=%s' \ % (len(verify), len(stats)) for s in stats: v_port = -1 v = verify.get(s.table_id, None) if v: v_port = v[3].port s_port = s.instructions[0].actions[0].port if v_port != s_port: return 'port is mismatched. table_id=%s verify=%s, stats=%s' \ % (s.table_id, v_port, s_port) return True def _add_flow_for_flow_mod_tests(self, dp): a1 = dp.ofproto_parser.OFPActionOutput(1, 1500) a2 = dp.ofproto_parser.OFPActionOutput(2, 1500) # table_id, cookie, priority, dl_dst, action) tables = {0: [0xffff, 10, b'\xee' * 6, a1], 1: [0xff00, 10, b'\xee' * 6, a2], 2: [0xf000, 100, b'\xee' * 6, a1], 3: [0x0000, 10, b'\xff' * 6, a1]} self._verify = tables for table_id, val in tables.items(): match = dp.ofproto_parser.OFPMatch() match.set_dl_dst(val[2]) self.mod_flow(dp, match=match, actions=[val[3]], table_id=table_id, cookie=val[0], priority=val[1]) dp.send_barrier() def test_flow_mod_table_id(self, dp): self._add_flow_for_flow_mod_tests(dp) # modify flow of table_id=3 action = dp.ofproto_parser.OFPActionOutput(3, 1500) self._verify[3][3] = action table_id = 3 self.mod_flow(dp, command=dp.ofproto.OFPFC_MODIFY, actions=[action], table_id=table_id) dp.send_barrier() self.send_flow_stats(dp) def verify_flow_mod_table_id(self, dp, msg): return self._verify_flow_value(dp, msg) def test_flow_mod_cookie(self, dp): self._add_flow_for_flow_mod_tests(dp) # modify flow of table_id=1 action = dp.ofproto_parser.OFPActionOutput(3, 1500) self._verify[1][3] = action cookie = 0xff00 cookie_mask = 0xffff table_id = 1 self.mod_flow(dp, command=dp.ofproto.OFPFC_MODIFY, actions=[action], table_id=table_id, cookie=cookie, cookie_mask=cookie_mask) dp.send_barrier() self.send_flow_stats(dp) def verify_flow_mod_cookie(self, dp, msg): return self._verify_flow_value(dp, msg) def test_flow_mod_cookie_mask(self, dp): self._add_flow_for_flow_mod_tests(dp) # modify flow of table_id=0,1 action = dp.ofproto_parser.OFPActionOutput(3, 1500) self._verify[0][3] = action self._verify[1][3] = action cookie = 0xffff cookie_mask = 0xff00 for table_id in range(2): self.mod_flow(dp, command=dp.ofproto.OFPFC_MODIFY, actions=[action], table_id=table_id, cookie=cookie, cookie_mask=cookie_mask) dp.send_barrier() self.send_flow_stats(dp) def verify_flow_mod_cookie_mask(self, dp, msg): return self._verify_flow_value(dp, msg) def test_flow_mod_match(self, dp): self._add_flow_for_flow_mod_tests(dp) # modify flow of table_id=3 action = dp.ofproto_parser.OFPActionOutput(3, 1500) self._verify[3][3] = action match = dp.ofproto_parser.OFPMatch() match.set_dl_dst(b'\xff' * 6) table_id = 3 self.mod_flow(dp, command=dp.ofproto.OFPFC_MODIFY, actions=[action], table_id=table_id, match=match) dp.send_barrier() self.send_flow_stats(dp) def verify_flow_mod_match(self, dp, msg): return self._verify_flow_value(dp, msg) def test_flow_mod_strict(self, dp): self._add_flow_for_flow_mod_tests(dp) # modify flow of table_id=2 action = dp.ofproto_parser.OFPActionOutput(3, 1500) self._verify[2][3] = action match = dp.ofproto_parser.OFPMatch() match.set_dl_dst(b'\xee' * 6) priority = 100 table_id = 2 self.mod_flow(dp, command=dp.ofproto.OFPFC_MODIFY_STRICT, actions=[action], table_id=table_id, match=match, priority=priority) dp.send_barrier() self.send_flow_stats(dp) def verify_flow_mod_strict(self, dp, msg): return self._verify_flow_value(dp, msg) def test_flow_del_table_id(self, dp): self._add_flow_for_flow_mod_tests(dp) # delete flow of table_id=3 del self._verify[3] table_id = 3 self.mod_flow(dp, command=dp.ofproto.OFPFC_DELETE, table_id=table_id) dp.send_barrier() self.send_flow_stats(dp) def verify_flow_del_table_id(self, dp, msg): return self._verify_flow_value(dp, msg) def test_flow_del_table_id_all(self, dp): self._add_flow_for_flow_mod_tests(dp) # delete all flows self._verify = {} self.mod_flow(dp, command=dp.ofproto.OFPFC_DELETE, table_id=dp.ofproto.OFPTT_ALL) dp.send_barrier() self.send_flow_stats(dp) def verify_flow_del_table_id_all(self, dp, msg): return self._verify_flow_value(dp, msg) def test_flow_del_cookie(self, dp): self._add_flow_for_flow_mod_tests(dp) # delete flow of table_id=1 del self._verify[1] cookie = 0xff00 cookie_mask = 0xffff self.mod_flow(dp, command=dp.ofproto.OFPFC_DELETE, table_id=dp.ofproto.OFPTT_ALL, cookie=cookie, cookie_mask=cookie_mask) dp.send_barrier() self.send_flow_stats(dp) def verify_flow_del_cookie(self, dp, msg): return self._verify_flow_value(dp, msg) def test_flow_del_cookie_mask(self, dp): self._add_flow_for_flow_mod_tests(dp) # delete flow of table_id=0,1 del self._verify[0] del self._verify[1] cookie = 0xffff cookie_mask = 0xff00 self.mod_flow(dp, command=dp.ofproto.OFPFC_DELETE, table_id=dp.ofproto.OFPTT_ALL, cookie=cookie, cookie_mask=cookie_mask) dp.send_barrier() self.send_flow_stats(dp) def verify_flow_del_cookie_mask(self, dp, msg): return self._verify_flow_value(dp, msg) def test_flow_del_match(self, dp): self._add_flow_for_flow_mod_tests(dp) # delete flow of table_id=3 del self._verify[3] match = dp.ofproto_parser.OFPMatch() match.set_dl_dst(b'\xff' * 6) self.mod_flow(dp, command=dp.ofproto.OFPFC_DELETE, table_id=dp.ofproto.OFPTT_ALL, match=match) dp.send_barrier() self.send_flow_stats(dp) def verify_flow_del_match(self, dp, msg): return self._verify_flow_value(dp, msg) def test_flow_del_out_port(self, dp): self._add_flow_for_flow_mod_tests(dp) # delete flow of table_id=1 del self._verify[1] out_port = 2 self.mod_flow(dp, command=dp.ofproto.OFPFC_DELETE, table_id=dp.ofproto.OFPTT_ALL, out_port=out_port) dp.send_barrier() self.send_flow_stats(dp) def verify_flow_del_out_port(self, dp, msg): return self._verify_flow_value(dp, msg) def test_flow_del_strict(self, dp): self._add_flow_for_flow_mod_tests(dp) # delete flow of table_id=2 del self._verify[2] match = dp.ofproto_parser.OFPMatch() match.set_dl_dst(b'\xee' * 6) priority = 100 self.mod_flow(dp, command=dp.ofproto.OFPFC_DELETE_STRICT, table_id=dp.ofproto.OFPTT_ALL, match=match, priority=priority) dp.send_barrier() self.send_flow_stats(dp) def verify_flow_del_strict(self, dp, msg): return self._verify_flow_value(dp, msg) def _send_port_mod(self, dp, config, mask): p = self.get_port(dp) if not p: err = 'need attached port to switch.' self.results[self.current] = err self.start_next_test(dp) return self._verify = [p.port_no, config & mask] m = dp.ofproto_parser.OFPPortMod(dp, p.port_no, p.hw_addr, config, mask, 0) dp.send_msg(m) dp.send_barrier() # TODO: waiting to port UP|DOWN. time.sleep(1) m = dp.ofproto_parser.OFPFeaturesRequest(dp) dp.send_msg(m) def _verify_port_mod_config(self, dp, msg): port_no = self._verify[0] config = self._verify[1] port = msg.ports[port_no] if config != port.config: return "config is mismatched. verify=%s, stats=%s" \ % (bin(config), bin(port.config)) return True def test_port_mod_config_01_all(self, dp): config = 0b1100101 mask = 0b1111111 self._send_port_mod(dp, config, mask) def verify_port_mod_config_01_all(self, dp, msg): return self._verify_port_mod_config(dp, msg) def test_port_mod_config_02_none(self, dp): config = 0 mask = 0b1111111 self._send_port_mod(dp, config, mask) def verify_port_mod_config_02_none(self, dp, msg): return self._verify_port_mod_config(dp, msg) def test_port_mod_config_03_mask(self, dp): config = 0b1100101 mask = 0b1111000 self._send_port_mod(dp, config, mask) def verify_port_mod_config_03_mask(self, dp, msg): res = self._verify_port_mod_config(dp, msg) # reset port config port_no = self._verify[0] p = msg.ports[port_no] m = dp.ofproto_parser.OFPPortMod(dp, p.port_no, p.hw_addr, 0, 0b1111111, 0) dp.send_msg(m) dp.send_barrier() return res def test_port_stats_port_no(self, dp): p = self.get_port(dp) if not p: err = 'need attached port to switch.' self.results[self.current] = err self.start_next_test(dp) return self._verify = p.port_no m = dp.ofproto_parser.OFPPortStatsRequest(dp, p.port_no) dp.send_msg(m) def verify_port_stats_port_no(self, dp, msg): ports = msg.body if len(ports) > 1: return 'reply some ports.\n%s' % (ports) if ports[0].port_no != self._verify: return 'port_no is mismatched. request=%s reply=%s' \ % (self._verify, ports[0].port_no) return True def _add_flow_flow_removed(self, dp, reason, table_id=0, cookie=0xff, priority=100, in_port=1, idle_timeout=0, hard_timeout=0): self._verify = {} self._verify['params'] = {'reason': reason, 'table_id': table_id, 'cookie': cookie, 'priority': priority} self._verify['in_port'] = in_port self._verify['timeout'] = idle_timeout if hard_timeout: if (idle_timeout == 0 or idle_timeout > hard_timeout): self._verify['timeout'] = hard_timeout match = dp.ofproto_parser.OFPMatch() match.set_in_port(in_port) self.mod_flow(dp, match=match, cookie=cookie, priority=priority, table_id=table_id, idle_timeout=idle_timeout, hard_timeout=hard_timeout, flags=dp.ofproto.OFPFF_SEND_FLOW_REM) def _verify_flow_removed(self, dp, msg): params = self._verify['params'] in_port = self._verify['in_port'] timeout = self._verify['timeout'] if timeout: duration_nsec = (msg.duration_sec * 10 ** 9) + msg.duration_nsec timeout_nsec = timeout * 10 ** 9 # grace of -0.5 and +1.5 second to timeout. l = (timeout - 0.5) * 10 ** 9 h = (timeout + 1.5) * 10 ** 9 if not l < duration_nsec < h: return 'bad duration time. set=%s(nsec), duration=%s(nsec)' \ % (timeout_nsec, duration_nsec) for name, val in params.items(): r_val = getattr(msg, name) if val != r_val: return '%s is mismatched. verify=%s, reply=%s' \ % (name, val, r_val) for f in msg.match.fields: if f.header == ofproto_v1_2.OXM_OF_IN_PORT: if f.value != in_port: return 'in_port is mismatched. verify=%s, reply=%s' \ % (in_port, f.value) return True def test_flow_removed_idle_timeout(self, dp): reason = dp.ofproto.OFPRR_IDLE_TIMEOUT idle_timeout = 2 self._add_flow_flow_removed(dp, reason, idle_timeout=idle_timeout) def verify_flow_removed_idle_timeout(self, dp, msg): return self._verify_flow_removed(dp, msg) def test_flow_removed_idle_timeout_hit(self, dp): reason = dp.ofproto.OFPRR_IDLE_TIMEOUT idle_timeout = 5 in_port = 1 sleep = 2 # add target flow self._add_flow_flow_removed(dp, reason, in_port=in_port, idle_timeout=idle_timeout) self._verify['timeout'] = idle_timeout + sleep # sleep time.sleep(sleep) # packet out output = dp.ofproto.OFPP_TABLE actions = [dp.ofproto_parser.OFPActionOutput(output, 0)] m = dp.ofproto_parser.OFPPacketOut(dp, 0xffffffff, in_port, actions, None) dp.send_msg(m) def verify_flow_removed_idle_timeout_hit(self, dp, msg): return self._verify_flow_removed(dp, msg) def test_flow_removed_hard_timeout(self, dp): reason = dp.ofproto.OFPRR_HARD_TIMEOUT hard_timeout = 2 self._add_flow_flow_removed(dp, reason, hard_timeout=hard_timeout) def verify_flow_removed_hard_timeout(self, dp, msg): return self._verify_flow_removed(dp, msg) def test_flow_removed_hard_timeout_hit(self, dp): reason = dp.ofproto.OFPRR_HARD_TIMEOUT hard_timeout = 5 in_port = 1 sleep = 2 self._add_flow_flow_removed(dp, reason, in_port=in_port, hard_timeout=hard_timeout) dp.send_barrier() # sleep time.sleep(sleep) # packet out output = dp.ofproto.OFPP_TABLE actions = [dp.ofproto_parser.OFPActionOutput(output, 0)] m = dp.ofproto_parser.OFPPacketOut(dp, 0xffffffff, in_port, actions, None) dp.send_msg(m) def verify_flow_removed_hard_timeout_hit(self, dp, msg): return self._verify_flow_removed(dp, msg) def test_flow_removed_delete(self, dp): reason = dp.ofproto.OFPRR_DELETE self._add_flow_flow_removed(dp, reason) dp.send_barrier() self.delete_all_flows(dp) def verify_flow_removed_delete(self, dp, msg): return self._verify_flow_removed(dp, msg) def test_flow_removed_table_id(self, dp): reason = dp.ofproto.OFPRR_DELETE table_id = 1 self._add_flow_flow_removed(dp, reason, table_id=table_id) dp.send_barrier() self.delete_all_flows(dp) def verify_flow_removed_table_id(self, dp, msg): return self._verify_flow_removed(dp, msg) def _send_packet_out(self, dp, buffer_id=0xffffffff, in_port=None, output=None, data=''): if in_port is None: in_port = dp.ofproto.OFPP_LOCAL if output is None: output = dp.ofproto.OFPP_CONTROLLER self._verify['in_port'] = in_port self._verify['data'] = data actions = [dp.ofproto_parser.OFPActionOutput(output, len(data))] m = dp.ofproto_parser.OFPPacketOut(dp, buffer_id, in_port, actions, data) dp.send_msg(m) def _verify_packet_in(self, dp, msg): for name, val in self._verify.items(): if name == 'in_port': for f in msg.match.fields: if f.header == ofproto_v1_2.OXM_OF_IN_PORT: r_val = f.value else: r_val = getattr(msg, name) if val != r_val: return '%s is mismatched. verify=%s, reply=%s' \ % (name, val, r_val) return True def test_packet_in_action(self, dp): self._verify = {} self._verify['reason'] = dp.ofproto.OFPR_ACTION self._send_packet_out(dp) def verify_packet_in_action(self, dp, msg): return self._verify_packet_in(dp, msg) def test_packet_in_data(self, dp): self._verify = {} self._verify['reason'] = dp.ofproto.OFPR_ACTION data = 'test' self._send_packet_out(dp, data=data) def verify_packet_in_data(self, dp, msg): return self._verify_packet_in(dp, msg) def test_packet_in_table_id(self, dp): in_port = 1 table_id = 2 output = dp.ofproto.OFPP_TABLE self._verify = {} self._verify['reason'] = dp.ofproto.OFPR_ACTION self._verify['table_id'] = table_id # add flow (goto_table) match = dp.ofproto_parser.OFPMatch() match.set_in_port(in_port) inst = [dp.ofproto_parser.OFPInstructionGotoTable(table_id)] self.mod_flow(dp, inst=inst, match=match) # add flow (output) match = dp.ofproto_parser.OFPMatch() match.set_in_port(in_port) out = dp.ofproto.OFPP_CONTROLLER actions = [dp.ofproto_parser.OFPActionOutput(out, 0)] self.mod_flow(dp, actions=actions, match=match, table_id=table_id) dp.send_barrier() # packet out self._send_packet_out(dp, in_port=in_port, output=output) def verify_packet_in_table_id(self, dp, msg): return self._verify_packet_in(dp, msg) # handler @set_ev_cls(ofp_event.EventOFPEchoReply, MAIN_DISPATCHER) def echo_replay_handler(self, ev): if self.current.find('echo_request') > 0: self.run_verify(ev) @set_ev_cls(ofp_event.EventOFPStatsReply, MAIN_DISPATCHER) def stats_reply_handler(self, ev): if self.current is None: msg = ev.msg dp = msg.datapath if self._verify == dp.ofproto.OFPST_TABLE: self.table_stats = msg.body self.start_next_test(dp) else: self.run_verify(ev) @set_ev_cls(ofp_event.EventOFPSwitchFeatures, MAIN_DISPATCHER) def features_replay_handler(self, ev): if self.current is None: pass else: self.run_verify(ev) @set_ev_cls(ofp_event.EventOFPGetConfigReply, MAIN_DISPATCHER) def get_config_replay_handler(self, ev): self.run_verify(ev) @set_ev_cls(ofp_event.EventOFPBarrierReply, MAIN_DISPATCHER) def barrier_replay_handler(self, ev): if self.current == 'test_barrier_request': self.run_verify(ev) @set_ev_cls(ofp_event.EventOFPPortStatus, MAIN_DISPATCHER) def port_status_handler(self, ev): pass @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER) def packet_in_handler(self, ev): if self.current.find('packet_in'): self.run_verify(ev) @set_ev_cls(ofp_event.EventOFPFlowRemoved, MAIN_DISPATCHER) def flow_removed_handler(self, ev): if self.current.find('flow_removed') > 0: self.run_verify(ev) @set_ev_cls(ofp_event.EventOFPErrorMsg, MAIN_DISPATCHER) def error_handler(self, ev): if self.current.find('error') > 0: self.run_verify(ev) def is_supported(self, t): unsupported = [ ] for u in unsupported: if t.find(u) != -1: return False return True ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/integrated/test_vrrp_linux_multi.py0000664000175000017500000000641300000000000024616 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013 Isaku Yamahata # # 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. r""" Usage: osken-manager --verbose \ os_ken.services.protocols.vrrp.dumper \ os_ken.services.protocols.vrrp.sample_manager.py \ os_ken.tests.integrated.test_vrrp_linux_multi \ os_ken.app.rest os_ken.services.protocols.vrrp.dumper is optional. os_ken.app.rest is merely to prevent osken-manager from exiting. ---------------- /--<--veth0-->| | OSKen | linux bridge |<--veth2--> command to generate packets \--<--veth1-->| (vrrpbr) | ---------------- # ip link add veth0 type veth peer name veth0-br # ip link add veth1 type veth peer name veth1-br # ip link add veth2 type veth peer name veth2-br # ip link add vrrpbr type bridge # ip link set dev veth0-br master vrrpbr # ip link set dev veth1-br master vrrpbr # ip link set dev veth2-br master vrrpbr # ip link set veth0 up # ip link set veth0-br up # ip link set veth1 up # ip link set veth1-br up # ip link set veth2 up # ip link set veth2-br up # ip link set vrrpbr up if you like, capture packets on each interfaces like # tshark -i vrrpbr # tshark -i veth0 # tshark -i veth1 # tshark -i veth2 virtual router mac address: 00:00:5E:00:01:{VRID} = 00:00:5E:00:01:07 during working, send packets destined to mac address 00:00:5E:00:01:07 from veth2 by packet generator like packeth NOTE: vrid: 7 and ip address: 10.0.0.1... are hardcoded below """ from os_ken.base import app_manager from os_ken.lib import hub from os_ken.lib import mac as lib_mac from os_ken.lib.packet import vrrp from os_ken.services.protocols.vrrp import api as vrrp_api from os_ken.services.protocols.vrrp import event as vrrp_event from os_ken.services.protocols.vrrp import monitor_linux from . import vrrp_common class VRRPConfigApp(vrrp_common.VRRPCommon): _IFNAME0 = 'veth0' _IFNAME1 = 'veth1' def __init__(self, *args, **kwargs): super(VRRPConfigApp, self).__init__(*args, **kwargs) def start(self): hub.spawn(self._main) def _configure_vrrp_router(self, vrrp_version, priority, primary_ip_address, ifname, vrid): interface = vrrp_event.VRRPInterfaceNetworkDevice( lib_mac.DONTCARE_STR, primary_ip_address, None, ifname) self.logger.debug('%s', interface) vip = '10.0.%d.1' % vrid ip_addresses = [vip] config = vrrp_event.VRRPConfig( version=vrrp_version, vrid=vrid, priority=priority, ip_addresses=ip_addresses) self.logger.debug('%s', config) rep = vrrp_api.vrrp_config(self, interface, config) self.logger.debug('%s', rep) return rep ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/integrated/test_vrrp_linux_multi.sh0000664000175000017500000000216300000000000024576 0ustar00zuulzuul00000000000000#! /bin/sh # Copyright (C) 2013 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013 YAMAMOTO Takashi # # 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. ip link add veth0 type veth peer name veth0-br ip link add veth1 type veth peer name veth1-br ip link add veth2 type veth peer name veth2-br ip link add vrrpbr type bridge ip link set dev veth0-br master vrrpbr ip link set dev veth1-br master vrrpbr ip link set dev veth2-br master vrrpbr ip link set veth0 up ip link set veth0-br up ip link set veth1 up ip link set veth1-br up ip link set veth2 up ip link set veth2-br up ip link set vrrpbr up ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/integrated/test_vrrp_multi.py0000664000175000017500000001175400000000000023403 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013 Isaku Yamahata # # 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. r""" Usage: osken-manager --verbose \ os_ken.topology.switches \ os_ken.tests.integrated.test_vrrp_multi \ os_ken.services.protocols.vrrp.dumper os_ken.services.protocols.vrrp.dumper is optional. +---+ ---------------- /--|OVS|<--veth-->| | OSKen +---+ | linux bridge |<--veth--> command to generate packets \--|OVS|<--veth-->| | +---+ ---------------- configure OVSs to connect os_ken example # ip link add br0 type bridge # ip link add veth0-ovs type veth peer name veth0-br # ip link add veth1-ovs type veth peer name veth1-br # ip link set dev veth0-br master b0 # ip link set dev veth1-br master b0 # ip link show type bridge 22: b0: mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether d6:97:42:8a:55:0e brd ff:ff:ff:ff:ff:ff # bridge link show 23: veth0-br state DOWN @veth0-ovs: mtu 1500 master b0 state disabled priority 32 cost 2 24: veth1-br state DOWN @veth1-ovs: mtu 1500 master b0 state disabled priority 32 cost 2 # ovs-vsctl add-br s0 # ovs-vsctl add-port s0 veth0-ovs # ovs-vsctl add-br s1 # ovs-vsctl add-port s1 veth1-ovs # ovs-vsctl set-controller s0 tcp:127.0.0.1:6633 # ovs-vsctl set bridge s0 protocols='[OpenFlow12]' # ovs-vsctl set-controller s1 tcp:127.0.0.1:6633 # ovs-vsctl set bridge s1 protocols='[OpenFlow12]' # ovs-vsctl show 20c2a046-ae7e-4453-a576-11034db24985 Manager "ptcp:6634" Bridge "s0" Controller "tcp:127.0.0.1:6633" is_connected: true Port "veth0-ovs" Interface "veth0-ovs" Port "s0" Interface "s0" type: internal Bridge "s1" Controller "tcp:127.0.0.1:6633" is_connected: true Port "veth1-ovs" Interface "veth1-ovs" Port "s1" Interface "s1" type: internal ovs_version: "1.9.90" # ip link veth0-br set up # ip link veth0-ovs set up # ip link veth1-br set up # ip link veth1-ovs set up # ip link b0 set up """ from os_ken.base import app_manager from os_ken.controller import handler from os_ken.lib import dpid as lib_dpid from os_ken.lib import hub from os_ken.lib.packet import vrrp from os_ken.services.protocols.vrrp import api as vrrp_api from os_ken.services.protocols.vrrp import event as vrrp_event from os_ken.services.protocols.vrrp import monitor_openflow from os_ken.topology import event as topo_event from os_ken.topology import api as topo_api from . import vrrp_common class VRRPConfigApp(vrrp_common.VRRPCommon): _IFNAME0 = 0 _IFNAME1 = 1 def __init__(self, *args, **kwargs): super(VRRPConfigApp, self).__init__(*args, **kwargs) self.start_main = False @handler.set_ev_cls(topo_event.EventSwitchEnter) def _switch_enter_handler(self, ev): if self.start_main: return switches = topo_api.get_switch(self) if len(switches) < 2: return self.start_main = True app_mgr = app_manager.AppManager.get_instance() self.logger.debug('%s', app_mgr.applications) self.switches = app_mgr.applications['switches'] hub.spawn(self._main) def _configure_vrrp_router(self, vrrp_version, priority, ip_addr, switch_index, vrid): switches = self.switches self.logger.debug('%s', switches.dps) dpid = sorted(switches.dps.keys())[switch_index] self.logger.debug('%s', lib_dpid.dpid_to_str(dpid)) self.logger.debug('%s', switches.port_state) # hack: use the smallest port no to avoid picking OVS local port port_no = sorted(switches.port_state[dpid].keys())[0] self.logger.debug('%d', port_no) port = switches.port_state[dpid][port_no] self.logger.debug('%s', port) mac = port.hw_addr self.logger.debug('%s', mac) interface = vrrp_event.VRRPInterfaceOpenFlow( mac, ip_addr, None, dpid, port_no) self.logger.debug('%s', interface) config = vrrp_event.VRRPConfig( version=vrrp_version, vrid=vrid, priority=priority, ip_addresses=[ip_addr]) self.logger.debug('%s', config) rep = vrrp_api.vrrp_config(self, interface, config) self.logger.debug('%s', rep) return rep ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/integrated/test_vrrp_multi.sh0000664000175000017500000000237100000000000023360 0ustar00zuulzuul00000000000000#! /bin/sh # Copyright (C) 2013 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013 YAMAMOTO Takashi # # 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. if [ -z "$VSCTL" ]; then VSCTL=ovs-vsctl fi # create two bridges. # conncect them using patch ports. create() { BR=$1 LOCAL_PORT=patch$2 PEER_PORT=patch$3 CONT=$4 ${VSCTL} add-br ${BR} -- set bridge ${BR} datapath_type=netdev ${VSCTL} add-port ${BR} ${LOCAL_PORT} ${VSCTL} set interface ${LOCAL_PORT} type=patch ${VSCTL} set interface ${LOCAL_PORT} options:peer=${PEER_PORT} ${VSCTL} set bridge ${BR} protocols='[OpenFlow12]' ${VSCTL} set-controller ${BR} ${CONT} } CONT=tcp:127.0.0.1:6633 create s0 0 1 ${CONT} create s1 1 0 ${CONT} ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/integrated/tester.py0000664000175000017500000001613000000000000021440 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone 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. # vim: tabstop=4 shiftwidth=4 softtabstop=4 import sys import logging import itertools from os_ken import utils from os_ken.lib import mac from os_ken.base import app_manager from os_ken.controller import ofp_event from os_ken.controller import handler from os_ken.controller import dpset from os_ken.controller.handler import MAIN_DISPATCHER from os_ken.controller.handler import CONFIG_DISPATCHER from os_ken.controller.handler import set_ev_cls from os_ken.ofproto import ofproto_v1_0 from os_ken.ofproto import ofproto_v1_2 LOG = logging.getLogger(__name__) LOG_TEST_START = 'TEST_START: %s' LOG_TEST_RESULTS = 'TEST_RESULTS:' LOG_TEST_FINISH = 'TEST_FINISHED: Completed=[%s] (OK=%s NG=%s SKIP=%s)' LOG_TEST_UNSUPPORTED = 'SKIP (unsupported)' class TestFlowBase(app_manager.OSKenApp): """ To run the tests is required for the following pair of functions. 1. test_() To send flows to switch. 2. verify_() or _verify_default() To check flows of switch. """ _CONTEXTS = {'dpset': dpset.DPSet} def __init__(self, *args, **kwargs): super(TestFlowBase, self).__init__(*args, **kwargs) self.pending = [] self.results = {} self.current = None self.unclear = 0 for t in dir(self): if t.startswith("test_"): self.pending.append(t) self.pending.sort(reverse=True) self.unclear = len(self.pending) def delete_all_flows(self, dp): if dp.ofproto == ofproto_v1_0: match = dp.ofproto_parser.OFPMatch(dp.ofproto.OFPFW_ALL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) m = dp.ofproto_parser.OFPFlowMod(dp, match, 0, dp.ofproto.OFPFC_DELETE, 0, 0, 0, 0, dp.ofproto.OFPP_NONE, 0, None) elif dp.ofproto == ofproto_v1_2: match = dp.ofproto_parser.OFPMatch() m = dp.ofproto_parser.OFPFlowMod(dp, 0, 0, dp.ofproto.OFPTT_ALL, dp.ofproto.OFPFC_DELETE, 0, 0, 0, 0xffffffff, dp.ofproto.OFPP_ANY, dp.ofproto.OFPG_ANY, 0, match, []) dp.send_msg(m) def send_flow_stats(self, dp): if dp.ofproto == ofproto_v1_0: match = dp.ofproto_parser.OFPMatch(dp.ofproto.OFPFW_ALL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) m = dp.ofproto_parser.OFPFlowStatsRequest(dp, 0, match, 0, dp.ofproto.OFPP_NONE) elif dp.ofproto == ofproto_v1_2: match = dp.ofproto_parser.OFPMatch() m = dp.ofproto_parser.OFPFlowStatsRequest(dp, dp.ofproto.OFPTT_ALL, dp.ofproto.OFPP_ANY, dp.ofproto.OFPG_ANY, 0, 0, match) dp.send_msg(m) def verify_default(self, dp, stats): return 'function %s() is not found.' % ("verify" + self.current[4:], ) def start_next_test(self, dp): self.delete_all_flows(dp) dp.send_barrier() if len(self.pending): t = self.pending.pop() if self.is_supported(t): LOG.info(LOG_TEST_START, t) self.current = t getattr(self, t)(dp) dp.send_barrier() self.send_flow_stats(dp) else: self.results[t] = LOG_TEST_UNSUPPORTED self.unclear -= 1 self.start_next_test(dp) else: self.print_results() def print_results(self): LOG.info("TEST_RESULTS:") ok = 0 ng = 0 skip = 0 for t in sorted(self.results.keys()): if self.results[t] is True: ok += 1 elif self.results[t] == LOG_TEST_UNSUPPORTED: skip += 1 else: ng += 1 LOG.info(" %s: %s", t, self.results[t]) LOG.info(LOG_TEST_FINISH, self.unclear == 0, ok, ng, skip) @handler.set_ev_cls(ofp_event.EventOFPFlowStatsReply, handler.MAIN_DISPATCHER) def flow_reply_handler(self, ev): self.run_verify(ev) @handler.set_ev_cls(ofp_event.EventOFPStatsReply, handler.MAIN_DISPATCHER) def stats_reply_handler(self, ev): self.run_verify(ev) def run_verify(self, ev): msg = ev.msg dp = msg.datapath verify_func = self.verify_default v = "verify" + self.current[4:] if hasattr(self, v): verify_func = getattr(self, v) result = verify_func(dp, msg.body) if result is True: self.unclear -= 1 self.results[self.current] = result self.start_next_test(dp) @handler.set_ev_cls(dpset.EventDP) def handler_datapath(self, ev): if ev.enter: self.start_next_test(ev.dp) @set_ev_cls(ofp_event.EventOFPBarrierReply, MAIN_DISPATCHER) def barrier_replay_handler(self, ev): pass def haddr_to_str(self, addr): return mac.haddr_to_str(addr) def haddr_to_bin(self, string): return mac.haddr_to_bin(string) def haddr_masked(self, haddr_bin, mask_bin): return mac.haddr_bitand(haddr_bin, mask_bin) def ipv4_to_str(self, integre): ip_list = [str((integre >> (24 - (n * 8)) & 255)) for n in range(4)] return '.'.join(ip_list) def ipv4_to_int(self, string): ip = string.split('.') assert len(ip) == 4 i = 0 for b in ip: b = int(b) i = (i << 8) | b return i def ipv4_masked(self, ip_int, mask_int): return ip_int & mask_int def ipv6_to_str(self, integres): return ':'.join(hex(x)[2:] for x in integres) def ipv6_to_int(self, string): ip = string.split(':') assert len(ip) == 8 return [int(x, 16) for x in ip] def ipv6_masked(self, ipv6_int, mask_int): return [x & y for (x, y) in itertools.izip(ipv6_int, mask_int)] def is_supported(self, t): return True ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/integrated/vrrp_common.py0000664000175000017500000002126300000000000022476 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013 Isaku Yamahata # # 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. import time import random from os_ken.base import app_manager from os_ken.lib import hub from os_ken.lib import mac as lib_mac from os_ken.lib.packet import vrrp from os_ken.services.protocols.vrrp import api as vrrp_api from os_ken.services.protocols.vrrp import event as vrrp_event _VRID = 7 _PRIMARY_IP_ADDRESS0 = '10.0.0.2' _PRIMARY_IP_ADDRESS1 = '10.0.0.3' class VRRPCommon(app_manager.OSKenApp): _IFNAME0 = None _IFNAME1 = None def __init__(self, *args, **kwargs): super(VRRPCommon, self).__init__(*args, **kwargs) def _main(self): self._main_version(vrrp.VRRP_VERSION_V3) self._main_version(vrrp.VRRP_VERSION_V2) print("done!") def _main_version(self, vrrp_version): self._main_version_priority(vrrp_version, vrrp.VRRP_PRIORITY_ADDRESS_OWNER) self._main_version_priority(vrrp_version, vrrp.VRRP_PRIORITY_BACKUP_MAX) self._main_version_priority(vrrp_version, vrrp.VRRP_PRIORITY_BACKUP_DEFAULT) self._main_version_priority(vrrp_version, vrrp.VRRP_PRIORITY_BACKUP_MIN) def _main_version_priority(self, vrrp_version, priority): self._main_version_priority_sleep(vrrp_version, priority, False) self._main_version_priority_sleep(vrrp_version, priority, True) def _check(self, vrrp_api, instances): while True: while True: rep = vrrp_api.vrrp_list(self) if len(rep.instance_list) >= len(instances) * 2: if any(i.state == vrrp_event.VRRP_STATE_INITIALIZE for i in rep.instance_list): continue break print('%s / %s' % (len(rep.instance_list), len(instances) * 2)) time.sleep(1) # for i in rep.instance_list: # print('%s %s %s %s %s' % (i.instance_name, # i.monitor_name, # i.config, # i.interface, # i.state)) assert len(rep.instance_list) == len(instances) * 2 num_of_master = 0 d = dict(((i.instance_name, i) for i in rep.instance_list)) bad = 0 for i in rep.instance_list: assert i.state in (vrrp_event.VRRP_STATE_MASTER, vrrp_event.VRRP_STATE_BACKUP) if i.state == vrrp_event.VRRP_STATE_MASTER: num_of_master += 1 vr = instances[i.config.vrid] if (vr[0].config.priority > vr[1].config.priority and i.instance_name == vr[1].instance_name) or \ (vr[0].config.priority < vr[1].config.priority and i.instance_name == vr[0].instance_name): if i.state == vrrp_event.VRRP_STATE_MASTER: print("bad master:") print('%s %s' % (d[vr[0].instance_name].state, d[vr[0].instance_name].config.priority)) print('%s %s' % (d[vr[1].instance_name].state, d[vr[1].instance_name].config.priority)) bad += 1 # assert i.state != vrrp_event.VRRP_STATE_MASTER if bad > 0: # this could be a transient state print("%s bad masters" % bad) time.sleep(1) continue if num_of_master >= len(instances): assert num_of_master == len(instances) break print('%s / %s' % (num_of_master, len(instances))) time.sleep(1) continue def _main_version_priority_sleep(self, vrrp_version, priority, do_sleep): app_mgr = app_manager.AppManager.get_instance() self.logger.debug('%s', app_mgr.applications) vrrp_mgr = app_mgr.applications['VRRPManager'] step = 5 instances = {} for vrid in range(1, 256, step): if vrid == _VRID: continue print("vrid %s" % vrid) l = {} prio = max(vrrp.VRRP_PRIORITY_BACKUP_MIN, min(vrrp.VRRP_PRIORITY_BACKUP_MAX, vrid)) rep0 = self._configure_vrrp_router(vrrp_version, prio, _PRIMARY_IP_ADDRESS0, self._IFNAME0, vrid) assert rep0.instance_name is not None l[0] = rep0 prio = max(vrrp.VRRP_PRIORITY_BACKUP_MIN, min(vrrp.VRRP_PRIORITY_BACKUP_MAX, 256 - vrid)) rep1 = self._configure_vrrp_router(vrrp_version, prio, _PRIMARY_IP_ADDRESS1, self._IFNAME1, vrid) assert rep1.instance_name is not None l[1] = rep1 instances[vrid] = l print("vrid %s" % _VRID) l = {} rep0 = self._configure_vrrp_router(vrrp_version, priority, _PRIMARY_IP_ADDRESS0, self._IFNAME0, _VRID) assert rep0.instance_name is not None l[0] = rep0 rep1 = self._configure_vrrp_router( vrrp_version, vrrp.VRRP_PRIORITY_BACKUP_DEFAULT, _PRIMARY_IP_ADDRESS1, self._IFNAME1, _VRID) assert rep1.instance_name is not None l[1] = rep1 instances[_VRID] = l self.logger.debug('%s', vrrp_mgr._instances) if do_sleep: print("priority %s" % priority) print("waiting for instances starting") self._check(vrrp_api, instances) for vrid in instances.keys(): if vrid == _VRID: continue which = vrid & 1 new_priority = int(random.uniform(vrrp.VRRP_PRIORITY_BACKUP_MIN, vrrp.VRRP_PRIORITY_BACKUP_MAX)) i = instances[vrid][which] vrrp_api.vrrp_config_change(self, i.instance_name, priority=new_priority) i.config.priority = new_priority if do_sleep: print("priority shuffled") self._check(vrrp_api, instances) for vrid in instances.keys(): if vrid == _VRID: continue which = vrid & 1 vrrp_api.vrrp_shutdown(self, instances[vrid][which].instance_name) vrrp_api.vrrp_shutdown(self, instances[_VRID][0].instance_name) if do_sleep: print("shutting down instances") while True: rep = vrrp_api.vrrp_list(self) if len(rep.instance_list) <= len(instances): break print("left %s" % len(rep.instance_list)) time.sleep(1) assert len(rep.instance_list) == len(instances) print("waiting for the rest becoming master") while True: rep = vrrp_api.vrrp_list(self) if all(i.state == vrrp_event.VRRP_STATE_MASTER for i in rep.instance_list): break time.sleep(1) vrrp_api.vrrp_shutdown(self, instances[_VRID][1].instance_name) for vrid in instances.keys(): if vrid == _VRID: continue which = 1 - (vrid & 1) vrrp_api.vrrp_shutdown(self, instances[vrid][which].instance_name) print("waiting for instances shutting down") while True: rep = vrrp_api.vrrp_list(self) if not rep.instance_list: break print("left %s" % len(rep.instance_list)) time.sleep(1) ././@PaxHeader0000000000000000000000000000003300000000000011451 xustar000000000000000027 mtime=1724334546.130107 os-ken-2.10.0/os_ken/tests/mininet/0000775000175000017500000000000000000000000017074 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.0301008 os-ken-2.10.0/os_ken/tests/mininet/l2/0000775000175000017500000000000000000000000017411 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003300000000000011451 xustar000000000000000027 mtime=1724334546.134107 os-ken-2.10.0/os_ken/tests/mininet/l2/mpls/0000775000175000017500000000000000000000000020364 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/mininet/l2/mpls/PopMPLS_mpls.mn0000664000175000017500000000023300000000000023203 0ustar00zuulzuul00000000000000TEST_NAME=MPLS-PopMPLS DUMP_HOST=h2 DUMP_IF=h2-eth0 OSKEN_APP=test_mpls PCAP_MZ="-t tcp -M 80 -P $TEST_NAME -c 3 -r" PCAP_FILTER="! mpls && ip.proto==TCP" ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/mininet/l2/mpls/PushMPLS_ip.mn0000664000175000017500000000024400000000000023023 0ustar00zuulzuul00000000000000TEST_NAME=IP-PushMPLS DUMP_HOST=h2 DUMP_IF=h2-eth0 OSKEN_APP=test_mpls PCAP_MZ="-t tcp -P $TEST_NAME -c 3 -b 00:00:00:00:00:02" PCAP_FILTER="mpls && ip.proto==TCP" ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/mininet/l2/mpls/PushMPLS_mpls.mn0000664000175000017500000000027100000000000023366 0ustar00zuulzuul00000000000000TEST_NAME=MPLS-PushMPLS DUMP_HOST=h2 DUMP_IF=h2-eth0 OSKEN_APP=test_mpls PCAP_MZ="-t tcp -M 100 -P $TEST_NAME -c 3 -r" PCAP_FILTER="mpls.label==100 && mpls.label==200 && ip.proto==TCP" ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/mininet/l2/mpls/test_mpls.py0000664000175000017500000001120200000000000022744 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone 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. import logging import struct from os_ken.base import app_manager from os_ken.controller import ofp_event from os_ken.controller import dpset from os_ken.controller.handler import MAIN_DISPATCHER from os_ken.controller.handler import set_ev_cls from os_ken.ofproto import ofproto_v1_2 from os_ken.ofproto import ether from os_ken.lib.mac import haddr_to_str LOG = logging.getLogger(__name__) class RunTestMininet(app_manager.OSKenApp): _CONTEXTS = {'dpset': dpset.DPSet} OFP_VERSIONS = [ofproto_v1_2.OFP_VERSION] def __init__(self, *args, **kwargs): super(RunTestMininet, self).__init__(*args, **kwargs) def _add_flow(self, dp, match, actions): inst = [dp.ofproto_parser.OFPInstructionActions( dp.ofproto.OFPIT_APPLY_ACTIONS, actions)] mod = dp.ofproto_parser.OFPFlowMod( dp, cookie=0, cookie_mask=0, table_id=0, command=dp.ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=0, priority=0xff, buffer_id=0xffffffff, out_port=dp.ofproto.OFPP_ANY, out_group=dp.ofproto.OFPG_ANY, flags=0, match=match, instructions=inst) dp.send_msg(mod) def _define_flow(self, dp): in_port = 1 out_port = 2 eth_IP = ether.ETH_TYPE_IP eth_MPLS = ether.ETH_TYPE_MPLS # MPLS(80) -> PopMPLS LOG.debug("--- add_flow PopMPLS") m_label = 80 match = dp.ofproto_parser.OFPMatch() match.set_in_port(in_port) match.set_dl_type(eth_MPLS) match.set_mpls_label(m_label) actions = [dp.ofproto_parser.OFPActionPopMpls(eth_IP), dp.ofproto_parser.OFPActionOutput(out_port, 0)] self._add_flow(dp, match, actions) # IP -> PushMPLS(90) LOG.debug("--- add_flow PushMPLS") s_label = 90 match = dp.ofproto_parser.OFPMatch() match.set_in_port(in_port) match.set_dl_type(eth_IP) f = dp.ofproto_parser.OFPMatchField.make( dp.ofproto.OXM_OF_MPLS_LABEL, s_label) actions = [dp.ofproto_parser.OFPActionPushMpls(eth_MPLS), dp.ofproto_parser.OFPActionSetField(f), dp.ofproto_parser.OFPActionOutput(out_port, 0)] self._add_flow(dp, match, actions) # MPLS(100) -> PushMPLS(200) LOG.debug("--- add_flow PushMPLS") m_label = 100 s_label = 200 match = dp.ofproto_parser.OFPMatch() match.set_in_port(in_port) match.set_dl_type(eth_MPLS) match.set_mpls_label(m_label) f = dp.ofproto_parser.OFPMatchField.make( dp.ofproto.OXM_OF_MPLS_LABEL, s_label) actions = [dp.ofproto_parser.OFPActionPushMpls(eth_MPLS), dp.ofproto_parser.OFPActionSetField(f), dp.ofproto_parser.OFPActionOutput(out_port, 0)] self._add_flow(dp, match, actions) # MPLS(1000):MPLS -> PopMPLS # LOG.debug("--- add_flow PopMPLS") # SKIP: ovs not supported m_label = 1000 match = dp.ofproto_parser.OFPMatch() match.set_in_port(in_port) match.set_dl_type(eth_MPLS) match.set_mpls_label(m_label) actions = [dp.ofproto_parser.OFPActionPopMpls(eth_MPLS), dp.ofproto_parser.OFPActionOutput(out_port, 0)] # self._add_flow(dp, match, actions) @set_ev_cls(dpset.EventDP, dpset.DPSET_EV_DISPATCHER) def handler_datapath(self, ev): if ev.enter: self._define_flow(ev.dp) @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER) def packet_in_handler(self, ev): msg = ev.msg dst, src, eth_type = struct.unpack_from('!6s6sH', buffer(msg.data), 0) in_port = msg.match.fields[0].value LOG.info("----------------------------------------") LOG.info("* PacketIn") LOG.info("in_port=%d, eth_type: %s", in_port, hex(eth_type)) LOG.info("packet reason=%d buffer_id=%d", msg.reason, msg.buffer_id) LOG.info("packet in datapath_id=%s src=%s dst=%s", msg.datapath.id, haddr_to_str(src), haddr_to_str(dst)) ././@PaxHeader0000000000000000000000000000003300000000000011451 xustar000000000000000027 mtime=1724334546.134107 os-ken-2.10.0/os_ken/tests/mininet/l2/vlan/0000775000175000017500000000000000000000000020351 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/mininet/l2/vlan/PopVLAN_vlan.mn0000664000175000017500000000023200000000000023141 0ustar00zuulzuul00000000000000TEST_NAME=VLAN-PopVLAN DUMP_HOST=h2 DUMP_IF=h2-eth0 OSKEN_APP=test_vlan PCAP_MZ="-t tcp -Q 8 -P $TEST_NAME -c 3 -r" PCAP_FILTER="! vlan && ip.proto==TCP" ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/mininet/l2/vlan/PopVLAN_vlanvlan.mn0000664000175000017500000000027100000000000024025 0ustar00zuulzuul00000000000000TEST_NAME=VLAN:VLAN-PopVLAN DUMP_HOST=h2 DUMP_IF=h2-eth0 OSKEN_APP=test_vlan PCAP_MZ="-t tcp -Q 100,99 -P $TEST_NAME -c 3 -r" PCAP_FILTER="vlan.id!=100 && vlan.id==99 && ip.proto==TCP" ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/mininet/l2/vlan/PushVLAN_icmp.mn0000664000175000017500000000025600000000000023320 0ustar00zuulzuul00000000000000TEST_NAME=ICMP-PushVLAN DUMP_HOST=h2 DUMP_IF=h2-eth0 OSKEN_APP=test_vlan PCAP_MZ="-t icmp ping -P $TEST_NAME -c 3 -r -b 00:00:00:00:00:02" PCAP_FILTER="vlan && icmp.type==8" ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/mininet/l2/vlan/test_vlan.py0000664000175000017500000001135400000000000022726 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone 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. import logging import struct from os_ken.base import app_manager from os_ken.controller import ofp_event from os_ken.controller import dpset from os_ken.controller.handler import MAIN_DISPATCHER from os_ken.controller.handler import set_ev_cls from os_ken.ofproto import ofproto_v1_2 from os_ken.ofproto import ether from os_ken.ofproto import inet from os_ken.lib.mac import haddr_to_str LOG = logging.getLogger(__name__) class RunTestMininet(app_manager.OSKenApp): _CONTEXTS = {'dpset': dpset.DPSet} OFP_VERSIONS = [ofproto_v1_2.OFP_VERSION] def __init__(self, *args, **kwargs): super(RunTestMininet, self).__init__(*args, **kwargs) def _add_flow(self, dp, match, actions): inst = [dp.ofproto_parser.OFPInstructionActions( dp.ofproto.OFPIT_APPLY_ACTIONS, actions)] mod = dp.ofproto_parser.OFPFlowMod( dp, cookie=0, cookie_mask=0, table_id=0, command=dp.ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=0, priority=0xff, buffer_id=0xffffffff, out_port=dp.ofproto.OFPP_ANY, out_group=dp.ofproto.OFPG_ANY, flags=0, match=match, instructions=inst) dp.send_msg(mod) def _define_flow(self, dp): in_port = 1 out_port = 2 eth_IP = ether.ETH_TYPE_IP eth_VLAN = ether.ETH_TYPE_8021Q ip_ICMP = inet.IPPROTO_ICMP # VLAN(8) -> PopVLAN LOG.debug("--- add_flow VLAN(8) to PopVLAN") m_vid = 8 match = dp.ofproto_parser.OFPMatch() match.set_in_port(in_port) match.set_dl_type(eth_IP) match.set_vlan_vid(m_vid) actions = [dp.ofproto_parser.OFPActionPopVlan(), dp.ofproto_parser.OFPActionOutput(out_port, 0)] self._add_flow(dp, match, actions) # ICMP -> PushVLAN(9) LOG.debug("--- add_flow ICMP to PushVLAN(9)") s_vid = 9 match = dp.ofproto_parser.OFPMatch() match.set_in_port(in_port) match.set_dl_type(eth_IP) match.set_ip_proto(ip_ICMP) f = dp.ofproto_parser.OFPMatchField.make( dp.ofproto.OXM_OF_VLAN_VID, s_vid) actions = [dp.ofproto_parser.OFPActionPushVlan(eth_VLAN), dp.ofproto_parser.OFPActionSetField(f), dp.ofproto_parser.OFPActionOutput(out_port, 0)] self._add_flow(dp, match, actions) # VLAN(10) -> PushVLAN(20) # LOG.debug("--- add_flow VLAN(10) to PushVLAN(100)") # SKIP: ovs not supported m_vid = 10 s_vid = 20 match = dp.ofproto_parser.OFPMatch() match.set_in_port(in_port) match.set_dl_type(eth_IP) match.set_vlan_vid(m_vid) f = dp.ofproto_parser.OFPMatchField.make( dp.ofproto.OXM_OF_VLAN_VID, s_vid) actions = [dp.ofproto_parser.OFPActionPushVlan(eth_VLAN), dp.ofproto_parser.OFPActionSetField(f), dp.ofproto_parser.OFPActionOutput(out_port, 0)] # self._add_flow(dp, match, actions) # VLAN(100):VLAN -> PopVLAN LOG.debug("--- add_flow VLAN(100):VLAN to PopVLAN") m_vid = 100 match = dp.ofproto_parser.OFPMatch() match.set_in_port(in_port) match.set_dl_type(eth_VLAN) match.set_vlan_vid(m_vid) actions = [dp.ofproto_parser.OFPActionPopVlan(), dp.ofproto_parser.OFPActionOutput(out_port, 0)] self._add_flow(dp, match, actions) @set_ev_cls(dpset.EventDP, dpset.DPSET_EV_DISPATCHER) def handler_datapath(self, ev): if ev.enter: self._define_flow(ev.dp) @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER) def packet_in_handler(self, ev): msg = ev.msg dst, src, eth_type = struct.unpack_from('!6s6sH', buffer(msg.data), 0) in_port = msg.match.fields[0].value LOG.info("----------------------------------------") LOG.info("* PacketIn") LOG.info("in_port=%d, eth_type: %s", in_port, hex(eth_type)) LOG.info("packet reason=%d buffer_id=%d", msg.reason, msg.buffer_id) LOG.info("packet in datapath_id=%s src=%s dst=%s", msg.datapath.id, haddr_to_str(src), haddr_to_str(dst)) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.0301008 os-ken-2.10.0/os_ken/tests/mininet/l3/0000775000175000017500000000000000000000000017412 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003300000000000011451 xustar000000000000000027 mtime=1724334546.134107 os-ken-2.10.0/os_ken/tests/mininet/l3/icmp/0000775000175000017500000000000000000000000020342 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/mininet/l3/icmp/ICMP_ping.mn0000664000175000017500000000022300000000000022440 0ustar00zuulzuul00000000000000TEST_NAME=ICMP-Req DUMP_HOST=h2 DUMP_IF=h2-eth0 OSKEN_APP=test_icmp PCAP_MZ="-t icmp ping -c 3 -r -b 00:00:00:00:00:00" PCAP_FILTER="icmp.type==8" ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/mininet/l3/icmp/ICMP_reply.mn0000664000175000017500000000020600000000000022637 0ustar00zuulzuul00000000000000TEST_NAME=ICMP-Reply DUMP_HOST=h1 DUMP_IF=h1-eth0 OSKEN_APP=test_icmp PCAP_MZ="-t icmp ping -c 3 -r -B h2" PCAP_FILTER="icmp.type==0" ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/mininet/l3/icmp/test_icmp.py0000664000175000017500000000571000000000000022706 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone 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. import logging import struct from os_ken.base import app_manager from os_ken.controller import ofp_event from os_ken.controller import dpset from os_ken.controller.handler import MAIN_DISPATCHER from os_ken.controller.handler import set_ev_cls from os_ken.ofproto import ofproto_v1_2 from os_ken.lib.mac import haddr_to_str LOG = logging.getLogger(__name__) class RunTestMininet(app_manager.OSKenApp): _CONTEXTS = {'dpset': dpset.DPSet} OFP_VERSIONS = [ofproto_v1_2.OFP_VERSION] def __init__(self, *args, **kwargs): super(RunTestMininet, self).__init__(*args, **kwargs) def _add_flow(self, dp, match, actions): inst = [dp.ofproto_parser.OFPInstructionActions( dp.ofproto.OFPIT_APPLY_ACTIONS, actions)] mod = dp.ofproto_parser.OFPFlowMod( dp, cookie=0, cookie_mask=0, table_id=0, command=dp.ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=0, priority=0xff, buffer_id=0xffffffff, out_port=dp.ofproto.OFPP_ANY, out_group=dp.ofproto.OFPG_ANY, flags=0, match=match, instructions=inst) dp.send_msg(mod) def _define_flow(self, dp): in_port = 1 out_port = 2 # port:1 -> port:2 match = dp.ofproto_parser.OFPMatch() match.set_in_port(in_port) actions = [dp.ofproto_parser.OFPActionOutput(out_port, 0)] self._add_flow(dp, match, actions) # port:1 -> port:2 match = dp.ofproto_parser.OFPMatch() match.set_in_port(out_port) actions = [dp.ofproto_parser.OFPActionOutput(in_port, 0)] self._add_flow(dp, match, actions) @set_ev_cls(dpset.EventDP, dpset.DPSET_EV_DISPATCHER) def handler_datapath(self, ev): if ev.enter: self._define_flow(ev.dp) @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER) def packet_in_handler(self, ev): msg = ev.msg dst, src, eth_type = struct.unpack_from('!6s6sH', buffer(msg.data), 0) in_port = msg.match.fields[0].value LOG.info("----------------------------------------") LOG.info("* PacketIn") LOG.info("in_port=%d, eth_type: %s", in_port, hex(eth_type)) LOG.info("packet reason=%d buffer_id=%d", msg.reason, msg.buffer_id) LOG.info("packet in datapath_id=%s src=%s dst=%s", msg.datapath.id, haddr_to_str(src), haddr_to_str(dst)) ././@PaxHeader0000000000000000000000000000003300000000000011451 xustar000000000000000027 mtime=1724334546.134107 os-ken-2.10.0/os_ken/tests/mininet/l3/ip_ttl/0000775000175000017500000000000000000000000020705 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/mininet/l3/ip_ttl/DecNwTtl.mn0000664000175000017500000000025000000000000022722 0ustar00zuulzuul00000000000000TEST_NAME=DecNwTtl DUMP_HOST=h2 DUMP_IF=h2-eth0 OSKEN_APP=test_ip_ttl PCAP_MZ="-t icmp ttl=64 -P $TEST_NAME -c 3 -b 00:00:00:00:00:02" PCAP_FILTER="icmp && ip.ttl==63" ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/mininet/l3/ip_ttl/test_ip_ttl.py0000664000175000017500000000567200000000000023623 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone 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. import logging import struct from os_ken.base import app_manager from os_ken.controller import ofp_event from os_ken.controller import dpset from os_ken.controller.handler import MAIN_DISPATCHER from os_ken.controller.handler import set_ev_cls from os_ken.ofproto import ofproto_v1_2 from os_ken.ofproto import ether from os_ken.lib.mac import haddr_to_str LOG = logging.getLogger(__name__) class RunTestMininet(app_manager.OSKenApp): _CONTEXTS = {'dpset': dpset.DPSet} OFP_VERSIONS = [ofproto_v1_2.OFP_VERSION] def __init__(self, *args, **kwargs): super(RunTestMininet, self).__init__(*args, **kwargs) def _add_flow(self, dp, match, actions): inst = [dp.ofproto_parser.OFPInstructionActions( dp.ofproto.OFPIT_APPLY_ACTIONS, actions)] mod = dp.ofproto_parser.OFPFlowMod( dp, cookie=0, cookie_mask=0, table_id=0, command=dp.ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=0, priority=0xff, buffer_id=0xffffffff, out_port=dp.ofproto.OFPP_ANY, out_group=dp.ofproto.OFPG_ANY, flags=0, match=match, instructions=inst) dp.send_msg(mod) def _define_flow(self, dp): in_port = 1 out_port = 2 eth_IP = ether.ETH_TYPE_IP # ICMP -> DecNwTtl LOG.debug("--- add_flow DecNwTtl") match = dp.ofproto_parser.OFPMatch() match.set_in_port(in_port) match.set_dl_type(eth_IP) actions = [dp.ofproto_parser.OFPActionDecNwTtl(), dp.ofproto_parser.OFPActionOutput(out_port, 0)] self._add_flow(dp, match, actions) @set_ev_cls(dpset.EventDP, dpset.DPSET_EV_DISPATCHER) def handler_datapath(self, ev): if ev.enter: self._define_flow(ev.dp) @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER) def packet_in_handler(self, ev): msg = ev.msg dst, src, eth_type = struct.unpack_from('!6s6sH', buffer(msg.data), 0) in_port = msg.match.fields[0].value LOG.info("----------------------------------------") LOG.info("* PacketIn") LOG.info("in_port=%d, eth_type: %s", in_port, hex(eth_type)) LOG.info("packet reason=%d buffer_id=%d", msg.reason, msg.buffer_id) LOG.info("packet in datapath_id=%s src=%s dst=%s", msg.datapath.id, haddr_to_str(src), haddr_to_str(dst)) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.0301008 os-ken-2.10.0/os_ken/tests/mininet/packet_lib/0000775000175000017500000000000000000000000021171 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003300000000000011451 xustar000000000000000027 mtime=1724334546.134107 os-ken-2.10.0/os_ken/tests/mininet/packet_lib/arp/0000775000175000017500000000000000000000000021753 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/mininet/packet_lib/arp/ARP_gratuitous.mn0000664000175000017500000000032700000000000025221 0ustar00zuulzuul00000000000000# test-GratuitousARP-request TEST_NAME=GARP-Request DUMP_HOST=h1 DUMP_IF=h1-eth0 OSKEN_APP=test_arp PCAP_MZ="-S" PCAP_FILTER="arp.isgratuitous && arp.src.proto_ipv4==10.0.0.100 && arp.src.hw_mac==fe:ee:ee:ee:ee:ef" ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/mininet/packet_lib/arp/ARP_reply.mn0000664000175000017500000000036100000000000024144 0ustar00zuulzuul00000000000000# test-ARP-reply TEST_NAME=ARP-Reply DUMP_HOST=h1 DUMP_IF=h1-eth0 OSKEN_APP=test_arp PCAP_MZ="-t arp request,targetip=10.0.0.100 -c 3 -r" PCAP_FILTER="arp.opcode==reply && arp.src.proto_ipv4==10.0.0.100 && arp.src.hw_mac==fe:ee:ee:ee:ee:ef" ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/mininet/packet_lib/arp/ARP_request.mn0000664000175000017500000000041500000000000024501 0ustar00zuulzuul00000000000000# test-ARP-request TEST_NAME=ARP-Request DUMP_HOST=h1 DUMP_IF=h1-eth0 OSKEN_APP=test_arp PCAP_MZ="-t arp request,targetip=10.0.0.1" PCAP_FILTER="arp.opcode==request && arp.src.proto_ipv4==10.0.0.100 && arp.dst.proto_ipv4==10.0.0.1 && arp.src.hw_mac==fe:ee:ee:ee:ee:ef" ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/mininet/packet_lib/arp/test_arp.py0000664000175000017500000001621500000000000024153 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone 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. # vim: tabstop=4 shiftwidth=4 softtabstop=4 import logging import array import netaddr from os_ken.base import app_manager from os_ken.controller import dpset from os_ken.controller import ofp_event from os_ken.controller import handler from os_ken.ofproto import ofproto_v1_2 from os_ken.ofproto import ether from os_ken.ofproto import inet from os_ken.lib import mac from os_ken.lib.packet import packet from os_ken.lib.packet import ethernet from os_ken.lib.packet import arp from os_ken.lib.packet import ipv4 from os_ken.lib.packet import icmp LOG = logging.getLogger(__name__) class RunTestMininet(app_manager.OSKenApp): _CONTEXTS = {'dpset': dpset.DPSet} OFP_VERSIONS = [ofproto_v1_2.OFP_VERSION] ZERO_MAC = mac.haddr_to_bin('00:00:00:00:00:00') BROADCAST_MAC = mac.haddr_to_bin('ff:ff:ff:ff:ff:ff') OSKEN_MAC = mac.haddr_to_bin('fe:ee:ee:ee:ee:ef') HOST_MAC = mac.haddr_to_bin('00:00:00:00:00:01') OSKEN_IP = int(netaddr.IPAddress('10.0.0.100')) HOST_IP = int(netaddr.IPAddress('10.0.0.1')) def __init__(self, *args, **kwargs): super(RunTestMininet, self).__init__(*args, **kwargs) def _send_msg(self, dp, data): buffer_id = 0xffffffff in_port = dp.ofproto.OFPP_LOCAL actions = [dp.ofproto_parser.OFPActionOutput(1, 0)] msg = dp.ofproto_parser.OFPPacketOut( dp, buffer_id, in_port, actions, data) dp.send_msg(msg) def _add_flow(self, dp, match, actions): inst = [dp.ofproto_parser.OFPInstructionActions( dp.ofproto.OFPIT_APPLY_ACTIONS, actions)] mod = dp.ofproto_parser.OFPFlowMod( dp, cookie=0, cookie_mask=0, table_id=0, command=dp.ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=0, priority=0xff, buffer_id=0xffffffff, out_port=dp.ofproto.OFPP_ANY, out_group=dp.ofproto.OFPG_ANY, flags=0, match=match, instructions=inst) dp.send_msg(mod) def _find_protocol(self, pkt, name): for p in pkt.protocols: if hasattr(p, 'protocol_name'): if p.protocol_name == name: return p def _get_protocols(self, pkt): protocols = {} for p in pkt: if hasattr(p, 'protocol_name'): protocols[p.protocol_name] = p else: protocols['payload'] = p return protocols def _build_ether(self, ethertype, dst_mac=HOST_MAC): e = ethernet.ethernet(dst_mac, self.OSKEN_MAC, ethertype) return e def _build_arp(self, opcode, dst_ip=HOST_IP): if opcode == arp.ARP_REQUEST: _eth_dst_mac = self.BROADCAST_MAC _arp_dst_mac = self.ZERO_MAC elif opcode == arp.ARP_REPLY: _eth_dst_mac = self.HOST_MAC _arp_dst_mac = self.HOST_MAC e = self._build_ether(ether.ETH_TYPE_ARP, _eth_dst_mac) a = arp.arp(hwtype=1, proto=ether.ETH_TYPE_IP, hlen=6, plen=4, opcode=opcode, src_mac=self.OSKEN_MAC, src_ip=self.OSKEN_IP, dst_mac=_arp_dst_mac, dst_ip=dst_ip) p = packet.Packet() p.add_protocol(e) p.add_protocol(a) p.serialize() return p def _build_echo(self, _type, echo): e = self._build_ether(ether.ETH_TYPE_IP) ip = ipv4.ipv4(version=4, header_length=5, tos=0, total_length=84, identification=0, flags=0, offset=0, ttl=64, proto=inet.IPPROTO_ICMP, csum=0, src=self.OSKEN_IP, dst=self.HOST_IP) ping = icmp.icmp(_type, code=0, csum=0, data=echo) p = packet.Packet() p.add_protocol(e) p.add_protocol(ip) p.add_protocol(ping) p.serialize() return p def _garp(self): p = self._build_arp(arp.ARP_REQUEST, self.OSKEN_IP) return p.data def _arp_request(self): p = self._build_arp(arp.ARP_REQUEST, self.HOST_IP) return p.data def _arp_reply(self): p = self._build_arp(arp.ARP_REPLY, self.HOST_IP) return p.data def _echo_request(self, echo): p = self._build_echo(icmp.ICMP_ECHO_REQUEST, echo) return p.data def _echo_reply(self, echo): p = self._build_echo(icmp.ICMP_ECHO_REPLY, echo) return p.data @handler.set_ev_cls(ofp_event.EventOFPPacketIn, handler.MAIN_DISPATCHER) def packet_in_handler(self, ev): msg = ev.msg dp = msg.datapath pkt = packet.Packet(array.array('B', msg.data)) p_arp = self._find_protocol(pkt, "arp") p_icmp = self._find_protocol(pkt, "icmp") p_ipv4 = self._find_protocol(pkt, "ipv4") if p_arp: src_ip = str(netaddr.IPAddress(p_arp.src_ip)) dst_ip = str(netaddr.IPAddress(p_arp.dst_ip)) if p_arp.opcode == arp.ARP_REQUEST: LOG.debug("--- PacketIn: ARP_Request: %s->%s", src_ip, dst_ip) if p_arp.dst_ip == self.OSKEN_IP: LOG.debug("--- send Pkt: ARP_Reply") data = self._arp_reply() self._send_msg(dp, data) elif p_arp.dst_ip == self.HOST_IP: LOG.debug(" PacketIn: GARP") LOG.debug("--- send Pkt: ARP_Request") data = self._arp_request() self._send_msg(dp, data) elif p_arp.opcode == arp.ARP_REPLY: LOG.debug("--- PacketIn: ARP_Reply: %s->%s", src_ip, dst_ip) LOG.debug("--- send Pkt: Echo_Request") echo = icmp.echo(id_=66, seq=1) data = self._echo_request(echo) self._send_msg(dp, data) if p_icmp: src = str(netaddr.IPAddress(p_ipv4.src)) dst = str(netaddr.IPAddress(p_ipv4.dst)) if p_icmp.type == icmp.ICMP_ECHO_REQUEST: LOG.debug("--- PacketIn: Echo_Request: %s->%s", src, dst) if p_ipv4.dst == self.OSKEN_IP: LOG.debug("--- send Pkt: Echo_Reply") echo = p_icmp.data echo.data = bytearray(echo.data) data = self._echo_reply(echo) self._send_msg(dp, data) elif p_icmp.type == icmp.ICMP_ECHO_REPLY: LOG.debug("--- PacketIn: Echo_Reply: %s->%s", src, dst) @handler.set_ev_cls(dpset.EventDP, dpset.DPSET_EV_DISPATCHER) def handler_datapath(self, ev): if ev.enter: dp = ev.dp LOG.debug("--- send Pkt: Gratuitous ARP_Request") data = self._garp() self._send_msg(dp, data) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/mininet/run_mnet-test.sh0000775000175000017500000001540300000000000022242 0ustar00zuulzuul00000000000000#!/bin/sh RUN_DIR=`dirname $0` CMD_NAME=`basename $0 .sh` CMD_PATH=`readlink -f $0` CMD_DIR=`dirname $CMD_PATH` DUMP_SEC=10 DUMP_DELAY=2 DUMP_DIR=/tmp/test-mn/dump TEST_LIST= TEST_SUFFIX=.mn MN_PRE_FILE=/tmp/test-mn/mn-pre MN_POST_FILE=/tmp/test-mn/mn-post PKG_LIST="tshark tcpreplay mz" RTN=0 # usage usage() { echo "Usage: $0 [OPTION] [TEST DIR or FILE]..." echo "" echo "Run OSKen's test in mininet" echo "ex.) $ $0 l2 l3/icmp/ICMP_ping.mn" echo "" echo "Options:" echo " -h, --help show this help message and exit" exit 0 } # set default environment set_env() { POST_IF=h1-eth0 DUMP_HOST=h2 DUMP_IF=h2-eth0 TEST_NAME= DUMP_FILE= OSKEN_APP= OSKEN_LOG= PCAP_MZ= PCAP_FILE= PCAP_FILTER= PCAP_COM= CACHE_HIT= } # making mininet-test-pre-file mn_pre() { exec 3>&1 exec >$MN_PRE_FILE echo "sh echo '----------------------------------'" echo "sh echo '(pre) mininet topology dump.'" echo "sh echo '----------------------------------'" echo "dump" echo "net" echo "sh echo '----------------------------------'" echo "sh echo '(pre) tshark start.'" echo "sh echo '----------------------------------'" echo "$DUMP_HOST tshark -i $DUMP_IF -a duration:$DUMP_SEC -w $DUMP_FILE &" echo "sh sleep $DUMP_DELAY" echo "sh echo '----------------------------------'" exec 1>&3 } # making mininet-test-post-file mn_post() { exec 3>&1 exec >$MN_POST_FILE echo "sh ovs-vsctl del-controller s1" echo "sh ovs-vsctl set bridge s1 protocols='[OpenFlow10,OpenFlow12]'" echo "sh ovs-vsctl set-controller s1 tcp:127.0.0.1" echo "sh echo '----------------------------------'" echo "sh echo '(post) packet sending...'" echo "sh echo '----------------------------------'" echo $PCAP_COM echo "sh sleep 1" echo "sh echo '----------------------------------'" echo "sh echo '(post) dump flows.'" echo "sh echo '----------------------------------'" echo "sh ovs-ofctl dump-flows s1" echo "sh echo '----------------------------------'" exec 1>&3 } # ovs cache-hit incremental check ovs_cache_hit() { expr `sudo ovs-dpctl show|sed -n 's|lookups: hit:||gp'|awk '{print $1}'` - ${1:-0} } # starting osken-manager run_osken() { ERRSTAT=0 ERRTAG="run_osken() :" echo "Inf: OSKEN_APP=$OSKEN_APP" echo "Inf: osken-manager starting..." osken-manager --verbose $OSKEN_APP 2>$DUMP_DIR/$OSKEN_LOG & PID_OSKEN=$! sleep 1 [ -d /proc/$PID_OSKEN ] || err $ERRTAG "failed to start osken-manager." return $ERRSTAT } # starting mininet and test-script run_mn() { echo "Info: mininet starting..." sudo mn --mac --test none --pre $MN_PRE_FILE --post $MN_POST_FILE \ --controller remote 127.0.0.1 } # cleaning after mininet clean_mn() { wait_osken rm -f $MN_PRE_FILE $MN_POST_FILE } # check packet and chache-hit check() { PACKET=`tshark -r $DUMP_FILE -R "$PCAP_FILTER" 2>/dev/null` if [ ! "$PACKET" ]; then RESULT=NG REASON="(unmatched packet. please check $DUMP_FILE)" elif [ "$CACHE_HIT" ] && [ `ovs_cache_hit $CACHE_HIT` -eq 0 ]; then RESULT=NG REASON="(ovs cache hit miss.)" else RESULT=OK; REASON= fi echo echo "TEST ${TEST_NAME} : $RESULT $REASON" } # stoping osken-manager wait_osken() { kill -2 $PID_OSKEN wait $PID_OSKEN } # test-main test_mn() { DUMP_FILE=$DUMP_DIR/$DUMP_FILE touch $DUMP_FILE sudo chmod o+w $DUMP_FILE [ "$CACHE_HIT" ] && CACHE_HIT=`ovs_cache_hit 0` mn_pre mn_post run_osken; [ $? -ne 0 ] && return 1 run_mn; [ $? -ne 0 ] && return 1 check return 0 } err() { echo Error: $* ERRSTAT=1 } mnfile_check() { test=`basename $1 $TEST_SUFFIX` file=`readlink -f $1` TEST_DIR=`dirname $file` ERRSTAT=0 ERRTAG="mnfile_check() :" # test-file check if [ ! -r $file ]; then err $ERRTAG "cannot open the file: $file" return $ERRSTAT fi . $file || err $ERRTAG "failed to include $file" # parameter check [ "$OSKEN_APP" ] || err $ERRTAG: "OSKEN_APP is not defined" [ "$PCAP_FILE" -o "$PCAP_MZ" ] || err $ERRTAG: "PCAP_FILE or PCAP_MZ is not defined" [ "$PCAP_FILTER" ] || err $ERRTAG "PCAP_FILTER is not defined" [ "$TEST_NAME" ] || TEST_NAME=$test [ "$DUMP_FILE" ] || DUMP_FILE=$test.dump [ "$OSKEN_LOG" ] || OSKEN_LOG=osken-manager.$test.log [ $ERRSTAT -ne 0 ] && return $ERRSTAT # pcap check (pcap-file or mz-option) if [ "$PCAP_FILE" ]; then PCAP_FILE=$TEST_DIR/$PCAP_FILE [ -r $PCAP_FILE ] || err $ERRTAG "PCAP_FILE[$PCAP_FILE] cannot read" PCAP_COM="h1 tcpreplay -l 3 -i $POST_IF $PCAP_FILE" elif [ "$PCAP_MZ" ]; then PCAP_COM="h1 mz $POST_IF $PCAP_MZ" fi [ $ERRSTAT -ne 0 ] && return $ERRSTAT # osken-app check [ -r $TEST_DIR/$OSKEN_APP -o -r $TEST_DIR/${OSKEN_APP}.py ] && OSKEN_APP=$TEST_DIR/$OSKEN_APP return $ERRSTAT } arg_check() { ARGLIST= ERRTAG="argcheck() :" case "$1" in -h|--help) usage;; esac if [ $# -ne 0 ]; then ARGLIST=$* else ARGLIST=`find . -type f -name "*$TEST_SUFFIX"` fi for arg in $ARGLIST; do if [ -d $arg ]; then file=`find $arg -type f -name "*$TEST_SUFFIX"` elif [ -f $arg ]; then file=$arg else err $ERRTAG "$arg is not found" file= fi TEST_LIST="$TEST_LIST $file" done } pkg_check() { no_pkg= for pkg in $PKG_LIST; do [ ! `which $pkg` ] && no_pkg="$no_pkg $pkg" done for pkg in $no_pkg; do echo "Error: Package [ $pkg ] is not found. Please install." done [ "$no_pkg" ] && exit 1 } ### main [ -d $DUMP_DIR ] || mkdir -p $DUMP_DIR pkg_check arg_check $* echo "\n---------- test target ----------" for testfile in $TEST_LIST; do echo $testfile; done count=0 for testfile in $TEST_LIST; do echo "\n---------- test [$testfile] start ----------" set_env mnfile_check $testfile && test_mn case $? in 0) msg="finished : $RESULT" ;; *) msg="skipped with error"; RESULT="skip" ;; esac eval RESULT_${count}=\$RESULT eval REASON_${count}=\$REASON count=`expr $count + 1` num=`eval echo \\${num_$RESULT:-0}` eval num_${RESULT}=`expr $num + 1` [ "$RESULT" != "OK" ] && RTN=1 clean_mn echo "\n---------- test [$testfile] $msg ----------" done # output summary results echo "\n---------- test results ----------" count=0 for testfile in $TEST_LIST; do eval echo \$testfile : \$RESULT_${count} \$REASON_${count} count=`expr $count + 1` done echo "----------------------------------" echo "Ran $count tests. Result: ${num_OK:+OK=}$num_OK ${num_NG:+NG=}$num_NG ${num_skip:+skip=}$num_skip" exit $RTN ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.0341012 os-ken-2.10.0/os_ken/tests/packet_data/0000775000175000017500000000000000000000000017671 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.1421075 os-ken-2.10.0/os_ken/tests/packet_data/bgp4/0000775000175000017500000000000000000000000020525 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/bgp4/bgp4-keepalive.pcap0000664000175000017500000000016100000000000024167 0ustar00zuulzuul00000000000000òCWu%II"3DUfE;  P././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/bgp4/bgp4-open.pcap0000664000175000017500000000022300000000000023162 0ustar00zuulzuul00000000000000òsCW kk"3DUfE]  P5P5A././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/bgp4/bgp4-update.pcap0000664000175000017500000000022200000000000023502 0ustar00zuulzuul00000000000000òCWbj jj"3DUfE\  P4@P @PJ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/bgp4/bgp4-update_ipv6.pcap0000664000175000017500000000035100000000000024451 0ustar00zuulzuul00000000000000ò?X l    ȮmhP?fZC,  0  @@././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/bgp4/bgp4-update_vpnv6.pcap0000664000175000017500000000032100000000000024641 0ustar00zuulzuul00000000000000ò}XR "3DUfEZ  PF,s\9d @@@dd././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/bgp4/evpn_esi_arbitrary.pcap0000664000175000017500000000023400000000000025260 0ustar00zuulzuul00000000000000ò}W,tt"3DUfEf  P}>'$FQ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/bgp4/evpn_esi_as_based.pcap0000664000175000017500000000023400000000000025022 0ustar00zuulzuul00000000000000ò~WJ tt"3DUfEf  P>'$F"3DUfwQ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/bgp4/evpn_esi_l2_bridge.pcap0000664000175000017500000000023400000000000025112 0ustar00zuulzuul00000000000000ò}WI& tt"3DUfEf  PIU>'$F#EQ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/bgp4/evpn_esi_lacp.pcap0000664000175000017500000000023400000000000024200 0ustar00zuulzuul00000000000000ò}WN tt"3DUfEf  PZg>'$F4Q././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/bgp4/evpn_esi_mac_base.pcap0000664000175000017500000000023400000000000025013 0ustar00zuulzuul00000000000000òt}Wvtt"3DUfEf  PB>'$F4VxQ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/bgp4/evpn_esi_router_id.pcap0000664000175000017500000000023400000000000025255 0ustar00zuulzuul00000000000000ò]JWtt"3DUfEf  PA>'$F UfwQ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/bgp4/evpn_nlri_eth_a-d.pcap0000664000175000017500000000023400000000000024746 0ustar00zuulzuul00000000000000ò}W˔tt"3DUfEf  P}>'$FQ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/bgp4/evpn_nlri_eth_seg.pcap0000664000175000017500000000023200000000000025061 0ustar00zuulzuul00000000000000ò~Wrr"3DUfEd  Pw<%"F ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/bgp4/evpn_nlri_inc_multi_eth_tag.pcap0000664000175000017500000000022400000000000027122 0ustar00zuulzuul00000000000000ò~W5zll"3DUfE^  PZ6F ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/bgp4/evpn_nlri_ip_prefix.pcap0000664000175000017500000000027600000000000025440 0ustar00zuulzuul00000000000000òڪX8B4QBE@4P`@X `@`@T=@@-F"  ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/bgp4/evpn_nlri_mac_ip_ad.pcap0000664000175000017500000000025000000000000025337 0ustar00zuulzuul00000000000000òu~W[ "3DUfEr  PJ30F%0 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/bgp4/flowspec_action_redirect.pcap0000664000175000017500000000025500000000000026434 0ustar00zuulzuul00000000000000ò~XBBEwV@@^{b!X !B!@C,@@@d   ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/bgp4/flowspec_action_traffic_action.pcap0000664000175000017500000000025500000000000027606 0ustar00zuulzuul00000000000000ò~XBBEwX@@^{b䃩!X !E!DC,@@@d  ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/bgp4/flowspec_action_traffic_marking.pcap0000664000175000017500000000025500000000000027761 0ustar00zuulzuul00000000000000ò~XBBEwW@@^{b@!X !D!BC,@@@d   ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/bgp4/flowspec_action_traffic_rate.pcap0000664000175000017500000000025500000000000027264 0ustar00zuulzuul00000000000000ò~XVBBEwU@@^{b㺩!X !@!>C,@@@d  B././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/bgp4/flowspec_nlri_ipv4.pcap0000664000175000017500000000042100000000000025177 0ustar00zuulzuul00000000000000òhX B<BE@Rֽ~X DK?O@@]W  ./Y^gP"#(###  d   B d ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/bgp4/flowspec_nlri_ipv6.pcap0000664000175000017500000000041000000000000025177 0ustar00zuulzuul00000000000000ò,.XƼ E@6  6dO$: \)\@@TN 0P  C    d  B d././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/bgp4/flowspec_nlri_l2vpn.pcap0000664000175000017500000000036100000000000025361 0ustar00zuulzuul00000000000000òXE@@ph  -BA'X: E7Ep@@@d<6ddZd, D (././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/bgp4/flowspec_nlri_vpn4.pcap0000664000175000017500000000044100000000000025206 0ustar00zuulzuul00000000000000ògX5B<BEܞ@DI`#㓢9^Y KV?@@e_( ./Y^gP"#(###  d  (B d ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/bgp4/flowspec_nlri_vpn6.pcap0000664000175000017500000000042100000000000025206 0ustar00zuulzuul00000000000000òXE;@@7  :]9 ]hO@@@d\V 0P  C    d  B d././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.1421075 os-ken-2.10.0/os_ken/tests/packet_data/mrt/0000775000175000017500000000000000000000000020473 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/mrt/rib.20161101.0000_pick.bz20000664000175000017500000000041700000000000024146 0ustar00zuulzuul00000000000000BZh91AY&SYмn5B @IHA@X X&H!0ʠ*OT@mLLi2a4M6%5(h0 2 `#t90faR-s׻'U~LN@/ EȝZKi 8>$LozBSL2&!&|s>&h*5gpFY-^Ti8l A‚"O+K琪,]u*)KctAw$S ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/mrt/updates.20161101.0000.bz20000664000175000017500000005071300000000000024035 0ustar00zuulzuul00000000000000BZh91AY&SYX+c|x7skcn>Z<4ցhҼ ^=SI ABB hٚ\VBt"5'ťCYv>=wn6:lA@1ax0qvϤ@Q{>Anwr{P4 vܻw6C`[cvK`(LA@i0DI 4h&h 62LyJxhOƩ⧵6O!22h@=#M&zTh 4 &S4Spz'+{b̽/ޝEoGdOcZ{Bd@+kRn5# W $I$BI$cy;խy=ҊcS}kW(#w-:Lc1f=-ٮ1ebS<3Nv0m qZ̍ &6tW)0hɣ#F=1cl-%gZUur,- - PdlmSAG#q#,m${ gHI Ch.Y"e]״.;j $㲗ѳ?;iH7xܜ\^[絜Ȉ6/ 2ڳfYuk=a}gÞc^ٜê,B0npW9W(\p3 S_ 7I$IRӜjږvX]K̺ܿhi&0Te3d^Smp39G>Qcn (b$ܚ ;mW1:ھkqx֍/Dw757dVf^kuU C7c1/;yx/I+Y5G?Cc5oY68rW4op&0QqcCA+s% Zwy϶x unц333oL\g݈a>X؂5Q1`:X$#\`=$KU}eyr"6wzӜ1Q,٢lm4Yef,ȇ`*+ZU=Ƶ: {csm/A1M>y} a]Qf[׮=.E:+j~M= cG'1N c<yXׁ9/iW9/ p?кmw.*g4Vf(榐"`nVPxT4B 2" &ȁy.9害YoRHE2B+JJUh,k fp\5#tΨb?$dWʬ{ h}DWT%mKM'@@-R 0 I\+, ET%+kWU pN<<y J? ?,EBP6̒LʉS.eR2)AIYUH%al".%wY*Ja¸GJU6#2T$Rf3*)p/n3 ƀ$2u 0BG]]SV!^I B3²uE4 -,> 8qݐGh>UwFG2W|_Nljd2YV9Ye lK/P5DF0O\W^.lKn]MY#|AF=Iy*DΪM`h9i"X8Z%CK }+vλ)AN!>Ia9Y<級&¼kZ%NSA\꾪`/6ۨKCB AªȄIḀF6Yu-><3l6e v,%JЋ9wW եx_{S!S,##c,!Jh[G.M-bM;w\5+scᤥ!3.7P& Xl"T%u-8K[r4].^ʭP f0=o/ Ĭʬ[J01`cl;#,ry[U^ 6XeWT, q`v0H(ǒEf)>Ҹ/-­*7e"_eܦ)'y祺hؚeע̴-9CP7jiU)lpjN8qƈI8CKDq %JViQm"zZoK?;zΫ/s^9;KCK?Uߧ5{GKļ.t<5޷-+b4;|kyoZϱ|?NG̶,kE)+Q⁓ԦxUVkt] ̰ƧSp5;_9GHȺO9jij[67K,XY؉u,1g1ka9ܣ%ؐv][0x;1uf`^9/^oBO[ ΛvѵGۏ:6#Q@a33a~".ʔ&&.e:$qzD? g hbb <򊨪*TW_OdddeEU$' FբcU4 x 'f"Jy,[ʚBtZI2n}^rL 6rOk.niHESXJnU"+% DՕ\j|jeYѦ!(hE،F(vڭW}|[k0[--lff6RC`Ȫn[m[UkcL[86&̨Ҡʖc2cq FbvC d*e(i`Lb2Y+"&U(G 8z[X%2PXIb*3( bQd,bL VILUFXsJi #&BU8s>lm;m=G-G2:͔Lj|U<5}+t U9|#xi]/ΠW;/!y4ajARZ~ޒ'B|iT{E%銭OfK 侕!tzԣ[P+gUkwrHG~ ELTtƽ~>fSI*9ǜhOQ]-ɦi*(hD`FsTYF˚{;*˒kWh}_nW)j' Q9At8I&)Vϱ4,4e{9I.@`T!G6s&t+hs--śݫmoZ8=ff7l7[./p֚*\ R> _?1.>'#s4P_4\%z#򂭜Zz'8BͩEʥtD:'m\=9 SaOA*'@N/(KUr,ÒhITK?P u;<94%{1X F& JH|ߥ=CrdYU)UW*ڥMTYBȃˎo=tqqo8xM...2\kt*!ʹ85*+j-x"qjQnlJd|u-O7ų5%n97/mVO|:uU Oq?՚ב[됟L21:^-_ 7kO8zWz6'kk R-qpo%]bÂz4}F#rdɛ"o0c)o.rE`.r8W'I.RLͩo>ngkczFcׅ i/ʭهPŠ>_q_>~!y=y)O0>dw"|MSVꇫPʿ3#_#DZk_U\WZS;.@Cziɮo>`˓/m{Wc1cZߴ}B8#Ѵ߶܏ V>S"#ATKqk_?"Na%jޱ  4ݱ#4@`XG&d sh٘z%sr"259j}SYuȩ$ ;oP 1^bZ`.d wg||#_=(46-BliĵoF6ςFb}_ٲ{k1!\$Z߶oI _. ϐb#)Ӯ4|ߕ=g|lxi? ?G o۴> _rN/IJbe(ΌNp"Dwmn[03;k7y+195ȕ 0Ρ0*(0A* 9re{C& LCӥb"T"XOX ,FD  ]E)Wl0Yl׳h>X@*99I2Š)OH )AA4?fAx) ėt˜"2~O|<cs?:׆Z*xe;mŅW?iE%ke\ 7=4<ŗ1WGRn 2&>٨هXUdN]6b$hU6rbg@!F sDu}@ѽ\ucfFe3Oxߋ\rD^n*K6_3"GuOL<8l ucE9ud!, fB%̈̌IjgHI,m 9<;Rd *-1E춫c.ZI#yU Sѫ{|^'}mn-osKn f|HùnQiؒ]=z { _vՆ%ip7y2J[%j}uK+X%i:W"6}u=xp9}yѨ#+ l;sOl̀,ه)ʅvHaoNZk{mk;4Bd5 V>7Dh"0`YGbȳjvm{*4Ub6Jb͛Rz52EԷrS:g>8BF3g"A!u'T X0:~V@7Ƚʑ.2gft|iԦK[?Ѱ!@J%!T''X^:@Г#4 #J,quQÓ >ߑHuD}("?C'0}lT3JDGx} OS4 9t P(~Q͘ 2rn_Z6>ƒ r&s}5~gnT?M!Y>%iۅmOm{$*ѓ]jթӾ2դs7wgL|HZ<2KjY4HS=2ZsjLN+[/{G)O{0I55 UcҲe>Xrק^LebR}?pt>3/Fץi5J6pV}.{e2+y@=mvcNI@\vƪPVs [R'hfM%rɛ-j}EX|3&}i>DۘGqZt}g(J .%ex6ǁ|o}{}HbS-AɅlrt\`D2 9leQ=(uӴ7?2u>C Ok|sV͢-u:o9>2"ɒ?Jb^_K?t ~dohu^%߾| Jq/h(r>q̡R[vKV=|Cֿxgq"=),(XT[/feY& ZٶkhڍMͪVP/?kc'{/:F&x0:V?'e94F`i^ٲ6ɘe On,Kw& 6"l ZЭMj}~sh}_qnr4bpxustM9M[>|;Qn>c5x_~W Z}viWP庻(9\a߃AtX&ul̛:213%)Q^m^::JLDa2&QJca1?5-};4>sy3){Y2 O2F){wvv!|7&4XH_$|}CK.i7]\uk4f(ySWE41zu>.$ oJsN1wiHU [5I/ލ|VYMkG8daΗwoU9˯ziЊYtI=ЖT4+F:}lO/O^Hp]  ]WiӇ|(u8UHxmXZNn/D̎9~VJru}0f`jiot%жWR|ue1133(I;y֕0Dy Jm4tK?jt5NW?z\Fc&Le=sh\^"Aaf1&"&e\MYIQmyO{Z%YuwazN^ #"A~Pؔ""[ƀiB$1޲16"Dn#?aН^-ۖrV.6bFG`] wt.st8p$+ztx[)oF^mƴmDҪFUƵt9ˋk/(?9vK)G*\lEj>='2dRhkrzVb/ d~[ xOS=lM09Nۓ^?mU%':sה<aK0eIٶŨeQXm@VZѶѴMҰDUMiFh *e[RmQYL*eM-)mDZ6F00?'*jdxc+hd zCW\}?~T{_ɻ;ҹ#?b[Y`.?Q!01Е"I SBs%dD?tl`e& 7ڀ4YX)p@nSU w3"nN c  6O>X={?a_ˍ`~s_  ou\?:vHrx'r_{P~PsSFe4wS̻B|=7'? ycӼfKy'U;9]#ǃ/OC_>OF~~(/1cT|KLyOO՝z:`W^+וy8_~=BU\mST=OO ZDZw>nyf_5=o6ٰיc,1>%>ߟcog6G>\]>gD~!{.%\/]ǷZ=?=7=U|wSy7t|ws2똗.cEXbfVo zoG.Oy+765vrz~;ig(װ; 6ek'X}ŭfï~jnd\Jvp֐|y3fr7mTF7gwUfwHއSlâާӻ=6Էy1n f4Y hc#ۺ,]kgKj#qԷ1z'4^6as{F^'9n{}2a:'ݧL'UKѭ>"Eʕ@p}166&FChnگjrխ9jQ&?W}OWG_rdžS%v.r/~ϊb7v88:- [%I;z{Q>ncm?QNo_+U1->Ǯ}nJW#6=KڮlNv)&7fpoJ;uG)s*'*\+tzNH{MУ7UftLv[׮$yr~lۺ5Ne9-иw۽ q+t䝥-#r { b}'|=⵷L=3ژnU=m 2ef:Ft ˽ŭ93S Ԁ/|lR _wPT@ww6&V8f%Sl-uIVl}_jlD> lqVwy ;J|E2*?Go,evp3c=A}*Շ9ݿa/s6H:ձ*aW'ET=-*^=I@}6ũ QOs%4tvTYS3}LW%T7׀_"T E<3T,¦A,eL#+ j":T-g|MDu-ǎUfVjc[˸`hu}ͷM~/[ww|Ȱ 8CQzKer@U[qE5OOehh/WwE:B #yVEY ]:`a~om`[ oqkod3P̣tn3>NSlGN}M/BrP j 8ۨͪ5=|OuDniD:K)z'+<&t}NB$pcRƝ֞/D ꇶI~tf6( blC{5n{\_J Ǜ'48ϕ%%d Wٟ"ykϓ)@1~03x18e>j &I&qhZ~SXs .Yp.[ƺGƯr/SX8$fLzpFܘve%!‡Dhi`m+[}2c(E޿߾b:]]-W9oJX_Av21/Iģs\~6 ,U{, aݡL^O~DžT.D@$/n_}*΋[TDt=3I\$\+fɔ8A|9KHzK~ 9l{ AYR88ğ0֌r{WO:+}ʯTҸTTO&i?}`jNQ7M:#յE}֧`T+aWM a@( I_+WJ& 5o  '7`0 4274w'nk%.PZXɗ=cM\ݠ]<~_gϭPS"3 P{ Ɣ]-{y_^<:?'\e&il^:`66ojpܿx>ݦ˿TpgV}NaDi]-C7WV-z3 F~jZ/Jw{ ſU\So0JTWwTJငPx`mϏq>o!ٕ~Vn]߅i> ,fc-јr5+N\KЯ{Uj¥e(m S*ԱRqSݜk-&淺7Z|W.y~'FKJ[rY#Nhiح/ąrnѱŷ3GhŠnFR]|ő'G8DX97uCdr.NXfe0LI ww{ν5~~r_(l^҆\lNvjГp9jVTn8 x%jNeo17Mrna۷z/qVk6'MLKdh`fR/%2赋l'%ڱ\]فٙUN4VKBbQ{1ew֡^vQWq^Gڛxz sgk7M:fhcӐ0l63K^KiM*so-ӭ?D#xS0e=2`8!fN^lOSq-٣z.ӣӞx1x˺`hÌlr^RCBkxc .]ExXOqʜC36YvЭßzރdũfqYa:H[~5'cwR>%?//I8tO2f̲lծ#)4cbLd&bx޽O#y;Yef&45;RiUƴ1\uu/xKzaWdNdR~ťھOZ}.=NVM-;7 0~Uby/򫅿&Æ7yR| {[63,v~T,/_e[nC2uQ? [ iS*̎!ճd7R 0w/]F zhv?Eۭ6ytO}1kc)Oq8VC\_š Ժz7M~s:%m&?Ak Y=a+ĭM%j\{NsѸ6]gb/0sCUŞݎs[q=\n/=|z?W(}tL99UgOV.ZSf k!bN 5deVOkGɃu+Y5}DiZ ?(Sv.x&03+e>nq]?Q^W2ŒG9vs+22:|(6*[w]/е\Y1c18R̲η߳ksiGbrDƩ,ϿܕU$E& p#c|\.x#dcfI .77[Vn4՗ۋ>x磛K+NӴɱ5k,Jg#St2aOUʷnLi%t6/.J28) (Κ3F^,[U>G{~x^?u$-e/M@'VzTƭY{ɲrbOKbN.< ˙)>wem&(8|9'9qC{YʎGx%ΦC͙Ond2anpth̴"iyk3L4~o%~!"Z#( !]a4>,̓j'mg2,fb'| [8I ٱMʋYj[rE#qUߍXҺ2z[/ 7+y>ߘ{Hh}ks]n| Lx6cEX`.wPm[k5|mfMQUijm*ikKRԲFlX LE,& fF*XVF&,YVQJRZhZm+I@L )e4mbT`Ԣ 1ɬfB˕Z]^a)OFبhz 7'=Pێq:'}p ;#EN ĭm+tirfKlx3X>/mZp+u.qenCeȚ)ZR_&!  G#K-t݅ٺn gw[Kwpie%U_4_օ6.2'j~j{S{םnI|On|z'0%8h:5ׯ_o{KW?eʯBBݢr6ˈ|E_-DkYP:%ppW}'/R'ƣŮmv?{^9Xӎӟzso.fnT4D=y1U<Zˆ+r3BMcf-#)b[n{&mtVVL1bl`嗁GrQj{@k0[w\;f륖\n'-8#]wSm72Ɨo9GX9׎_y׶~`{Ƀc3\waȝ]5yk^m^X\]둮NZ4l-wۃk1?#zׁ%գ.oMroJ/ hC1wbwM ܒ4h<Ƽ_%f ~_O0?ve7RwҮ.}#=n8?RoyNm.{y?o>Ҿ0u}5gŽCf{Jخgh⊋:ټ*uÒ%>9}(W+{$l7 sV=ຩw-8vq.ظ'i:mW9Gwwt1}1qww"$걪'shSfW,}X_ f9mkVǫGJw(zÝЫOF̖e:SۥvԎe t֘f}120沜O1iaQjPǥEh4 @3 AGGɓN]N/|E jd2ubᚶUP:6{vdYmEܑKhdfK2LY`QbVX`a+,Zm-jJYKeRTՙjmUT_.p W././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.1461077 os-ken-2.10.0/os_ken/tests/packet_data/of10/0000775000175000017500000000000000000000000020436 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of10/1-1-ofp_packet_out.packet0000664000175000017500000000017200000000000025125 0ustar00zuulzuul00000000000000 z ?p }ET  `1-1 !"#$%&'()*+,-./././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of10/1-2-ofp_flow_mod.packet0000664000175000017500000000012000000000000024567 0ustar00zuulzuul00000000000000P? }{././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of10/1-4-ofp_packet_in.packet0000664000175000017500000000007400000000000024730 0ustar00zuulzuul00000000000000 <*c } }  ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of10/1-5-features_request.packet0000664000175000017500000000001000000000000025504 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of10/1-6-ofp_switch_features.packet0000664000175000017500000000020000000000000026163 0ustar00zuulzuul000000000000004VxC ?pPort7 }Port6././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of10/libofproto-OFP10-ofp_packet_out_packet_library.packet0000664000175000017500000000017200000000000032644 0ustar00zuulzuul00000000000000 z ?p }ET  `1-1 !"#$%&'()*+,-./././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of10/ovs-ofctl-of10-action_dec_mpls_ttl.packet0000664000175000017500000000013000000000000030304 0ustar00zuulzuul00000000000000X8 Gd# ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of10/ovs-ofctl-of10-action_dec_nw_ttl.packet0000664000175000017500000000013000000000000027755 0ustar00zuulzuul00000000000000X8 Gd# ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of10/ovs-ofctl-of10-action_pop_mpls.packet0000664000175000017500000000013000000000000027464 0ustar00zuulzuul00000000000000X8 Gd# ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of10/ovs-ofctl-of10-action_push_mpls.packet0000664000175000017500000000013000000000000027645 0ustar00zuulzuul00000000000000X8 d# G././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of10/ovs-ofctl-of10-action_set_mpls_label.packet0000664000175000017500000000013000000000000030620 0ustar00zuulzuul00000000000000X8 Gd#  ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of10/ovs-ofctl-of10-action_set_mpls_tc.packet0000664000175000017500000000013000000000000030147 0ustar00zuulzuul00000000000000X8 Gd#  ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of10/ovs-ofctl-of10-action_set_mpls_ttl.packet0000664000175000017500000000013000000000000030344 0ustar00zuulzuul00000000000000X8 Gd# ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.1541083 os-ken-2.10.0/os_ken/tests/packet_data/of12/0000775000175000017500000000000000000000000020440 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of12/3-0-ofp_desc_stats_reply.packet0000664000175000017500000000206000000000000026337 0ustar00zuulzuul000000000000000mfrhwswserialdp././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of12/3-1-ofp_packet_out.packet0000664000175000017500000000021200000000000025124 0ustar00zuulzuul00000000000000  ?p }ET  `1-1 !"#$%&'()*+,-./././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of12/3-10-ofp_hello.packet0000664000175000017500000000001000000000000024145 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of12/3-11-ofp_flow_stats_request.packet0000664000175000017500000000007000000000000027006 0ustar00zuulzuul000000000000008././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of12/3-12-ofp_flow_stats_reply.packet0000664000175000017500000000050000000000000026450 0ustar00zuulzuul00000000000000@8fXfۙ P<~0{ }Pț:w\b././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of12/3-13-ofp_echo_request.packet0000664000175000017500000000001400000000000025537 0ustar00zuulzuul00000000000000 hoge././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of12/3-14-ofp_echo_reply.packet0000664000175000017500000000001400000000000025203 0ustar00zuulzuul00000000000000 hoge././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of12/3-15-ofp_error_msg.packet0000664000175000017500000000002400000000000025053 0ustar00zuulzuul00000000000000 fugafuga././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of12/3-16-ofp_experimenter.packet0000664000175000017500000000002400000000000025564 0ustar00zuulzuul00000000000000 x[nazo././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of12/3-17-ofp_barrier_request.packet0000664000175000017500000000001000000000000026247 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of12/3-18-ofp_barrier_reply.packet0000664000175000017500000000001000000000000025713 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of12/3-19-ofp_role_request.packet0000664000175000017500000000003000000000000025566 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of12/3-2-ofp_flow_mod.packet0000664000175000017500000000020000000000000024572 0ustar00zuulzuul00000000000000{ }( ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of12/3-20-ofp_role_reply.packet0000664000175000017500000000003000000000000025221 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of12/3-21-ofp_group_mod.packet0000664000175000017500000000006000000000000025044 0ustar00zuulzuul000000000000000 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of12/3-22-ofp_port_mod.packet0000664000175000017500000000005000000000000024674 0ustar00zuulzuul00000000000000(././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of12/3-23-ofp_table_mod.packet0000664000175000017500000000002000000000000024775 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of12/3-24-ofp_desc_stats_request.packet0000664000175000017500000000002000000000000026754 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of12/3-25-ofp_aggregate_stats_request.packet0000664000175000017500000000007000000000000027772 0ustar00zuulzuul000000000000008././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of12/3-26-ofp_aggregate_stats_reply.packet0000664000175000017500000000005000000000000027434 0ustar00zuulzuul00000000000000(>././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of12/3-27-ofp_table_stats_request.packet0000664000175000017500000000002000000000000027130 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of12/3-28-ofp_table_stats_reply.packet0000664000175000017500000007762000000000000026620 0ustar00zuulzuul00000000000000私のテーブル>Flow Table 0x01>Flow Table 0x02>Flow Table 0x03>Flow Table 0x04>Flow Table 0x05>Flow Table 0x06>Flow Table 0x07>Flow Table 0x08> Flow Table 0x09> Flow Table 0x0a> Flow Table 0x0b> Flow Table 0x0c> Flow Table 0x0d>Flow Table 0x0e>Flow Table 0x0f>Flow Table 0x10>Flow Table 0x11>Flow Table 0x12>Flow Table 0x13>Flow Table 0x14>Flow Table 0x15>Flow Table 0x16>Flow Table 0x17>Flow Table 0x18>Flow Table 0x19>Flow Table 0x1a>Flow Table 0x1b>Flow Table 0x1c>Flow Table 0x1d>Flow Table 0x1e>Flow Table 0x1f> Flow Table 0x20>!Flow Table 0x21>"Flow Table 0x22>#Flow Table 0x23>$Flow Table 0x24>%Flow Table 0x25>&Flow Table 0x26>'Flow Table 0x27>(Flow Table 0x28>)Flow Table 0x29>*Flow Table 0x2a>+Flow Table 0x2b>,Flow Table 0x2c>-Flow Table 0x2d>.Flow Table 0x2e>/Flow Table 0x2f>0Flow Table 0x30>1Flow Table 0x31>2Flow Table 0x32>3Flow Table 0x33>4Flow Table 0x34>5Flow Table 0x35>6Flow Table 0x36>7Flow Table 0x37>8Flow Table 0x38>9Flow Table 0x39>:Flow Table 0x3a>;Flow Table 0x3b><Flow Table 0x3c>=Flow Table 0x3d>>Flow Table 0x3e>?Flow Table 0x3f>@Flow Table 0x40>AFlow Table 0x41>BFlow Table 0x42>CFlow Table 0x43>DFlow Table 0x44>EFlow Table 0x45>FFlow Table 0x46>GFlow Table 0x47>HFlow Table 0x48>IFlow Table 0x49>JFlow Table 0x4a>KFlow Table 0x4b>LFlow Table 0x4c>MFlow Table 0x4d>NFlow Table 0x4e>OFlow Table 0x4f>PFlow Table 0x50>QFlow Table 0x51>RFlow Table 0x52>SFlow Table 0x53>TFlow Table 0x54>UFlow Table 0x55>VFlow Table 0x56>WFlow Table 0x57>XFlow Table 0x58>YFlow Table 0x59>ZFlow Table 0x5a>[Flow Table 0x5b>\Flow Table 0x5c>]Flow Table 0x5d>^Flow Table 0x5e>_Flow Table 0x5f>`Flow Table 0x60>aFlow Table 0x61>bFlow Table 0x62>cFlow Table 0x63>dFlow Table 0x64>eFlow Table 0x65>fFlow Table 0x66>gFlow Table 0x67>hFlow Table 0x68>iFlow Table 0x69>jFlow Table 0x6a>kFlow Table 0x6b>lFlow Table 0x6c>mFlow Table 0x6d>nFlow Table 0x6e>oFlow Table 0x6f>pFlow Table 0x70>qFlow Table 0x71>rFlow Table 0x72>sFlow Table 0x73>tFlow Table 0x74>uFlow Table 0x75>vFlow Table 0x76>wFlow Table 0x77>xFlow Table 0x78>yFlow Table 0x79>zFlow Table 0x7a>{Flow Table 0x7b>|Flow Table 0x7c>}Flow Table 0x7d>~Flow Table 0x7e>Flow Table 0x7f>Flow Table 0x80>Flow Table 0x81>Flow Table 0x82>Flow Table 0x83>Flow Table 0x84>Flow Table 0x85>Flow Table 0x86>Flow Table 0x87>Flow Table 0x88>Flow Table 0x89>Flow Table 0x8a>Flow Table 0x8b>Flow Table 0x8c>Flow Table 0x8d>Flow Table 0x8e>Flow Table 0x8f>Flow Table 0x90>Flow Table 0x91>Flow Table 0x92>Flow Table 0x93>Flow Table 0x94>Flow Table 0x95>Flow Table 0x96>Flow Table 0x97>Flow Table 0x98>Flow Table 0x99>Flow Table 0x9a>Flow Table 0x9b>Flow Table 0x9c>Flow Table 0x9d>Flow Table 0x9e>Flow Table 0x9f>Flow Table 0xa0>Flow Table 0xa1>Flow Table 0xa2>Flow Table 0xa3>Flow Table 0xa4>Flow Table 0xa5>Flow Table 0xa6>Flow Table 0xa7>Flow Table 0xa8>Flow Table 0xa9>Flow Table 0xaa>Flow Table 0xab>Flow Table 0xac>Flow Table 0xad>Flow Table 0xae>Flow Table 0xaf>Flow Table 0xb0>Flow Table 0xb1>Flow Table 0xb2>Flow Table 0xb3>Flow Table 0xb4>Flow Table 0xb5>Flow Table 0xb6>Flow Table 0xb7>Flow Table 0xb8>Flow Table 0xb9>Flow Table 0xba>Flow Table 0xbb>Flow Table 0xbc>Flow Table 0xbd>Flow Table 0xbe>Flow Table 0xbf>Flow Table 0xc0>Flow Table 0xc1>Flow Table 0xc2>Flow Table 0xc3>Flow Table 0xc4>Flow Table 0xc5>Flow Table 0xc6>Flow Table 0xc7>Flow Table 0xc8>Flow Table 0xc9>Flow Table 0xca>Flow Table 0xcb>Flow Table 0xcc>Flow Table 0xcd>Flow Table 0xce>Flow Table 0xcf>Flow Table 0xd0>Flow Table 0xd1>Flow Table 0xd2>Flow Table 0xd3>Flow Table 0xd4>Flow Table 0xd5>Flow Table 0xd6>Flow Table 0xd7>Flow Table 0xd8>Flow Table 0xd9>Flow Table 0xda>Flow Table 0xdb>Flow Table 0xdc>Flow Table 0xdd>Flow Table 0xde>Flow Table 0xdf>Flow Table 0xe0>Flow Table 0xe1>Flow Table 0xe2>Flow Table 0xe3>Flow Table 0xe4>Flow Table 0xe5>Flow Table 0xe6>Flow Table 0xe7>Flow Table 0xe8>Flow Table 0xe9>Flow Table 0xea>Flow Table 0xeb>Flow Table 0xec>Flow Table 0xed>Flow Table 0xee>Flow Table 0xef>Flow Table 0xf0>Flow Table 0xf1>Flow Table 0xf2>Flow Table 0xf3>Flow Table 0xf4>Flow Table 0xf5>Flow Table 0xf6>Flow Table 0xf7>Flow Table 0xf8>Flow Table 0xf9>Flow Table 0xfa>Flow Table 0xfb>Flow Table 0xfc>Flow Table 0xfd>Flow Table 0xfe>././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of12/3-29-ofp_port_stats_request.packet0000664000175000017500000000003000000000000027030 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of12/3-3-ofp_flow_mod.packet0000664000175000017500000000012000000000000024574 0ustar00zuulzuul00000000000000P{ }././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of12/3-30-ofp_port_stats_reply.packet0000664000175000017500000000034000000000000026467 0ustar00zuulzuul00000000000000PPP././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of12/3-31-ofp_group_features_stats_request.packet0000664000175000017500000000002000000000000031066 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of12/3-32-ofp_group_features_stats_reply.packet0000664000175000017500000000007000000000000030537 0ustar00zuulzuul000000000000008././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of12/3-33-ofp_group_desc_stats_request.packet0000664000175000017500000000002000000000000030170 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of12/3-34-ofp_group_desc_stats_reply.packet0000664000175000017500000000007000000000000027641 0ustar00zuulzuul000000000000008( ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of12/3-35-ofp_queue_get_config_request.packet0000664000175000017500000000002000000000000030132 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of12/3-36-ofp_queue_get_config_reply.packet0000664000175000017500000000016000000000000027603 0ustar00zuulzuul00000000000000pcM0 XM0d././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of12/3-37-ofp_queue_stats_request.packet0000664000175000017500000000003000000000000027167 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of12/3-38-ofp_queue_stats_reply.packet0000664000175000017500000000016000000000000026637 0ustar00zuulzuul00000000000000p././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of12/3-39-ofp_port_status.packet0000664000175000017500000000012000000000000025446 0ustar00zuulzuul00000000000000 P ?p私のポート((((././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of12/3-4-ofp_packet_in.packet0000664000175000017500000000021400000000000024730 0ustar00zuulzuul00000000000000 *P  }*, . 0 }2 } }  ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of12/3-40-ofp_flow_removed.packet0000664000175000017500000000010000000000000025535 0ustar00zuulzuul00000000000000 @V }././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of12/3-41-ofp_error_msg_experimenter.packet0000664000175000017500000000003300000000000027641 0ustar00zuulzuul00000000000000`B?jikken data././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of12/3-5-ofp_features_request.packet0000664000175000017500000000001000000000000026354 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of12/3-59-ofp_packet_in.packet0000664000175000017500000000047200000000000025030 0ustar00zuulzuul00000000000000 :&  }  cFm ڀ"Ѐ$&d(e*, . 0 }24 H(6 ܀8C!:Ȁ<ɀ> `nt@B+D eF././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of12/3-6-ofp_features_reply.packet0000664000175000017500000000024000000000000026025 0ustar00zuulzuul00000000000000`ntO ?pPort7(((( }Port6((((././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of12/3-60-ofp_flow_mod.packet0000664000175000017500000000053000000000000024664 0ustar00zuulzuul00000000000000X{&  }  cFm ڀ"Ѐ$&d(e*, . 0 }24 H(6 ܀8C!:Ȁ<ɀ> `nt@B+D eF././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of12/3-61-ofp_group_stats_request.packet0000664000175000017500000000003000000000000027174 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of12/3-62-ofp_group_stats_reply.packet0000664000175000017500000000010000000000000026636 0ustar00zuulzuul00000000000000@0{09 )././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of12/3-7-ofp_set_config.packet0000664000175000017500000000001400000000000025114 0ustar00zuulzuul00000000000000 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of12/3-8-ofp_get_config_request.packet0000664000175000017500000000001000000000000026645 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of12/3-9-ofp_get_config_reply.packet0000664000175000017500000000001400000000000026315 0ustar00zuulzuul00000000000000 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of12/libofproto-OFP12-ofp_packet_out_packet_library.packet0000664000175000017500000000021200000000000032643 0ustar00zuulzuul00000000000000  ?p }ET  `1-1 !"#$%&'()*+,-./././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.1741095 os-ken-2.10.0/os_ken/tests/packet_data/of13/0000775000175000017500000000000000000000000020441 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-0-ofp_desc_reply.packet0000664000175000017500000000206000000000000025123 0ustar00zuulzuul000000000000000mfrhwswserialdp././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-1-ofp_packet_out.packet0000664000175000017500000000021200000000000025126 0ustar00zuulzuul00000000000000  ?p }ET  `1-1 !"#$%&'()*+,-./././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-10-ofp_hello.packet0000664000175000017500000000002000000000000024150 0ustar00zuulzuul00000000000000@././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-11-ofp_flow_stats_request.packet0000664000175000017500000000007000000000000027010 0ustar00zuulzuul000000000000008././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-12-ofp_flow_stats_reply.packet0000664000175000017500000000105000000000000026453 0ustar00zuulzuul00000000000000(8fXfۙ P<~0{ }8ț:w\b    4vG  c xexp_data# exp_data(ONF ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-13-ofp_echo_request.packet0000664000175000017500000000001400000000000025541 0ustar00zuulzuul00000000000000 hoge././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-14-ofp_echo_reply.packet0000664000175000017500000000001400000000000025205 0ustar00zuulzuul00000000000000 hoge././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-15-ofp_error_msg.packet0000664000175000017500000000002400000000000025055 0ustar00zuulzuul00000000000000 fugafuga././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-16-ofp_experimenter.packet0000664000175000017500000000002400000000000025566 0ustar00zuulzuul00000000000000 x[nazo././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-17-ofp_barrier_request.packet0000664000175000017500000000001000000000000026251 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-18-ofp_barrier_reply.packet0000664000175000017500000000001000000000000025715 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-19-ofp_role_request.packet0000664000175000017500000000003000000000000025570 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-2-ofp_flow_mod.packet0000664000175000017500000000043000000000000024601 0ustar00zuulzuul00000000000000{ }    4vG  ec(ONF ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-20-ofp_role_reply.packet0000664000175000017500000000003000000000000025223 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-21-ofp_group_mod.packet0000664000175000017500000000006000000000000025046 0ustar00zuulzuul000000000000000 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-22-ofp_port_mod.packet0000664000175000017500000000005000000000000024676 0ustar00zuulzuul00000000000000(././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-23-ofp_table_mod.packet0000664000175000017500000000002000000000000024777 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-24-ofp_desc_request.packet0000664000175000017500000000002000000000000025540 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-25-ofp_aggregate_stats_request.packet0000664000175000017500000000007000000000000027774 0ustar00zuulzuul000000000000008././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-26-ofp_aggregate_stats_reply.packet0000664000175000017500000000005000000000000027436 0ustar00zuulzuul00000000000000(>././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-27-ofp_table_stats_request.packet0000664000175000017500000000002000000000000027132 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-28-ofp_table_stats_reply.packet0000664000175000017500000000010000000000000026575 0ustar00zuulzuul00000000000000@././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-29-ofp_port_stats_request.packet0000664000175000017500000000003000000000000027032 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-3-ofp_flow_mod.packet0000664000175000017500000000012000000000000024576 0ustar00zuulzuul00000000000000P{ }././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-30-ofp_port_stats_reply.packet0000664000175000017500000000036000000000000026473 0ustar00zuulzuul00000000000000PPP././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-31-ofp_group_features_request.packet0000664000175000017500000000002000000000000027652 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-32-ofp_group_features_reply.packet0000664000175000017500000000007000000000000027323 0ustar00zuulzuul000000000000008././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-33-ofp_group_desc_request.packet0000664000175000017500000000002000000000000026754 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-34-ofp_group_desc_reply.packet0000664000175000017500000000007000000000000026425 0ustar00zuulzuul000000000000008( ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-35-ofp_queue_get_config_request.packet0000664000175000017500000000002000000000000030134 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-36-ofp_queue_get_config_reply.packet0000664000175000017500000000032300000000000027606 0ustar00zuulzuul00000000000000cM@ XMAdMMB././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-37-ofp_queue_stats_request.packet0000664000175000017500000000003000000000000027171 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-38-ofp_queue_stats_reply.packet0000664000175000017500000000021000000000000026635 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-39-ofp_port_status.packet0000664000175000017500000000012000000000000025450 0ustar00zuulzuul00000000000000 P ?p私のポート((((././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-4-ofp_packet_in.packet0000664000175000017500000000022400000000000024733 0ustar00zuulzuul00000000000000 *P  }*, . 0 }2 } }  ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-40-ofp_flow_removed.packet0000664000175000017500000000010000000000000025537 0ustar00zuulzuul00000000000000 @V }././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-41-ofp_error_msg_experimenter.packet0000664000175000017500000000003300000000000027643 0ustar00zuulzuul00000000000000`B?jikken data././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-42-ofp_get_async_request.packet0000664000175000017500000000001000000000000026575 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-43-ofp_get_async_reply.packet0000664000175000017500000000004000000000000026244 0ustar00zuulzuul00000000000000 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-44-ofp_set_async.packet0000664000175000017500000000004000000000000025046 0ustar00zuulzuul00000000000000 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-45-ofp_meter_mod.packet0000664000175000017500000000010000000000000025027 0ustar00zuulzuul00000000000000@d   ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-46-ofp_flow_mod.packet0000664000175000017500000000014000000000000024667 0ustar00zuulzuul00000000000000`{ }././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-47-ofp_meter_config_request.packet0000664000175000017500000000003000000000000027271 0ustar00zuulzuul00000000000000 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-48-ofp_meter_config_reply.packet0000664000175000017500000000005000000000000026737 0ustar00zuulzuul00000000000000( d ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-49-ofp_meter_stats_request.packet0000664000175000017500000000003000000000000027164 0ustar00zuulzuul00000000000000 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-5-ofp_features_request.packet0000664000175000017500000000001000000000000026356 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-50-ofp_meter_stats_reply.packet0000664000175000017500000000011000000000000026616 0ustar00zuulzuul00000000000000H d8S././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-51-ofp_meter_features_request.packet0000664000175000017500000000002000000000000027634 0ustar00zuulzuul00000000000000 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-52-ofp_meter_features_reply.packet0000664000175000017500000000004000000000000027302 0ustar00zuulzuul00000000000000 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-53-ofp_port_desc_request.packet0000664000175000017500000000002000000000000026606 0ustar00zuulzuul00000000000000 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-54-ofp_port_desc_reply.packet0000664000175000017500000000022000000000000026254 0ustar00zuulzuul00000000000000  ?pPort7(((( }Port6((((././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-55-ofp_table_features_request.packet0000664000175000017500000002557000000000000027634 0ustar00zuulzuul00000000000000+x Flow Table 0x00  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~D  D    "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ  "$&(*,.02468:<>@BDFHJ eeeXFlow Table 0x01  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~D  D    "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ  "$&(*,.02468:<>@BDFHJPFlow Table 0x02  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~D  D    "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ  "$&(*,.02468:<>@BDFHJPFlow Table 0x03  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~D  D    "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ  "$&(*,.02468:<>@BDFHJPFlow Table 0x04  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~D  D    "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ  "$&(*,.02468:<>@BDFHJPFlow Table 0x05  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~D  D    "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ  "$&(*,.02468:<>@BDFHJPFlow Table 0x06  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~D  D    "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ  "$&(*,.02468:<>@BDFHJPFlow Table 0x07  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~D  D    "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ  "$&(*,.02468:<>@BDFHJPFlow Table 0x08  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~D  D    "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ  "$&(*,.02468:<>@BDFHJP Flow Table 0x09  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~D  D    "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ  "$&(*,.02468:<>@BDFHJ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-56-ofp_table_features_reply.packet0000664000175000017500000002557000000000000027300 0ustar00zuulzuul00000000000000+x 私のテーブル  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~D  D    "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ  "$&(*,.02468:<>@BDFHJ eeeXFlow Table 0x01  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~D  D    "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ  "$&(*,.02468:<>@BDFHJPFlow Table 0x02  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~D  D    "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ  "$&(*,.02468:<>@BDFHJPFlow Table 0x03  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~D  D    "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ  "$&(*,.02468:<>@BDFHJPFlow Table 0x04  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~D  D    "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ  "$&(*,.02468:<>@BDFHJPFlow Table 0x05  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~D  D    "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ  "$&(*,.02468:<>@BDFHJPFlow Table 0x06  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~D  D    "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ  "$&(*,.02468:<>@BDFHJPFlow Table 0x07  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~D  D    "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ  "$&(*,.02468:<>@BDFHJPFlow Table 0x08  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~D  D    "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ  "$&(*,.02468:<>@BDFHJP Flow Table 0x09  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~D  D    "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ  "$&(*,.02468:<>@BDFHJ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-57-ofp_group_stats_request.packet0000664000175000017500000000003000000000000027203 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-58-ofp_group_stats_reply.packet0000664000175000017500000000011000000000000026646 0ustar00zuulzuul00000000000000H8{09 $M& )././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-59-ofp_packet_in.packet0000664000175000017500000000057200000000000025033 0ustar00zuulzuul00000000000000 z_  }  cFm ڀ"Ѐ$&d(e*, . 0 }24 H(6 ܀8C!:Ȁ<ɀ> `nt@B+D eFHJL NONF >@././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-6-ofp_features_reply.packet0000664000175000017500000000004000000000000026025 0ustar00zuulzuul00000000000000 `ntcO././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-60-ofp_flow_mod.packet0000664000175000017500000000062000000000000024666 0ustar00zuulzuul00000000000000{_  }  cFm ڀ"Ѐ$&d(e*, . 0 }24 H(6 ܀8C!:Ȁ<ɀ> `nt@B+D eFHJL NONF >@././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-61-ofp_experimenter_request.packet0000664000175000017500000000004000000000000027334 0ustar00zuulzuul00000000000000 ޭhogehoge././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-62-ofp_experimenter_reply.packet0000664000175000017500000000005000000000000027001 0ustar00zuulzuul00000000000000(ޭwwtestdata99999999././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-63-onf_flow_monitor_request.packet0000664000175000017500000000063000000000000027350 0ustar00zuulzuul00000000000000ONFN!1[  }  cFm ڀ"Ѐ$&d(e*, . 0 }24 H(6 ܀8C!:Ȁ<ɀ> `nt@B+D eFHJL NONF >@././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-7-ofp_set_config.packet0000664000175000017500000000001400000000000025116 0ustar00zuulzuul00000000000000 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-8-ofp_get_config_request.packet0000664000175000017500000000001000000000000026647 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/4-9-ofp_get_config_reply.packet0000664000175000017500000000001400000000000026317 0ustar00zuulzuul00000000000000 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/libofproto-OFP13-echo_reply.packet0000664000175000017500000000001000000000000026715 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/libofproto-OFP13-echo_request.packet0000664000175000017500000000001000000000000027252 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/libofproto-OFP13-error_msg.packet0000664000175000017500000000002400000000000026570 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/libofproto-OFP13-features_reply.packet0000664000175000017500000000004000000000000027620 0ustar00zuulzuul00000000000000 O././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/libofproto-OFP13-flow_mod.packet0000664000175000017500000000040000000000000026375 0ustar00zuulzuul000000000000004VxF̙̀w  LP>@ `# ,c  0( @   d././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/libofproto-OFP13-flow_mod.truncated640000664000175000017500000000000000000000000027265 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/libofproto-OFP13-flow_mod_conjunction.packet0000664000175000017500000000022000000000000031006 0ustar00zuulzuul000000000000004VxF̙̀w  LP>@# "././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/libofproto-OFP13-flow_mod_match_conj.packet0000664000175000017500000000015000000000000030564 0ustar00zuulzuul00000000000000h4Vx J  d././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/libofproto-OFP13-flow_removed.packet0000664000175000017500000000017000000000000027263 0ustar00zuulzuul00000000000000 x4VxdX,dF̙̀w  LP>@././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/libofproto-OFP13-get_config_reply.packet0000664000175000017500000000001400000000000030107 0ustar00zuulzuul00000000000000 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/libofproto-OFP13-hello.packet0000664000175000017500000000002000000000000025670 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/libofproto-OFP13-meter_mod.packet0000664000175000017500000000006000000000000026544 0ustar00zuulzuul000000000000000d  ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/libofproto-OFP13-ofp_packet_out_packet_library.packet0000664000175000017500000000021200000000000032645 0ustar00zuulzuul00000000000000  ?p }ET  `1-1 !"#$%&'()*+,-./././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/libofproto-OFP13-packet_in.packet0000664000175000017500000000010600000000000026527 0ustar00zuulzuul00000000000000 Fd(̀LP>@hoge././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/libofproto-OFP13-port_mod.packet0000664000175000017500000000005000000000000026413 0ustar00zuulzuul00000000000000(̙w(././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/libofproto-OFP13-port_status.packet0000664000175000017500000000012000000000000027155 0ustar00zuulzuul00000000000000 Peth0((((P././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/libofproto-OFP13-set_config.packet0000664000175000017500000000001400000000000026710 0ustar00zuulzuul00000000000000 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/libofproto-OFP13-table_mod.packet0000664000175000017500000000002000000000000026513 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/ovs-ofctl-of13-action_conjunction.packet0000664000175000017500000000022000000000000030172 0ustar00zuulzuul000000000000004VxF̙̀w  LP>@# "././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/ovs-ofctl-of13-action_controller.packet0000664000175000017500000000012000000000000030023 0ustar00zuulzuul00000000000000Pd# ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/ovs-ofctl-of13-action_controller2.packet0000664000175000017500000000020000000000000030104 0ustar00zuulzuul00000000000000dH@# %  ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/ovs-ofctl-of13-action_ct.packet0000664000175000017500000000015000000000000026251 0ustar00zuulzuul00000000000000h   # #././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/ovs-ofctl-of13-action_ct_clear.packet0000664000175000017500000000014000000000000027416 0ustar00zuulzuul00000000000000`  # +././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/ovs-ofctl-of13-action_ct_exec.packet0000664000175000017500000000017000000000000027257 0ustar00zuulzuul00000000000000x ""0(# #eC!././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/ovs-ofctl-of13-action_ct_nat.packet0000664000175000017500000000020000000000000027107 0ustar00zuulzuul00000000000000 @8# # # $3   ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/ovs-ofctl-of13-action_ct_nat_v6.packet0000664000175000017500000000022000000000000027524 0ustar00zuulzuul00000000000000 PH# #0# $  ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/ovs-ofctl-of13-action_dec_ttl_cnt_ids.packet0000664000175000017500000000015000000000000030764 0ustar00zuulzuul00000000000000hd ( # ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/ovs-ofctl-of13-action_fintimeout.packet0000664000175000017500000000013000000000000030024 0ustar00zuulzuul00000000000000Xd # <././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/ovs-ofctl-of13-action_learn.packet0000664000175000017500000000040000000000000026742 0ustar00zuulzuul00000000000000F̙̀w  LP>@ `# ,c  0( @   d././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/ovs-ofctl-of13-action_note.packet0000664000175000017500000000012000000000000026605 0ustar00zuulzuul00000000000000Pd# ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/ovs-ofctl-of13-action_output_trunc.packet0000664000175000017500000000012000000000000030413 0ustar00zuulzuul00000000000000Pd# '././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/ovs-ofctl-of13-action_resubmit.packet0000664000175000017500000000022000000000000027473 0ustar00zuulzuul00000000000000F̙̀w  LP>@# c././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/ovs-ofctl-of13-action_sample.packet0000664000175000017500000000013000000000000027122 0ustar00zuulzuul00000000000000Xd # ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/ovs-ofctl-of13-action_sample2.packet0000664000175000017500000000014000000000000027205 0ustar00zuulzuul00000000000000`d( # &././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/ovs-ofctl-of13-action_stack_pop.packet0000664000175000017500000000013000000000000027624 0ustar00zuulzuul00000000000000Xd # ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/ovs-ofctl-of13-action_stack_push.packet0000664000175000017500000000013000000000000030005 0ustar00zuulzuul00000000000000Xd # ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/ovs-ofctl-of13-match_conj.packet0000664000175000017500000000014000000000000026412 0ustar00zuulzuul00000000000000`4VxJ d././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/ovs-ofctl-of13-match_load_nx_register.packet0000664000175000017500000000015000000000000031012 0ustar00zuulzuul00000000000000h4Vx4  #  ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/ovs-ofctl-of13-match_move_nx_register.packet0000664000175000017500000000015000000000000031041 0ustar00zuulzuul00000000000000h4Vx4  #  ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/ovs-ofctl-of13-match_pkt_mark.packet0000664000175000017500000000014000000000000027271 0ustar00zuulzuul00000000000000`4Vx B1d././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of13/ovs-ofctl-of13-match_pkt_mark_masked.packet0000664000175000017500000000014000000000000030615 0ustar00zuulzuul00000000000000`4Vx C1d././@PaxHeader0000000000000000000000000000003200000000000011450 xustar000000000000000026 mtime=1724334546.18611 os-ken-2.10.0/os_ken/tests/packet_data/of14/0000775000175000017500000000000000000000000020442 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-0-ofp_desc_reply.packet0000664000175000017500000000206000000000000025125 0ustar00zuulzuul000000000000000mfrhwswserialdp././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-1-ofp_packet_out.packet0000664000175000017500000000021200000000000025130 0ustar00zuulzuul00000000000000  ?p }ET  `1-1 !"#$%&'()*+,-./././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-10-ofp_hello.packet0000664000175000017500000000002000000000000024152 0ustar00zuulzuul00000000000000@././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-11-ofp_flow_stats_request.packet0000664000175000017500000000007000000000000027012 0ustar00zuulzuul000000000000008././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-12-ofp_flow_stats_reply.packet0000664000175000017500000000105000000000000026455 0ustar00zuulzuul00000000000000(8fXfۙ P<~0{ }8ț:w\b    4vG  c xexp_data# exp_data(R././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-13-ofp_echo_request.packet0000664000175000017500000000001400000000000025543 0ustar00zuulzuul00000000000000 hoge././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-14-ofp_echo_reply.packet0000664000175000017500000000001400000000000025207 0ustar00zuulzuul00000000000000 hoge././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-15-ofp_error_msg.packet0000664000175000017500000000002400000000000025057 0ustar00zuulzuul00000000000000 fugafuga././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-16-ofp_experimenter.packet0000664000175000017500000000002400000000000025570 0ustar00zuulzuul00000000000000 x[nazo././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-17-ofp_barrier_request.packet0000664000175000017500000000001000000000000026253 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-18-ofp_barrier_reply.packet0000664000175000017500000000001000000000000025717 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-19-ofp_role_request.packet0000664000175000017500000000003000000000000025572 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-2-ofp_flow_mod.packet0000664000175000017500000000043000000000000024603 0ustar00zuulzuul00000000000000{ }    4vG  ec(R././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-20-ofp_role_reply.packet0000664000175000017500000000003000000000000025225 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-21-ofp_group_mod.packet0000664000175000017500000000006000000000000025050 0ustar00zuulzuul000000000000000 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-22-ofp_port_mod.packet0000664000175000017500000000017000000000000024703 0ustar00zuulzuul00000000000000x , eee././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-23-ofp_table_mod.packet0000664000175000017500000000013000000000000025003 0ustar00zuulzuul00000000000000X eee././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-24-ofp_desc_request.packet0000664000175000017500000000002000000000000025542 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-25-ofp_aggregate_stats_request.packet0000664000175000017500000000007000000000000027776 0ustar00zuulzuul000000000000008././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-26-ofp_aggregate_stats_reply.packet0000664000175000017500000000005000000000000027440 0ustar00zuulzuul00000000000000(>././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-27-ofp_table_stats_request.packet0000664000175000017500000000002000000000000027134 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-28-ofp_table_stats_reply.packet0000664000175000017500000000010000000000000026577 0ustar00zuulzuul00000000000000@././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-29-ofp_port_stats_request.packet0000664000175000017500000000003000000000000027034 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-3-ofp_flow_mod.packet0000664000175000017500000000012000000000000024600 0ustar00zuulzuul00000000000000P{ }././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-30-ofp_port_stats_reply.packet0000664000175000017500000000055000000000000026476 0ustar00zuulzuul00000000000000hP(,, eeexPP(././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-31-ofp_group_features_request.packet0000664000175000017500000000002000000000000027654 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-32-ofp_group_features_reply.packet0000664000175000017500000000007000000000000027325 0ustar00zuulzuul000000000000008././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-33-ofp_group_desc_request.packet0000664000175000017500000000002000000000000026756 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-34-ofp_group_desc_reply.packet0000664000175000017500000000007000000000000026427 0ustar00zuulzuul000000000000008( ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-35-ofp_queue_stats_request.packet0000664000175000017500000000003000000000000027171 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-36-ofp_queue_stats_reply.packet0000664000175000017500000000033000000000000026640 0ustar00zuulzuul00000000000000h eee00././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-37-ofp_port_status.packet0000664000175000017500000000027000000000000025456 0ustar00zuulzuul00000000000000  ?p私のポート ((((( eee././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-38-ofp_flow_removed.packet0000664000175000017500000000010000000000000025550 0ustar00zuulzuul00000000000000 @V }././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-39-ofp_error_msg_experimenter.packet0000664000175000017500000000003300000000000027654 0ustar00zuulzuul00000000000000`B?jikken data././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-4-ofp_packet_in.packet0000664000175000017500000000022400000000000024735 0ustar00zuulzuul00000000000000 *P  }*, . 0 }2 } }  ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-40-ofp_get_async_request.packet0000664000175000017500000000001000000000000026575 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-41-ofp_get_async_reply.packet0000664000175000017500000000024000000000000026246 0ustar00zuulzuul00000000000000    eee././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-42-ofp_set_async.packet0000664000175000017500000000024000000000000025050 0ustar00zuulzuul00000000000000    eee././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-43-ofp_meter_mod.packet0000664000175000017500000000010000000000000025027 0ustar00zuulzuul00000000000000@d   ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-44-ofp_flow_mod.packet0000664000175000017500000000014000000000000024667 0ustar00zuulzuul00000000000000`{ }././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-45-ofp_meter_config_request.packet0000664000175000017500000000003000000000000027271 0ustar00zuulzuul00000000000000 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-46-ofp_meter_config_reply.packet0000664000175000017500000000005000000000000026737 0ustar00zuulzuul00000000000000( d ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-47-ofp_meter_stats_request.packet0000664000175000017500000000003000000000000027164 0ustar00zuulzuul00000000000000 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-48-ofp_meter_stats_reply.packet0000664000175000017500000000011000000000000026627 0ustar00zuulzuul00000000000000H d8S././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-49-ofp_meter_features_request.packet0000664000175000017500000000002000000000000027645 0ustar00zuulzuul00000000000000 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-5-ofp_features_request.packet0000664000175000017500000000001000000000000026360 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-50-ofp_meter_features_reply.packet0000664000175000017500000000004000000000000027302 0ustar00zuulzuul00000000000000 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-51-ofp_port_desc_request.packet0000664000175000017500000000002000000000000026606 0ustar00zuulzuul00000000000000 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-52-ofp_port_desc_reply.packet0000664000175000017500000000040000000000000026254 0ustar00zuulzuul00000000000000  ?pPort7 ((((( eeeH }Port6 ((((././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-53-ofp_table_features_request.packet0000664000175000017500000002557000000000000027634 0ustar00zuulzuul00000000000000+x Flow Table 0x00  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~D  D    "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ  "$&(*,.02468:<>@BDFHJ eeeXFlow Table 0x01  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~D  D    "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ  "$&(*,.02468:<>@BDFHJPFlow Table 0x02  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~D  D    "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ  "$&(*,.02468:<>@BDFHJPFlow Table 0x03  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~D  D    "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ  "$&(*,.02468:<>@BDFHJPFlow Table 0x04  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~D  D    "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ  "$&(*,.02468:<>@BDFHJPFlow Table 0x05  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~D  D    "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ  "$&(*,.02468:<>@BDFHJPFlow Table 0x06  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~D  D    "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ  "$&(*,.02468:<>@BDFHJPFlow Table 0x07  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~D  D    "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ  "$&(*,.02468:<>@BDFHJPFlow Table 0x08  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~D  D    "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ  "$&(*,.02468:<>@BDFHJP Flow Table 0x09  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~D  D    "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ  "$&(*,.02468:<>@BDFHJ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-54-ofp_table_features_reply.packet0000664000175000017500000002557000000000000027300 0ustar00zuulzuul00000000000000+x 私のテーブル  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~D  D    "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ  "$&(*,.02468:<>@BDFHJ eeeXFlow Table 0x01  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~D  D    "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ  "$&(*,.02468:<>@BDFHJPFlow Table 0x02  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~D  D    "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ  "$&(*,.02468:<>@BDFHJPFlow Table 0x03  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~D  D    "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ  "$&(*,.02468:<>@BDFHJPFlow Table 0x04  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~D  D    "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ  "$&(*,.02468:<>@BDFHJPFlow Table 0x05  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~D  D    "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ  "$&(*,.02468:<>@BDFHJPFlow Table 0x06  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~D  D    "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ  "$&(*,.02468:<>@BDFHJPFlow Table 0x07  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~D  D    "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ  "$&(*,.02468:<>@BDFHJPFlow Table 0x08  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~D  D    "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ  "$&(*,.02468:<>@BDFHJP Flow Table 0x09  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~D  D    "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ   "$&(*,.02468:<>@BDFHJ  "$&(*,.02468:<>@BDFHJ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-55-ofp_group_stats_request.packet0000664000175000017500000000003000000000000027203 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-56-ofp_group_stats_reply.packet0000664000175000017500000000011000000000000026646 0ustar00zuulzuul00000000000000H8{09 $M& )././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-57-ofp_packet_in.packet0000664000175000017500000000055200000000000025031 0ustar00zuulzuul00000000000000 jI  }  cFm ڀ"Ѐ$&d(e*, . 0 }24 H(6 ܀8C!:Ȁ<ɀ> `nt@B+D eFHJL NR././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-58-ofp_flow_mod.packet0000664000175000017500000000060000000000000024675 0ustar00zuulzuul00000000000000{I  }  cFm ڀ"Ѐ$&d(e*, . 0 }24 H(6 ܀8C!:Ȁ<ɀ> `nt@B+D eFHJL NR././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-59-ofp_experimenter_request.packet0000664000175000017500000000004000000000000027345 0ustar00zuulzuul00000000000000 ޭhogehoge././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-6-ofp_features_reply.packet0000664000175000017500000000004000000000000026027 0ustar00zuulzuul00000000000000 `ntcO././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-60-ofp_experimenter_reply.packet0000664000175000017500000000005000000000000027001 0ustar00zuulzuul00000000000000(ޭwwtestdata99999999././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-61-ofp_table_desc_request.packet0000664000175000017500000000002000000000000026712 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-62-ofp_table_desc_reply.packet0000664000175000017500000000017000000000000026364 0ustar00zuulzuul00000000000000x eP eee././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-63-ofp_queue_desc_request.packet0000664000175000017500000000003000000000000026752 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-64-ofp_queue_desc_reply.packet0000664000175000017500000000021000000000000026416 0ustar00zuulzuul00000000000000 eX, eee././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-65-ofp_role_status.packet0000664000175000017500000000012000000000000025426 0ustar00zuulzuul00000000000000P eee././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-66-ofp_flow_monitor_request.packet0000664000175000017500000000006000000000000027354 0ustar00zuulzuul000000000000000! }././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-67-ofp_flow_monitor_reply.packet0000664000175000017500000000014000000000000027017 0ustar00zuulzuul00000000000000`@X ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-68-ofp_table_status.packet0000664000175000017500000000014000000000000025561 0ustar00zuulzuul00000000000000`P eee././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-69-ofp_bundle_ctrl_msg.packet0000664000175000017500000000011000000000000026230 0ustar00zuulzuul00000000000000!H eee././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-7-ofp_set_config.packet0000664000175000017500000000001400000000000025120 0ustar00zuulzuul00000000000000 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-70-ofp_bundle_add_msg.packet0000664000175000017500000000012000000000000026005 0ustar00zuulzuul00000000000000"P eee././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-71-ofp_requestforward.packet0000664000175000017500000000007000000000000026140 0ustar00zuulzuul00000000000000 80 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-8-ofp_get_config_request.packet0000664000175000017500000000001000000000000026651 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/5-9-ofp_get_config_reply.packet0000664000175000017500000000001400000000000026321 0ustar00zuulzuul00000000000000 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of14/libofproto-OFP14-ofp_packet_out_packet_library.packet0000664000175000017500000000021200000000000032647 0ustar00zuulzuul00000000000000  ?p }ET  `1-1 !"#$%&'()*+,-./././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.1981108 os-ken-2.10.0/os_ken/tests/packet_data/of15/0000775000175000017500000000000000000000000020443 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-aggregate_stats_reply.packet0000664000175000017500000000004000000000000031152 0ustar00zuulzuul00000000000000  ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-aggregate_stats_request.packet0000664000175000017500000000007000000000000031512 0ustar00zuulzuul000000000000008././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-barrier_reply.packet0000664000175000017500000000001000000000000027431 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-barrier_request.packet0000664000175000017500000000001000000000000027766 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-bundle_add.packet0000664000175000017500000000042000000000000026656 0ustar00zuulzuul00000000000000"4VxxF̙̀w  LP>@ `# ,c  0( @   d././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-bundle_ctrl.packet0000664000175000017500000000002000000000000027066 0ustar00zuulzuul00000000000000!././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-bundle_features_reply.packet0000664000175000017500000000014000000000000031156 0ustar00zuulzuul00000000000000`HUUUUUUUUffffwwwwwwww././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-bundle_features_request.packet0000664000175000017500000000014000000000000031513 0ustar00zuulzuul00000000000000`HUUUUUUUUffffwwwwwwww././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-controller_status.packet0000664000175000017500000000007000000000000030364 0ustar00zuulzuul00000000000000#80tls:192.168.34.23:6653././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-controller_status_reply.packet0000664000175000017500000000010000000000000031571 0ustar00zuulzuul00000000000000@0tls:192.168.34.23:6653././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-controller_status_request.packet0000664000175000017500000000002000000000000032127 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-desc_reply.packet0000664000175000017500000000206000000000000026730 0ustar00zuulzuul000000000000000mfrhwswserialdp././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-desc_request.packet0000664000175000017500000000002000000000000027257 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-echo_reply.packet0000664000175000017500000000001000000000000026721 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-echo_request.packet0000664000175000017500000000001000000000000027256 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-error_msg.packet0000664000175000017500000000002400000000000026574 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-error_msg_experimenter.packet0000664000175000017500000000003300000000000031363 0ustar00zuulzuul00000000000000`B?jikken data././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-experimenter.packet0000664000175000017500000000002400000000000027304 0ustar00zuulzuul00000000000000 x[nazo././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-experimenter_reply.packet0000664000175000017500000000005000000000000030516 0ustar00zuulzuul00000000000000(ޭwwtestdata99999999././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-experimenter_request.packet0000664000175000017500000000004000000000000031052 0ustar00zuulzuul00000000000000 ޭhogehoge././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-features_reply.packet0000664000175000017500000000004000000000000027624 0ustar00zuulzuul00000000000000 O././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-features_request.packet0000664000175000017500000000001000000000000030156 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-flow_desc_reply.packet0000664000175000017500000000012000000000000027752 0ustar00zuulzuul00000000000000P@"3DUfw  ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-flow_desc_request.packet0000664000175000017500000000010000000000000030305 0ustar00zuulzuul00000000000000@"3DUfw ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-flow_mod.packet0000664000175000017500000000040000000000000026401 0ustar00zuulzuul000000000000004VxxF̙̀w  LP>@ `# ,c  0( @   d././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-flow_mod_conjunction.packet0000664000175000017500000000022000000000000031012 0ustar00zuulzuul000000000000004VxxF̙̀w  LP>@# "././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-flow_mod_match_conj.packet0000664000175000017500000000015000000000000030570 0ustar00zuulzuul00000000000000h4Vxx J  d././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-flow_monitor_reply.packet0000664000175000017500000000014000000000000030525 0ustar00zuulzuul00000000000000`@X ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-flow_monitor_request.packet0000664000175000017500000000006000000000000031063 0ustar00zuulzuul000000000000000! }././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-flow_removed.packet0000664000175000017500000000007000000000000027266 0ustar00zuulzuul00000000000000 8"3DUfw  ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-flow_stats_reply.packet0000664000175000017500000000007000000000000030176 0ustar00zuulzuul000000000000008(  ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-flow_stats_request.packet0000664000175000017500000000007000000000000030533 0ustar00zuulzuul000000000000008././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-get_async_reply.packet0000664000175000017500000000024000000000000027764 0ustar00zuulzuul00000000000000    eee././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-get_async_request.packet0000664000175000017500000000001000000000000030314 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-get_config_reply.packet0000664000175000017500000000001400000000000030113 0ustar00zuulzuul00000000000000 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-get_config_request.packet0000664000175000017500000000001000000000000030444 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-group_desc_reply.packet0000664000175000017500000000010000000000000030135 0ustar00zuulzuul00000000000000@0 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-group_desc_request.packet0000664000175000017500000000003000000000000030474 0ustar00zuulzuul00000000000000ͫ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-group_features_reply.packet0000664000175000017500000000007000000000000031043 0ustar00zuulzuul000000000000008././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-group_features_request.packet0000664000175000017500000000002000000000000031373 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-group_mod.packet0000664000175000017500000000012000000000000026565 0ustar00zuulzuul00000000000000P884Vx ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-group_stats_reply.packet0000664000175000017500000000011000000000000030356 0ustar00zuulzuul00000000000000H8{09 $M& )././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-group_stats_request.packet0000664000175000017500000000003000000000000030714 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-hello.packet0000664000175000017500000000002000000000000025674 0ustar00zuulzuul00000000000000@././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-meter_desc_reply.packet0000664000175000017500000000005000000000000030121 0ustar00zuulzuul00000000000000( d ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-meter_desc_request.packet0000664000175000017500000000003000000000000030454 0ustar00zuulzuul00000000000000 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-meter_features_reply.packet0000664000175000017500000000005000000000000031021 0ustar00zuulzuul00000000000000 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-meter_features_request.packet0000664000175000017500000000002000000000000031353 0ustar00zuulzuul00000000000000 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-meter_mod.packet0000664000175000017500000000006000000000000026550 0ustar00zuulzuul000000000000000d  ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-meter_stats_reply.packet0000664000175000017500000000011000000000000030336 0ustar00zuulzuul00000000000000H d8S././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-meter_stats_request.packet0000664000175000017500000000003000000000000030674 0ustar00zuulzuul00000000000000 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-packet_in.packet0000664000175000017500000000010600000000000026533 0ustar00zuulzuul00000000000000 Fd(̀LP>@hoge././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-packet_out.packet0000664000175000017500000000006400000000000026737 0ustar00zuulzuul00000000000000 4 test././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-port_desc_reply.packet0000664000175000017500000000040000000000000027770 0ustar00zuulzuul00000000000000  ?pPort7 ((((( eeeH }Port6 ((((././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-port_desc_request.packet0000664000175000017500000000003000000000000030324 0ustar00zuulzuul00000000000000 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-port_mod.packet0000664000175000017500000000017000000000000026422 0ustar00zuulzuul00000000000000x , eee././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-port_stats_reply.packet0000664000175000017500000000055000000000000030216 0ustar00zuulzuul00000000000000hP(,, eeexPP(././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-port_stats_request.packet0000664000175000017500000000003000000000000030544 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-port_status.packet0000664000175000017500000000027000000000000027167 0ustar00zuulzuul00000000000000  ?p私のポート ((((( eee././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-queue_desc_reply.packet0000664000175000017500000000021000000000000030127 0ustar00zuulzuul00000000000000 eX, eee././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-queue_desc_request.packet0000664000175000017500000000003000000000000030464 0ustar00zuulzuul00000000000000ͫ޼././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-queue_stats_reply.packet0000664000175000017500000000033000000000000030352 0ustar00zuulzuul00000000000000h eee00././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-queue_stats_request.packet0000664000175000017500000000003000000000000030704 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-requestforward.packet0000664000175000017500000000013000000000000027650 0ustar00zuulzuul00000000000000 XP884Vx ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-role_reply.packet0000664000175000017500000000003000000000000026746 0ustar00zuulzuul00000000000000"3DUfw././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-role_request.packet0000664000175000017500000000003000000000000027303 0ustar00zuulzuul00000000000000"3DUfw././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-role_status.packet0000664000175000017500000000003000000000000027136 0ustar00zuulzuul00000000000000޼xV4././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-set_async.packet0000664000175000017500000000024000000000000026565 0ustar00zuulzuul00000000000000    eee././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-set_config.packet0000664000175000017500000000001400000000000026714 0ustar00zuulzuul00000000000000 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-table_desc_reply.packet0000664000175000017500000000017000000000000030077 0ustar00zuulzuul00000000000000x eP eee././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-table_desc_request.packet0000664000175000017500000000002000000000000030426 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-table_features_reply.packet0000664000175000017500000000014000000000000030774 0ustar00zuulzuul00000000000000` Ptable1././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-table_features_request.packet0000664000175000017500000000014000000000000031331 0ustar00zuulzuul00000000000000` Ptable1././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-table_mod.packet0000664000175000017500000000003000000000000026520 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-table_stats_reply.packet0000664000175000017500000000010000000000000030310 0ustar00zuulzuul00000000000000@././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-table_stats_request.packet0000664000175000017500000000002000000000000030646 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/of15/libofproto-OFP15-table_status.packet0000664000175000017500000000014000000000000027266 0ustar00zuulzuul00000000000000`P eee././@PaxHeader0000000000000000000000000000003300000000000011451 xustar000000000000000027 mtime=1724334546.202111 os-ken-2.10.0/os_ken/tests/packet_data/pcap/0000775000175000017500000000000000000000000020614 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/pcap/big_endian.pcap0000664000175000017500000000011600000000000023536 0ustar00zuulzuul000000000000004Vx test_data_1#Eg test_data_2././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/pcap/geneve_unknown.pcap0000664000175000017500000000030400000000000024506 0ustar00zuulzuul00000000000000òTx !<0!@@^l ()2 Bt yLXVVEH@@F (l*< BtBtyMX0\\ENF@@~aj (HJE:B B y././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data/pcap/zebra_v3.pcap0000664000175000017500000000234200000000000023175 0ustar00zuulzuul00000000000000ò/XW|KKE=qj@@ND (I61 8]8]  /X|JJE VUl,! IIIIIIIIIId`Y Ep@@ (ʉ*$V W> Vl,! IIIIIIIIIIdoYDqqEc@@ (-'-ۃnVW WLW> / @oYgqqEcq@@! (ʉ+T$VW WLW> / @YwNNE@@@ (ۃn-'\Z4 W\GWL  YAnnE`@@ (ۃz-'\ZT W\HWL   ././@PaxHeader0000000000000000000000000000003300000000000011451 xustar000000000000000027 mtime=1724334546.202111 os-ken-2.10.0/os_ken/tests/packet_data_generator3/0000775000175000017500000000000000000000000022022 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/packet_data_generator3/gen.py0000664000175000017500000003113400000000000023147 0ustar00zuulzuul00000000000000#! /usr/bin/env python3 import getopt import os import re import socketserver import subprocess import sys import tempfile import threading from os_ken.ofproto import ofproto_parser from os_ken.ofproto import ofproto_v1_0 from os_ken.ofproto import ofproto_v1_0_parser from os_ken.ofproto import ofproto_v1_5 from os_ken.ofproto import ofproto_v1_5_parser from os_ken.ofproto import ofproto_protocol TimeoutExpired = subprocess.TimeoutExpired STD_MATCH = [ 'in_port=43981', 'dl_vlan=999', 'dl_dst=aa:bb:cc:99:88:77', 'dl_type=0x0800', # ETH_TYPE_IP 'nw_dst=192.168.2.1', 'tun_src=192.168.2.3', 'tun_dst=192.168.2.4', 'tun_id=50000'] MESSAGES = [ {'name': 'action_learn', 'versions': [4], 'cmd': 'add-flow', 'args': ['table=2', 'importance=39032'] + STD_MATCH + [ 'actions=strip_vlan,mod_nw_dst:192.168.2.9,' + 'learn(table=99,priority=1,hard_timeout=300,' + 'OXM_OF_VLAN_VID[0..11],' + 'OXM_OF_ETH_DST[]=OXM_OF_ETH_SRC[],' + 'load:0->OXM_OF_VLAN_VID[],' + 'load:OXM_OF_TUNNEL_ID[]->OXM_OF_TUNNEL_ID[],' + 'output:OXM_OF_IN_PORT[]),goto_table:100']}, {'name': 'match_conj', 'versions': [4], 'cmd': 'mod-flows', 'args': ['table=3', 'cookie=0x123456789abcdef0/0xffffffffffffffff', 'dl_vlan=1234', 'conj_id=0xabcdef', 'actions=strip_vlan,goto_table:100']}, {'name': 'match_pkt_mark', 'versions': [4], 'cmd': 'mod-flows', 'args': ['table=3', 'cookie=0x123456789abcdef0/0xffffffffffffffff', 'dl_vlan=1234', 'pkt_mark=54321', 'actions=strip_vlan,goto_table:100']}, {'name': 'match_pkt_mark_masked', 'versions': [4], 'cmd': 'mod-flows', 'args': ['table=3', 'cookie=0x123456789abcdef0/0xffffffffffffffff', 'dl_vlan=1234', 'pkt_mark=0xd431/0xffff', 'actions=strip_vlan,goto_table:100']}, {'name': 'action_conjunction', 'versions': [4], 'cmd': 'mod-flows', 'args': (['table=2', 'cookie=0x123456789abcdef0/0xffffffffffffffff'] + STD_MATCH + ['actions=conjunction(0xabcdef,1/2)'])}, {'name': 'match_load_nx_register', 'versions': [4], 'cmd': 'mod-flows', 'args': ['table=3', 'cookie=0x123456789abcdef0/0xffffffffffffffff', 'reg0=0x1234', 'reg5=0xabcd/0xffff', 'actions=load:0xdeadbee->NXM_NX_REG0[4..31]']}, {'name': 'match_move_nx_register', 'versions': [4], 'cmd': 'mod-flows', 'args': ['table=3', 'cookie=0x123456789abcdef0/0xffffffffffffffff', 'reg0=0x1234', 'reg5=0xabcd/0xffff', 'actions=move:NXM_NX_REG0[10..15]->NXM_NX_REG1[0..5]']}, {'name': 'action_resubmit', 'versions': [4], 'cmd': 'add-flow', 'args': (['table=3', 'importance=39032'] + STD_MATCH + ['actions=resubmit(1234,99)'])}, {'name': 'action_ct', 'versions': [4], 'cmd': 'add-flow', 'args': (['table=3,', 'importance=39032'] + ['dl_type=0x0800,ct_state=-trk'] + ['actions=ct(table=4,zone=NXM_NX_REG0[4..31])'])}, {'name': 'action_ct_exec', 'versions': [4], 'cmd': 'add-flow', 'args': (['table=3,', 'importance=39032'] + ['dl_type=0x0800,ct_state=+trk+est'] + ['actions=ct(commit,exec(set_field:0x654321->ct_mark))'])}, {'name': 'action_ct_nat', 'versions': [4], 'cmd': 'add-flow', 'args': (['table=3,', 'importance=39032'] + ['dl_type=0x0800'] + ['actions=ct(commit,nat(src=10.1.12.0-10.1.13.255:1-1023)'])}, {'name': 'action_ct_nat_v6', 'versions': [4], 'cmd': 'add-flow', 'args': (['table=3,', 'importance=39032'] + ['dl_type=0x86dd'] + ['actions=ct(commit,nat(dst=2001:1::1-2001:1::ffff)'])}, {'name': 'action_ct_clear', 'versions': [4], 'cmd': 'add-flow', 'args': (['table=3,', 'importance=39032'] + ['dl_type=0x0800,ct_state=+trk'] + ['actions=ct_clear'])}, {'name': 'action_note', 'versions': [4], 'cmd': 'add-flow', 'args': (['priority=100'] + ['actions=note:04.05.06.07.00.00'])}, {'name': 'action_controller', 'versions': [4], 'cmd': 'add-flow', 'args': (['priority=100'] + ['actions=controller(reason=packet_out,max_len=1024,id=1)'])}, {'name': 'action_fintimeout', 'versions': [4], 'cmd': 'add-flow', 'args': (['priority=100,tcp'] + ['actions=fin_timeout(idle_timeout=30,hard_timeout=60)'])}, {'name': 'action_dec_nw_ttl', 'versions': [1], 'cmd': 'add-flow', 'args': (['priority=100,mpls'] + ['actions=dec_ttl'])}, {'name': 'action_push_mpls', 'versions': [1], 'cmd': 'add-flow', 'args': (['priority=100,ip'] + ['actions=push_mpls:0x8847'])}, {'name': 'action_pop_mpls', 'versions': [1], 'cmd': 'add-flow', 'args': (['priority=100,mpls'] + ['actions=pop_mpls:0x0800'])}, {'name': 'action_set_mpls_ttl', 'versions': [1], 'cmd': 'add-flow', 'args': (['priority=100,mpls'] + ['actions=set_mpls_ttl(127)'])}, {'name': 'action_dec_mpls_ttl', 'versions': [1], 'cmd': 'add-flow', 'args': (['priority=100,mpls'] + ['actions=dec_mpls_ttl'])}, {'name': 'action_set_mpls_label', 'versions': [1], 'cmd': 'add-flow', 'args': (['priority=100,mpls'] + ['actions=set_mpls_label(10)'])}, {'name': 'action_set_mpls_tc', 'versions': [1], 'cmd': 'add-flow', 'args': (['priority=100,mpls'] + ['actions=set_mpls_tc(10)'])}, {'name': 'action_dec_ttl_cnt_ids', 'versions': [4], 'cmd': 'add-flow', 'args': (['priority=100,tcp'] + ['actions=dec_ttl(1,2,3,4,5)'])}, {'name': 'action_stack_push', 'versions': [4], 'cmd': 'add-flow', 'args': (['priority=100'] + ['actions=push:NXM_NX_REG2[1..5]'])}, {'name': 'action_stack_pop', 'versions': [4], 'cmd': 'add-flow', 'args': (['priority=100'] + ['actions=pop:NXM_NX_REG2[1..5]'])}, {'name': 'action_sample', 'versions': [4], 'cmd': 'add-flow', 'args': (['priority=100'] + ['actions=sample(probability=3,collector_set_id=1,' + 'obs_domain_id=2,obs_point_id=3)'])}, {'name': 'action_sample2', 'versions': [4], 'cmd': 'add-flow', 'args': (['priority=100'] + ['actions=sample(probability=3,collector_set_id=1,' + 'obs_domain_id=2,obs_point_id=3,sampling_port=8080)'])}, {'name': 'action_controller2', 'versions': [4], 'cmd': 'add-flow', 'args': (['priority=100'] + ['actions=controller(reason=packet_out,max_len=1024,' + 'id=10,userdata=01.02.03.04.05,pause)'])}, {'name': 'action_output_trunc', 'versions': [4], 'cmd': 'add-flow', 'args': (['priority=100'] + ['actions=output(port=8080,max_len=1024)'])}, {'name': 'bundle-add', 'versions': [4], 'bundled': True, 'cmd': 'add-flow', 'args': ['table=33', 'dl_vlan=1234', 'actions=strip_vlan,goto_table:100']}, # ToDo: The following actions are not eligible # {'name': 'action_regload2'}, # {'name': 'action_outputreg2'}, ] buf = [] class MyHandler(socketserver.BaseRequestHandler): verbose = False @staticmethod def _add_msg_to_buf(data, msg_len): # HACK: Clear xid into zero buf.append(data[:4] + b'\x00\x00\x00\x00' + data[8:msg_len]) def handle(self): desc = ofproto_protocol.ProtocolDesc() residue = b'' while True: if residue: data = residue residue = b'' else: data = self.request.recv(1024) if data == b'': break if self.verbose: print(data) h = ofproto_parser.header(data) if self.verbose: print(h) version, msg_type, msg_len, xid = h residue = data[msg_len:] desc.set_version(version=version) if msg_type == desc.ofproto.OFPT_HELLO: hello = desc.ofproto_parser.OFPHello(desc) hello.serialize() self.request.send(hello.buf) elif msg_type == desc.ofproto.OFPT_FLOW_MOD: self._add_msg_to_buf(data, msg_len) elif version == 4 and msg_type == desc.ofproto.OFPT_EXPERIMENTER: # This is for OF13 Ext-230 bundle # TODO: support bundle for OF>1.3 exp = desc.ofproto_parser.OFPExperimenter.parser( object(), version, msg_type, msg_len, xid, data) self._add_msg_to_buf(data, msg_len) if isinstance(exp, desc.ofproto_parser.ONFBundleCtrlMsg): ctrlrep = desc.ofproto_parser.ONFBundleCtrlMsg( desc, exp.bundle_id, exp.type + 1, 0, []) ctrlrep.xid = xid ctrlrep.serialize() self.request.send(ctrlrep.buf) elif msg_type == desc.ofproto.OFPT_BARRIER_REQUEST: brep = desc.ofproto_parser.OFPBarrierReply(desc) brep.xid = xid brep.serialize() self.request.send(brep.buf) class MyVerboseHandler(MyHandler): verbose = True if __name__ == '__main__': optlist, args = getopt.getopt(sys.argv[1:], 'dvo:') debug = False ofctl_cmd = '/usr/bin/ovs-ofctl' verbose = False for o, a in optlist: if o == '-d': debug = True elif o == '-v': verbose = True elif o == '-o': ofctl_cmd = a if not os.access(ofctl_cmd, os.X_OK): raise Exception("%s is not executable" % ofctl_cmd) ovs_version = subprocess.Popen([ofctl_cmd, '--version'], stdout=subprocess.PIPE) has_names = False try: ver_tuple = re.search(r'\s(\d+)\.(\d+)(\.\d*|\s*$)', ovs_version.stdout.readline().decode()).groups() if int(ver_tuple[0]) > 2 or \ int(ver_tuple[0]) == 2 and int(ver_tuple[1]) >= 8: has_names = True except AttributeError: pass outpath = '../packet_data' socketdir = tempfile.mkdtemp() socketname = os.path.join(socketdir, 'ovs') server = socketserver.UnixStreamServer(socketname, MyVerboseHandler if verbose else MyHandler) if debug or verbose: print("Serving at %s" % socketname) for msg in MESSAGES: bundled = msg.get('bundled', False) for v in msg['versions']: cmdargs = [ofctl_cmd, '-O', 'OpenFlow%2d' % (v + 9)] if verbose: cmdargs.append('-v') if has_names: cmdargs.append('--no-names') if bundled: cmdargs.append('--bundle') cmdargs.append(msg['cmd']) cmdargs.append('unix:%s' % socketname) cmdargs.append('\n'.join(msg['args'])) if verbose: print("Running cmd: " + ' '.join(cmdargs) + "\n") t = threading.Thread(target=subprocess.call, args=[cmdargs], kwargs={'timeout': 5}) t.start() server.handle_request() if debug: for buf1 in buf: print(buf1) buf = [] else: for i, buf1 in enumerate(buf): suffix = ('-%d' % (i + 1)) if i else '' outf = os.path.join( outpath, "of%d" % (v + 9), "ovs-ofctl-of%d-%s%s.packet" % ( v + 9, msg['name'], suffix)) print("Writing %s..." % outf) with open(outf, 'wb') as f: f.write(buf1) buf = [] try: t.join() except TimeoutExpired as e: print(e) if debug: while True: server.handle_request() print(buf.pop()) os.unlink(socketname) os.rmdir(socketdir) ././@PaxHeader0000000000000000000000000000003300000000000011451 xustar000000000000000027 mtime=1724334546.202111 os-ken-2.10.0/os_ken/tests/switch/0000775000175000017500000000000000000000000016732 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/__init__.py0000664000175000017500000000000000000000000021031 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.0341012 os-ken-2.10.0/os_ken/tests/switch/of10/0000775000175000017500000000000000000000000017477 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.2061112 os-ken-2.10.0/os_ken/tests/switch/of10/action/0000775000175000017500000000000000000000000020754 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of10/action/00_OUTPUT.json0000664000175000017500000001104700000000000023211 0ustar00zuulzuul00000000000000[ "action: 00_OUTPUT", { "description": "ethernet/ipv4/tcp-->'actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": {} } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/ipv6/tcp-->'actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": {} } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/arp-->'actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": {} } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of10/action/01_SET_VLAN_VID.json0000664000175000017500000001344600000000000024134 0ustar00zuulzuul00000000000000[ "action: 01_SET_VLAN_VID", { "description": "ethernet/vlan(vid=100)/ipv4/tcp-->'vlan_vid=100,actions=mod_vlan_vid:203,output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionVlanVid": { "vlan_vid": 203 } }, { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_vlan": 100 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan(vid=100)/ipv6/tcp-->'vlan_vid=100,actions=mod_vlan_vid:203,output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionVlanVid": { "vlan_vid": 203 } }, { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_vlan": 100 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan(vid=100)/arp-->'vlan_vid=100,actions=mod_vlan_vid:203,output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionVlanVid": { "vlan_vid": 203 } }, { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_vlan": 100 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=203, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of10/action/02_SET_VLAN_PCP.json0000664000175000017500000001342400000000000024131 0ustar00zuulzuul00000000000000[ "action: 02_SET_VLAN_PCP", { "description": "ethernet/vlan(pcp=3)/ipv4/tcp-->'vlan_pcp=3,actions=mod_vlan_pcp:5,output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionVlanPcp": { "vlan_pcp": 5 } }, { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_vlan_pcp": 3 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan(pcp=3)/ipv6/tcp-->'vlan_pcp=3,actions=mod_vlan_pcp:5,output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionVlanPcp": { "vlan_pcp": 5 } }, { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_vlan_pcp": 3 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan(pcp=3)/arp-->'vlan_pcp=3,actions=mod_vlan_pcp:5,output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionVlanPcp": { "vlan_pcp": 5 } }, { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_vlan_pcp": 3 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of10/action/03_STRIP_VLAN.json0000664000175000017500000001256300000000000023701 0ustar00zuulzuul00000000000000[ "action: 03_STRIP_VLAN", { "description": "ethernet/vlan(vid=100)/ipv4/tcp-->'vlan_vid=100,actions=strip_vlan,output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionStripVlan": {} }, { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_vlan": 100 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan(vid=100)/ipv6/tcp-->'vlan_vid=100,actions=strip_vlan,output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionStripVlan": {} }, { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_vlan": 100 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan(vid=100)/arp-->'vlan_vid=100,actions=strip_vlan,output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionStripVlan": {} }, { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_vlan": 100 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of10/action/04_SET_DL_SRC.json0000664000175000017500000001314300000000000023675 0ustar00zuulzuul00000000000000[ "action: 04_SET_DL_SRC", { "description": "ethernet(src='12:11:11:11:11:11')/ipv4/tcp-->'eth_src=12:11:11:11:11:11,actions=mod_dl_src:aa:aa:aa:aa:aa:aa,output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionSetDlSrc": { "dl_addr": "aa:aa:aa:aa:aa:aa" } }, { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_src": "12:11:11:11:11:11" } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet(src='12:11:11:11:11:11')/ipv6/tcp-->'eth_src=12:11:11:11:11:11,actions=mod_dl_src:aa:aa:aa:aa:aa:aa,output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionSetDlSrc": { "dl_addr": "aa:aa:aa:aa:aa:aa" } }, { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_src": "12:11:11:11:11:11" } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet(src='12:11:11:11:11:11')/arp-->'eth_src=12:11:11:11:11:11,actions=mod_dl_src:aa:aa:aa:aa:aa:aa,output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionSetDlSrc": { "dl_addr": "aa:aa:aa:aa:aa:aa" } }, { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_src": "12:11:11:11:11:11" } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of10/action/05_SET_DL_DST.json0000664000175000017500000001314300000000000023701 0ustar00zuulzuul00000000000000[ "action: 05_SET_DL_DST", { "description": "ethernet(dst='22:22:22:22:22:22')/ipv4/tcp-->'eth_dst=22:22:22:22:22:22,actions=mod_dl_dst:ba:bb:bb:bb:bb:bb,output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionSetDlDst": { "dl_addr": "ba:bb:bb:bb:bb:bb" } }, { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_dst": "22:22:22:22:22:22" } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet(dst='22:22:22:22:22:22')/ipv6/tcp-->'eth_dst=22:22:22:22:22:22,actions=mod_dl_dst:ba:bb:bb:bb:bb:bb,output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionSetDlDst": { "dl_addr": "ba:bb:bb:bb:bb:bb" } }, { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_dst": "22:22:22:22:22:22" } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet(dst='22:22:22:22:22:22')/arp-->'eth_dst=22:22:22:22:22:22,actions=mod_dl_dst:ba:bb:bb:bb:bb:bb,output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionSetDlDst": { "dl_addr": "ba:bb:bb:bb:bb:bb" } }, { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_dst": "22:22:22:22:22:22" } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of10/action/06_SET_NW_SRC.json0000664000175000017500000001016100000000000023721 0ustar00zuulzuul00000000000000[ "action: 06_SET_NW_SRC", { "description": "ethernet/ipv4(src='192.168.10.10')/tcp-->'nw_src=192.168.10.10,actions=mod_nw_src:10.10.10.10,output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionSetNwSrc": { "nw_addr": "10.10.10.10" } }, { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_src": "192.168.10.10" } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='10.10.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv4(src='192.168.10.10')/tcp-->'nw_src=192.168.10.10,actions=mod_nw_src:10.10.10.10,output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionSetNwSrc": { "nw_addr": "10.10.10.10" } }, { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_src": "192.168.10.10" } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='10.10.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of10/action/07_SET_NW_DST.json0000664000175000017500000001016100000000000023725 0ustar00zuulzuul00000000000000[ "action: 07_SET_NW_DST", { "description": "ethernet/ipv4(dst='192.168.20.20')/tcp-->'nw_dst=192.168.20.20,actions=mod_nw_dst:10.10.20.20,output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionSetNwDst": { "nw_addr": "10.10.20.20" } }, { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_dst": "192.168.20.20" } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='10.10.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv4(dst='192.168.20.20')/tcp-->'nw_dst=192.168.20.20,actions=mod_nw_dst:10.10.20.20,output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionSetNwDst": { "nw_addr": "10.10.20.20" } }, { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_dst": "192.168.20.20" } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='10.10.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of10/action/08_SET_NW_TOS_IPv4.json0000664000175000017500000001000200000000000024575 0ustar00zuulzuul00000000000000[ "action: 08_SET_NW_TOS (IPv4)", { "description": "ethernet/ipv4(tos=32)/tcp-->'nw_tos=32,actions=mod_nw_tos:64,output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionSetNwTos": { "tos": 64 } }, { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_tos": 32 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=64, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv4(tos=32)/tcp-->'nw_tos=32,actions=mod_nw_tos:64,output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionSetNwTos": { "tos": 64 } }, { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_tos": 32 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=64, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of10/action/08_SET_NW_TOS_IPv6.json0000664000175000017500000001013400000000000024605 0ustar00zuulzuul00000000000000[ "action: 08_SET_NW_TOS (IPv6)", { "description": "ethernet/ipv6(traffic_class=32)/tcp-->'nw_tos=32,actions=mod_nw_tos:64,output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionSetNwTos": { "tos": 64 } }, { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 34525, "nw_tos": 32 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv6(traffic_class=32)/tcp-->'nw_tos=32,actions=mod_nw_tos:64,output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionSetNwTos": { "tos": 64 } }, { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 34525, "nw_tos": 32 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of10/action/09_SET_TP_SRC_IPv4_TCP.json0000664000175000017500000001020200000000000025267 0ustar00zuulzuul00000000000000[ "action: 09_SET_TP_SRC (IPv4/TCP)", { "description": "ethernet/ipv4/tcp(src_port=11111)-->'tp_dst=11111,actions=mod_tp_src:12345,output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionSetTpSrc": { "tp": 12345 } }, { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_proto": 6, "tp_src": 11111 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv4/tcp(src_port=11111)-->'tp_dst=11111,actions=mod_tp_src:12345,output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionSetTpSrc": { "tp": 12345 } }, { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_proto": 6, "tp_src": 11111 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of10/action/09_SET_TP_SRC_IPv4_UDP.json0000664000175000017500000001003000000000000025270 0ustar00zuulzuul00000000000000[ "action: 09_SET_TP_SRC (IPv4/UDP)", { "description": "ethernet/ipv4/udp(src_port=11111)-->'tp_dst=11111,actions=mod_tp_src:12345,output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionSetTpSrc": { "tp": 12345 } }, { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_proto": 17, "tp_src": 11111 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv4/udp(src_port=11111)-->'tp_dst=11111,actions=mod_tp_src:12345,output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionSetTpSrc": { "tp": 12345 } }, { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_proto": 17, "tp_src": 11111 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of10/action/09_SET_TP_SRC_IPv6_TCP.json0000664000175000017500000001031000000000000025271 0ustar00zuulzuul00000000000000[ "action: 09_SET_TP_SRC (IPv6/TCP)", { "description": "ethernet/ipv6/tcp(src_port=11111)-->'tp_dst=11111,actions=mod_tp_src:12345,output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionSetTpSrc": { "tp": 12345 } }, { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 34525, "nw_proto": 6, "tp_src": 11111 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv6/tcp(src_port=11111)-->'tp_dst=11111,actions=mod_tp_src:12345,output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionSetTpSrc": { "tp": 12345 } }, { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 34525, "nw_proto": 6, "tp_src": 11111 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of10/action/09_SET_TP_SRC_IPv6_UDP.json0000664000175000017500000001013600000000000025301 0ustar00zuulzuul00000000000000[ "action: 09_SET_TP_SRC (IPv6/UDP)", { "description": "ethernet/ipv6/udp(src_port=11111)-->'tp_dst=11111,actions=mod_tp_src:12345,output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionSetTpSrc": { "tp": 12345 } }, { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 34525, "nw_proto": 17, "tp_src": 11111 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv6/udp(src_port=11111)-->'tp_dst=11111,actions=mod_tp_src:12345,output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionSetTpSrc": { "tp": 12345 } }, { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 34525, "nw_proto": 17, "tp_src": 11111 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of10/action/10_SET_TP_DST_IPv4_TCP.json0000664000175000017500000001017000000000000025266 0ustar00zuulzuul00000000000000[ "action: 10_SET_TP_DST (IPv4/TCP)", { "description": "ethernet/ipv4/tcp(dst_port=2222)-->'tp_dst=2222,actions=mod_tp_dst:6789,output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionSetTpDst": { "tp": 6789 } }, { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_proto": 6, "tp_dst": 2222 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=6789, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv4/tcp(dst_port=2222)-->'tp_dst=2222,actions=mod_tp_dst:6789,output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionSetTpDst": { "tp": 6789 } }, { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_proto": 6, "tp_dst": 2222 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=6789, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of10/action/10_SET_TP_DST_IPv4_UDP.json0000664000175000017500000001001600000000000025267 0ustar00zuulzuul00000000000000[ "action: 10_SET_TP_DST (IPv4/UDP)", { "description": "ethernet/ipv4/udp(dst_port=2222)-->'tp_dst=2222,actions=mod_tp_dst:6789,output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionSetTpDst": { "tp": 6789 } }, { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_proto": 17, "tp_dst": 2222 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=6789, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv4/udp(dst_port=2222)-->'tp_dst=2222,actions=mod_tp_dst:6789,output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionSetTpDst": { "tp": 6789 } }, { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_proto": 17, "tp_dst": 2222 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=6789, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of10/action/10_SET_TP_DST_IPv6_TCP.json0000664000175000017500000001027600000000000025277 0ustar00zuulzuul00000000000000[ "action: 10_SET_TP_DST (IPv4/TCP)", { "description": "ethernet/ipv6/tcp(dst_port=2222)-->'tp_dst=2222,actions=mod_tp_dst:6789,output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionSetTpDst": { "tp": 6789 } }, { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 34525, "nw_proto": 6, "tp_dst": 2222 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=6789, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv6/tcp(dst_port=2222)-->'tp_dst=2222,actions=mod_tp_dst:6789,output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionSetTpDst": { "tp": 6789 } }, { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 34525, "nw_proto": 6, "tp_dst": 2222 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=6789, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of10/action/10_SET_TP_DST_IPv6_UDP.json0000664000175000017500000001012400000000000025271 0ustar00zuulzuul00000000000000[ "action: 10_SET_TP_DST (IPv6/UDP)", { "description": "ethernet/ipv6/udp(dst_port=2222)-->'tp_dst=2222,actions=mod_tp_dst:6789,output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionSetTpDst": { "tp": 6789 } }, { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 34525, "nw_proto": 17, "tp_dst": 2222 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=6789, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv6/udp(dst_port=2222)-->'tp_dst=2222,actions=mod_tp_dst:6789,output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionSetTpDst": { "tp": 6789 } }, { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 34525, "nw_proto": 17, "tp_dst": 2222 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=6789, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.2101116 os-ken-2.10.0/os_ken/tests/switch/of10/match/0000775000175000017500000000000000000000000020573 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of10/match/00_IN_PORT.json0000664000175000017500000003224300000000000023143 0ustar00zuulzuul00000000000000[ "match: 00_IN_PORT", { "description": "ethernet/ipv4/tcp-->'in_port=1,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "in_port": 1 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/ipv4/tcp-->'in_port=1,actions=output:CONTROLLER'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 65533 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "in_port": 1 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/ipv4/tcp-->'in_port=2,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "in_port": 2 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss": [ 0 ] } ] }, { "description": "ethernet/ipv6/tcp-->'in_port=1,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "in_port": 1 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/ipv6/tcp-->'in_port=1,actions=output:CONTROLLER'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 65533 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "in_port": 1 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/ipv6/tcp-->'in_port=2,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "in_port": 2 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss": [ 0 ] } ] }, { "description": "ethernet/arp-->'in_port=1,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "in_port": 1 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description": "ethernet/arp-->'in_port=1,actions=output:CONTROLLER'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 65533 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "in_port": 1 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description": "ethernet/arp-->'in_port=2,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "in_port": 2 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss": [ 0 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of10/match/01_DL_SRC.json0000664000175000017500000003324300000000000023001 0ustar00zuulzuul00000000000000[ "match: 01_DL_SRC", { "description": "ethernet(src='12:11:11:11:11:11')/ipv4/tcp-->'dl_src=12:11:11:11:11:11,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_src": "12:11:11:11:11:11" } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet(src='12:11:11:11:11:11')/ipv4/tcp-->'dl_src=12:11:11:11:11:11,actions=output:CONTROLLER'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 65533 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_src": "12:11:11:11:11:11" } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet(src='aa:aa:aa:aa:aa:aa')/ipv4/tcp-->'dl_src=12:11:11:11:11:11,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_src": "12:11:11:11:11:11" } } } } ], "tests": [ { "ingress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss": [ 0 ] } ] }, { "description": "ethernet(src='12:11:11:11:11:11')/ipv6/tcp-->'dl_src=12:11:11:11:11:11,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_src": "12:11:11:11:11:11" } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet(src='12:11:11:11:11:11')/ipv6/tcp-->'dl_src=12:11:11:11:11:11,actions=output:CONTROLLER'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 65533 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_src": "12:11:11:11:11:11" } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet(src='aa:aa:aa:aa:aa:aa')/ipv6/tcp-->'dl_src=12:11:11:11:11:11,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_src": "12:11:11:11:11:11" } } } } ], "tests": [ { "ingress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss": [ 0 ] } ] }, { "description": "ethernet(src='12:11:11:11:11:11')/arp-->'dl_src=12:11:11:11:11:11,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_src": "12:11:11:11:11:11" } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description": "ethernet(src='12:11:11:11:11:11')/arp-->'dl_src=12:11:11:11:11:11,actions=output:CONTROLLER'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 65533 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_src": "12:11:11:11:11:11" } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description": "ethernet(src='aa:aa:aa:aa:aa:aa')/arp-->'dl_src=12:11:11:11:11:11,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_src": "12:11:11:11:11:11" } } } } ], "tests": [ { "ingress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss": [ 0 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of10/match/02_DL_DST.json0000664000175000017500000003324300000000000023005 0ustar00zuulzuul00000000000000[ "match: 02_DL_DST", { "description": "ethernet(dst='22:22:22:22:22:22')/ipv4/tcp-->'dl_dst=22:22:22:22:22:22,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_dst": "22:22:22:22:22:22" } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet(dst='22:22:22:22:22:22')/ipv4/tcp-->'dl_dst=22:22:22:22:22:22,actions=output:CONTROLLER'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 65533 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_dst": "22:22:22:22:22:22" } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet(dst='ba:bb:bb:bb:bb:bb')/ipv4/tcp-->'dl_dst=22:22:22:22:22:22,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_dst": "22:22:22:22:22:22" } } } } ], "tests": [ { "ingress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss": [ 0 ] } ] }, { "description": "ethernet(dst='22:22:22:22:22:22')/ipv6/tcp-->'dl_dst=22:22:22:22:22:22,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_dst": "22:22:22:22:22:22" } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet(dst='22:22:22:22:22:22')/ipv6/tcp-->'dl_dst=22:22:22:22:22:22,actions=output:CONTROLLER'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 65533 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_dst": "22:22:22:22:22:22" } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet(dst='ba:bb:bb:bb:bb:bb')/ipv6/tcp-->'dl_dst=22:22:22:22:22:22,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_dst": "22:22:22:22:22:22" } } } } ], "tests": [ { "ingress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss": [ 0 ] } ] }, { "description": "ethernet(dst='22:22:22:22:22:22')/arp-->'dl_dst=22:22:22:22:22:22,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_dst": "22:22:22:22:22:22" } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description": "ethernet(dst='22:22:22:22:22:22')/arp-->'dl_dst=22:22:22:22:22:22,actions=output:CONTROLLER'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 65533 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_dst": "22:22:22:22:22:22" } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description": "ethernet(dst='ba:bb:bb:bb:bb:bb')/arp-->'dl_dst=22:22:22:22:22:22,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_dst": "22:22:22:22:22:22" } } } } ], "tests": [ { "ingress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss": [ 0 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of10/match/03_DL_VLAN.json0000664000175000017500000003443600000000000023121 0ustar00zuulzuul00000000000000[ "match: 03_DL_VLAN", { "description": "ethernet/vlan(vid=100)/ipv4/tcp-->'dl_vlan=100,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_vlan": 100 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan(vid=100)/ipv4/tcp-->'dl_vlan=100,actions=output:CONTROLLER'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 65533 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_vlan": 100 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan(vid=203)/ipv4/tcp-->'dl_vlan=100,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_vlan": 100 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss": [ 0 ] } ] }, { "description": "ethernet/vlan(vid=100)/ipv6/tcp-->'dl_vlan=100,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_vlan": 100 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan(vid=100)/ipv6/tcp-->'dl_vlan=100,actions=output:CONTROLLER'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 65533 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_vlan": 100 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan(vid=203)/ipv6/tcp-->'dl_vlan=100,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_vlan": 100 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss": [ 0 ] } ] }, { "description": "ethernet/vlan(vid=100)/arp-->'dl_vlan=100,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_vlan": 100 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description": "ethernet/vlan(vid=100)/arp-->'dl_vlan=100,actions=output:CONTROLLER'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 65533 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_vlan": 100 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "PACKET_IN": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description": "ethernet/vlan(vid=203)/arp-->'dl_vlan=100,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_vlan": 100 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * 30)" ], "table-miss": [ 0 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of10/match/04_DL_VLAN_PCP.json0000664000175000017500000003530000000000000023613 0ustar00zuulzuul00000000000000[ "match: 04_DL_VLAN_PCP", { "description": "ethernet/vlan(pcp=3)/ipv4/tcp-->'dl_vlan_pcp=3,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_vlan": 100, "dl_vlan_pcp": 3 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan(pcp=3)/ipv4/tcp-->'dl_vlan_pcp=3,actions=output:CONTROLLER'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 65533 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_vlan": 100, "dl_vlan_pcp": 3 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan(pcp=5)/ipv4/tcp-->'dl_vlan_pcp=3,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_vlan": 100, "dl_vlan_pcp": 3 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss": [ 0 ] } ] }, { "description": "ethernet/vlan(pcp=3)/ipv6/tcp-->'dl_vlan_pcp=3,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_vlan": 100, "dl_vlan_pcp": 3 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan(pcp=3)/ipv6/tcp-->'dl_vlan_pcp=3,actions=output:CONTROLLER'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 65533 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_vlan": 100, "dl_vlan_pcp": 3 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan(pcp=5)/ipv6/tcp-->'dl_vlan_pcp=3,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_vlan": 100, "dl_vlan_pcp": 3 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss": [ 0 ] } ] }, { "description": "ethernet/vlan(pcp=3)/arp-->'dl_vlan_pcp=3,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_vlan": 100, "dl_vlan_pcp": 3 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description": "ethernet/vlan(pcp=3)/arp-->'dl_vlan_pcp=3,actions=output:CONTROLLER'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 65533 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_vlan": 100, "dl_vlan_pcp": 3 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "PACKET_IN": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description": "ethernet/vlan(pcp=5)/arp-->'dl_vlan_pcp=3,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_vlan": 100, "dl_vlan_pcp": 3 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * 30)" ], "table-miss": [ 0 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of10/match/05_DL_TYPE.json0000664000175000017500000003261700000000000023143 0ustar00zuulzuul00000000000000[ "match: 05_DL_TYPE", { "description": "ethernet(ethertype=0x0800)/ipv4/tcp-->'dl_type=0x0800,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet(ethertype=0x0800)/ipv4/tcp-->'dl_type=0x0800,actions=output:CONTROLLER'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 65533 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet(ethertype=0x0800)/ipv4/tcp-->'dl_type=0x0806,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2054 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss": [ 0 ] } ] }, { "description": "ethernet(ethertype=0x86dd)/ipv6/tcp-->'dl_type=0x86dd,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 34525 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet(ethertype=0x86dd)/ipv6/tcp-->'dl_type=0x86dd,actions=output:CONTROLLER'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 65533 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 34525 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet(ethertype=0x86dd)/ipv6/tcp-->'dl_type=0x0806,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2054 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss": [ 0 ] } ] }, { "description": "ethernet(ethertype=0x0806)/arp-->'dl_type=0x0806,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2054 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description": "ethernet(ethertype=0x0806)/arp-->'dl_type=0x0806,actions=output:CONTROLLER'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 65533 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2054 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description": "ethernet(ethertype=0x0806)/arp-->'dl_type=0x0800,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss": [ 0 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of10/match/06_NW_TOS_IPv4.json0000664000175000017500000002367500000000000023723 0ustar00zuulzuul00000000000000[ "match: 06_NW_TOS (IPv4)", { "description": "ethernet/ipv4(tos=32)/tcp-->'nw_tos=32,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_tos": 32 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/ipv4(tos=32)/tcp-->'nw_tos=32,actions=output:CONTROLLER'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 65533 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_tos": 32 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/ipv4(tos=65)/tcp-->'nw_tos=32,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_tos": 32 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss": [ 0 ] } ] }, { "description": "ethernet/vlan/ipv4(tos=32)/tcp-->'nw_tos=32,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_tos": 32 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv4(tos=32)/tcp-->'nw_tos=32,actions=output:CONTROLLER'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 65533 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_tos": 32 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv4(tos=65)/tcp-->'nw_tos=32,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_tos": 32 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss": [ 0 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of10/match/06_NW_TOS_IPv6.json0000664000175000017500000002426100000000000023715 0ustar00zuulzuul00000000000000[ "match: 06_NW_TOS (IPv6)", { "description": "ethernet/ipv6(traffic_class=32)/tcp-->'nw_tos=32,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 34525, "nw_tos": 32 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/ipv6(traffic_class=32)/tcp-->'nw_tos=32,actions=output:CONTROLLER'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 65533 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 34525, "nw_tos": 32 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/ipv6(traffic_class=65)/tcp-->'nw_tos=32,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 34525, "nw_tos": 32 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss": [ 0 ] } ] }, { "description": "ethernet/vlan/ipv6(traffic_class=32)/tcp-->'nw_tos=32,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 34525, "nw_tos": 32 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv6(traffic_class=32)/tcp-->'nw_tos=32,actions=output:CONTROLLER'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 65533 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 34525, "nw_tos": 32 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv6(traffic_class=65)/tcp-->'nw_tos=32,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 34525, "nw_tos": 32 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss": [ 0 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of10/match/07_NW_PROTO_IPv4.json0000664000175000017500000002372500000000000024156 0ustar00zuulzuul00000000000000[ "match: 07_NW_PROTO (IPv4)", { "description": "ethernet/ipv4(proto=6)/tcp-->'nw_proto=6,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_proto": 6 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/ipv4(proto=6)/tcp-->'nw_proto=6,actions=output:CONTROLLER'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 65533 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_proto": 6 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/ipv4(proto=6)/tcp-->'nw_proto=17,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_proto": 17 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss": [ 0 ] } ] }, { "description": "ethernet/vlan/ipv4(proto=6)/tcp-->'nw_proto=6,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_proto": 6 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv4(proto=6)/tcp-->'nw_proto=6,actions=output:CONTROLLER'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 65533 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_proto": 6 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv4(proto=6)/tcp-->'nw_proto=17,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_proto": 17 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss": [ 0 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of10/match/07_NW_PROTO_IPv6.json0000664000175000017500000002420100000000000024146 0ustar00zuulzuul00000000000000[ "match: 07_NW_PROTO (IPv6)", { "description": "ethernet/ipv6(nxt=6)/tcp-->'nw_proto=6,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 34525, "nw_proto": 6 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/ipv6(nxt=6)/tcp-->'nw_proto=6,actions=output:CONTROLLER'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 65533 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 34525, "nw_proto": 6 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/ipv6(nxt=6)/tcp-->'nw_proto=17,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 34525, "nw_proto": 17 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss": [ 0 ] } ] }, { "description": "ethernet/vlan/ipv6(nxt=6)/tcp-->'nw_proto=6,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 34525, "nw_proto": 6 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv6(nxt=6)/tcp-->'nw_proto=6,actions=output:CONTROLLER'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 65533 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 34525, "nw_proto": 6 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv6(nxt=6)/tcp-->'nw_proto=17,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 34525, "nw_proto": 17 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss": [ 0 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of10/match/08_NW_SRC.json0000664000175000017500000002422000000000000023030 0ustar00zuulzuul00000000000000[ "match: 08_NW_SRC", { "description": "ethernet/ipv4(src='192.168.10.10')/tcp-->'nw_src=192.168.10.10,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_src": "192.168.10.10" } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/ipv4(src='192.168.10.10')/tcp-->'nw_src=192.168.10.10,actions=output:CONTROLLER'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 65533 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_src": "192.168.10.10" } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/ipv4(src='10.10.10.10')/tcp-->'nw_src=192.168.10.10,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_src": "192.168.10.10" } } } } ], "tests": [ { "ingress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss": [ 0 ] } ] }, { "description": "ethernet/vlan/ipv4(src='192.168.10.10')/tcp-->'nw_src=192.168.10.10,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_src": "192.168.10.10" } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv4(src='192.168.10.10')/tcp-->'nw_src=192.168.10.10,actions=output:CONTROLLER'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 65533 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_src": "192.168.10.10" } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv4(src='10.10.10.10')/tcp-->'nw_src=192.168.10.10,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_src": "192.168.10.10" } } } } ], "tests": [ { "ingress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss": [ 0 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of10/match/08_NW_SRC_Mask.json0000664000175000017500000002466700000000000024022 0ustar00zuulzuul00000000000000[ "match: 08_NW_SRC (Mask)", { "description": "ethernet/ipv4(src='192.168.10.10')/tcp-->'nw_src=192.168.10.0/24,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_src": "192.168.10.0", "nw_src_mask": 24 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/ipv4(src='192.168.10.10')/tcp-->'nw_src=192.168.10.0/24,actions=output:CONTROLLER'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 65533 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_src": "192.168.10.0", "nw_src_mask": 24 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/ipv4(src='10.10.10.10')/tcp-->'nw_src=192.168.10.0/24,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_src": "192.168.10.0", "nw_src_mask": 24 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss": [ 0 ] } ] }, { "description": "ethernet/vlan/ipv4(src='192.168.10.10')/tcp-->'nw_src=192.168.10.0/24,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_src": "192.168.10.0", "nw_src_mask": 24 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv4(src='192.168.10.10')/tcp-->'nw_src=192.168.10.0/24,actions=output:CONTROLLER'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 65533 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_src": "192.168.10.0", "nw_src_mask": 24 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv4(src='10.10.10.10')/tcp-->'nw_src=192.168.10.0/24,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_src": "192.168.10.0", "nw_src_mask": 24 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss": [ 0 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of10/match/09_NW_DST.json0000664000175000017500000002422000000000000023034 0ustar00zuulzuul00000000000000[ "match: 09_NW_DST", { "description": "ethernet/ipv4(dst='192.168.20.20')/tcp-->'nw_dst=192.168.20.20,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_dst": "192.168.20.20" } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/ipv4(dst='192.168.20.20')/tcp-->'nw_dst=192.168.20.20,actions=output:CONTROLLER'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 65533 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_dst": "192.168.20.20" } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/ipv4(dst='10.10.20.20')/tcp-->'nw_dst=192.168.20.20,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_dst": "192.168.20.20" } } } } ], "tests": [ { "ingress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss": [ 0 ] } ] }, { "description": "ethernet/vlan/ipv4(dst='192.168.20.20')/tcp-->'nw_dst=192.168.20.20,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_dst": "192.168.20.20" } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv4(dst='192.168.20.20')/tcp-->'nw_dst=192.168.20.20,actions=output:CONTROLLER'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 65533 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_dst": "192.168.20.20" } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv4(dst='10.10.20.20')/tcp-->'nw_dst=192.168.20.20,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_dst": "192.168.20.20" } } } } ], "tests": [ { "ingress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss": [ 0 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of10/match/09_NW_DST_Mask.json0000664000175000017500000002466700000000000024026 0ustar00zuulzuul00000000000000[ "match: 09_NW_DST (Mask)", { "description": "ethernet/ipv4(dst='192.168.20.20')/tcp-->'nw_dst=192.168.20.0/24,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_dst": "192.168.20.0", "nw_dst_mask": 24 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/ipv4(dst='192.168.20.20')/tcp-->'nw_dst=192.168.20.0/24,actions=output:CONTROLLER'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 65533 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_dst": "192.168.20.0", "nw_dst_mask": 24 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/ipv4(dst='10.10.20.20')/tcp-->'nw_dst=192.168.20.0/24,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_dst": "192.168.20.0", "nw_dst_mask": 24 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss": [ 0 ] } ] }, { "description": "ethernet/vlan/ipv4(dst='192.168.20.20')/tcp-->'nw_dst=192.168.20.0/24,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_dst": "192.168.20.0", "nw_dst_mask": 24 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv4(dst='192.168.20.20')/tcp-->'nw_dst=192.168.20.0/24,actions=output:CONTROLLER'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 65533 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_dst": "192.168.20.0", "nw_dst_mask": 24 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv4(dst='10.10.20.20')/tcp-->'nw_dst=192.168.20.0/24,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_dst": "192.168.20.0", "nw_dst_mask": 24 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss": [ 0 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of10/match/10_TP_SRC_IPv4_TCP.json0000664000175000017500000002442700000000000024401 0ustar00zuulzuul00000000000000[ "match: 10_TP_SRC (IPv4/TCP)", { "description": "ethernet/ipv4/tcp(src_port=11111)-->'tp_src=11111,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_proto": 6, "tp_src": 11111 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/ipv4/tcp(src_port=11111)-->'tp_src=11111,actions=output:CONTROLLER'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 65533 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_proto": 6, "tp_src": 11111 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/ipv4/tcp(src_port=12345)-->'tp_src=11111,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_proto": 6, "tp_src": 11111 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss": [ 0 ] } ] }, { "description": "ethernet/vlan/ipv4/tcp(src_port=11111)-->'tp_src=11111,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_proto": 6, "tp_src": 11111 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv4/tcp(src_port=11111)-->'tp_src=11111,actions=output:CONTROLLER'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 65533 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_proto": 6, "tp_src": 11111 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv4/tcp(src_port=12345)-->'tp_src=11111,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_proto": 6, "tp_src": 11111 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss": [ 0 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of10/match/10_TP_SRC_IPv4_UDP.json0000664000175000017500000002401700000000000024376 0ustar00zuulzuul00000000000000[ "match: 10_TP_SRC (IPv4/UDP)", { "description": "ethernet/ipv4/udp(src_port=11111)-->'tp_src=11111,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_proto": 17, "tp_src": 11111 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/ipv4/udp(src_port=11111)-->'tp_src=11111,actions=output:CONTROLLER'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 65533 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_proto": 17, "tp_src": 11111 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/ipv4/udp(src_port=12345)-->'tp_src=11111,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_proto": 17, "tp_src": 11111 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=17, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "udp(dst_port=6789, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss": [ 0 ] } ] }, { "description": "ethernet/vlan/ipv4/udp(src_port=11111)-->'tp_src=11111,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_proto": 17, "tp_src": 11111 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv4/udp(src_port=11111)-->'tp_src=11111,actions=output:CONTROLLER'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 65533 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_proto": 17, "tp_src": 11111 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv4/udp(src_port=12345)-->'tp_src=11111,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_proto": 17, "tp_src": 11111 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=17, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "udp(dst_port=6789, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss": [ 0 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of10/match/10_TP_SRC_IPv6_TCP.json0000664000175000017500000002471700000000000024405 0ustar00zuulzuul00000000000000[ "match: 10_TP_SRC (IPv4/TCP)", { "description": "ethernet/ipv6/tcp(src_port=11111)-->'tp_src=11111,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 34525, "nw_proto": 6, "tp_src": 11111 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/ipv6/tcp(src_port=11111)-->'tp_src=11111,actions=output:CONTROLLER'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 65533 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 34525, "nw_proto": 6, "tp_src": 11111 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/ipv6/tcp(src_port=12345)-->'tp_src=11111,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 34525, "nw_proto": 6, "tp_src": 11111 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss": [ 0 ] } ] }, { "description": "ethernet/vlan/ipv6/tcp(src_port=11111)-->'tp_src=11111,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 34525, "nw_proto": 6, "tp_src": 11111 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv6/tcp(src_port=11111)-->'tp_src=11111,actions=output:CONTROLLER'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 65533 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 34525, "nw_proto": 6, "tp_src": 11111 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv6/tcp(src_port=12345)-->'tp_src=11111,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 34525, "nw_proto": 6, "tp_src": 11111 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss": [ 0 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of10/match/10_TP_SRC_IPv6_UDP.json0000664000175000017500000002430700000000000024402 0ustar00zuulzuul00000000000000[ "match: 10_TP_SRC (IPv6/UDP)", { "description": "ethernet/ipv6/udp(src_port=11111)-->'tp_src=11111,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 34525, "nw_proto": 17, "tp_src": 11111 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/ipv6/udp(src_port=11111)-->'tp_src=11111,actions=output:CONTROLLER'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 65533 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 34525, "nw_proto": 17, "tp_src": 11111 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/ipv6/udp(src_port=12345)-->'tp_src=11111,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 34525, "nw_proto": 17, "tp_src": 11111 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=17, hop_limit=127, traffic_class=65)", "udp(dst_port=6789, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss": [ 0 ] } ] }, { "description": "ethernet/vlan/ipv6/udp(src_port=11111)-->'tp_src=11111,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 34525, "nw_proto": 17, "tp_src": 11111 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv6/udp(src_port=11111)-->'tp_src=11111,actions=output:CONTROLLER'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 65533 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 34525, "nw_proto": 17, "tp_src": 11111 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv6/udp(src_port=12345)-->'tp_src=11111,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 34525, "nw_proto": 17, "tp_src": 11111 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=17, hop_limit=127, traffic_class=65)", "udp(dst_port=6789, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss": [ 0 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of10/match/11_TP_DST_IPv4_TCP.json0000664000175000017500000002440500000000000024401 0ustar00zuulzuul00000000000000[ "match: 11_TP_DST (IPv4/TCP)", { "description": "ethernet/ipv4/tcp(dst_port=2222)-->'tp_dst=2222,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_proto": 6, "tp_dst": 2222 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/ipv4/tcp(dst_port=2222)-->'tp_dst=2222,actions=output:CONTROLLER'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 65533 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_proto": 6, "tp_dst": 2222 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/ipv4/tcp(dst_port=6789)-->'tp_dst=2222,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_proto": 6, "tp_dst": 2222 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss": [ 0 ] } ] }, { "description": "ethernet/vlan/ipv4/tcp(dst_port=2222)-->'tp_dst=2222,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_proto": 6, "tp_dst": 2222 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv4/tcp(dst_port=2222)-->'tp_dst=2222,actions=output:CONTROLLER'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 65533 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_proto": 6, "tp_dst": 2222 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv4/tcp(dst_port=6789)-->'tp_dst=2222,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_proto": 6, "tp_dst": 2222 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss": [ 0 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of10/match/11_TP_DST_IPv4_UDP.json0000664000175000017500000002377500000000000024414 0ustar00zuulzuul00000000000000[ "match: 11_TP_DST (IPv4/UDP)", { "description": "ethernet/ipv4/udp(dst_port=2222)-->'tp_dst=2222,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_proto": 17, "tp_dst": 2222 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/ipv4/udp(dst_port=2222)-->'tp_dst=2222,actions=output:CONTROLLER'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 65533 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_proto": 17, "tp_dst": 2222 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/ipv4/udp(dst_port=6789)-->'tp_dst=2222,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_proto": 17, "tp_dst": 2222 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=17, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "udp(dst_port=6789, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss": [ 0 ] } ] }, { "description": "ethernet/vlan/ipv4/udp(dst_port=2222)-->'tp_dst=2222,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_proto": 17, "tp_dst": 2222 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv4/udp(dst_port=2222)-->'tp_dst=2222,actions=output:CONTROLLER'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 65533 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_proto": 17, "tp_dst": 2222 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv4/udp(dst_port=6789)-->'tp_dst=2222,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 2048, "nw_proto": 17, "tp_dst": 2222 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=17, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "udp(dst_port=6789, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss": [ 0 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of10/match/11_TP_DST_IPv6_TCP.json0000664000175000017500000002467500000000000024414 0ustar00zuulzuul00000000000000[ "match: 11_TP_DST (IPv6/TCP)", { "description": "ethernet/ipv6/tcp(dst_port=2222)-->'tp_dst=2222,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 34525, "nw_proto": 6, "tp_dst": 2222 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/ipv6/tcp(dst_port=2222)-->'tp_dst=2222,actions=output:CONTROLLER'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 65533 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 34525, "nw_proto": 6, "tp_dst": 2222 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/ipv6/tcp(dst_port=6789)-->'tp_dst=2222,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 34525, "nw_proto": 6, "tp_dst": 2222 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss": [ 0 ] } ] }, { "description": "ethernet/vlan/ipv6/tcp(dst_port=2222)-->'tp_dst=2222,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 34525, "nw_proto": 6, "tp_dst": 2222 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv6/tcp(dst_port=2222)-->'tp_dst=2222,actions=output:CONTROLLER'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 65533 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 34525, "nw_proto": 6, "tp_dst": 2222 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv6/tcp(dst_port=6789)-->'tp_dst=2222,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 34525, "nw_proto": 6, "tp_dst": 2222 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss": [ 0 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of10/match/11_TP_DST_IPv6_UDP.json0000664000175000017500000002426500000000000024411 0ustar00zuulzuul00000000000000[ "match: 11_TP_DST (IPv6/UDP)", { "description": "ethernet/ipv6/udp(dst_port=2222)-->'tp_dst=2222,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 34525, "nw_proto": 17, "tp_dst": 2222 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/ipv6/udp(dst_port=2222)-->'tp_dst=2222,actions=output:CONTROLLER'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 65533 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 34525, "nw_proto": 17, "tp_dst": 2222 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/ipv6/udp(dst_port=6789)-->'tp_dst=2222,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 34525, "nw_proto": 17, "tp_dst": 2222 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=17, hop_limit=127, traffic_class=65)", "udp(dst_port=6789, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss": [ 0 ] } ] }, { "description": "ethernet/vlan/ipv6/udp(dst_port=2222)-->'tp_dst=2222,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 34525, "nw_proto": 17, "tp_dst": 2222 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv6/udp(dst_port=2222)-->'tp_dst=2222,actions=output:CONTROLLER'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 65533 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 34525, "nw_proto": 17, "tp_dst": 2222 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN": [ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv6/udp(dst_port=6789)-->'tp_dst=2222,actions=output:2'", "prerequisite": [ { "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "port": 2 } } ], "command": 0, "cookie": 0, "match": { "OFPMatch": { "dl_type": 34525, "nw_proto": 17, "tp_dst": 2222 } } } } ], "tests": [ { "ingress": [ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=17, hop_limit=127, traffic_class=65)", "udp(dst_port=6789, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss": [ 0 ] } ] } ] ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.0341012 os-ken-2.10.0/os_ken/tests/switch/of13/0000775000175000017500000000000000000000000017502 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.2141118 os-ken-2.10.0/os_ken/tests/switch/of13/action/0000775000175000017500000000000000000000000020757 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/00_OUTPUT.json0000664000175000017500000001213100000000000023207 0ustar00zuulzuul00000000000000[ "action: 00_OUTPUT", { "description": "ethernet/ipv4/tcp-->'actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/ipv6/tcp-->'actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/arp-->'actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/11_COPY_TTL_OUT.json0000664000175000017500000001222600000000000024202 0ustar00zuulzuul00000000000000[ "action: 11_COPY_TTL_OUT", { "description": "ethernet/mpls(ttl=64)/ipv4(ttl=32)/tcp-->'eth_type=0x8847,actions=copy_ttl_out,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionCopyTtlOut":{} }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=32)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls(ttl=64)/ipv6(hop_limit=32)/tcp-->'eth_type=0x8847,actions=copy_ttl_out,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionCopyTtlOut":{} }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=32, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=32)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=32, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/12_COPY_TTL_IN.json0000664000175000017500000001222100000000000024035 0ustar00zuulzuul00000000000000[ "action: 12_COPY_TTL_IN", { "description": "ethernet/mpls(ttl=64)/ipv4(ttl=32)/tcp-->'eth_type=0x8847,actions=copy_ttl_in,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionCopyTtlIn":{} }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls(ttl=64)/ipv6(hop_limit=32)/tcp-->'eth_type=0x8847,actions=copy_ttl_in,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionCopyTtlIn":{} }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=32, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/15_SET_MPLS_TTL.json0000664000175000017500000001717500000000000024203 0ustar00zuulzuul00000000000000[ "action: 15_SET_MPLS_TTL", { "description": "ethernet/mpls(ttl=64)/ipv4/tcp-->'eth_type=0x8847,actions=set_mpls_ttl:127,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetMplsTtl":{ "mpls_ttl":127 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=127)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls(ttl=64)/ipv6/tcp-->'eth_type=0x8847,actions=set_mpls_ttl:127,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetMplsTtl":{ "mpls_ttl":127 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=127)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls(ttl=64)/arp-->'eth_type=0x8847,actions=set_mpls_ttl:127,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetMplsTtl":{ "mpls_ttl":127 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=127)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/16_DEC_MPLS_TTL.json0000664000175000017500000001650200000000000024135 0ustar00zuulzuul00000000000000[ "action: 16_DEC_MPLS_TTL", { "description": "ethernet/mpls(ttl=64)/ipv4/tcp-->'eth_type=0x8847,actions=dec_mpls_ttl,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionDecMplsTtl":{} }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=63)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls(ttl=64)/ipv6/tcp-->'eth_type=0x8847,actions=dec_mpls_ttl,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionDecMplsTtl":{} }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=63)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls(ttl=64)/arp-->'eth_type=0x8847,actions=dec_mpls_ttl,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionDecMplsTtl":{} }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=63)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/17_PUSH_VLAN.json0000664000175000017500000001656400000000000023574 0ustar00zuulzuul00000000000000[ "action: 17_PUSH_VLAN", { "description": "ethernet/ipv4/tcp-->'eth_type=0x0800,actions=push_vlan:0x8100,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPushVlan":{ "ethertype":33024 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/ipv6/tcp-->'eth_type=0x86dd,actions=push_vlan:0x8100,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPushVlan":{ "ethertype":33024 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/arp-->'eth_type=0x0806,actions=push_vlan:0x8100,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPushVlan":{ "ethertype":33024 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/17_PUSH_VLAN_multiple.json0000664000175000017500000001754000000000000025502 0ustar00zuulzuul00000000000000[ "action: 17_PUSH_VLAN (multiple)", { "description": "ethernet/vlan/ipv4/tcp-->'eth_type=0x0800,actions=push_vlan:0x88a8,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPushVlan":{ "ethertype":34984 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(pcp=3, cfi=0, vid=100, ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv6/tcp-->'eth_type=0x86dd,actions=push_vlan:0x88a8,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPushVlan":{ "ethertype":34984 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(pcp=3, cfi=0, vid=100, ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/arp-->'eth_type=0x0806,actions=push_vlan:0x88a8,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPushVlan":{ "ethertype":34984 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(pcp=3, cfi=0, vid=100, ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/18_POP_VLAN.json0000664000175000017500000002016300000000000023442 0ustar00zuulzuul00000000000000[ "action: 18_POP_VLAN", { "description": "ethernet/vlan(vid=100)/ipv4/tcp-->'eth_type=0x0800,vlan_vid=0,actions=pop_vlan,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"vlan_vid", "mask":4096, "value":4096 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopVlan":{} }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan(vid=100)/ipv6/tcp-->'eth_type=0x86dd,vlan_vid=0,actions=pop_vlan,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"vlan_vid", "mask":4096, "value":4096 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopVlan":{} }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan(vid=100)/arp-->'eth_type=0x0806,vlan_vid=0,actions=pop_vlan,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"vlan_vid", "mask":4096, "value":4096 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopVlan":{} }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/19_PUSH_MPLS.json0000664000175000017500000001653200000000000023604 0ustar00zuulzuul00000000000000[ "action: 19_PUSH_MPLS", { "description": "ethernet/ipv4/tcp-->'eth_type=0x0800,actions=push_mpls:0x8847,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPushMpls":{ "ethertype":34887 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/ipv6/tcp-->'eth_type=0x86dd,actions=push_mpls:0x8847,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPushMpls":{ "ethertype":34887 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/arp-->'eth_type=0x0806,actions=push_mpls:0x8847,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPushMpls":{ "ethertype":34887 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(ttl=0)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/19_PUSH_MPLS_multiple.json0000664000175000017500000001744400000000000025522 0ustar00zuulzuul00000000000000[ "action: 19_PUSH_MPLS (multiple)", { "description": "ethernet/mpls/ipv4/tcp-->'eth_type=0x8847,actions=push_mpls:0x8847,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPushMpls":{ "ethertype":34887 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=0, label=100, exp=3, ttl=64)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/ipv6/tcp-->'eth_type=0x8847,actions=push_mpls:0x8847,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPushMpls":{ "ethertype":34887 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=0, label=100, exp=3, ttl=64)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/arp-->'eth_type=0x8847,actions=push_mpls:0x8847,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPushMpls":{ "ethertype":34887 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=0, label=100, exp=3, ttl=64)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/20_POP_MPLS.json0000664000175000017500000001665600000000000023462 0ustar00zuulzuul00000000000000[ "action: 20_POP_MPLS", { "description": "ethernet/mpls/ipv4/tcp-->'eth_type=0x8847,actions=pop_mpls:0x0800,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/ipv6/tcp-->'eth_type=0x8847,actions=pop_mpls:0x86dd,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/arp-->'eth_type=0x8847,actions=pop_mpls:0x0806,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/23_SET_NW_TTL_IPv4.json0000664000175000017500000003165400000000000024613 0ustar00zuulzuul00000000000000[ "action: 23_SET_NW_TTL (IPv4)", { "description": "ethernet/ipv4(ttl=64)/tcp-->'eth_type=0x0800,actions=set_nw_ttl:32,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetNwTtl":{ "nw_ttl":32 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv4(ttl=64)/tcp-->'eth_type=0x0800,actions=set_nw_ttl:32,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetNwTtl":{ "nw_ttl":32 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/ipv4(ttl=64)/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,eth_type=0x0800,actions=set_nw_ttl:32,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetNwTtl":{ "nw_ttl":32 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/itag/ethernet/ipv4(ttl=64)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,eth_type=0x0800,actions=set_nw_ttl:32,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetNwTtl":{ "nw_ttl":32 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/23_SET_NW_TTL_IPv6.json0000664000175000017500000003212000000000000024602 0ustar00zuulzuul00000000000000[ "action: 23_SET_NW_TTL (IPv6)", { "description": "ethernet/ipv6(hop_limit=64)/tcp-->'eth_type=0x86dd,actions=set_nw_ttl:32,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetNwTtl":{ "nw_ttl":32 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=32, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv6(hop_limit=64)/tcp-->'eth_type=0x86dd,actions=set_nw_ttl:32,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetNwTtl":{ "nw_ttl":32 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=32, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/ipv6(hop_limit=64)/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,eth_type=0x86dd,actions=set_nw_ttl:32,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetNwTtl":{ "nw_ttl":32 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=32, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/itag/ethernet/ipv6(hop_limit=64)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,eth_type=0x86dd,actions=set_nw_ttl:32,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetNwTtl":{ "nw_ttl":32 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=32, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/24_DEC_NW_TTL_IPv4.json0000664000175000017500000003103400000000000024544 0ustar00zuulzuul00000000000000[ "action: 24_DEC_NW_TTL (IPv4)", { "description": "ethernet/ipv4(ttl=64)/tcp-->'eth_type=0x0800,actions=dec_nw_ttl,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionDecNwTtl":{} }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=63)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv4(ttl=64)/tcp-->'eth_type=0x0800,actions=dec_nw_ttl,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionDecNwTtl":{} }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=63)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/ipv4(ttl=64)/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,eth_type=0x0800,actions=dec_nw_ttl,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionDecNwTtl":{} }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=63)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/itag/ethernet/ipv4(ttl=64)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,eth_type=0x0800,actions=dec_nw_ttl,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionDecNwTtl":{} }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=63)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/24_DEC_NW_TTL_IPv6.json0000664000175000017500000003130000000000000024542 0ustar00zuulzuul00000000000000[ "action: 24_DEC_NW_TTL (IPv6)", { "description": "ethernet/ipv6(hop_limit=64)/tcp-->'eth_type=0x86dd,actions=dec_nw_ttl,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionDecNwTtl":{} }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=63, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv6(hop_limit=64)/tcp-->'eth_type=0x86dd,actions=dec_nw_ttl,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionDecNwTtl":{} }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=63, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/ipv6(hop_limit=64)/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,eth_type=0x86dd,actions=dec_nw_ttl,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionDecNwTtl":{} }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=63, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/itag/ethernet/ipv6(hop_limit=64)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,eth_type=0x86dd,actions=dec_nw_ttl,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionDecNwTtl":{} }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=63, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.2261126 os-ken-2.10.0/os_ken/tests/switch/of13/action/25_SET_FIELD/0000775000175000017500000000000000000000000022623 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/25_SET_FIELD/03_ETH_DST.json0000664000175000017500000002050200000000000025151 0ustar00zuulzuul00000000000000[ "action: set_field: 03_ETH_DST", { "description": "ethernet(dst='22:22:22:22:22:22')/ipv4/tcp-->'eth_dst=22:22:22:22:22:22,actions=set_field:ba:bb:bb:bb:bb:bb->eth_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_dst", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"eth_dst", "value":"ba:bb:bb:bb:bb:bb" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet(dst='22:22:22:22:22:22')/ipv6/tcp-->'eth_dst=22:22:22:22:22:22,actions=set_field:ba:bb:bb:bb:bb:bb->eth_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_dst", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"eth_dst", "value":"ba:bb:bb:bb:bb:bb" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet(dst='22:22:22:22:22:22')/arp-->'eth_dst=22:22:22:22:22:22,actions=set_field:ba:bb:bb:bb:bb:bb->eth_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_dst", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"eth_dst", "value":"ba:bb:bb:bb:bb:bb" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/25_SET_FIELD/04_ETH_SRC.json0000664000175000017500000002050200000000000025147 0ustar00zuulzuul00000000000000[ "action: set_field: 04_ETH_SRC", { "description": "ethernet(src='12:11:11:11:11:11')/ipv4/tcp-->'eth_src=12:11:11:11:11:11,actions=set_field:aa:aa:aa:aa:aa:aa->eth_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_src", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"eth_src", "value":"aa:aa:aa:aa:aa:aa" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet(src='12:11:11:11:11:11')/ipv6/tcp-->'eth_src=12:11:11:11:11:11,actions=set_field:aa:aa:aa:aa:aa:aa->eth_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_src", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"eth_src", "value":"aa:aa:aa:aa:aa:aa" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet(src='12:11:11:11:11:11')/arp-->'eth_src=12:11:11:11:11:11,actions=set_field:aa:aa:aa:aa:aa:aa->eth_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_src", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"eth_src", "value":"aa:aa:aa:aa:aa:aa" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/25_SET_FIELD/05_ETH_TYPE.json0000664000175000017500000002024400000000000025305 0ustar00zuulzuul00000000000000[ "action: set_field: 05_ETH_TYPE", { "description": "ethernet(ethertype=0x0800)/ipv4/tcp-->'eth_type=0x0800,actions=set_field:0x8848->eth_type,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"eth_type", "value":34888 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34888)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet(ethertype=0x86dd)/ipv6/tcp-->'eth_type=0x86dd,actions=set_field:0x8848->eth_type,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"eth_type", "value":34888 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34888)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet(ethertype=0x0806)/arp-->'eth_type=0x0806,actions=set_field:0x8848->eth_type,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"eth_type", "value":34888 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34888)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/25_SET_FIELD/06_VLAN_VID.json0000664000175000017500000002126200000000000025270 0ustar00zuulzuul00000000000000[ "action: set_field: 06_VLAN_VID", { "description": "ethernet/vlan(vid=100)/ipv4/tcp-->'vlan_vid=100,actions=set_field:203->vlan_vid,output:2'", "notes":"A value of VLAN_VID (4196) means '100 | OFPVID_PRESENT(0x1000)'.", "notes":"A value of VLAN_VID (4299) means '203 | OFPVID_PRESENT(0x1000)'.", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "value":4196 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"vlan_vid", "value":4299 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan(vid=100)/ipv6/tcp-->'vlan_vid=100,actions=set_field:203->vlan_vid,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "value":4196 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"vlan_vid", "value":4299 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan(vid=100)/arp-->'vlan_vid=100,actions=set_field:203->vlan_vid,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "value":4196 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"vlan_vid", "value":4299 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=203, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/25_SET_FIELD/07_VLAN_PCP.json0000664000175000017500000002240700000000000025273 0ustar00zuulzuul00000000000000[ "action: set_field: 07_VLAN_PCP", { "description": "ethernet/vlan(pcp=3)/ipv4/tcp-->'vlan_pcp=3,actions=set_field:5->vlan_pcp,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "value":4196 } }, { "OXMTlv":{ "field":"vlan_pcp", "value":3 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"vlan_pcp", "value":5 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan(pcp=3)/ipv6/tcp-->'vlan_pcp=3,actions=set_field:5->vlan_pcp,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "value":4196 } }, { "OXMTlv":{ "field":"vlan_pcp", "value":3 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"vlan_pcp", "value":5 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan(pcp=3)/arp-->'vlan_pcp=3,actions=set_field:5->vlan_pcp,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "value":4196 } }, { "OXMTlv":{ "field":"vlan_pcp", "value":3 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"vlan_pcp", "value":5 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/25_SET_FIELD/08_IP_DSCP_IPv4.json0000664000175000017500000003612400000000000026016 0ustar00zuulzuul00000000000000[ "action: set_field: 08_IP_DSCP (IPv4)", { "description": "ethernet/ipv4(tos=32)/tcp-->'ip_dscp=8,actions=set_field:16->ip_dscp,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ip_dscp", "value":16 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=64, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv4(tos=32)/tcp-->'ip_dscp=8,actions=set_field:16->ip_dscp,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ip_dscp", "value":16 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=64, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/ipv4(tos=32)/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,ip_dscp=8,actions=set_field:16->ip_dscp,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ip_dscp", "value":16 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=64, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/itag/ethernet/ipv4(tos=32)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ip_dscp=8,actions=set_field:16->ip_dscp,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ip_dscp", "value":16 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=64, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/25_SET_FIELD/08_IP_DSCP_IPv6.json0000664000175000017500000003641000000000000026016 0ustar00zuulzuul00000000000000[ "action: set_field: 08_IP_DSCP (IPv6)", { "description": "ethernet/ipv6(traffic_class=32)/tcp-->'ip_dscp=8,actions=set_field:16->ip_dscp,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ip_dscp", "value":16 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv6(traffic_class=32)/tcp-->'ip_dscp=8,actions=set_field:16->ip_dscp,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ip_dscp", "value":16 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/ipv6(traffic_class=32)/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ip_dscp=8,actions=set_field:16->ip_dscp,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ip_dscp", "value":16 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/itag/ethernet/ipv6(traffic_class=32)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ip_dscp=8,actions=set_field:16->ip_dscp,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ip_dscp", "value":16 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/25_SET_FIELD/09_IP_ECN_IPv4.json0000664000175000017500000003607300000000000025676 0ustar00zuulzuul00000000000000[ "action: set_field: 09_IP_ECN (IPv4)", { "description": "ethernet/ipv4(tos=32)/tcp-->'ip_ecn=0,actions=set_field:1->ip_ecn,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ip_ecn", "value":1 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=33, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv4(tos=32)/tcp-->'ip_ecn=0,actions=set_field:1->ip_ecn,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ip_ecn", "value":1 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=33, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/ipv4(tos=32)/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,ip_ecn=0,actions=set_field:1->ip_ecn,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ip_ecn", "value":1 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=33, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/itag/ethernet/ipv4(tos=32)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ip_ecn=0,actions=set_field:1->ip_ecn,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ip_ecn", "value":1 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=33, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/25_SET_FIELD/09_IP_ECN_IPv6.json0000664000175000017500000003635700000000000025705 0ustar00zuulzuul00000000000000[ "action: set_field: 09_IP_ECN (IPv6)", { "description": "ethernet/ipv6(traffic_class=32)/tcp-->'ip_ecn=0,actions=set_field:1->ip_ecn,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ip_ecn", "value":1 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=33)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv6(traffic_class=32)/tcp-->'ip_ecn=0,actions=set_field:1->ip_ecn,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ip_ecn", "value":1 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=33)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/ipv6(traffic_class=32)/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ip_ecn=0,actions=set_field:1->ip_ecn,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ip_ecn", "value":1 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=33)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/itag/ethernet/ipv6(traffic_class=32)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ip_ecn=0,actions=set_field:1->ip_ecn,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ip_ecn", "value":1 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=33)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/25_SET_FIELD/10_IP_PROTO_IPv4.json0000664000175000017500000003615500000000000026165 0ustar00zuulzuul00000000000000[ "action: set_field: 10_IP_PROTO (IPv4)", { "description": "ethernet/ipv4(proto=6)/tcp-->'ip_proto=6,actions=set_field:17->ip_proto,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ip_proto", "value":17 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv4(proto=6)/tcp-->'ip_proto=6,actions=set_field:17->ip_proto,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ip_proto", "value":17 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/ipv4(proto=6)/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,ip_proto=6,actions=set_field:17->ip_proto,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ip_proto", "value":17 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/itag/ethernet/ipv4(proto=6)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ip_proto=6,actions=set_field:17->ip_proto,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ip_proto", "value":17 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/25_SET_FIELD/10_IP_PROTO_IPv6.json0000664000175000017500000003636100000000000026166 0ustar00zuulzuul00000000000000[ "action: set_field: 10_IP_PROTO (IPv6)", { "description": "ethernet/ipv6(nxt=6)/tcp-->'ip_proto=6,actions=set_field:17->ip_proto,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ip_proto", "value":17 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv6(nxt=6)/tcp-->'ip_proto=6,actions=set_field:17->ip_proto,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ip_proto", "value":17 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/ipv6(nxt=6)/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ip_proto=6,actions=set_field:17->ip_proto,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ip_proto", "value":17 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/itag/ethernet/ipv6(nxt=6)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ip_proto=6,actions=set_field:17->ip_proto,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ip_proto", "value":17 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/25_SET_FIELD/11_IPV4_SRC.json0000664000175000017500000003650200000000000025256 0ustar00zuulzuul00000000000000[ "action: set_field: 11_IPV4_SRC", { "description": "ethernet/ipv4(src='192.168.10.10')/tcp-->'ipv4_src=192.168.10.10,actions=set_field:10.10.10.10->ipv4_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv4_src", "value":"10.10.10.10" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='10.10.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv4(src='192.168.10.10')/tcp-->'ipv4_src=192.168.10.10,actions=set_field:10.10.10.10->ipv4_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv4_src", "value":"10.10.10.10" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='10.10.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/ipv4(src='192.168.10.10')/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,ipv4_src=192.168.10.10,actions=set_field:10.10.10.10->ipv4_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv4_src", "value":"10.10.10.10" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='10.10.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/itag/ethernet/ipv4(src='192.168.10.10')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv4_src=192.168.10.10,actions=set_field:10.10.10.10->ipv4_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv4_src", "value":"10.10.10.10" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='10.10.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/25_SET_FIELD/12_IPV4_DST.json0000664000175000017500000003650200000000000025262 0ustar00zuulzuul00000000000000[ "action: set_field: 12_IPV4_DST", { "description": "ethernet/ipv4(dst='192.168.20.20')/tcp-->'ipv4_dst=192.168.20.20,actions=set_field:10.10.20.20->ipv4_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv4_dst", "value":"10.10.20.20" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='10.10.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv4(dst='192.168.20.20')/tcp-->'ipv4_dst=192.168.20.20,actions=set_field:10.10.20.20->ipv4_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv4_dst", "value":"10.10.20.20" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='10.10.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/ipv4(dst='192.168.20.20')/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,ipv4_dst=192.168.20.20,actions=set_field:10.10.20.20->ipv4_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv4_dst", "value":"10.10.20.20" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='10.10.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/itag/ethernet/ipv4(dst='192.168.20.20')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv4_dst=192.168.20.20,actions=set_field:10.10.20.20->ipv4_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv4_dst", "value":"10.10.20.20" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='10.10.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/25_SET_FIELD/13_TCP_SRC_IPv4.json0000664000175000017500000004031400000000000026022 0ustar00zuulzuul00000000000000[ "action: set_field: 13_TCP_SRC (IPv4)", { "description": "ethernet/ipv4/tcp(src_port=11111)-->'tcp_src=11111,actions=set_field:12345->tcp_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tcp_src", "value":12345 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv4/tcp(src_port=11111)-->'tcp_src=11111,actions=set_field:12345->tcp_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tcp_src", "value":12345 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/ipv4/tcp(src_port=11111)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,tcp_src=11111,actions=set_field:12345->tcp_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tcp_src", "value":12345 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/itag/ethernet/ipv4/tcp(src_port=11111)-->'actions=pop_pbb,goto_table:1','table_id:1,tcp_src=11111,actions=set_field:12345->tcp_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tcp_src", "value":12345 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/25_SET_FIELD/13_TCP_SRC_IPv6.json0000664000175000017500000004053000000000000026024 0ustar00zuulzuul00000000000000[ "action: set_field: 13_TCP_SRC (IPv6)", { "description": "ethernet/ipv6/tcp(src_port=11111)-->'tcp_src=11111,actions=set_field:12345->tcp_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tcp_src", "value":12345 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv6/tcp(src_port=11111)-->'tcp_src=11111,actions=set_field:12345->tcp_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tcp_src", "value":12345 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/ipv6/tcp(src_port=11111)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,tcp_src=11111,actions=set_field:12345->tcp_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tcp_src", "value":12345 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/itag/ethernet/ipv6/tcp(src_port=11111)-->'actions=pop_pbb,goto_table:1','table_id:1,tcp_src=11111,actions=set_field:12345->tcp_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tcp_src", "value":12345 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/25_SET_FIELD/14_TCP_DST_IPv4.json0000664000175000017500000004027000000000000026027 0ustar00zuulzuul00000000000000[ "action: set_field: 14_TCP_DST (IPv4)", { "description": "ethernet/ipv4/tcp(dst_port=2222)-->'tcp_dst=2222,actions=set_field:6789->tcp_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tcp_dst", "value":6789 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=6789, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv4/tcp(dst_port=2222)-->'tcp_dst=2222,actions=set_field:6789->tcp_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tcp_dst", "value":6789 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=6789, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/ipv4/tcp(dst_port=2222)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,tcp_dst=2222,actions=set_field:6789->tcp_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tcp_dst", "value":6789 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=6789, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/itag/ethernet/ipv4/tcp(dst_port=2222)-->'actions=pop_pbb,goto_table:1','table_id:1,tcp_dst=2222,actions=set_field:6789->tcp_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tcp_dst", "value":6789 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=6789, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/25_SET_FIELD/14_TCP_DST_IPv6.json0000664000175000017500000004050400000000000026031 0ustar00zuulzuul00000000000000[ "action: set_field: 14_TCP_DST (IPv6)", { "description": "ethernet/ipv6/tcp(dst_port=2222)-->'tcp_dst=2222,actions=set_field:6789->tcp_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tcp_dst", "value":6789 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=6789, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv6/tcp(dst_port=2222)-->'tcp_dst=2222,actions=set_field:6789->tcp_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tcp_dst", "value":6789 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=6789, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/ipv6/tcp(dst_port=2222)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,tcp_dst=2222,actions=set_field:6789->tcp_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tcp_dst", "value":6789 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=6789, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/itag/ethernet/ipv6/tcp(dst_port=2222)-->'actions=pop_pbb,goto_table:1','table_id:1,tcp_dst=2222,actions=set_field:6789->tcp_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tcp_dst", "value":6789 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=6789, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/25_SET_FIELD/15_UDP_SRC_IPv4.json0000664000175000017500000003777000000000000026042 0ustar00zuulzuul00000000000000[ "action: set_field: 15_UDP_SRC (IPv4)", { "description": "ethernet/ipv4/udp(src_port=11111)-->'udp_src=11111,actions=set_field:12345->udp_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"udp_src", "value":12345 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv4/udp(src_port=11111)-->'udp_src=11111,actions=set_field:12345->udp_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"udp_src", "value":12345 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/ipv4/udp(src_port=11111)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,udp_src=11111,actions=set_field:12345->udp_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"udp_src", "value":12345 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/itag/ethernet/ipv4/udp(src_port=11111)-->'actions=pop_pbb,goto_table:1','table_id:1,udp_src=11111,actions=set_field:12345->udp_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"udp_src", "value":12345 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/25_SET_FIELD/15_UDP_SRC_IPv6.json0000664000175000017500000004020400000000000026026 0ustar00zuulzuul00000000000000[ "action: set_field: 15_UDP_SRC (IPv6)", { "description": "ethernet/ipv6/udp(src_port=11111)-->'udp_src=11111,actions=set_field:12345->udp_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"udp_src", "value":12345 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv6/udp(src_port=11111)-->'udp_src=11111,actions=set_field:12345->udp_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"udp_src", "value":12345 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/ipv6/udp(src_port=11111)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,udp_src=11111,actions=set_field:12345->udp_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"udp_src", "value":12345 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/itag/ethernet/ipv6/udp(src_port=11111)-->'actions=pop_pbb,goto_table:1','table_id:1,udp_src=11111,actions=set_field:12345->udp_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"udp_src", "value":12345 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/25_SET_FIELD/16_UDP_DST_IPv4.json0000664000175000017500000003774400000000000026047 0ustar00zuulzuul00000000000000[ "action: set_field: 16_UDP_DST (IPv4)", { "description": "ethernet/ipv4/udp(dst_port=2222)-->'udp_dst=2222,actions=set_field:6789->udp_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"udp_dst", "value":6789 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=6789, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv4/udp(dst_port=2222)-->'udp_dst=2222,actions=set_field:6789->udp_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"udp_dst", "value":6789 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=6789, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/ipv4/udp(dst_port=2222)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,udp_dst=2222,actions=set_field:6789->udp_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"udp_dst", "value":6789 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=6789, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/itag/ethernet/ipv4/udp(dst_port=2222)-->'actions=pop_pbb,goto_table:1','table_id:1,udp_dst=2222,actions=set_field:6789->udp_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"udp_dst", "value":6789 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=6789, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/25_SET_FIELD/16_UDP_DST_IPv6.json0000664000175000017500000004016000000000000026033 0ustar00zuulzuul00000000000000[ "action: set_field: 16_UDP_DST (IPv6)", { "description": "ethernet/ipv6/udp(dst_port=2222)-->'udp_dst=2222,actions=set_field:6789->udp_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"udp_dst", "value":6789 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=6789, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv6/udp(dst_port=2222)-->'udp_dst=2222,actions=set_field:6789->udp_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"udp_dst", "value":6789 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=6789, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/ipv6/udp(dst_port=2222)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,udp_dst=2222,actions=set_field:6789->udp_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"udp_dst", "value":6789 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=6789, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/itag/ethernet/ipv6/udp(dst_port=2222)-->'actions=pop_pbb,goto_table:1','table_id:1,udp_dst=2222,actions=set_field:6789->udp_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"udp_dst", "value":6789 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=6789, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/25_SET_FIELD/17_SCTP_SRC_IPv4.json0000664000175000017500000003643100000000000026156 0ustar00zuulzuul00000000000000[ "action: set_field: 17_SCTP_SRC (IPv4)", { "description": "ethernet/ipv4/sctp(src_port=11111)-->'sctp_src=11111,actions=set_field:12345->sctp_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"sctp_src", "value":12345 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=12345)" ] } ] }, { "description": "ethernet/vlan/ipv4/sctp(src_port=11111)-->'sctp_src=11111,actions=set_field:12345->sctp_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"sctp_src", "value":12345 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=12345)" ] } ] }, { "description": "ethernet/mpls/ipv4/sctp(src_port=11111)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,sctp_src=11111,actions=set_field:12345->sctp_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"sctp_src", "value":12345 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=12345)" ] } ] }, { "description": "ethernet/itag/ethernet/ipv4/sctp(src_port=11111)-->'actions=pop_pbb,goto_table:1','table_id:1,sctp_src=11111,actions=set_field:12345->sctp_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"sctp_src", "value":12345 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=12345)" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/25_SET_FIELD/17_SCTP_SRC_IPv6.json0000664000175000017500000003664500000000000026167 0ustar00zuulzuul00000000000000[ "action: set_field: 17_SCTP_SRC (IPv6)", { "description": "ethernet/ipv6/udp(sctp_port=11111)-->'sctp_src=11111,actions=set_field:12345->sctp_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"sctp_src", "value":12345 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=12345)" ] } ] }, { "description": "ethernet/vlan/ipv6/sctp(src_port=11111)-->'sctp_src=11111,actions=set_field:12345->sctp_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"sctp_src", "value":12345 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=12345)" ] } ] }, { "description": "ethernet/mpls/ipv6/sctp(src_port=11111)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,sctp_src=11111,actions=set_field:12345->sctp_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"sctp_src", "value":12345 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=12345)" ] } ] }, { "description": "ethernet/itag/ethernet/ipv6/sctp(src_port=11111)-->'actions=pop_pbb,goto_table:1','table_id:1,sctp_src=11111,actions=set_field:12345->sctp_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"sctp_src", "value":12345 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=12345)" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/25_SET_FIELD/18_SCTP_DST_IPv4.json0000664000175000017500000003640500000000000026163 0ustar00zuulzuul00000000000000[ "action: set_field: 18_SCTP_DST (IPv4)", { "description": "ethernet/ipv4/sctp(dst_port=2222)-->'sctp_dst=2222,actions=set_field:6789->sctp_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"sctp_dst", "value":6789 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=6789, src_port=11111)" ] } ] }, { "description": "ethernet/vlan/ipv4/sctp(dst_port=2222)-->'sctp_dst=2222,actions=set_field:6789->sctp_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"sctp_dst", "value":6789 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=6789, src_port=11111)" ] } ] }, { "description": "ethernet/mpls/ipv4/sctp(dst_port=2222)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,sctp_dst=2222,actions=set_field:6789->sctp_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"sctp_dst", "value":6789 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=6789, src_port=11111)" ] } ] }, { "description": "ethernet/itag/ethernet/ipv4/sctp(dst_port=2222)-->'actions=pop_pbb,goto_table:1','table_id:1,sctp_dst=2222,actions=set_field:6789->sctp_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"sctp_dst", "value":6789 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=6789, src_port=11111)" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/25_SET_FIELD/18_SCTP_DST_IPv6.json0000664000175000017500000003662100000000000026165 0ustar00zuulzuul00000000000000[ "action: set_field: 18_SCTP_DST (IPv6)", { "description": "ethernet/ipv6/sctp(dst_port=2222)-->'sctp_dst=2222,actions=set_field:6789->sctp_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"sctp_dst", "value":6789 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=6789, src_port=11111)" ] } ] }, { "description": "ethernet/vlan/ipv6/sctp(dst_port=2222)-->'sctp_dst=2222,actions=set_field:6789->sctp_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"sctp_dst", "value":6789 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=6789, src_port=11111)" ] } ] }, { "description": "ethernet/mpls/ipv6/sctp(dst_port=2222)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,sctp_dst=2222,actions=set_field:6789->sctp_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"sctp_dst", "value":6789 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=6789, src_port=11111)" ] } ] }, { "description": "ethernet/itag/ethernet/ipv6/sctp(dst_port=2222)-->'actions=pop_pbb,goto_table:1','table_id:1,sctp_dst=2222,actions=set_field:6789->sctp_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"sctp_dst", "value":6789 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=6789, src_port=11111)" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/25_SET_FIELD/19_ICMPV4_TYPE.json0000664000175000017500000003576500000000000025652 0ustar00zuulzuul00000000000000[ "action: set_field: 19_ICMPV4_TYPE", { "description": "ethernet/ipv4/icmp(type=8)-->'icmpv4_type=8,actions=set_field:0->icmpv4_type,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_type", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"icmpv4_type", "value":0 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=0)" ] } ] }, { "description": "ethernet/vlan/ipv4/icmp(type=8)-->'icmpv4_type=8,actions=set_field:0->icmpv4_type,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_type", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"icmpv4_type", "value":0 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=0)" ] } ] }, { "description": "ethernet/mpls/ipv4/icmp(type=8)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,icmpv4_type=8,actions=set_field:0->icmpv4_type,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_type", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"icmpv4_type", "value":0 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=0)" ] } ] }, { "description": "ethernet/itag/ethernet/ipv4/icmp(type=8)-->'actions=pop_pbb,goto_table:1','table_id:1,icmpv4_type=8,actions=set_field:0->icmpv4_type,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_type", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"icmpv4_type", "value":0 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=0)" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/25_SET_FIELD/20_ICMPV4_CODE.json0000664000175000017500000003600100000000000025553 0ustar00zuulzuul00000000000000[ "action: set_field: 20_ICMPV4_CODE", { "description": "ethernet/ipv4/icmp(code=0)-->'icmpv4_code=0,actions=set_field:10->icmpv4_code,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"icmpv4_code", "value":10 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=10,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ] } ] }, { "description": "ethernet/vlan/ipv4/icmp(code=0)-->'icmpv4_code=0,actions=set_field:10->icmpv4_code,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"icmpv4_code", "value":10 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=10,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ] } ] }, { "description": "ethernet/mpls/ipv4/icmp(code=0)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,icmpv4_code=0,actions=set_field:10->icmpv4_code,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"icmpv4_code", "value":10 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=10,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ] } ] }, { "description": "ethernet/itag/ethernet/ipv4/icmp(code=0)-->'actions=pop_pbb,goto_table:1','table_id:1,icmpv4_code=0,actions=set_field:10->icmpv4_code,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"icmpv4_code", "value":10 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=10,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/25_SET_FIELD/21_ARP_OP.json0000664000175000017500000003336200000000000025047 0ustar00zuulzuul00000000000000[ "action: set_field: 21_ARP_OP", { "description": "ethernet/arp(opcode=1)-->'arp_op=1,actions=set_field:2->arp_op,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_op", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"arp_op", "value":2 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=2, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description": "ethernet/vlan/arp(opcode=1)-->'arp_op=1,actions=set_field:2->arp_op,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_op", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"arp_op", "value":2 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=2, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description": "ethernet/mpls/arp(opcode=1)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,arp_op=1,actions=set_field:2->arp_op,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_op", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"arp_op", "value":2 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=2, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description": "ethernet/itag/ethernet/arp(opcode=1)-->'actions=pop_pbb,goto_table:1','table_id:1,arp_op=1,actions=set_field:2->arp_op,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_op", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"arp_op", "value":2 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=2, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/25_SET_FIELD/22_ARP_SPA.json0000664000175000017500000003376300000000000025162 0ustar00zuulzuul00000000000000[ "action: set_field: 22_ARP_SPA", { "description": "ethernet/arp(src_ip='192.168.10.10')-->'arp_spa=192.168.10.10,actions=set_field:10.10.10.10->arp_spa,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"arp_spa", "value":"10.10.10.10" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='10.10.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description": "ethernet/vlan/arp(src_ip='192.168.10.10')-->'arp_spa=192.168.10.10,actions=set_field:10.10.10.10->arp_spa,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"arp_spa", "value":"10.10.10.10" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='10.10.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description": "ethernet/mpls/arp(src_ip='192.168.10.10')-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,arp_spa=192.168.10.10,actions=set_field:10.10.10.10->arp_spa,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"arp_spa", "value":"10.10.10.10" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='10.10.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description": "ethernet/itag/ethernet/arp(src_ip='192.168.10.10')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_spa=192.168.10.10,actions=set_field:10.10.10.10->arp_spa,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"arp_spa", "value":"10.10.10.10" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='10.10.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/25_SET_FIELD/23_ARP_TPA.json0000664000175000017500000003376300000000000025164 0ustar00zuulzuul00000000000000[ "action: set_field: 23_ARP_TPA", { "description": "ethernet/arp(dst_ip='192.168.20.20')-->'arp_tpa=192.168.20.20,actions=set_field:10.10.20.20->arp_tpa,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"arp_tpa", "value":"10.10.20.20" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description": "ethernet/vlan/arp(dst_ip='192.168.20.20')-->'arp_tpa=192.168.20.20,actions=set_field:10.10.20.20->arp_tpa,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"arp_tpa", "value":"10.10.20.20" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description": "ethernet/mpls/arp(dst_ip='192.168.20.20')-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,arp_tpa=192.168.20.20,actions=set_field:10.10.20.20->arp_tpa,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"arp_tpa", "value":"10.10.20.20" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description": "ethernet/itag/ethernet/arp(dst_ip='192.168.20.20')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_tpa=192.168.20.20,actions=set_field:10.10.20.20->arp_tpa,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"arp_tpa", "value":"10.10.20.20" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/25_SET_FIELD/24_ARP_SHA.json0000664000175000017500000003413700000000000025150 0ustar00zuulzuul00000000000000[ "action: set_field: 24_ARP_SHA", { "description": "ethernet/arp(src_mac='12:11:11:11:11:11')-->'arp_sha=12:11:11:11:11:11,actions=set_field:aa:aa:aa:aa:aa:aa->arp_sha,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"arp_sha", "value":"aa:aa:aa:aa:aa:aa" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description": "ethernet/vlan/arp(src_mac='12:11:11:11:11:11')-->'arp_sha=12:11:11:11:11:11,actions=set_field:aa:aa:aa:aa:aa:aa->arp_sha,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"arp_sha", "value":"aa:aa:aa:aa:aa:aa" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * 30)" ] } ] }, { "description": "ethernet/mpls/arp(src_mac='12:11:11:11:11:11')-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,arp_sha=12:11:11:11:11:11,actions=set_field:aa:aa:aa:aa:aa:aa->arp_sha,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"arp_sha", "value":"aa:aa:aa:aa:aa:aa" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description": "ethernet/itag/ethernet/arp(src_mac='12:11:11:11:11:11')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_sha=12:11:11:11:11:11,actions=set_field:aa:aa:aa:aa:aa:aa->arp_sha,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"arp_sha", "value":"aa:aa:aa:aa:aa:aa" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/25_SET_FIELD/25_ARP_THA.json0000664000175000017500000003413700000000000025152 0ustar00zuulzuul00000000000000[ "action: set_field: 25_ARP_THA", { "description": "ethernet/arp(dst_mac='22:22:22:22:22:22')-->'arp_tha=22:22:22:22:22:22,actions=set_field:ba:bb:bb:bb:bb:bb->arp_tha,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"arp_tha", "value":"ba:bb:bb:bb:bb:bb" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description": "ethernet/vlan/arp(dst_mac='22:22:22:22:22:22')-->'arp_tha=22:22:22:22:22:22,actions=set_field:ba:bb:bb:bb:bb:bb->arp_tha,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"arp_tha", "value":"ba:bb:bb:bb:bb:bb" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description": "ethernet/mpls/arp(dst_mac='22:22:22:22:22:22')-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,arp_tha=22:22:22:22:22:22,actions=set_field:ba:bb:bb:bb:bb:bb->arp_tha,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"arp_tha", "value":"ba:bb:bb:bb:bb:bb" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description": "ethernet/itag/ethernet/arp(dst_mac='22:22:22:22:22:22')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_tha=22:22:22:22:22:22,actions=set_field:ba:bb:bb:bb:bb:bb->arp_tha,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"arp_tha", "value":"ba:bb:bb:bb:bb:bb" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/25_SET_FIELD/26_IPV6_SRC.json0000664000175000017500000003653200000000000025271 0ustar00zuulzuul00000000000000[ "action: set_field: 26_IPV6_SRC", { "description": "ethernet/ipv6(src='10::10')/tcp-->'ipv6_src=10::10,actions=set_field:a0::a0->ipv6_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "value":"10::10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv6_src", "value":"a0::a0" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='a0::a0', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv6(src='10::10')/tcp-->'ipv6_src=10::10,actions=set_field:a0::a0->ipv6_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "value":"10::10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv6_src", "value":"a0::a0" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='a0::a0', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/ipv6(src='10::10')/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_src=10::10,actions=set_field:a0::a0->ipv6_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "value":"10::10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv6_src", "value":"a0::a0" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='a0::a0', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/itag/ethernet/ipv6(src='10::10')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_src=10::10,actions=set_field:a0::a0->ipv6_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "value":"10::10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv6_src", "value":"a0::a0" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='a0::a0', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/25_SET_FIELD/27_IPV6_DST.json0000664000175000017500000003653300000000000025276 0ustar00zuulzuul00000000000000[ "action: set_field: 27_IPV6_DST", { "description": "ethernet/ipv6(dst='20::20')/tcp-->'ipv6_dst=20::20,actions=set_field:b0::b0->ipv6_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv6_dst", "value":"b0::b0" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv6(dst='20::20')/tcp-->'ipv6_dst=20::20,actions=set_field:b0::b0->ipv6_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv6_dst", "value":"b0::b0" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/ipv6(dst='20::20')/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_dst=20::20,actions=set_field:b0::b0->ipv6_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv6_dst", "value":"b0::b0" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/itag/ethernet/ipv6(dst='20::20')/tcp--->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_dst=20::20,actions=set_field:b0::b0->ipv6_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv6_dst", "value":"b0::b0" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/25_SET_FIELD/28_IPV6_FLABEL.json0000664000175000017500000003652500000000000025573 0ustar00zuulzuul00000000000000[ "action: set_field: 28_IPV6_FLABEL", { "description": "ethernet/ipv6(flow_label=100)/tcp-->'ipv6_flabel=100,actions=set_field:203->ipv6_flabel,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv6_flabel", "value":203 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=203, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv6(flow_label=100)/tcp-->'ipv6_flabel=100,actions=set_field:203->ipv6_flabel,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv6_flabel", "value":203 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=203, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/ipv6(flow_label=100)/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_flabel=100,actions=set_field:203->ipv6_flabel,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv6_flabel", "value":203 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=203, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/itag/ethernet/ipv6(flow_label=100)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_flabel=100,actions=set_field:203->ipv6_flabel,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv6_flabel", "value":203 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=203, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/25_SET_FIELD/29_ICMPV6_TYPE.json0000664000175000017500000004043500000000000025643 0ustar00zuulzuul00000000000000[ "action: set_field: 29_ICMPV6_TYPE", { "description": "ethernet/ipv6/icmpv6(type=128)-->'icmpv6_type=128,actions=set_field:135->icmpv6_type,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":128 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"icmpv6_type", "value":135 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=135)" ] } ] }, { "description": "ethernet/vlan/ipv6/icmpv6(type=128)-->'icmpv6_type=128,actions=set_field:135->icmpv6_type,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":128 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"icmpv6_type", "value":135 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=135)" ] } ] }, { "description": "ethernet/mpls/ipv6/icmpv6(type=128)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,icmpv6_type=128,actions=set_field:135->icmpv6_type,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":128 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"icmpv6_type", "value":135 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=135)" ] } ] }, { "description": "ethernet/itag/ethernet/ipv6/icmpv6(type=128)-->'actions=pop_pbb,goto_table:1','table_id:1,icmpv6_type=128,actions=set_field:135->icmpv6_type,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":128 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"icmpv6_type", "value":135 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=135)" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/25_SET_FIELD/30_ICMPV6_CODE.json0000664000175000017500000004036500000000000025566 0ustar00zuulzuul00000000000000[ "action: set_field: 30_ICMPV6_CODE", { "description": "ethernet/ipv6/icmpv6(code=0)-->'icmpv6_code=0,actions=set_field:1->icmpv6_code,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"icmpv6_code", "value":1 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=1,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ] } ] }, { "description": "ethernet/vlan/ipv6/icmpv6(code=0)-->'icmpv6_code=0,actions=set_field:1->icmpv6_code,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"icmpv6_code", "value":1 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=1,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ] } ] }, { "description": "ethernet/mpls/ipv6/icmpv6(code=0)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,icmpv6_code=0,actions=set_field:1->icmpv6_code,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"icmpv6_code", "value":1 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=1,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ] } ] }, { "description": "ethernet/itag/ethernet/ipv6/icmpv6(code=0)-->'actions=pop_pbb,goto_table:1','table_id:1,icmpv6_code=0,actions=set_field:1->icmpv6_code,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"icmpv6_code", "value":1 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=1,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/25_SET_FIELD/31_IPV6_ND_TARGET.json0000664000175000017500000004110400000000000026174 0ustar00zuulzuul00000000000000[ "action: set_field: 31_IPV6_ND_TARGET", { "description": "ethernet/ipv6/icmpv6(data=nd_neighbor(dst='20::20'))-->'ipv6_nd_target=20::20,actions=set_field:a0::a0->ipv6_nd_target,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_target", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv6_nd_target", "value":"a0::a0" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='12:11:11:11:11:11'),dst='20::20'),type_=135)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='12:11:11:11:11:11'),dst='a0::a0'),type_=135)" ] } ] }, { "description": "ethernet/vlan/ipv6/icmpv6(data=nd_neighbor(dst='20::20'))-->'ipv6_nd_target=20::20,actions=set_field:a0::a0->ipv6_nd_target,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_target", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv6_nd_target", "value":"a0::a0" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='12:11:11:11:11:11'),dst='20::20'),type_=135)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='12:11:11:11:11:11'),dst='a0::a0'),type_=135)" ] } ] }, { "description": "ethernet/mpls/ipv6/icmpv6(data=nd_neighbor(dst='20::20'))-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_nd_target=20::20,actions=set_field:a0::a0->ipv6_nd_target,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_target", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv6_nd_target", "value":"a0::a0" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='12:11:11:11:11:11'),dst='20::20'),type_=135)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='12:11:11:11:11:11'),dst='a0::a0'),type_=135)" ] } ] }, { "description": "ethernet/itag/ethernet/ipv6/icmpv6(data=nd_neighbor(dst='20::20'))-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_nd_target=20::20,actions=set_field:a0::a0->ipv6_nd_target,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_target", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv6_nd_target", "value":"a0::a0" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='12:11:11:11:11:11'),dst='20::20'),type_=135)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='12:11:11:11:11:11'),dst='a0::a0'),type_=135)" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/25_SET_FIELD/32_IPV6_ND_SLL.json0000664000175000017500000004151600000000000025650 0ustar00zuulzuul00000000000000[ "action: set_field: 32_IPV6_ND_SLL", { "description": "ethernet/ipv6/icmpv6(data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22')))-->'ipv6_nd_sll=22:22:22:22:22:22,actions=set_field:aa:aa:aa:aa:aa:aa->ipv6_nd_sll,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_sll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv6_nd_sll", "value":"aa:aa:aa:aa:aa:aa" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=135)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='aa:aa:aa:aa:aa:aa'),dst='20::20'),type_=135)" ] } ] }, { "description": "ethernet/vlan/ipv6/icmpv6(data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22')))-->'ipv6_nd_sll=12:11:11:11:11,actions=set_field:aa:aa:aa:aa:aa:aa->ipv6_nd_sll,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_sll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv6_nd_sll", "value":"aa:aa:aa:aa:aa:aa" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=135)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='aa:aa:aa:aa:aa:aa'),dst='20::20'),type_=135)" ] } ] }, { "description": "ethernet/mpls/ipv6/icmpv6(data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22')))-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_nd_sll=22:22:22:22:22:22,actions=set_field:aa:aa:aa:aa:aa:aa->ipv6_nd_sll,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_sll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv6_nd_sll", "value":"aa:aa:aa:aa:aa:aa" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=135)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='aa:aa:aa:aa:aa:aa'),dst='20::20'),type_=135)" ] } ] }, { "description": "ethernet/itag/ethernet/ipv6/icmpv6(data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22')))-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_nd_sll=22:22:22:22:22:22,actions=set_field:aa:aa:aa:aa:aa:aa->ipv6_nd_sll,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_sll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv6_nd_sll", "value":"aa:aa:aa:aa:aa:aa" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=135)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='aa:aa:aa:aa:aa:aa'),dst='20::20'),type_=135)" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/25_SET_FIELD/33_IPV6_ND_TLL.json0000664000175000017500000004152100000000000025646 0ustar00zuulzuul00000000000000[ "action: set_field: 33_IPV6_ND_TLL", { "description": "ethernet/ipv6/icmpv6(data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22')))-->'ipv6_nd_tll=22:22:22:22:22:22,actions=set_field:aa:aa:aa:aa:aa:aa->ipv6_nd_tll,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":136 } }, { "OXMTlv":{ "field":"ipv6_nd_tll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv6_nd_tll", "value":"aa:aa:aa:aa:aa:aa" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=136)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='aa:aa:aa:aa:aa:aa'),dst='20::20'),type_=136)" ] } ] }, { "description": "ethernet/vlan/ipv6/icmpv6(data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22')))-->'ipv6_nd_tll=22:22:22:22:22:22,actions=set_field:aa:aa:aa:aa:aa:aa->ipv6_nd_tll,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":136 } }, { "OXMTlv":{ "field":"ipv6_nd_tll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv6_nd_tll", "value":"aa:aa:aa:aa:aa:aa" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=136)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='aa:aa:aa:aa:aa:aa'),dst='20::20'),type_=136)" ] } ] }, { "description": "ethernet/mpls/ipv6/icmpv6(data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22')))-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_nd_tll=22:22:22:22:22:22,actions=set_field:aa:aa:aa:aa:aa:aa->ipv6_nd_tll,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":136 } }, { "OXMTlv":{ "field":"ipv6_nd_tll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv6_nd_tll", "value":"aa:aa:aa:aa:aa:aa" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=136)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='aa:aa:aa:aa:aa:aa'),dst='20::20'),type_=136)" ] } ] }, { "description": "ethernet/itag/ethernet/ipv6/icmpv6(data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22')))-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_nd_tll=22:22:22:22:22:22,actions=set_field:aa:aa:aa:aa:aa:aa->ipv6_nd_tll,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":136 } }, { "OXMTlv":{ "field":"ipv6_nd_tll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv6_nd_tll", "value":"aa:aa:aa:aa:aa:aa" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=136)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='aa:aa:aa:aa:aa:aa'),dst='20::20'),type_=136)" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/25_SET_FIELD/34_MPLS_LABEL.json0000664000175000017500000002244200000000000025502 0ustar00zuulzuul00000000000000[ "action: set_field: 34_MPLS_LABEL", { "description": "ethernet/mpls(label=100)/ipv4/tcp-->'mpls_label=100,actions=set_field:203->mpls_label,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_label", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"mpls_label", "value":203 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=203, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls(label=100)/ipv6/tcp-->'mpls_label=100,actions=set_field:203->mpls_label,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_label", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"mpls_label", "value":203 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=203, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls(label=100)/arp-->'mpls_label=100,actions=set_field:203->mpls_label,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_label", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"mpls_label", "value":203 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=203, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/25_SET_FIELD/35_MPLS_TC.json0000664000175000017500000002232700000000000025174 0ustar00zuulzuul00000000000000[ "action: set_field: 35_MPLS_TC", { "description": "ethernet/mpls(exp=3)/ipv4/tcp-->'mpls_tc=3,actions=set_field:5->mpls_tc,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_tc", "value":3 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"mpls_tc", "value":5 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=5, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls(exp=3)/ipv6/tcp-->'mpls_tc=3,actions=set_field:5->mpls_tc,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_tc", "value":3 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"mpls_tc", "value":5 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=5, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls(exp=3)/arp-->'mpls_tc=3,actions=set_field:5->mpls_tc,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_tc", "value":3 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"mpls_tc", "value":5 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=5, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/25_SET_FIELD/36_MPLS_BOS.json0000664000175000017500000002234400000000000025311 0ustar00zuulzuul00000000000000[ "action: set_field: 36_MPLS_BOS", { "description": "ethernet/mpls(bsb=1)/ipv4/tcp-->'mpls_bos=1,actions=set_field:0->mpls_bos,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_bos", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"mpls_bos", "value":0 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=0, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls(bsb=1)/ipv6/tcp-->'mpls_bos=1,actions=set_field:0->mpls_bos,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_bos", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"mpls_bos", "value":0 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=0, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls(bsb=1)/arp-->'mpls_bos=1,actions=set_field:0->mpls_bos,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_bos", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"mpls_bos", "value":0 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=0, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/25_SET_FIELD/37_PBB_ISID.json0000664000175000017500000002545600000000000025256 0ustar00zuulzuul00000000000000[ "action: set_field: 37_PBB_ISID", { "description": "ethernet/svlan/itag(sid=100)/ethernet/svlan/vlan/ipv4/tcp-->'pbb_itag=100,actions=set_field:203->pbb_itag,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_isid", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"pbb_isid", "value":203 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=203)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/svlan/itag(sid=100)/ethernet/svlan/vlan/ipv6/tcp-->'pbb_itag=100,actions=set_field:203->pbb_itag,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_isid", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"pbb_isid", "value":203 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=203)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/svlan/itag(sid=100)/ethernet/svlan/vlan/arp-->'pbb_itag=100,actions=set_field:203->pbb_itag,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_isid", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"pbb_isid", "value":203 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=203)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/25_SET_FIELD/38_TUNNEL_ID.json0000664000175000017500000002651200000000000025417 0ustar00zuulzuul00000000000000[ "action: set_field: 38_TUNNEL_ID", { "description": "ethernet/ipv4/tcp-->'actions=set_field:12345->tunnel_id,goto_table:1','table_id:1,tunnel_id=12345,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tunnel_id", "value":12345 } } } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"tunnel_id", "value":12345 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/ipv6/tcp-->'actions=set_field:12345->tunnel_id,goto_table:1','table_id:1,tunnel_id=12345,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tunnel_id", "value":12345 } } } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"tunnel_id", "value":12345 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/arp-->'actions=set_field:12345->tunnel_id,goto_table:1','table_id:1,tunnel_id=12345,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tunnel_id", "value":12345 } } } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"tunnel_id", "value":12345 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/26_PUSH_PBB.json0000664000175000017500000001715100000000000023430 0ustar00zuulzuul00000000000000[ "action: 26_PUSH_PBB", { "description": "ethernet/ipv4/tcp-->'eth_type=0x0800,actions=push_pbb:0x88e7,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPushPbb":{ "ethertype":35047 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag()", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/ipv6/tcp-->'eth_type=0x86dd,actions=push_pbb:0x88e7,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPushPbb":{ "ethertype":35047 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag()", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/arp-->'eth_type=0x0806,actions=push_pbb:0x88e7,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPushPbb":{ "ethertype":35047 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag()", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/26_PUSH_PBB_multiple.json0000664000175000017500000002135700000000000025346 0ustar00zuulzuul00000000000000[ "action: 26_PUSH_PBB (multiple)", { "description": "ethernet/ipv4/tcp-->'eth_type=0x0800,actions=push_pbb:0x88e7,push_pbb:0x88e7,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPushPbb":{ "ethertype":35047 } }, { "OFPActionPushPbb":{ "ethertype":35047 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag()", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag()", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/ipv6/tcp-->'eth_type=0x86dd,actions=push_pbb:0x88e7,push_pbb:0x88e7,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPushPbb":{ "ethertype":35047 } }, { "OFPActionPushPbb":{ "ethertype":35047 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag()", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag()", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/arp-->'eth_type=0x0806,actions=push_pbb:0x88e7,push_pbb:0x88e7,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPushPbb":{ "ethertype":35047 } }, { "OFPActionPushPbb":{ "ethertype":35047 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag()", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag()", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/action/27_POP_PBB.json0000664000175000017500000002011000000000000023275 0ustar00zuulzuul00000000000000[ "action: 27_POP_PBB", { "description": "ethernet/itag/ethernet/svlan/vlan/ipv4/tcp-->'eth_type=0x88e7,actions=pop_pbb,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/itag/ethernet/svlan/vlan/ipv6/tcp-->'eth_type=0x88e7,actions=pop_pbb,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/itag/ethernet/svlan/vlan/arp-->'eth_type=0x88e7,actions=pop_pbb,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] } ] ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.2261126 os-ken-2.10.0/os_ken/tests/switch/of13/group/0000775000175000017500000000000000000000000020636 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/group/00_ALL.json0000664000175000017500000002732600000000000022452 0ustar00zuulzuul00000000000000[ "group: 00_ALL", { "description":"2Mbps(ethernet/ipv4/tcp)-->'in_port=1,actions=group:all(actions=output:2/actions=output:3)'", "prerequisite":[ { "OFPGroupMod":{ "group_id":0, "buckets":[ { "OFPBucket":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ] } }, { "OFPBucket":{ "actions":[ { "OFPActionOutput":{ "port":3 } } ] } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionGroup":{ "group_id":0 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(proto=6)", "tcp()", "bytes(b'\\x11' * (1500 - 54))" ], "pktps":175, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":2000 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":3 } } ] }, "kbps":2000 } ] } } ] }, { "description":"2Mbps(ethernet/ipv6/tcp)-->'in_port=1,actions=group:all(actions=output:2/actions=output:3)'", "prerequisite":[ { "OFPGroupMod":{ "group_id":0, "buckets":[ { "OFPBucket":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ] } }, { "OFPBucket":{ "actions":[ { "OFPActionOutput":{ "port":3 } } ] } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionGroup":{ "group_id":0 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(nxt=6)", "tcp()", "bytes(b'\\x11' * (1500 - 74))" ], "pktps":175, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":2000 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":3 } } ] }, "kbps":2000 } ] } } ] }, { "description":"2Mbps(ethernet/arp)-->'in_port=1,actions=group:all(actions=output:2/actions=output:3)'", "prerequisite":[ { "OFPGroupMod":{ "group_id":0, "buckets":[ { "OFPBucket":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ] } }, { "OFPBucket":{ "actions":[ { "OFPActionOutput":{ "port":3 } } ] } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionGroup":{ "group_id":0 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_mac='22:22:22:22:22:22', src_mac='12:11:11:11:11:11')", "bytes(b'\\x11' * (1500 - 42))" ], "pktps":175, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":2000 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":3 } } ] }, "kbps":2000 } ] } } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/group/01_SELECT_Ether.json0000664000175000017500000003045000000000000024141 0ustar00zuulzuul00000000000000[ "group: 01_SELECT_Ether", { "description":"2Mbps(ethernet(dst=random,src=random)/ipv4/tcp)-->'in_port=1,actions=group:select(actions=output:2/actions=output:3)'", "prerequisite":[ { "OFPGroupMod":{ "group_id":0, "type":1, "buckets":[ { "OFPBucket":{ "weight":1, "actions":[ { "OFPActionOutput":{ "port":2 } } ] } }, { "OFPBucket":{ "weight":1, "actions":[ { "OFPActionOutput":{ "port":3 } } ] } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionGroup":{ "group_id":0 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst=netaddr.EUI(randint(0, 2 ** 48 - 1)), src=netaddr.EUI(randint(0, 2 ** 48 - 1) & 0xfeffffffffff), ethertype=2048)", "ipv4(proto=6)", "tcp()", "bytes(b'\\x11' * (1500 - 54))" ], "pktps":175, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":1000 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":3 } } ] }, "kbps":1000 } ] } } ] }, { "description":"2Mbps(ethernet(dst=random,src=random)/ipv6/tcp)-->'in_port=1,actions=group:select(actions=output:2/actions=output:3)'", "prerequisite":[ { "OFPGroupMod":{ "group_id":0, "type":1, "buckets":[ { "OFPBucket":{ "weight":1, "actions":[ { "OFPActionOutput":{ "port":2 } } ] } }, { "OFPBucket":{ "weight":1, "actions":[ { "OFPActionOutput":{ "port":3 } } ] } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionGroup":{ "group_id":0 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst=netaddr.EUI(randint(0, 2 ** 48 - 1)), src=netaddr.EUI(randint(0, 2 ** 48 - 1) & 0xfeffffffffff), ethertype=34525)", "ipv6(nxt=6)", "tcp()", "bytes(b'\\x11' * (1500 - 74))" ], "pktps":175, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":1000 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":3 } } ] }, "kbps":1000 } ] } } ] }, { "description":"2Mbps(ethernet(dst=random,src=random)/arp)-->'in_port=1,actions=group:select(actions=output:2/actions=output:3)'", "prerequisite":[ { "OFPGroupMod":{ "group_id":0, "type":1, "buckets":[ { "OFPBucket":{ "weight":1, "actions":[ { "OFPActionOutput":{ "port":2 } } ] } }, { "OFPBucket":{ "weight":1, "actions":[ { "OFPActionOutput":{ "port":3 } } ] } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionGroup":{ "group_id":0 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst=netaddr.EUI(randint(0, 2 ** 48 - 1)), src=netaddr.EUI(randint(0, 2 ** 48 - 1) & 0xfeffffffffff), ethertype=2054)", "arp(dst_mac='22:22:22:22:22:22', src_mac='12:11:11:11:11:11')", "bytes(b'\\x11' * (1500 - 42))" ], "pktps":175, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":1000 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":3 } } ] }, "kbps":1000 } ] } } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/group/01_SELECT_IP.json0000664000175000017500000003117700000000000023411 0ustar00zuulzuul00000000000000[ "group: 01_SELECT_IP", { "description":"2Mbps(ethernet/ipv4(src=random,dst=random)/tcp(src_port=random,dst_port=random))-->'in_port=1,actions=group:select(actions=output:2/actions=output:3)'", "prerequisite":[ { "OFPGroupMod":{ "group_id":0, "type":1, "buckets":[ { "OFPBucket":{ "weight":1, "actions":[ { "OFPActionOutput":{ "port":2 } } ] } }, { "OFPBucket":{ "weight":1, "actions":[ { "OFPActionOutput":{ "port":3 } } ] } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionGroup":{ "group_id":0 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(proto=6, dst=netaddr.IPAddress(randint(0, 2 ** 32 - 1)), src=netaddr.IPAddress(randint(0, 2 ** 32 - 1)))", "tcp(dst_port=randint(0, 2 ** 16 - 1), src_port=randint(0, 2 ** 16 - 1))", "bytes(b'\\x11' * (1500 - 54))" ], "pktps":175, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":1000 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":3 } } ] }, "kbps":1000 } ] } } ] }, { "description":"2Mbps(ethernet/ipv6(src=random,dst=random)/tcp(src_port=random,dst_port=random))-->'in_port=1,actions=group:select(actions=output:2/actions=output:3)'", "prerequisite":[ { "OFPGroupMod":{ "group_id":0, "type":1, "buckets":[ { "OFPBucket":{ "weight":1, "actions":[ { "OFPActionOutput":{ "port":2 } } ] } }, { "OFPBucket":{ "weight":1, "actions":[ { "OFPActionOutput":{ "port":3 } } ] } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionGroup":{ "group_id":0 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(nxt=6, dst=netaddr.IPAddress(randint(0, 2 ** 128 - 1)), src=netaddr.IPAddress(randint(0, 2 ** 128 - 1)))", "tcp(dst_port=randint(0, 2 ** 16 - 1), src_port=randint(0, 2 ** 16 - 1))", "bytes(b'\\x11' * (1500 - 74))" ], "pktps":175, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":1000 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":3 } } ] }, "kbps":1000 } ] } } ] }, { "description":"2Mbps(ethernet/arp(src_ip=random,dst_ip=random)-->'in_port=1,actions=group:select(actions=output:2/actions=output:3)'", "prerequisite":[ { "OFPGroupMod":{ "group_id":0, "type":1, "buckets":[ { "OFPBucket":{ "weight":1, "actions":[ { "OFPActionOutput":{ "port":2 } } ] } }, { "OFPBucket":{ "weight":1, "actions":[ { "OFPActionOutput":{ "port":3 } } ] } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionGroup":{ "group_id":0 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_mac='22:22:22:22:22:22', src_mac='12:11:11:11:11:11', dst_ip=netaddr.IPAddress(randint(0, 2 ** 32 - 1)), src_ip=netaddr.IPAddress(randint(0, 2 ** 32 - 1)))", "bytes(b'\\x11' * (1500 - 42))" ], "pktps":175, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":1000 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":3 } } ] }, "kbps":1000 } ] } } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/group/01_SELECT_Weight_Ether.json0000664000175000017500000003054200000000000025452 0ustar00zuulzuul00000000000000[ "group: 01_SELECT_Weight_Ether", { "description":"2Mbps(ethernet(dst=random,src=random)/ipv4/tcp)-->'in_port=1,actions=group:select(weight=1,actions=output:2/weight=2,actions=output:3)'", "prerequisite":[ { "OFPGroupMod":{ "group_id":0, "type":1, "buckets":[ { "OFPBucket":{ "weight":1, "actions":[ { "OFPActionOutput":{ "port":2 } } ] } }, { "OFPBucket":{ "weight":2, "actions":[ { "OFPActionOutput":{ "port":3 } } ] } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionGroup":{ "group_id":0 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst=netaddr.EUI(randint(0, 2 ** 48 - 1)), src=netaddr.EUI(randint(0, 2 ** 48 - 1) & 0xfeffffffffff), ethertype=2048)", "ipv4(proto=6)", "tcp()", "bytes(b'\\x11' * (1500 - 54))" ], "pktps":175, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":667 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":3 } } ] }, "kbps":1333 } ] } } ] }, { "description":"2Mbps(ethernet(dst=random,src=random)/ipv6/tcp)-->'in_port=1,actions=group:select(weight=1,actions=output:2/weight=2,actions=output:3)'", "prerequisite":[ { "OFPGroupMod":{ "group_id":0, "type":1, "buckets":[ { "OFPBucket":{ "weight":1, "actions":[ { "OFPActionOutput":{ "port":2 } } ] } }, { "OFPBucket":{ "weight":2, "actions":[ { "OFPActionOutput":{ "port":3 } } ] } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionGroup":{ "group_id":0 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst=netaddr.EUI(randint(0, 2 ** 48 - 1)), src=netaddr.EUI(randint(0, 2 ** 48 - 1) & 0xfeffffffffff), ethertype=34525)", "ipv6(nxt=6)", "tcp()", "bytes(b'\\x11' * (1500 - 74))" ], "pktps":175, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":667 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":3 } } ] }, "kbps":1333 } ] } } ] }, { "description":"2Mbps(ethernet(dst=random,src=random)/arp)-->'in_port=1,actions=group:select(weight=1,actions=output:2/weight=2,actions=output:3)'", "prerequisite":[ { "OFPGroupMod":{ "group_id":0, "type":1, "buckets":[ { "OFPBucket":{ "weight":1, "actions":[ { "OFPActionOutput":{ "port":2 } } ] } }, { "OFPBucket":{ "weight":2, "actions":[ { "OFPActionOutput":{ "port":3 } } ] } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionGroup":{ "group_id":0 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst=netaddr.EUI(randint(0, 2 ** 48 - 1)), src=netaddr.EUI(randint(0, 2 ** 48 - 1) & 0xfeffffffffff), ethertype=2054)", "arp(dst_mac='22:22:22:22:22:22', src_mac='12:11:11:11:11:11')", "bytes(b'\\x11' * (1500 - 42))" ], "pktps":175, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":667 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":3 } } ] }, "kbps":1333 } ] } } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/group/01_SELECT_Weight_IP.json0000664000175000017500000003127100000000000024713 0ustar00zuulzuul00000000000000[ "group: 01_SELECT_Weight_IP", { "description":"2Mbps(ethernet/ipv4(src=random,dst=random)/tcp(src_port=random,dst_port=random))-->'in_port=1,actions=group:select(weight=1,actions=output:2/weight=2,actions=output:3)'", "prerequisite":[ { "OFPGroupMod":{ "group_id":0, "type":1, "buckets":[ { "OFPBucket":{ "weight":1, "actions":[ { "OFPActionOutput":{ "port":2 } } ] } }, { "OFPBucket":{ "weight":2, "actions":[ { "OFPActionOutput":{ "port":3 } } ] } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionGroup":{ "group_id":0 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(proto=6, dst=netaddr.IPAddress(randint(0, 2 ** 32 - 1)), src=netaddr.IPAddress(randint(0, 2 ** 32 - 1)))", "tcp(dst_port=randint(0, 2 ** 16 - 1), src_port=randint(0, 2 ** 16 - 1))", "bytes(b'\\x11' * (1500 - 54))" ], "pktps":175, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":667 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":3 } } ] }, "kbps":1333 } ] } } ] }, { "description":"2Mbps(ethernet/ipv6(src=random,dst=random)/tcp(src_port=random,dst_port=random))-->'in_port=1,actions=group:select(weight=1,actions=output:2/weight=2,actions=output:3)'", "prerequisite":[ { "OFPGroupMod":{ "group_id":0, "type":1, "buckets":[ { "OFPBucket":{ "weight":1, "actions":[ { "OFPActionOutput":{ "port":2 } } ] } }, { "OFPBucket":{ "weight":2, "actions":[ { "OFPActionOutput":{ "port":3 } } ] } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionGroup":{ "group_id":0 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(nxt=6, dst=netaddr.IPAddress(randint(0, 2 ** 128 - 1)), src=netaddr.IPAddress(randint(0, 2 ** 128 - 1)))", "tcp(dst_port=randint(0, 2 ** 16 - 1), src_port=randint(0, 2 ** 16 - 1))", "bytes(b'\\x11' * (1500 - 74))" ], "pktps":175, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":667 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":3 } } ] }, "kbps":1333 } ] } } ] }, { "description":"2Mbps(ethernet/arp(src_ip=random,dst_ip=random)-->'in_port=1,actions=group:select(weight=1,actions=output:2/weight=2,actions=output:3)'", "prerequisite":[ { "OFPGroupMod":{ "group_id":0, "type":1, "buckets":[ { "OFPBucket":{ "weight":1, "actions":[ { "OFPActionOutput":{ "port":2 } } ] } }, { "OFPBucket":{ "weight":2, "actions":[ { "OFPActionOutput":{ "port":3 } } ] } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionGroup":{ "group_id":0 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_mac='22:22:22:22:22:22', src_mac='12:11:11:11:11:11', dst_ip=netaddr.IPAddress(randint(0, 2 ** 32 - 1)), src_ip=netaddr.IPAddress(randint(0, 2 ** 32 - 1)))", "bytes(b'\\x11' * (1500 - 42))" ], "pktps":175, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":667 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":3 } } ] }, "kbps":1333 } ] } } ] } ] ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.2421134 os-ken-2.10.0/os_ken/tests/switch/of13/match/0000775000175000017500000000000000000000000020576 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/00_IN_PORT.json0000664000175000017500000004457400000000000023160 0ustar00zuulzuul00000000000000[ "match: 00_IN_PORT", { "description":"ethernet/ipv4/tcp-->'in_port=1,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4/tcp-->'in_port=1,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4/tcp-->'in_port=2,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/ipv6/tcp-->'in_port=1,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6/tcp-->'in_port=1,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6/tcp-->'in_port=2,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/arp-->'in_port=1,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp-->'in_port=1,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp-->'in_port=2,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 0 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/02_METADATA.json0000664000175000017500000006331700000000000023164 0ustar00zuulzuul00000000000000[ "match: 02_METADATA", { "description":"ethernet/ipv4/tcp-->'actions=write_metadata:255/0xffffffff,goto_table:1','table_id:1,metadata=255,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[] } }, "instructions":[ { "OFPInstructionWriteMetadata":{ "metadata":255, "metadata_mask":4294967295 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"metadata", "value":255 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4/tcp-->'actions=write_metadata:255/0xffffffff,goto_table:1','table_id:1,metadata=255,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[] } }, "instructions":[ { "OFPInstructionWriteMetadata":{ "metadata":255, "metadata_mask":4294967295 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"metadata", "value":255 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4/tcp-->'actions=write_metadata:155/0xffffffff,goto_table:1','table_id:1,metadata=255,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[] } }, "instructions":[ { "OFPInstructionWriteMetadata":{ "metadata":155, "metadata_mask":4294967295 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"metadata", "value":255 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/ipv6/tcp-->'actions=write_metadata:255/0xffffffff,goto_table:1','table_id:1,metadata=255,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[] } }, "instructions":[ { "OFPInstructionWriteMetadata":{ "metadata":255, "metadata_mask":4294967295 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"metadata", "value":255 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6/tcp-->'actions=write_metadata:255/0xffffffff,goto_table:1','table_id=1,metadata=255,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[] } }, "instructions":[ { "OFPInstructionWriteMetadata":{ "metadata":255, "metadata_mask":4294967295 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"metadata", "value":255 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6/tcp-->'actions=write_metadata:155/0xffffffff,goto_table:1','table_id:1,metadata=255,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[] } }, "instructions":[ { "OFPInstructionWriteMetadata":{ "metadata":155, "metadata_mask":4294967295 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"metadata", "value":255 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/arp-->'actions=write_metadata:255/0xffffffff,goto_table:1','table_id:1,metadata=255,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[] } }, "instructions":[ { "OFPInstructionWriteMetadata":{ "metadata":255, "metadata_mask":4294967295 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"metadata", "value":255 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp-->'actions=write_metadata:255/0xffffffff,goto_table:1','table_id:1,metadata=255,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[] } }, "instructions":[ { "OFPInstructionWriteMetadata":{ "metadata":255, "metadata_mask":4294967295 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"metadata", "value":255 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp-->'actions=write_metadata:155/0xffffffff,goto_table:1','table_id:1,metadata=255,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[] } }, "instructions":[ { "OFPInstructionWriteMetadata":{ "metadata":155, "metadata_mask":4294967295 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"metadata", "value":255 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/02_METADATA_Mask.json0000664000175000017500000006460200000000000024135 0ustar00zuulzuul00000000000000[ "match: 02_METADATA (Mask)", { "description":"ethernet/ipv4/tcp-->'actions=write_metadata:255/0xffffffff,goto_table:1','table_id:1,metadata=240(mask=0xfffffff0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[] } }, "instructions":[ { "OFPInstructionWriteMetadata":{ "metadata":255, "metadata_mask":4294967295 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"metadata", "mask":4294967280, "value":240 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4/tcp-->'actions=write_metadata:255/0xffffffff,goto_table:1','table_id:1,metadata=240(mask=0xfffffff0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[] } }, "instructions":[ { "OFPInstructionWriteMetadata":{ "metadata":255, "metadata_mask":4294967295 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"metadata", "mask":4294967280, "value":240 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4/tcp-->'actions=write_metadata:155/0xffffffff,goto_table:1','table_id:1,metadata=240(mask=0xfffffff0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[] } }, "instructions":[ { "OFPInstructionWriteMetadata":{ "metadata":155, "metadata_mask":4294967295 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"metadata", "mask":4294967280, "value":240 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/ipv6/tcp-->'actions=write_metadata:255/0xffffffff,goto_table:1','table_id:1,metadata=240(mask=0xfffffff0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[] } }, "instructions":[ { "OFPInstructionWriteMetadata":{ "metadata":255, "metadata_mask":4294967295 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"metadata", "mask":4294967280, "value":240 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6/tcp-->'actions=write_metadata:255/0xffffffff,goto_table:1','table_id:1,metadata=240(mask=0xfffffff0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[] } }, "instructions":[ { "OFPInstructionWriteMetadata":{ "metadata":255, "metadata_mask":4294967295 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"metadata", "mask":4294967280, "value":240 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6/tcp-->'actions=write_metadata:155/0xffffffff,goto_table:1','table_id:1,metadata=240(mask=0xfffffff0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[] } }, "instructions":[ { "OFPInstructionWriteMetadata":{ "metadata":155, "metadata_mask":4294967295 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"metadata", "mask":4294967280, "value":240 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/arp-->'actions=write_metadata:255/0xffffffff,goto_table:1','table_id:1,metadata=240(mask=0xfffffff0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[] } }, "instructions":[ { "OFPInstructionWriteMetadata":{ "metadata":255, "metadata_mask":4294967295 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"metadata", "mask":4294967280, "value":240 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp-->'actions=write_metadata:255/0xffffffff,goto_table:1','table_id:1,metadata=240(mask=0xfffffff0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[] } }, "instructions":[ { "OFPInstructionWriteMetadata":{ "metadata":255, "metadata_mask":4294967295 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"metadata", "mask":4294967280, "value":240 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp-->'actions=write_metadata:155/0xffffffff,goto_table:1','table_id:1,metadata=240(mask=0xfffffff0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[] } }, "instructions":[ { "OFPInstructionWriteMetadata":{ "metadata":155, "metadata_mask":4294967295 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"metadata", "mask":4294967280, "value":240 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/03_ETH_DST.json0000664000175000017500000004561700000000000023142 0ustar00zuulzuul00000000000000[ "match: 03_ETH_DST", { "description":"ethernet(dst='22:22:22:22:22:22')/ipv4/tcp-->'eth_dst=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_dst", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet(dst='22:22:22:22:22:22')/ipv4/tcp-->'eth_dst=22:22:22:22:22:22,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_dst", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet(dst='ba:bb:bb:bb:bb:bb')/ipv4/tcp-->'eth_dst=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_dst", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet(dst='22:22:22:22:22:22')/ipv6/tcp-->'eth_dst=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_dst", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet(dst='22:22:22:22:22:22')/ipv6/tcp-->'eth_dst=22:22:22:22:22:22,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_dst", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet(dst='ba:bb:bb:bb:bb:bb')/ipv6/tcp-->'eth_dst=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_dst", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet(dst='22:22:22:22:22:22')/arp-->'eth_dst=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_dst", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet(dst='22:22:22:22:22:22')/arp-->'eth_dst=22:22:22:22:22:22,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_dst", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet(dst='ba:bb:bb:bb:bb:bb')/arp-->'eth_dst=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_dst", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 0 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/03_ETH_DST_Mask.json0000664000175000017500000004732200000000000024110 0ustar00zuulzuul00000000000000[ "match: 03_ETH_DST (Mask)", { "description":"ethernet(dst='22:22:22:22:22:22')/ipv4/tcp-->'eth_dst=22:22:22:22:22:00(mask=ff:ff:ff:ff:ff:00),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_dst", "mask":"ff:ff:ff:ff:ff:00", "value":"22:22:22:22:22:00" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet(dst='22:22:22:22:22:22')/ipv4/tcp-->'eth_dst=22:22:22:22:22:00(mask=ff:ff:ff:ff:ff:00),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_dst", "mask":"ff:ff:ff:ff:ff:00", "value":"22:22:22:22:22:00" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet(dst='ba:bb:bb:bb:bb:bb')/ipv4/tcp-->'eth_dst=22:22:22:22:22:00(mask=ff:ff:ff:ff:ff:00),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_dst", "mask":"ff:ff:ff:ff:ff:00", "value":"22:22:22:22:22:00" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet(dst='22:22:22:22:22:22')/ipv6/tcp-->'eth_dst=22:22:22:22:22:00(mask=ff:ff:ff:ff:ff:00),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_dst", "mask":"ff:ff:ff:ff:ff:00", "value":"22:22:22:22:22:00" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet(dst='22:22:22:22:22:22')/ipv6/tcp-->'eth_dst=22:22:22:22:22:00(mask=ff:ff:ff:ff:ff:00),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_dst", "mask":"ff:ff:ff:ff:ff:00", "value":"22:22:22:22:22:00" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet(dst='ba:bb:bb:bb:bb:bb')/ipv6/tcp-->'eth_dst=22:22:22:22:22:00(mask=ff:ff:ff:ff:ff:00),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_dst", "mask":"ff:ff:ff:ff:ff:00", "value":"22:22:22:22:22:00" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet(dst='22:22:22:22:22:22')/arp-->'eth_dst=22:22:22:22:22:00(mask=ff:ff:ff:ff:ff:00),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_dst", "mask":"ff:ff:ff:ff:ff:00", "value":"22:22:22:22:22:00" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet(dst='22:22:22:22:22:22')/arp-->'eth_dst=22:22:22:22:22:00(mask=ff:ff:ff:ff:ff:00),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_dst", "mask":"ff:ff:ff:ff:ff:00", "value":"22:22:22:22:22:00" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet(dst='ba:bb:bb:bb:bb:bb')/arp-->'eth_dst=22:22:22:22:22:00(mask=ff:ff:ff:ff:ff:00),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_dst", "mask":"ff:ff:ff:ff:ff:00", "value":"22:22:22:22:22:00" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 0 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/04_ETH_SRC.json0000664000175000017500000004561700000000000023140 0ustar00zuulzuul00000000000000[ "match: 04_ETH_SRC", { "description":"ethernet(src='12:11:11:11:11:11')/ipv4/tcp-->'eth_src=12:11:11:11:11:11,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_src", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet(src='12:11:11:11:11:11')/ipv4/tcp-->'eth_src=12:11:11:11:11:11,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_src", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet(src='aa:aa:aa:aa:aa:aa')/ipv4/tcp-->'eth_src=12:11:11:11:11:11,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_src", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet(src='12:11:11:11:11:11')/ipv6/tcp-->'eth_src=12:11:11:11:11:11,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_src", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet(src='12:11:11:11:11:11')/ipv6/tcp-->'eth_src=12:11:11:11:11:11,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_src", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet(src='aa:aa:aa:aa:aa:aa')/ipv6/tcp-->'eth_src=12:11:11:11:11:11,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_src", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet(src='12:11:11:11:11:11')/arp-->'eth_src=12:11:11:11:11:11,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_src", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet(src='12:11:11:11:11:11')/arp-->'eth_src=12:11:11:11:11:11,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_src", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet(src='aa:aa:aa:aa:aa:aa')/arp-->'eth_src=12:11:11:11:11:11,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_src", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 0 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/04_ETH_SRC_Mask.json0000664000175000017500000004732200000000000024106 0ustar00zuulzuul00000000000000[ "match: 04_ETH_SRC (Mask)", { "description":"ethernet(src='12:11:11:11:11:11')/ipv4/tcp-->'eth_src=00:11:11:11:11:11(mask=00:ff:ff:ff:ff:ff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_src", "mask":"00:ff:ff:ff:ff:ff", "value":"00:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet(src='12:11:11:11:11:11')/ipv4/tcp-->'eth_src=00:11:11:11:11:11(mask=00:ff:ff:ff:ff:ff),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_src", "mask":"00:ff:ff:ff:ff:ff", "value":"00:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet(src='aa:aa:aa:aa:aa:aa')/ipv4/tcp-->'eth_src=00:11:11:11:11:11(mask=00:ff:ff:ff:ff:ff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_src", "mask":"00:ff:ff:ff:ff:ff", "value":"00:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet(src='12:11:11:11:11:11')/ipv6/tcp-->'eth_src=00:11:11:11:11:11(mask=00:ff:ff:ff:ff:ff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_src", "mask":"00:ff:ff:ff:ff:ff", "value":"00:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet(src='12:11:11:11:11:11')/ipv6/tcp-->'eth_src=00:11:11:11:11:11(mask=00:ff:ff:ff:ff:ff),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_src", "mask":"00:ff:ff:ff:ff:ff", "value":"00:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet(src='aa:aa:aa:aa:aa:aa')/ipv6/tcp-->'eth_src=00:11:11:11:11:11(mask=00:ff:ff:ff:ff:ff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_src", "mask":"00:ff:ff:ff:ff:ff", "value":"00:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet(src='12:11:11:11:11:11')/arp-->'eth_src=00:11:11:11:11:11(mask=00:ff:ff:ff:ff:ff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_src", "mask":"00:ff:ff:ff:ff:ff", "value":"00:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet(src='12:11:11:11:11:11')/arp-->'eth_src=00:11:11:11:11:11(mask=00:ff:ff:ff:ff:ff),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_src", "mask":"00:ff:ff:ff:ff:ff", "value":"00:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet(src='aa:aa:aa:aa:aa:aa')/arp-->'eth_src=00:11:11:11:11:11(mask=00:ff:ff:ff:ff:ff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_src", "mask":"00:ff:ff:ff:ff:ff", "value":"00:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 0 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/05_ETH_TYPE.json0000664000175000017500000004517300000000000023270 0ustar00zuulzuul00000000000000[ "match: 05_ETH_TYPE", { "description":"ethernet(ethertype=0x0800)/ipv4/tcp-->'eth_type=0x0800,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet(ethertype=0x0800)/ipv4/tcp-->'eth_type=0x0800,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet(ethertype=0x0800)/ipv4/tcp-->'eth_type=0x0806,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet(ethertype=0x86dd)/ipv6/tcp-->'eth_type=0x86dd,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet(ethertype=0x86dd)/ipv6/tcp-->'eth_type=0x86dd,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet(ethertype=0x86dd)/ipv6/tcp-->'eth_type=0x0806,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet(ethertype=0x0806)/arp-->'eth_type=0x0806,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet(ethertype=0x0806)/arp-->'eth_type=0x0806,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet(ethertype=0x0806)/arp-->'eth_type=0x0800,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 0 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/06_VLAN_VID.json0000664000175000017500000004714700000000000023255 0ustar00zuulzuul00000000000000[ "match: 06_VLAN_VID", { "description":"ethernet/vlan(vid=100)/ipv4/tcp-->'vlan_vid=100,actions=output:2'", "notes":"A value of VLAN_VID (4196) means '100 | OFPVID_PRESENT(0x1000)'.", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "value":4196 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan(vid=100)/ipv4/tcp-->'vlan_vid=100,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "value":4196 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan(vid=203)/ipv4/tcp-->'vlan_vid=100,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "value":4196 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan(vid=100)/ipv6/tcp-->'vlan_vid=100,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "value":4196 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan(vid=100)/ipv6/tcp-->'vlan_vid=100,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "value":4196 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan(vid=203)/ipv6/tcp-->'vlan_vid=100,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "value":4196 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan(vid=100)/arp-->'vlan_vid=100,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "value":4196 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/vlan(vid=100)/arp-->'vlan_vid=100,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "value":4196 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/vlan(vid=203)/arp-->'vlan_vid=100,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "value":4196 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * 30)" ], "table-miss":[ 0 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/06_VLAN_VID_Mask.json0000664000175000017500000005006600000000000024222 0ustar00zuulzuul00000000000000[ "match: 06_VLAN_VID (Mask)", { "description":"ethernet/vlan(vid=100)/ipv4/tcp-->'vlan_vid=96(mask=0xf0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "mask":240, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan(vid=100)/ipv4/tcp-->'vlan_vid=96(mask=0xf0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "mask":240, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan(vid=203)/ipv4/tcp-->'vlan_vid=96(mask=0xf0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "mask":240, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan(vid=100)/ipv6/tcp-->'vlan_vid=96(mask=0xf0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "mask":240, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan(vid=100)/ipv6/tcp-->'vlan_vid=96(mask=0xf0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "mask":240, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan(vid=203)/ipv6/tcp-->'vlan_vid=96(mask=0xf0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "mask":240, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan(vid=100)/arp-->'vlan_vid=96(mask=0xf0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "mask":240, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/vlan(vid=100)/arp-->'vlan_vid=96(mask=0xf0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "mask":240, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/vlan(vid=203)/arp-->'vlan_vid=96(mask=0xf0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "mask":240, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * 30)" ], "table-miss":[ 0 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/07_VLAN_PCP.json0000664000175000017500000005442400000000000023252 0ustar00zuulzuul00000000000000[ "match: 07_VLAN_PCP", { "description":"ethernet/vlan(pcp=3)/ipv4/tcp-->'vlan_pcp=3,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "mask":null, "value":4196 } }, { "OXMTlv":{ "field":"vlan_pcp", "value":3 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan(pcp=3)/ipv4/tcp-->'vlan_pcp=3,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "mask":null, "value":4196 } }, { "OXMTlv":{ "field":"vlan_pcp", "value":3 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan(pcp=5)/ipv4/tcp-->'vlan_pcp=3,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "mask":4096, "value":4096 } }, { "OXMTlv":{ "field":"vlan_pcp", "value":3 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan(pcp=3)/ipv6/tcp-->'vlan_pcp=3,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "mask":null, "value":4196 } }, { "OXMTlv":{ "field":"vlan_pcp", "value":3 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan(pcp=3)/ipv6/tcp-->'vlan_pcp=3,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "mask":null, "value":4196 } }, { "OXMTlv":{ "field":"vlan_pcp", "value":3 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan(pcp=5)/ipv6/tcp-->'vlan_pcp=3,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "mask":4096, "value":4096 } }, { "OXMTlv":{ "field":"vlan_pcp", "value":3 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan(pcp=3)/arp-->'vlan_pcp=3,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "mask":null, "value":4196 } }, { "OXMTlv":{ "field":"vlan_pcp", "value":3 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/vlan(pcp=3)/arp-->'vlan_pcp=3,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "mask":null, "value":4196 } }, { "OXMTlv":{ "field":"vlan_pcp", "value":3 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/vlan(pcp=5)/arp-->'vlan_pcp=3,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "mask":4096, "value":4096 } }, { "OXMTlv":{ "field":"vlan_pcp", "value":3 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * 30)" ], "table-miss":[ 0 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/08_IP_DSCP_IPv4.json0000664000175000017500000011246700000000000023776 0ustar00zuulzuul00000000000000[ "match: 08_IP_DSCP (IPv4)", { "description":"ethernet/ipv4(tos=32)/tcp-->'ip_dscp=8,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4(tos=32)/tcp-->'ip_dscp=8,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4(tos=65)/tcp-->'ip_dscp=8,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv4(tos=32)/tcp-->'ip_dscp=8,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv4(tos=32)/tcp-->'ip_dscp=8,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv4(tos=65)/tcp-->'ip_dscp=8,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv4(tos=32)/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,ip_dscp=8,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv4(tos=32)/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,ip_dscp=8,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv4(tos=65)/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,ip_dscp=8,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv4(tos=32)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ip_dscp=8,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4(tos=32)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ip_dscp=8,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4(tos=65)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ip_dscp=8,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/08_IP_DSCP_IPv6.json0000664000175000017500000011343700000000000023776 0ustar00zuulzuul00000000000000[ "match: 08_IP_DSCP (IPv6)", { "description":"ethernet/ipv6(traffic_class=32)/tcp-->'ip_dscp=8,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6(traffic_class=32)/tcp-->'ip_dscp=8,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6(traffic_class=65)/tcp-->'ip_dscp=8,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv6(traffic_class=32)/tcp-->'ip_dscp=8,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6(traffic_class=32)/tcp-->'ip_dscp=8,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6(traffic_class=65)/tcp-->'ip_dscp=8,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv6(traffic_class=32)/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ip_dscp=8,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6(traffic_class=32)/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ip_dscp=8,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6(traffic_class=65)/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ip_dscp=8,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(traffic_class=32)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ip_dscp=8,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(traffic_class=32)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ip_dscp=8,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(traffic_class=65)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ip_dscp=8,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/09_IP_ECN_IPv4.json0000664000175000017500000011243700000000000023650 0ustar00zuulzuul00000000000000 [ "match: 09_IP_ECN (IPv4)", { "description":"ethernet/ipv4(tos=32)/tcp-->'ip_ecn=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4(tos=32)/tcp-->'ip_ecn=0,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4(tos=65)/tcp-->'ip_ecn=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv4(tos=32)/tcp-->'ip_ecn=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv4(tos=32)/tcp-->'ip_ecn=0,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv4(tos=65)/tcp-->'ip_ecn=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv4(tos=32)/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,ip_ecn=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv4(tos=32)/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,ip_ecn=0,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv4(tos=65)/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,ip_ecn=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv4(tos=32)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ip_ecn=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4(tos=32)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ip_ecn=0,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4(tos=65)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ip_ecn=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/09_IP_ECN_IPv6.json0000664000175000017500000011340600000000000023647 0ustar00zuulzuul00000000000000[ "match: 09_IP_ECN (IPv6)", { "description":"ethernet/ipv6(traffic_class=32)/tcp-->'ip_ecn=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6(traffic_class=32)/tcp-->'ip_ecn=0,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6(traffic_class=65)/tcp-->'ip_ecn=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv6(traffic_class=32)/tcp-->'ip_ecn=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6(traffic_class=32)/tcp-->'ip_ecn=0,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6(traffic_class=65)/tcp-->'ip_ecn=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv6(traffic_class=32)/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ip_ecn=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6(traffic_class=32)/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ip_ecn=0,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6(traffic_class=65)/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ip_ecn=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(traffic_class=32)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ip_ecn=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(traffic_class=32)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ip_ecn=0,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(traffic_class=65)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ip_ecn=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/10_IP_PROTO_IPv4.json0000664000175000017500000011254400000000000024135 0ustar00zuulzuul00000000000000[ "match: 10_IP_PROTO (IPv4)", { "description":"ethernet/ipv4(proto=6)/tcp-->'ip_proto=6,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4(proto=6)/tcp-->'ip_proto=6,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4(proto=6)/tcp-->'ip_proto=17,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv4(proto=6)/tcp-->'ip_proto=6,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv4(proto=6)/tcp-->'ip_proto=6,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv4(proto=6)/tcp-->'ip_proto=17,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv4(proto=6)/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,ip_proto=6,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv4(proto=6)/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,ip_proto=6,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv4(proto=6)/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,ip_proto=17,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv4(proto=6)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ip_proto=6,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4(proto=6)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ip_proto=6,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4(proto=6)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ip_proto=17,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/10_IP_PROTO_IPv6.json0000664000175000017500000011327400000000000024140 0ustar00zuulzuul00000000000000[ "match: 10_IP_PROTO (IPv6)", { "description":"ethernet/ipv6(nxt=6)/tcp-->'ip_proto=6,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6(nxt=6)/tcp-->'ip_proto=6,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6(nxt=6)/tcp-->'ip_proto=17,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv6(nxt=6)/tcp-->'ip_proto=6,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6(nxt=6)/tcp-->'ip_proto=6,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6(nxt=6)/tcp-->'ip_proto=17,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv6(nxt=6)/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ip_proto=6,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6(nxt=6)/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ip_proto=6,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6(nxt=6)/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ip_proto=17,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(nxt=6)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ip_proto=6,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(nxt=6)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ip_proto=6,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(nxt=6)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ip_proto=17,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/11_IPV4_SRC.json0000664000175000017500000011342500000000000023231 0ustar00zuulzuul00000000000000[ "match: 11_IPV4_SRC", { "description":"ethernet/ipv4(src='192.168.10.10')/tcp-->'ipv4_src=192.168.10.10,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4(src='192.168.10.10')/tcp-->'ipv4_src=192.168.10.10,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4(src='10.10.10.10')/tcp-->'ipv4_src=192.168.10.10,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv4(src='192.168.10.10')/tcp-->'ipv4_src=192.168.10.10,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv4(src='192.168.10.10')/tcp-->'ipv4_src=192.168.10.10,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv4(src='10.10.10.10')/tcp-->'ipv4_src=192.168.10.10,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv4(src='192.168.10.10')/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,ipv4_src=192.168.10.10,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv4(src='192.168.10.10')/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,ipv4_src=192.168.10.10,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv4(src='10.10.10.10')/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,ipv4_src=192.168.10.10,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv4(src='192.168.10.10')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv4_src=192.168.10.10,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4(src='192.168.10.10')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv4_src=192.168.10.10,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4(src='10.10.10.10')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv4_src=192.168.10.10,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/11_IPV4_SRC_Mask.json0000664000175000017500000011536400000000000024210 0ustar00zuulzuul00000000000000[ "match: 11_IPV4_SRC (Mask)", { "description":"ethernet/ipv4(src='192.168.10.10')/tcp-->'ipv4_src=192.168.10.0(mask=255.255.255.0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "mask":"255.255.255.0", "value":"192.168.10.0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4(src='192.168.10.10')/tcp-->'ipv4_src=192.168.10.0(mask=255.255.255.0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "mask":"255.255.255.0", "value":"192.168.10.0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4(src='10.10.10.10')/tcp-->'ipv4_src=192.168.10.0(mask=255.255.255.0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "mask":"255.255.255.0", "value":"192.168.10.0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv4(src='192.168.10.10')/tcp-->'ipv4_src=192.168.10.0(mask=255.255.255.0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "mask":"255.255.255.0", "value":"192.168.10.0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv4(src='192.168.10.10')/tcp-->'ipv4_src=192.168.10.0(mask=255.255.255.0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "mask":"255.255.255.0", "value":"192.168.10.0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv4(src='10.10.10.10')/tcp-->'ipv4_src=192.168.10.0(mask=255.255.255.0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "mask":"255.255.255.0", "value":"192.168.10.0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv4(src='192.168.10.10')/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,ipv4_src=192.168.10.0(mask=255.255.255.0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "mask":"255.255.255.0", "value":"192.168.10.0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv4(src='192.168.10.10')/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,ipv4_src=192.168.10.0(mask=255.255.255.0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "mask":"255.255.255.0", "value":"192.168.10.0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv4(src='10.10.10.10')/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,ipv4_src=192.168.10.0(mask=255.255.255.0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "mask":"255.255.255.0", "value":"192.168.10.0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv4(src='192.168.10.10')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv4_src=192.168.10.0(mask=255.255.255.0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "mask":"255.255.255.0", "value":"192.168.10.0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4(src='192.168.10.10')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv4_src=192.168.10.0(mask=255.255.255.0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "mask":"255.255.255.0", "value":"192.168.10.0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4(src='10.10.10.10')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv4_src=192.168.10.0(mask=255.255.255.0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "mask":"255.255.255.0", "value":"192.168.10.0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/12_IPV4_DST.json0000664000175000017500000011342500000000000023235 0ustar00zuulzuul00000000000000[ "match: 12_IPV4_DST", { "description":"ethernet/ipv4(dst='192.168.20.20')/tcp-->'ipv4_dst=192.168.20.20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4(dst='192.168.20.20')/tcp-->'ipv4_dst=192.168.20.20,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4(dst='10.10.20.20')/tcp-->'ipv4_dst=192.168.20.20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv4(dst='192.168.20.20')/tcp-->'ipv4_dst=192.168.20.20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv4(dst='192.168.20.20')/tcp-->'ipv4_dst=192.168.20.20,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv4(dst='10.10.20.20')/tcp-->'ipv4_dst=192.168.20.20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv4(dst='192.168.20.20')/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,ipv4_dst=192.168.20.20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv4(dst='192.168.20.20')/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,ipv4_dst=192.168.20.20,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv4(dst='10.10.20.20')/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,ipv4_dst=192.168.20.20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv4(dst='192.168.20.20')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv4_dst=192.168.20.20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4(dst='192.168.20.20')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv4_dst=192.168.20.20,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4(dst='10.10.20.20')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv4_dst=192.168.20.20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/12_IPV4_DST_Mask.json0000664000175000017500000011536500000000000024215 0ustar00zuulzuul00000000000000 [ "match: 12_IPV4_DST (Mask)", { "description":"ethernet/ipv4(dst='192.168.20.20')/tcp-->'ipv4_dst=192.168.0.20(mask=255.255.0.255),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "mask":"255.255.0.255", "value":"192.168.0.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4(dst='192.168.20.20')/tcp-->'ipv4_dst=192.168.0.20(mask=255.255.0.255),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "mask":"255.255.0.255", "value":"192.168.0.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4(dst='10.10.20.20')/tcp-->'ipv4_dst=192.168.0.20(mask=255.255.0.255),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "mask":"255.255.0.255", "value":"192.168.0.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv4(dst='192.168.20.20')/tcp-->'ipv4_dst=192.168.0.20(mask=255.255.0.255),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "mask":"255.255.0.255", "value":"192.168.0.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv4(dst='192.168.20.20')/tcp-->'ipv4_dst=192.168.0.20(mask=255.255.0.255),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "mask":"255.255.0.255", "value":"192.168.0.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv4(dst='10.10.20.20')/tcp-->'ipv4_dst=192.168.0.20(mask=255.255.0.255),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "mask":"255.255.0.255", "value":"192.168.0.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv4(dst='192.168.20.20')/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,ipv4_dst=192.168.0.20(mask=255.255.0.255),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "mask":"255.255.0.255", "value":"192.168.0.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv4(dst='192.168.20.20')/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,ipv4_dst=192.168.0.20(mask=255.255.0.255),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "mask":"255.255.0.255", "value":"192.168.0.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv4(dst='10.10.20.20')/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,ipv4_dst=192.168.0.20(mask=255.255.0.255),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "mask":"255.255.0.255", "value":"192.168.0.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv4(dst='192.168.20.20')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv4_dst=192.168.0.20(mask=255.255.0.255),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "mask":"255.255.0.255", "value":"192.168.0.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4(dst='192.168.20.20')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv4_dst=192.168.0.20(mask=255.255.0.255),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "mask":"255.255.0.255", "value":"192.168.0.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4(dst='10.10.20.20')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv4_dst=192.168.0.20(mask=255.255.0.255),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "mask":"255.255.0.255", "value":"192.168.0.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/13_TCP_SRC_IPv4.json0000664000175000017500000012112700000000000023777 0ustar00zuulzuul00000000000000[ "match: 13_TCP_SRC (IPv4)", { "description":"ethernet/ipv4/tcp(src_port=11111)-->'tcp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4/tcp(src_port=11111)-->'tcp_src=11111,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4/tcp(src_port=12345)-->'tcp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv4/tcp(src_port=11111)-->'tcp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv4/tcp(src_port=11111)-->'tcp_src=11111,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv4/tcp(src_port=12345)-->'tcp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv4/tcp(src_port=11111)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,tcp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv4/tcp(src_port=11111)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,tcp_src=11111,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv4/tcp(src_port=12345)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,tcp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv4/tcp(src_port=11111)-->'actions=pop_pbb,goto_table:1','table_id:1,tcp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4/tcp(src_port=11111)-->'actions=pop_pbb,goto_table:1','table_id:1,tcp_src=11111,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4/tcp(src_port=12345)-->'actions=pop_pbb,goto_table:1','table_id:1,tcp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/13_TCP_SRC_IPv6.json0000664000175000017500000012170700000000000024005 0ustar00zuulzuul00000000000000[ "match: 13_TCP_SRC (IPv6)", { "description":"ethernet/ipv6/tcp(src_port=11111)-->'tcp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6/tcp(src_port=11111)-->'tcp_src=11111,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6/tcp(src_port=12345)-->'tcp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv6/tcp(src_port=11111)-->'tcp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6/tcp(src_port=11111)-->'tcp_src=11111,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6/tcp(src_port=12345)-->'tcp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv6/tcp(src_port=11111)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,tcp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6/tcp(src_port=11111)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,tcp_src=11111,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6/tcp(src_port=12345)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,tcp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/tcp(src_port=11111)-->'actions=pop_pbb,goto_table:1','table_id:1,tcp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/tcp(src_port=11111)-->'actions=pop_pbb,goto_table:1','table_id:1,tcp_src=11111,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/tcp(src_port=12345)-->'actions=pop_pbb,goto_table:1','table_id:1,tcp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/14_TCP_DST_IPv4.json0000664000175000017500000012106300000000000024002 0ustar00zuulzuul00000000000000[ "match: 14_TCP_DST (IPv4)", { "description":"ethernet/ipv4/tcp(dst_port=2222)-->'tcp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4/tcp(dst_port=2222)-->'tcp_dst=2222,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4/tcp(dst_port=6789)-->'tcp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv4/tcp(dst_port=2222)-->'tcp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv4/tcp(dst_port=2222)-->'tcp_dst=2222,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv4/tcp(dst_port=6789)-->'tcp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv4/tcp(dst_port=2222)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,tcp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv4/tcp(dst_port=2222)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,tcp_dst=2222,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv4/tcp(dst_port=6789)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,tcp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv4/tcp(dst_port=2222)-->'actions=pop_pbb,goto_table:1','table_id:1,tcp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4/tcp(dst_port=2222)-->'actions=pop_pbb,goto_table:1','table_id:1,tcp_dst=2222,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4/tcp(dst_port=6789)-->'actions=pop_pbb,goto_table:1','table_id:1,tcp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/14_TCP_DST_IPv6.json0000664000175000017500000012164300000000000024010 0ustar00zuulzuul00000000000000[ "match: 14_TCP_DST (IPv6)", { "description":"ethernet/ipv6/tcp(dst_port=2222)-->'tcp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6/tcp(dst_port=2222)-->'tcp_dst=2222,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6/tcp(dst_port=6789)-->'tcp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv6/tcp(dst_port=2222)-->'tcp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6/tcp(dst_port=2222)-->'tcp_dst=2222,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6/tcp(dst_port=6789)-->'tcp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv6/tcp(dst_port=2222)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,tcp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6/tcp(dst_port=2222)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,tcp_dst=2222,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6/tcp(dst_port=6789)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,tcp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/tcp(dst_port=2222)-->'actions=pop_pbb,goto_table:1','table_id:1,tcp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/tcp(dst_port=2222)-->'actions=pop_pbb,goto_table:1','table_id:1,tcp_dst=2222,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/tcp(dst_port=6789)-->'actions=pop_pbb,goto_table:1','table_id:1,tcp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/15_UDP_SRC_IPv4.json0000664000175000017500000012010700000000000024000 0ustar00zuulzuul00000000000000[ "match: 15_UDP_SRC (IPv4)", { "description":"ethernet/ipv4/udp(src_port=11111)-->'udp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4/udp(src_port=11111)-->'udp_src=11111,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4/udp(src_port=12345)-->'udp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=17, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "udp(dst_port=6789, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv4/udp(src_port=11111)-->'udp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv4/udp(src_port=11111)-->'udp_src=11111,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv4/udp(src_port=12345)-->'udp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=17, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "udp(dst_port=6789, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv4/udp(src_port=11111)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,udp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv4/udp(src_port=11111)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,udp_src=11111,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv4/udp(src_port=12345)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,udp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv4(tos=65, proto=17, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "udp(dst_port=6789, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv4/udp(src_port=11111)-->'actions=pop_pbb,goto_table:1','table_id:1,udp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4/udp(src_port=11111)-->'actions=pop_pbb,goto_table:1','table_id:1,udp_src=11111,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4/udp(src_port=12345)-->'actions=pop_pbb,goto_table:1','table_id:1,udp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=17, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "udp(dst_port=6789, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/15_UDP_SRC_IPv6.json0000664000175000017500000012066700000000000024015 0ustar00zuulzuul00000000000000[ "match: 15_UDP_SRC (IPv6)", { "description":"ethernet/ipv6/udp(src_port=11111)-->'udp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6/udp(src_port=11111)-->'udp_src=11111,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6/udp(src_port=12345)-->'udp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=17, hop_limit=127, traffic_class=65)", "udp(dst_port=6789, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv6/udp(src_port=11111)-->'udp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6/udp(src_port=11111)-->'udp_src=11111,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6/udp(src_port=12345)-->'udp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=17, hop_limit=127, traffic_class=65)", "udp(dst_port=6789, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv6/udp(src_port=11111)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,udp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6/udp(src_port=11111)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,udp_src=11111,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6/udp(src_port=12345)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,udp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=17, hop_limit=127, traffic_class=65)", "udp(dst_port=6789, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/udp(src_port=11111)-->'actions=pop_pbb,goto_table:1','table_id:1,udp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/udp(src_port=11111)-->'actions=pop_pbb,goto_table:1','table_id:1,udp_src=11111,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/udp(src_port=12345)-->'actions=pop_pbb,goto_table:1','table_id:1,udp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=17, hop_limit=127, traffic_class=65)", "udp(dst_port=6789, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/16_UDP_DST_IPv4.json0000664000175000017500000012004300000000000024003 0ustar00zuulzuul00000000000000[ "match: 16_UDP_DST (IPv4)", { "description":"ethernet/ipv4/udp(dst_port=2222)-->'udp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4/udp(dst_port=2222)-->'udp_dst=2222,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4/udp(dst_port=6789)-->'udp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=17, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "udp(dst_port=6789, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv4/udp(dst_port=2222)-->'udp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv4/udp(dst_port=2222)-->'udp_dst=2222,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv4/udp(dst_port=6789)-->'udp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=17, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "udp(dst_port=6789, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv4/udp(dst_port=2222)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,udp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv4/udp(dst_port=2222)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,udp_dst=2222,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv4/udp(dst_port=6789)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,udp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv4(tos=65, proto=17, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "udp(dst_port=6789, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv4/udp(dst_port=2222)-->'actions=pop_pbb,goto_table:1','table_id:1,udp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4/udp(dst_port=2222)-->'actions=pop_pbb,goto_table:1','table_id:1,udp_dst=2222,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4/udp(dst_port=6789)-->'actions=pop_pbb,goto_table:1','table_id:1,udp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=17, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "udp(dst_port=6789, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/16_UDP_DST_IPv6.json0000664000175000017500000012062300000000000024011 0ustar00zuulzuul00000000000000[ "match: 16_UDP_DST (IPv6)", { "description":"ethernet/ipv6/udp(dst_port=2222)-->'udp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6/udp(dst_port=2222)-->'udp_dst=2222,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6/udp(dst_port=6789)-->'udp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=17, hop_limit=127, traffic_class=65)", "udp(dst_port=6789, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv6/udp(dst_port=2222)-->'udp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6/udp(dst_port=2222)-->'udp_dst=2222,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6/udp(dst_port=6789)-->'udp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=17, hop_limit=127, traffic_class=65)", "udp(dst_port=6789, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv6/udp(dst_port=2222)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,udp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6/udp(dst_port=2222)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,udp_dst=2222,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6/udp(dst_port=6789)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,udp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=17, hop_limit=127, traffic_class=65)", "udp(dst_port=6789, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/udp(dst_port=2222)-->'actions=pop_pbb,goto_table:1','table_id:1,udp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/udp(dst_port=2222)-->'actions=pop_pbb,goto_table:1','table_id:1,udp_dst=2222,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/udp(dst_port=6789)-->'actions=pop_pbb,goto_table:1','table_id:1,udp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=17, hop_limit=127, traffic_class=65)", "udp(dst_port=6789, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/17_SCTP_SRC_IPv4.json0000664000175000017500000011441400000000000024127 0ustar00zuulzuul00000000000000[ "match: 17_SCTP_SRC (IPv4)", { "description":"ethernet/ipv4/sctp(src_port=11111)-->'sctp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/ipv4/sctp(src_port=11111)-->'sctp_src=11111,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/ipv4/sctp(src_port=12345)-->'sctp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=132, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=6789, src_port=12345)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv4/sctp(src_port=11111)-->'sctp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/vlan/ipv4/sctp(src_port=11111)-->'sctp_src=11111,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/vlan/ipv4/sctp(src_port=12345)-->'sctp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=132, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=6789, src_port=12345)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv4/sctp(src_port=11111)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,sctp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/mpls/ipv4/sctp(src_port=11111)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,sctp_src=11111,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/mpls/ipv4/sctp(src_port=12345)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,sctp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv4(tos=65, proto=132, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=6789, src_port=12345)" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv4/sctp(src_port=11111)-->'actions=pop_pbb,goto_table:1','table_id:1,sctp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4/sctp(src_port=11111)-->'actions=pop_pbb,goto_table:1','table_id:1,sctp_src=11111,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4/sctp(src_port=12345)-->'actions=pop_pbb,goto_table:1','table_id:1,sctp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=132, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=6789, src_port=12345)" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/17_SCTP_SRC_IPv6.json0000664000175000017500000011517400000000000024135 0ustar00zuulzuul00000000000000[ "match: 17_SCTP_SRC (IPv6)", { "description":"ethernet/ipv6/sctp(src_port=11111)-->'sctp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/ipv6/sctp(src_port=11111)-->'sctp_src=11111,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/ipv6/sctp(src_port=12345)-->'sctp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=132, hop_limit=127, traffic_class=65)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=6789, src_port=12345)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv6/sctp(src_port=11111)-->'sctp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/vlan/ipv6/sctp(src_port=11111)-->'sctp_src=11111,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/vlan/ipv6/sctp(src_port=12345)-->'sctp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=132, hop_limit=127, traffic_class=65)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=6789, src_port=12345)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv6/sctp(src_port=11111)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,sctp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/mpls/ipv6/sctp(src_port=11111)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,sctp_src=11111,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/mpls/ipv6/sctp(src_port=12345)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,sctp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=132, hop_limit=127, traffic_class=65)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=6789, src_port=12345)" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/sctp(src_port=11111)-->'actions=pop_pbb,goto_table:1','table_id:1,sctp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/sctp(src_port=11111)-->'actions=pop_pbb,goto_table:1','table_id:1,sctp_src=11111,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/sctp(src_port=12345)-->'actions=pop_pbb,goto_table:1','table_id:1,sctp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=132, hop_limit=127, traffic_class=65)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=6789, src_port=12345)" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/18_SCTP_DST_IPv4.json0000664000175000017500000011435000000000000024132 0ustar00zuulzuul00000000000000[ "match: 18_SCTP_DST (IPv4)", { "description":"ethernet/ipv4/sctp(dst_port=2222)-->'sctp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/ipv4/sctp(dst_port=2222)-->'sctp_dst=2222,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/ipv4/sctp(dst_port=6789)-->'sctp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=132, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=6789, src_port=12345)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv4/sctp(dst_port=2222)-->'sctp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/vlan/ipv4/sctp(dst_port=2222)-->'sctp_dst=2222,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/vlan/ipv4/sctp(dst_port=6789)-->'sctp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=132, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=6789, src_port=12345)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv4/sctp(dst_port=2222)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,sctp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/mpls/ipv4/sctp(dst_port=2222)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,sctp_dst=2222,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/mpls/ipv4/sctp(dst_port=6789)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,sctp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv4(tos=65, proto=132, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=6789, src_port=12345)" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv4/sctp(dst_port=2222)-->'actions=pop_pbb,goto_table:1','table_id:1,sctp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4/sctp(dst_port=2222)-->'actions=pop_pbb,goto_table:1','table_id:1,sctp_dst=2222,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4/sctp(dst_port=6789)-->'actions=pop_pbb,goto_table:1','table_id:1,sctp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=132, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=6789, src_port=12345)" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/18_SCTP_DST_IPv6.json0000664000175000017500000011513000000000000024131 0ustar00zuulzuul00000000000000[ "match: 18_SCTP_DST (IPv6)", { "description":"ethernet/ipv6/sctp(dst_port=2222)-->'sctp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/ipv6/sctp(dst_port=2222)-->'sctp_dst=2222,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/ipv6/sctp(dst_port=6789)-->'sctp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=132, hop_limit=127, traffic_class=65)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=6789, src_port=12345)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv6/sctp(dst_port=2222)-->'sctp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/vlan/ipv6/sctp(dst_port=2222)-->'sctp_dst=2222,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/vlan/ipv6/sctp(dst_port=6789)-->'sctp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=132, hop_limit=127, traffic_class=65)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=6789, src_port=12345)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv6/sctp(dst_port=2222)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,sctp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/mpls/ipv6/sctp(dst_port=2222)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,sctp_dst=2222,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/mpls/ipv6/sctp(dst_port=6789)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,sctp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=132, hop_limit=127, traffic_class=65)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=6789, src_port=12345)" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/sctp(dst_port=2222)-->'actions=pop_pbb,goto_table:1','table_id:1,sctp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/sctp(dst_port=2222)-->'actions=pop_pbb,goto_table:1','table_id:1,sctp_dst=2222,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/sctp(dst_port=6789)-->'actions=pop_pbb,goto_table:1','table_id:1,sctp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=132, hop_limit=127, traffic_class=65)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=6789, src_port=12345)" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/19_ICMPV4_TYPE.json0000664000175000017500000011406400000000000023613 0ustar00zuulzuul00000000000000[ "match: 19_ICMPV4_TYPE", { "description":"ethernet/ipv4/icmp(type=8)-->'icmpv4_type=8,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_type", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ] } ] }, { "description":"ethernet/ipv4/icmp(type=8)-->'icmpv4_type=8,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_type", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ] } ] }, { "description":"ethernet/ipv4/icmp(type=3)-->'icmpv4_type=8,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_type", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=1, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "icmp(code=1,csum=0,data=dest_unreach(data=b'\\xd3]\\xb7\\xe3\\x9e\\xbb\\xf3\\xd6\\x9bq\\xd7\\x9f\\x82\\x18\\xa3\\x92Y\\xa7\\xa2\\x9a\\xab\\xb2\\xdb\\xaf\\xc3\\x1c\\xb3\\x00\\x10\\x83\\x10Q\\x87 \\x92\\x8b'),type_=3)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv4/icmp(type=8)-->'icmpv4_type=8,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_type", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ] } ] }, { "description":"ethernet/vlan/ipv4/icmp(type=8)-->'icmpv4_type=8,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_type", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ] } ] }, { "description":"ethernet/vlan/ipv4/icmp(type=3)-->'icmpv4_type=8,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_type", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=1, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "icmp(code=1,csum=0,data=dest_unreach(data=b'\\xd3]\\xb7\\xe3\\x9e\\xbb\\xf3\\xd6\\x9bq\\xd7\\x9f\\x82\\x18\\xa3\\x92Y\\xa7\\xa2\\x9a\\xab\\xb2\\xdb\\xaf\\xc3\\x1c\\xb3\\x00\\x10\\x83\\x10Q\\x87 \\x92\\x8b'),type_=3)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv4/icmp(type=8)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,icmpv4_type=8,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_type", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ] } ] }, { "description":"ethernet/mpls/ipv4/icmp(type=8)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,icmpv4_type=8,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_type", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ] } ] }, { "description":"ethernet/mpls/ipv4/icmp(type=3)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,icmpv4_type=8,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_type", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv4(tos=65, proto=1, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "icmp(code=1,csum=0,data=dest_unreach(data=b'\\xd3]\\xb7\\xe3\\x9e\\xbb\\xf3\\xd6\\x9bq\\xd7\\x9f\\x82\\x18\\xa3\\x92Y\\xa7\\xa2\\x9a\\xab\\xb2\\xdb\\xaf\\xc3\\x1c\\xb3\\x00\\x10\\x83\\x10Q\\x87 \\x92\\x8b'),type_=3)" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv4/icmp(type=8)-->'actions=pop_pbb,goto_table:1','table_id:1,icmpv4_type=8,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_type", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4/icmp(type=8)-->'actions=pop_pbb,goto_table:1','table_id:1,icmpv4_type=8,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_type", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4/icmp(type=3)-->'actions=pop_pbb,goto_table:1','table_id:1,icmpv4_type=8,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_type", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=1, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "icmp(code=1,csum=0,data=dest_unreach(data=b'\\xd3]\\xb7\\xe3\\x9e\\xbb\\xf3\\xd6\\x9bq\\xd7\\x9f\\x82\\x18\\xa3\\x92Y\\xa7\\xa2\\x9a\\xab\\xb2\\xdb\\xaf\\xc3\\x1c\\xb3\\x00\\x10\\x83\\x10Q\\x87 \\x92\\x8b'),type_=3)" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/20_ICMPV4_CODE.json0000664000175000017500000011406400000000000023534 0ustar00zuulzuul00000000000000[ "match: 20_ICMPV4_CODE", { "description":"ethernet/ipv4/icmp(code=0)-->'icmpv4_code=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ] } ] }, { "description":"ethernet/ipv4/icmp(code=0)-->'icmpv4_code=0,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ] } ] }, { "description":"ethernet/ipv4/icmp(code=1)-->'icmpv4_code=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=1, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "icmp(code=1,csum=0,data=dest_unreach(data=b'\\xd3]\\xb7\\xe3\\x9e\\xbb\\xf3\\xd6\\x9bq\\xd7\\x9f\\x82\\x18\\xa3\\x92Y\\xa7\\xa2\\x9a\\xab\\xb2\\xdb\\xaf\\xc3\\x1c\\xb3\\x00\\x10\\x83\\x10Q\\x87 \\x92\\x8b'),type_=3)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv4/icmp(code=0)-->'icmpv4_code=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ] } ] }, { "description":"ethernet/vlan/ipv4/icmp(code=0)-->'icmpv4_code=0,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ] } ] }, { "description":"ethernet/vlan/ipv4/icmp(code=1)-->'icmpv4_code=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=1, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "icmp(code=1,csum=0,data=dest_unreach(data=b'\\xd3]\\xb7\\xe3\\x9e\\xbb\\xf3\\xd6\\x9bq\\xd7\\x9f\\x82\\x18\\xa3\\x92Y\\xa7\\xa2\\x9a\\xab\\xb2\\xdb\\xaf\\xc3\\x1c\\xb3\\x00\\x10\\x83\\x10Q\\x87 \\x92\\x8b'),type_=3)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv4/icmp(code=0)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,icmpv4_code=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ] } ] }, { "description":"ethernet/mpls/ipv4/icmp(code=0)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,icmpv4_code=0,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ] } ] }, { "description":"ethernet/mpls/ipv4/icmp(code=1)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,icmpv4_code=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv4(tos=65, proto=1, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "icmp(code=1,csum=0,data=dest_unreach(data=b'\\xd3]\\xb7\\xe3\\x9e\\xbb\\xf3\\xd6\\x9bq\\xd7\\x9f\\x82\\x18\\xa3\\x92Y\\xa7\\xa2\\x9a\\xab\\xb2\\xdb\\xaf\\xc3\\x1c\\xb3\\x00\\x10\\x83\\x10Q\\x87 \\x92\\x8b'),type_=3)" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv4/icmp(code=0)-->'actions=pop_pbb,goto_table:1','table_id:1,icmpv4_code=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4/icmp(code=0)-->'actions=pop_pbb,goto_table:1','table_id:1,icmpv4_code=0,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4/icmp(code=1)-->'actions=pop_pbb,goto_table:1','table_id:1,icmpv4_code=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=1, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "icmp(code=1,csum=0,data=dest_unreach(data=b'\\xd3]\\xb7\\xe3\\x9e\\xbb\\xf3\\xd6\\x9bq\\xd7\\x9f\\x82\\x18\\xa3\\x92Y\\xa7\\xa2\\x9a\\xab\\xb2\\xdb\\xaf\\xc3\\x1c\\xb3\\x00\\x10\\x83\\x10Q\\x87 \\x92\\x8b'),type_=3)" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/21_ARP_OP.json0000664000175000017500000010375000000000000023021 0ustar00zuulzuul00000000000000[ "match: 21_ARP_OP", { "description":"ethernet/arp(opcode=1)-->'arp_op=1,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_op", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp(opcode=1)-->'arp_op=1,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_op", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp(opcode=2)-->'arp_op=1,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_op", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/arp(opcode=1)-->'arp_op=1,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_op", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/vlan/arp(opcode=1)-->'arp_op=1,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_op", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/vlan/arp(opcode=2)-->'arp_op=1,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_op", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * 30)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/arp(opcode=1)-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_op=1,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_op", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/mpls/arp(opcode=1)-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_op=1,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_op", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/mpls/arp(opcode=2)-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_op=1,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_op", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/arp(opcode=1)-->'actions=pop_pbb,goto_table:1','table_id:1,arp_op=1,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_op", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/itag/ethernet/arp(opcode=1)-->'actions=pop_pbb,goto_table:1','table_id:1,arp_op=1,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_op", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/itag/ethernet/arp(opcode=2)-->'actions=pop_pbb,goto_table:1','table_id:1,arp_op=1,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_op", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/22_ARP_SPA.json0000664000175000017500000010473100000000000023127 0ustar00zuulzuul00000000000000[ "match: 22_ARP_SPA", { "description":"ethernet/arp(src_ip='192.168.10.10')-->'arp_spa=192.168.10.10,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp(src_ip='192.168.10.10')-->'arp_spa=192.168.10.10,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp(src_ip='10.10.10.10')-->'arp_spa=192.168.10.10,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/arp(src_ip='192.168.10.10')-->'arp_spa=192.168.10.10,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/vlan/arp(src_ip='192.168.10.10')-->'arp_spa=192.168.10.10,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/vlan/arp(src_ip='10.10.10.10')-->'arp_spa=192.168.10.10,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * 30)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/arp(src_ip='192.168.10.10')-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_spa=192.168.10.10,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/mpls/arp(src_ip='192.168.10.10')-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_spa=192.168.10.10,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/mpls/arp(src_ip='10.10.10.10')-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_spa=192.168.10.10,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/arp(src_ip='192.168.10.10')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_spa=192.168.10.10,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/itag/ethernet/arp(src_ip='192.168.10.10')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_spa=192.168.10.10,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/itag/ethernet/arp(src_ip='10.10.10.10')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_spa=192.168.10.10,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/22_ARP_SPA_Mask.json0000664000175000017500000010667000000000000024106 0ustar00zuulzuul00000000000000[ "match: 22_ARP_SPA (Mask)", { "description":"ethernet/arp(src_ip='192.168.10.10')-->'arp_spa=192.168.10.0(mask=255.255.255.0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "mask":"255.255.255.0", "value":"192.168.10.0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp(src_ip='192.168.10.10')-->'arp_spa=192.168.10.0(mask=255.255.255.0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "mask":"255.255.255.0", "value":"192.168.10.0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp(src_ip='10.10.10.10')-->'arp_spa=192.168.10.0(mask=255.255.255.0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "mask":"255.255.255.0", "value":"192.168.10.0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/arp(src_ip='192.168.10.10')-->'arp_spa=192.168.10.0(mask=255.255.255.0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "mask":"255.255.255.0", "value":"192.168.10.0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/vlan/arp(src_ip='192.168.10.10')-->'arp_spa=192.168.10.0(mask=255.255.255.0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "mask":"255.255.255.0", "value":"192.168.10.0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/vlan/arp(src_ip='10.10.10.10')-->'arp_spa=192.168.10.0(mask=255.255.255.0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "mask":"255.255.255.0", "value":"192.168.10.0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * 30)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/arp(src_ip='192.168.10.10')-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_spa=192.168.10.0(mask=255.255.255.0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "mask":"255.255.255.0", "value":"192.168.10.0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/mpls/arp(src_ip='192.168.10.10')-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_spa=192.168.10.0(mask=255.255.255.0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "mask":"255.255.255.0", "value":"192.168.10.0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/mpls/arp(src_ip='10.10.10.10')-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_spa=192.168.10.0(mask=255.255.255.0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "mask":"255.255.255.0", "value":"192.168.10.0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/arp(src_ip='192.168.10.10')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_spa=192.168.10.0(mask=255.255.255.0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "mask":"255.255.255.0", "value":"192.168.10.0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/itag/ethernet/arp(src_ip='192.168.10.10')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_spa=192.168.10.0(mask=255.255.255.0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "mask":"255.255.255.0", "value":"192.168.10.0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/itag/ethernet/arp(src_ip='10.10.10.10')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_spa=192.168.10.0(mask=255.255.255.0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "mask":"255.255.255.0", "value":"192.168.10.0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/23_ARP_TPA.json0000664000175000017500000010473100000000000023131 0ustar00zuulzuul00000000000000[ "match: 23_ARP_TPA", { "description":"ethernet/arp(dst_ip='192.168.20.20')-->'arp_tpa=192.168.20.20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp(dst_ip='192.168.20.20')-->'arp_tpa=192.168.20.20,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp(dst_ip='10.10.20.20')-->'arp_tpa=192.168.20.20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/arp(dst_ip='192.168.20.20')-->'arp_tpa=192.168.20.20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/vlan/arp(dst_ip='192.168.20.20')-->'arp_tpa=192.168.20.20,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/vlan/arp(dst_ip='10.10.20.20')-->'arp_tpa=192.168.20.20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * 30)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/arp(dst_ip='192.168.20.20')-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_tpa=192.168.20.20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/mpls/arp(dst_ip='192.168.20.20')-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_tpa=192.168.20.20,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/mpls/arp(dst_ip='10.10.20.20')-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_tpa=192.168.20.20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/arp(dst_ip='192.168.20.20')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_tpa=192.168.20.20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/itag/ethernet/arp(dst_ip='192.168.20.20')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_tpa=192.168.20.20,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/itag/ethernet/arp(dst_ip='10.10.20.20')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_tpa=192.168.20.20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/23_ARP_TPA_Mask.json0000664000175000017500000010667000000000000024110 0ustar00zuulzuul00000000000000[ "match: 23_ARP_TPA (Mask)", { "description":"ethernet/arp(dst_ip='192.168.20.20')-->'arp_tpa=192.168.0.20(mask=255.255.0.255),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "mask":"255.255.0.255", "value":"192.168.0.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp(dst_ip='192.168.20.20')-->'arp_tpa=192.168.0.20(mask=255.255.0.255),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "mask":"255.255.0.255", "value":"192.168.0.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp(dst_ip='10.10.20.20')-->'arp_tpa=192.168.0.20(mask=255.255.0.255),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "mask":"255.255.0.255", "value":"192.168.0.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/arp(dst_ip='192.168.20.20')-->'arp_tpa=192.168.0.20(mask=255.255.0.255),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "mask":"255.255.0.255", "value":"192.168.0.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/vlan/arp(dst_ip='192.168.20.20')-->'arp_tpa=192.168.0.20(mask=255.255.0.255),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "mask":"255.255.0.255", "value":"192.168.0.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/vlan/arp(dst_ip='10.10.20.20')-->'arp_tpa=192.168.0.20(mask=255.255.0.255),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "mask":"255.255.0.255", "value":"192.168.0.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * 30)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/arp(dst_ip='192.168.20.20')-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_tpa=192.168.0.20(mask=255.255.0.255),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "mask":"255.255.0.255", "value":"192.168.0.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/mpls/arp(dst_ip='192.168.20.20')-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_tpa=192.168.0.20(mask=255.255.0.255),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "mask":"255.255.0.255", "value":"192.168.0.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/mpls/arp(dst_ip='10.10.20.20')-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_tpa=192.168.0.20(mask=255.255.0.255),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "mask":"255.255.0.255", "value":"192.168.0.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/arp(dst_ip='192.168.20.20')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_tpa=192.168.0.20(mask=255.255.0.255),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "mask":"255.255.0.255", "value":"192.168.0.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/itag/ethernet/arp(dst_ip='192.168.20.20')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_tpa=192.168.0.20(mask=255.255.0.255),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "mask":"255.255.0.255", "value":"192.168.0.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/itag/ethernet/arp(dst_ip='10.10.20.20')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_tpa=192.168.0.20(mask=255.255.0.255),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "mask":"255.255.0.255", "value":"192.168.0.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/24_ARP_SHA.json0000664000175000017500000010517500000000000023124 0ustar00zuulzuul00000000000000[ "match: 24_ARP_SHA", { "description":"ethernet/arp(src_mac='12:11:11:11:11:11')-->'arp_sha=12:11:11:11:11:11,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp(src_mac='12:11:11:11:11:11')-->'arp_sha=12:11:11:11:11:11,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp(src_mac='aa:aa:aa:aa:aa:aa')-->'arp_sha=12:11:11:11:11:11,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/arp(src_mac='12:11:11:11:11:11')-->'arp_sha=12:11:11:11:11:11,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/vlan/arp(src_mac='12:11:11:11:11:11')-->'arp_sha=12:11:11:11:11:11,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/vlan/arp(src_mac='aa:aa:aa:aa:aa:aa')-->'arp_sha=12:11:11:11:11:11,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * 30)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/arp(src_mac='12:11:11:11:11:11')-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_sha=12:11:11:11:11:11,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/mpls/arp(src_mac='12:11:11:11:11:11')-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_sha=12:11:11:11:11:11,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/mpls/arp(src_mac='aa:aa:aa:aa:aa:aa')-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_sha=12:11:11:11:11:11,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/arp(src_mac='12:11:11:11:11:11')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_sha=12:11:11:11:11:11,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/itag/ethernet/arp(src_mac='12:11:11:11:11:11')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_sha=12:11:11:11:11:11,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/itag/ethernet/arp(src_mac='aa:aa:aa:aa:aa:aa')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_sha=12:11:11:11:11:11,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/24_ARP_SHA_Mask.json0000664000175000017500000010732400000000000024075 0ustar00zuulzuul00000000000000[ "match: 24_ARP_SHA (Mask)", { "description":"ethernet/arp(src_mac='12:11:11:11:11:11')-->'arp_sha=12:11:11:00:11:11(mask=ff:ff:ff:00:ff:ff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "mask":"ff:ff:ff:00:ff:ff", "value":"12:11:11:00:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp(src_mac='12:11:11:11:11:11')-->'arp_sha=12:11:11:00:11:11(mask=ff:ff:ff:00:ff:ff),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "mask":"ff:ff:ff:00:ff:ff", "value":"12:11:11:00:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp(src_mac='aa:aa:aa:aa:aa:aa')-->'arp_sha=12:11:11:00:11:11(mask=ff:ff:ff:00:ff:ff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "mask":"ff:ff:ff:00:ff:ff", "value":"12:11:11:00:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/arp(src_mac='12:11:11:11:11:11')-->'arp_sha=12:11:11:00:11:11(mask=ff:ff:ff:00:ff:ff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "mask":"ff:ff:ff:00:ff:ff", "value":"12:11:11:00:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/vlan/arp(src_mac='12:11:11:11:11:11')-->'arp_sha=12:11:11:00:11:11(mask=ff:ff:ff:00:ff:ff),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "mask":"ff:ff:ff:00:ff:ff", "value":"12:11:11:00:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/vlan/arp(src_mac='aa:aa:aa:aa:aa:aa')-->'arp_sha=12:11:11:00:11:11(mask=ff:ff:ff:00:ff:ff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "mask":"ff:ff:ff:00:ff:ff", "value":"12:11:11:00:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * 30)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/arp(src_mac='12:11:11:11:11:11')-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_sha=12:11:11:00:11:11(mask=ff:ff:ff:00:ff:ff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "mask":"ff:ff:ff:00:ff:ff", "value":"12:11:11:00:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/mpls/arp(src_mac='12:11:11:11:11:11')-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_sha=12:11:11:00:11:11(mask=ff:ff:ff:00:ff:ff),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "mask":"ff:ff:ff:00:ff:ff", "value":"12:11:11:00:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/mpls/arp(src_mac='aa:aa:aa:aa:aa:aa')-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_sha=12:11:11:00:11:11(mask=ff:ff:ff:00:ff:ff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "mask":"ff:ff:ff:00:ff:ff", "value":"12:11:11:00:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/arp(src_mac='12:11:11:11:11:11')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_sha=12:11:11:00:11:11(mask=ff:ff:ff:00:ff:ff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "mask":"ff:ff:ff:00:ff:ff", "value":"12:11:11:00:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/itag/ethernet/arp(src_mac='12:11:11:11:11:11')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_sha=12:11:11:00:11:11(mask=ff:ff:ff:00:ff:ff),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "mask":"ff:ff:ff:00:ff:ff", "value":"12:11:11:00:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/itag/ethernet/arp(src_mac='aa:aa:aa:aa:aa:aa')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_sha=12:11:11:00:11:11(mask=ff:ff:ff:00:ff:ff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "mask":"ff:ff:ff:00:ff:ff", "value":"12:11:11:00:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/25_ARP_THA.json0000664000175000017500000010517500000000000023126 0ustar00zuulzuul00000000000000[ "match: 25_ARP_THA", { "description":"ethernet/arp(dst_mac='22:22:22:22:22:22')-->'arp_tha=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp(dst_mac='22:22:22:22:22:22')-->'arp_tha=22:22:22:22:22:22,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp(dst_mac='ba:bb:bb:bb:bb:bb')-->'arp_tha=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/arp(dst_mac='22:22:22:22:22:22')-->'arp_tha=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/vlan/arp(dst_mac='22:22:22:22:22:22')-->'arp_tha=22:22:22:22:22:22,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/vlan/arp(dst_mac='ba:bb:bb:bb:bb:bb')-->'arp_tha=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * 30)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/arp(dst_mac='22:22:22:22:22:22')-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_tha=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/mpls/arp(dst_mac='22:22:22:22:22:22')-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_tha=22:22:22:22:22:22,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/mpls/arp(dst_mac='ba:bb:bb:bb:bb:bb')-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_tha=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/arp(dst_mac='22:22:22:22:22:22')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_tha=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/itag/ethernet/arp(dst_mac='22:22:22:22:22:22')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_tha=22:22:22:22:22:22,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/itag/ethernet/arp(dst_mac='ba:bb:bb:bb:bb:bb')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_tha=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/25_ARP_THA_Mask.json0000664000175000017500000010732400000000000024077 0ustar00zuulzuul00000000000000[ "match: 25_ARP_THA (Mask)", { "description":"ethernet/arp(dst_mac='22:22:22:22:22:22')-->'arp_tha=22:22:00:22:22:22(mask=ff:ff:00:ff:ff:ff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "mask":"ff:ff:00:ff:ff:ff", "value":"22:22:00:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp(dst_mac='22:22:22:22:22:22')-->'arp_tha=22:22:00:22:22:22(mask=ff:ff:00:ff:ff:ff),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "mask":"ff:ff:00:ff:ff:ff", "value":"22:22:00:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp(dst_mac='ba:bb:bb:bb:bb:bb')-->'arp_tha=22:22:00:22:22:22(mask=ff:ff:00:ff:ff:ff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "mask":"ff:ff:00:ff:ff:ff", "value":"22:22:00:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/arp(dst_mac='22:22:22:22:22:22')-->'arp_tha=22:22:00:22:22:22(mask=ff:ff:00:ff:ff:ff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "mask":"ff:ff:00:ff:ff:ff", "value":"22:22:00:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/vlan/arp(dst_mac='22:22:22:22:22:22')-->'arp_tha=22:22:00:22:22:22(mask=ff:ff:00:ff:ff:ff),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "mask":"ff:ff:00:ff:ff:ff", "value":"22:22:00:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/vlan/arp(dst_mac='ba:bb:bb:bb:bb:bb')-->'arp_tha=22:22:00:22:22:22(mask=ff:ff:00:ff:ff:ff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "mask":"ff:ff:00:ff:ff:ff", "value":"22:22:00:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * 30)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/arp(dst_mac='22:22:22:22:22:22')-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_tha=22:22:00:22:22:22(mask=ff:ff:00:ff:ff:ff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "mask":"ff:ff:00:ff:ff:ff", "value":"22:22:00:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/mpls/arp(dst_mac='22:22:22:22:22:22')-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_tha=22:22:00:22:22:22(mask=ff:ff:00:ff:ff:ff),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "mask":"ff:ff:00:ff:ff:ff", "value":"22:22:00:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/mpls/arp(dst_mac='ba:bb:bb:bb:bb:bb')-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_tha=22:22:00:22:22:22(mask=ff:ff:00:ff:ff:ff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "mask":"ff:ff:00:ff:ff:ff", "value":"22:22:00:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/arp(dst_mac='22:22:22:22:22:22')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_tha=22:22:00:22:22:22(mask=ff:ff:00:ff:ff:ff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "mask":"ff:ff:00:ff:ff:ff", "value":"22:22:00:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/itag/ethernet/arp(dst_mac='22:22:22:22:22:22')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_tha=22:22:00:22:22:22(mask=ff:ff:00:ff:ff:ff),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "mask":"ff:ff:00:ff:ff:ff", "value":"22:22:00:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/itag/ethernet/arp(dst_mac='ba:bb:bb:bb:bb:bb')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_tha=22:22:00:22:22:22(mask=ff:ff:00:ff:ff:ff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "mask":"ff:ff:00:ff:ff:ff", "value":"22:22:00:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/26_IPV6_SRC.json0000664000175000017500000011362100000000000023237 0ustar00zuulzuul00000000000000[ "match: 26_IPV6_SRC", { "description":"ethernet/ipv6(src='10::10')/tcp-->'ipv6_src=10::10,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "value":"10::10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6(src='10::10')/tcp-->'ipv6_src=10::10,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "value":"10::10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6(src='a0::a0')/tcp-->'ipv6_src=10::10,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "value":"10::10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv6(src='10::10')/tcp-->'ipv6_src=10::10,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "value":"10::10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6(src='10::10')/tcp-->'ipv6_src=10::10,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "value":"10::10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6(src='a0::a0')/tcp-->'ipv6_src=10::10,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "value":"10::10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv6(src='10::10')/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_src=10::10,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "value":"10::10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6(src='10::10')/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_src=10::10,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "value":"10::10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6(src='a0::a0')/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_src=10::10,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "value":"10::10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(src='10::10')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_src=10::10,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "value":"10::10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(src='10::10')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_src=10::10,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "value":"10::10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(src='a0::a0')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_src=10::10,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "value":"10::10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/26_IPV6_SRC_Mask.json0000664000175000017500000011663000000000000024215 0ustar00zuulzuul00000000000000[ "match: 26_IPV6_SRC (Mask)", { "description":"ethernet/ipv6(src='10::10')/tcp-->'ipv6_src=10::0(mask=ffff:ffff:ffff:ffff:ffff:ffff:ffff:0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "mask":"ffff:ffff:ffff:ffff:ffff:ffff:ffff:0", "value":"10::0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6(src='10::10')/tcp-->'ipv6_src=10::0(mask=ffff:ffff:ffff:ffff:ffff:ffff:ffff:0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "mask":"ffff:ffff:ffff:ffff:ffff:ffff:ffff:0", "value":"10::0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6(src='a0::a0')/tcp-->'ipv6_src=10::0(mask=ffff:ffff:ffff:ffff:ffff:ffff:ffff:0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "mask":"ffff:ffff:ffff:ffff:ffff:ffff:ffff:0", "value":"10::0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv6(src='10::10')/tcp-->'ipv6_src=10::0(mask=ffff:ffff:ffff:ffff:ffff:ffff:ffff:0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "mask":"ffff:ffff:ffff:ffff:ffff:ffff:ffff:0", "value":"10::0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6(src='10::10')/tcp-->'ipv6_src=10::0(mask=ffff:ffff:ffff:ffff:ffff:ffff:ffff:0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "mask":"ffff:ffff:ffff:ffff:ffff:ffff:ffff:0", "value":"10::0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6(src='a0::a0')/tcp-->'ipv6_src=10::0(mask=ffff:ffff:ffff:ffff:ffff:ffff:ffff:0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "mask":"ffff:ffff:ffff:ffff:ffff:ffff:ffff:0", "value":"10::0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv6(src='10::10')/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_src=10::0(mask=ffff:ffff:ffff:ffff:ffff:ffff:ffff:0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "mask":"ffff:ffff:ffff:ffff:ffff:ffff:ffff:0", "value":"10::0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6(src='10::10')/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_src=10::0(mask=ffff:ffff:ffff:ffff:ffff:ffff:ffff:0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "mask":"ffff:ffff:ffff:ffff:ffff:ffff:ffff:0", "value":"10::0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6(src='a0::a0')/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_src=10::0(mask=ffff:ffff:ffff:ffff:ffff:ffff:ffff:0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "mask":"ffff:ffff:ffff:ffff:ffff:ffff:ffff:0", "value":"10::0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(src='10::10')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_src=10::0(mask=ffff:ffff:ffff:ffff:ffff:ffff:ffff:0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "mask":"ffff:ffff:ffff:ffff:ffff:ffff:ffff:0", "value":"10::0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(src='10::10')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_src=10::0(mask=ffff:ffff:ffff:ffff:ffff:ffff:ffff:0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "mask":"ffff:ffff:ffff:ffff:ffff:ffff:ffff:0", "value":"10::0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(src='a0::a0')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_src=10::0(mask=ffff:ffff:ffff:ffff:ffff:ffff:ffff:0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "mask":"ffff:ffff:ffff:ffff:ffff:ffff:ffff:0", "value":"10::0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/27_IPV6_DST.json0000664000175000017500000011362100000000000023243 0ustar00zuulzuul00000000000000[ "match: 27_IPV6_DST", { "description":"ethernet/ipv6(dst='20::20')/tcp-->'ipv6_dst=20::20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6(dst='20::20')/tcp-->'ipv6_dst=20::20,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6(dst='b0::b0')/tcp-->'ipv6_dst=20::20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv6(dst='20::20')/tcp-->'ipv6_dst=20::20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6(dst='20::20')/tcp-->'ipv6_dst=20::20,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6(dst='b0::b0')/tcp-->'ipv6_dst=20::20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv6(dst='20::20')/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_dst=20::20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6(dst='20::20')/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_dst=20::20,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6(dst='b0::b0')/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_dst=20::20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(dst='20::20')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_dst=20::20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(dst='20::20')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_dst=20::20,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(dst='b0::b0')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_dst=20::20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/27_IPV6_DST_Mask.json0000664000175000017500000011663000000000000024221 0ustar00zuulzuul00000000000000[ "match: 27_IPV6_DST (Mask)", { "description":"ethernet/ipv6(dst='20::20')/tcp-->'ipv6_dst=0::20(mask=0:ffff:ffff:ffff:ffff:ffff:ffff:ffff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "mask":"0:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "value":"0::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6(dst='20::20')/tcp-->'ipv6_dst=0::20(mask=0:ffff:ffff:ffff:ffff:ffff:ffff:ffff),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "mask":"0:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "value":"0::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6(dst='b0::b0')/tcp-->'ipv6_dst=0::20(mask=0:ffff:ffff:ffff:ffff:ffff:ffff:ffff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "mask":"0:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "value":"0::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv6(dst='20::20')/tcp-->'ipv6_dst=0::20(mask=0:ffff:ffff:ffff:ffff:ffff:ffff:ffff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "mask":"0:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "value":"0::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6(dst='20::20')/tcp-->'ipv6_dst=0::20(mask=0:ffff:ffff:ffff:ffff:ffff:ffff:ffff),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "mask":"0:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "value":"0::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6(dst='b0::b0')/tcp-->'ipv6_dst=0::20(mask=0:ffff:ffff:ffff:ffff:ffff:ffff:ffff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "mask":"0:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "value":"0::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv6(dst='20::20')/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_dst=0::20(mask=0:ffff:ffff:ffff:ffff:ffff:ffff:ffff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "mask":"0:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "value":"0::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6(dst='20::20')/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_dst=0::20(mask=0:ffff:ffff:ffff:ffff:ffff:ffff:ffff),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "mask":"0:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "value":"0::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6(dst='b0::b0')/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_dst=0::20(mask=0:ffff:ffff:ffff:ffff:ffff:ffff:ffff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "mask":"0:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "value":"0::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(dst='20::20')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_dst=0::20(mask=0:ffff:ffff:ffff:ffff:ffff:ffff:ffff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "mask":"0:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "value":"0::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(dst='20::20')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_dst=0::20(mask=0:ffff:ffff:ffff:ffff:ffff:ffff:ffff),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "mask":"0:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "value":"0::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(dst='b0::b0')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_dst=0::20(mask=0:ffff:ffff:ffff:ffff:ffff:ffff:ffff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "mask":"0:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "value":"0::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/28_IPV6_FLABEL.json0000664000175000017500000011362400000000000023542 0ustar00zuulzuul00000000000000[ "match: 28_IPV6_FLABEL", { "description":"ethernet/ipv6(flow_label=100)/tcp-->'ipv6_flabel=100,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6(flow_label=100)/tcp-->'ipv6_flabel=100,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6(flow_label=203)/tcp-->'ipv6_flabel=100,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv6(flow_label=100)/tcp-->'ipv6_flabel=100,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6(flow_label=100)/tcp-->'ipv6_flabel=100,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6(flow_label=203)/tcp-->'ipv6_flabel=100,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv6(flow_label=100)/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_flabel=100,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6(flow_label=100)/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_flabel=100,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6(flow_label=203)/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_flabel=100,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(flow_label=100)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_flabel=100,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(flow_label=100)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_flabel=100,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(flow_label=203)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_flabel=100,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/28_IPV6_FLABEL_Mask.json0000664000175000017500000011535700000000000024522 0ustar00zuulzuul00000000000000[ "match: 28_IPV6_FLABEL (Mask)", { "description":"ethernet/ipv6(flow_label=100)/tcp-->'ipv6_flabel=96(mask=0x000ffff0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "mask":1048560, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6(flow_label=100)/tcp-->'ipv6_flabel=96(mask=0x000ffff0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "mask":1048560, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6(flow_label=203)/tcp-->'ipv6_flabel=96(mask=0x000ffff0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "mask":1048560, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv6(flow_label=100)/tcp-->'ipv6_flabel=96(mask=0x000ffff0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "mask":1048560, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6(flow_label=100)/tcp-->'ipv6_flabel=96(mask=0x000ffff0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "mask":1048560, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6(flow_label=203)/tcp-->'ipv6_flabel=96(mask=0x000ffff0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "mask":1048560, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv6(flow_label=100)/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_flabel=96(mask=0x000ffff0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "mask":1048560, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6(flow_label=100)/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_flabel=96(mask=0x000ffff0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "mask":1048560, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6(flow_label=203)/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_flabel=96(mask=0x000ffff0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "mask":1048560, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(flow_label=100)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_flabel=96(mask=0x000ffff0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "mask":1048560, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(flow_label=100)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_flabel=96(mask=0x000ffff0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "mask":1048560, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(flow_label=203)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_flabel=96(mask=0x000ffff0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "mask":1048560, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/29_ICMPV6_TYPE.json0000664000175000017500000012045000000000000023612 0ustar00zuulzuul00000000000000[ "match: 29_ICMPV6_TYPE", { "description":"ethernet/ipv6/icmpv6(type=128)-->'icmpv6_type=128,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":128 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ] } ] }, { "description":"ethernet/ipv6/icmpv6(type=128)-->'icmpv6_type=128,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":128 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ] } ] }, { "description":"ethernet/ipv6/icmpv6(type=135)-->'icmpv6_type=128,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":128 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=58, hop_limit=127, traffic_class=65)", "icmpv6(code=1,data=nd_neighbor(option=nd_option_sla(hw_src='aa:aa:aa:aa:aa:aa'),dst='a0::a0'),type_=135)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv6/icmpv6(type=128)-->'icmpv6_type=128,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":128 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ] } ] }, { "description":"ethernet/vlan/ipv6/icmpv6(type=128)-->'icmpv6_type=128,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":128 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ] } ] }, { "description":"ethernet/vlan/ipv6/icmpv6(type=135)-->'icmpv6_type=128,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":128 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=58, hop_limit=127, traffic_class=65)", "icmpv6(code=1,data=nd_neighbor(option=nd_option_sla(hw_src='aa:aa:aa:aa:aa:aa'),dst='a0::a0'),type_=135)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv6/icmpv6(type=128)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,icmpv6_type=128,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":128 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ] } ] }, { "description":"ethernet/mpls/ipv6/icmpv6(type=128)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,icmpv6_type=128,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":128 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ] } ] }, { "description":"ethernet/mpls/ipv6/icmpv6(type=135)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,icmpv6_type=128,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":128 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=58, hop_limit=127, traffic_class=65)", "icmpv6(code=1,data=nd_neighbor(option=nd_option_sla(hw_src='aa:aa:aa:aa:aa:aa'),dst='a0::a0'),type_=135)" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/icmpv6(type=128)-->'actions=pop_pbb,goto_table:1','table_id:1,icmpv6_type=128,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":128 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/icmpv6(type=128)-->'actions=pop_pbb,goto_table:1','table_id:1,icmpv6_type=128,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":128 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/icmpv6(type=135)-->'actions=pop_pbb,goto_table:1','table_id:1,icmpv6_type=128,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":128 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=58, hop_limit=127, traffic_class=65)", "icmpv6(code=1,data=nd_neighbor(option=nd_option_sla(hw_src='aa:aa:aa:aa:aa:aa'),dst='a0::a0'),type_=135)" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/30_ICMPV6_CODE.json0000664000175000017500000012034000000000000023531 0ustar00zuulzuul00000000000000[ "match: 30_ICMPV6_CODE", { "description":"ethernet/ipv6/icmpv6(code=0)-->'icmpv6_code=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ] } ] }, { "description":"ethernet/ipv6/icmpv6(code=0)-->'icmpv6_code=0,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ] } ] }, { "description":"ethernet/ipv6/icmpv6(code=1)-->'icmpv6_code=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=58, hop_limit=127, traffic_class=65)", "icmpv6(code=1,data=nd_neighbor(option=nd_option_sla(hw_src='aa:aa:aa:aa:aa:aa'),dst='a0::a0'),type_=135)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv6/icmpv6(code=0)-->'icmpv6_code=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ] } ] }, { "description":"ethernet/vlan/ipv6/icmpv6(code=0)-->'icmpv6_code=0,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ] } ] }, { "description":"ethernet/vlan/ipv6/icmpv6(code=1)-->'icmpv6_code=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=58, hop_limit=127, traffic_class=65)", "icmpv6(code=1,data=nd_neighbor(option=nd_option_sla(hw_src='aa:aa:aa:aa:aa:aa'),dst='a0::a0'),type_=135)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv6/icmpv6(code=0)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,icmpv6_code=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ] } ] }, { "description":"ethernet/mpls/ipv6/icmpv6(code=0)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,icmpv6_code=0,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ] } ] }, { "description":"ethernet/mpls/ipv6/icmpv6(code=1)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,icmpv6_code=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=58, hop_limit=127, traffic_class=65)", "icmpv6(code=1,data=nd_neighbor(option=nd_option_sla(hw_src='aa:aa:aa:aa:aa:aa'),dst='a0::a0'),type_=135)" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/icmpv6(code=0)-->'actions=pop_pbb,goto_table:1','table_id:1,icmpv6_code=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/icmpv6(code=0)-->'actions=pop_pbb,goto_table:1','table_id:1,icmpv6_code=0,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/icmpv6(code=1)-->'actions=pop_pbb,goto_table:1','table_id:1,icmpv6_code=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=58, hop_limit=127, traffic_class=65)", "icmpv6(code=1,data=nd_neighbor(option=nd_option_sla(hw_src='aa:aa:aa:aa:aa:aa'),dst='a0::a0'),type_=135)" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/31_IPV6_ND_TARGET.json0000664000175000017500000012370700000000000024161 0ustar00zuulzuul00000000000000[ "match: 31_IPV6_ND_TARGET", { "description":"ethernet/ipv6/icmpv6(data=nd_neighbor(dst='20::20'))-->'ipv6_nd_target=20::20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_target", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='12:11:11:11:11:11'),dst='20::20'),type_=135)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='12:11:11:11:11:11'),dst='20::20'),type_=135)" ] } ] }, { "description":"ethernet/ipv6/icmpv6(data=nd_neighbor(dst='20::20'))-->'ipv6_nd_target=20::20,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_target", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='12:11:11:11:11:11'),dst='20::20'),type_=135)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='12:11:11:11:11:11'),dst='20::20'),type_=135)" ] } ] }, { "description":"ethernet/ipv6/icmpv6(data=nd_neighbor(dst='b0::b0'))-->'ipv6_nd_target=20::20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_target", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=58, hop_limit=127, traffic_class=65)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='aa:aa:aa:aa:aa:aa'),dst='b0::b0'),type_=135)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv6/icmpv6(data=nd_neighbor(dst='20::20'))-->'ipv6_nd_target=20::20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_target", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='12:11:11:11:11:11'),dst='20::20'),type_=135)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='12:11:11:11:11:11'),dst='20::20'),type_=135)" ] } ] }, { "description":"ethernet/vlan/ipv6/icmpv6(data=nd_neighbor(dst='20::20'))-->'ipv6_nd_target=20::20,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_target", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='12:11:11:11:11:11'),dst='20::20'),type_=135)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='12:11:11:11:11:11'),dst='20::20'),type_=135)" ] } ] }, { "description":"ethernet/vlan/ipv6/icmpv6(data=nd_neighbor(dst='b0::b0'))-->'ipv6_nd_target=20::20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_target", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=58, hop_limit=127, traffic_class=65)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='aa:aa:aa:aa:aa:aa'),dst='b0::b0'),type_=135)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv6/icmpv6(data=nd_neighbor(dst='20::20'))-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_nd_target=20::20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_target", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='12:11:11:11:11:11'),dst='20::20'),type_=135)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='12:11:11:11:11:11'),dst='20::20'),type_=135)" ] } ] }, { "description":"ethernet/mpls/ipv6/icmpv6(data=nd_neighbor(dst='20::20'))-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_nd_target=20::20,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_target", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='12:11:11:11:11:11'),dst='20::20'),type_=135)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='12:11:11:11:11:11'),dst='20::20'),type_=135)" ] } ] }, { "description":"ethernet/mpls/ipv6/icmpv6(data=nd_neighbor(dst='b0::b0'))-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_nd_target=20::20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_target", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=58, hop_limit=127, traffic_class=65)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='aa:aa:aa:aa:aa:aa'),dst='b0::b0'),type_=135)" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/icmpv6(data=nd_neighbor(dst='20::20'))-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_nd_target=20::20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_target", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='12:11:11:11:11:11'),dst='20::20'),type_=135)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='12:11:11:11:11:11'),dst='20::20'),type_=135)" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/icmpv6(data=nd_neighbor(dst='20::20'))-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_nd_target=20::20,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_target", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='12:11:11:11:11:11'),dst='20::20'),type_=135)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='12:11:11:11:11:11'),dst='20::20'),type_=135)" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/icmpv6(data=nd_neighbor(dst='b0::b0'))-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_nd_target=20::20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_target", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=58, hop_limit=127, traffic_class=65)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='aa:aa:aa:aa:aa:aa'),dst='b0::b0'),type_=135)" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/32_IPV6_ND_SLL.json0000664000175000017500000012506400000000000023624 0ustar00zuulzuul00000000000000[ "match: 32_IPV6_ND_SLL", { "description":"ethernet/ipv6/icmpv6(data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22')))-->'ipv6_nd_sll=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_sll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=135)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=135)" ] } ] }, { "description":"ethernet/ipv6/icmpv6(data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22')))-->'ipv6_nd_sll=22:22:22:22:22:22,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_sll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=135)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=135)" ] } ] }, { "description":"ethernet/ipv6/icmpv6(data=nd_neighbor(option=nd_option_sla(hw_src='aa:aa:aa:aa:aa:aa')))-->'ipv6_nd_sll=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_sll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=58, hop_limit=127, traffic_class=65)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='aa:aa:aa:aa:aa:aa'),dst='b0::b0'),type_=135)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv6/icmpv6(data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22')))-->'ipv6_nd_sll=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_sll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=135)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=135)" ] } ] }, { "description":"ethernet/vlan/ipv6/icmpv6(data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22')))-->'ipv6_nd_sll=22:22:22:22:22:22,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_sll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=135)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=135)" ] } ] }, { "description":"ethernet/vlan/ipv6/icmpv6(data=nd_neighbor(option=nd_option_sla(hw_src='aa:aa:aa:aa:aa:aa')))-->'ipv6_nd_sll=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_sll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=58, hop_limit=127, traffic_class=65)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='aa:aa:aa:aa:aa:aa'),dst='b0::b0'),type_=135)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv6/icmpv6(data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22')))-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_nd_sll=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_sll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=135)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=135)" ] } ] }, { "description":"ethernet/mpls/ipv6/icmpv6(data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22')))-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_nd_sll=22:22:22:22:22:22,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_sll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=135)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=135)" ] } ] }, { "description":"ethernet/mpls/ipv6/icmpv6(data=nd_neighbor(option=nd_option_sla(hw_src='aa:aa:aa:aa:aa:aa')))-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_nd_sll=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_sll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=58, hop_limit=127, traffic_class=65)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='aa:aa:aa:aa:aa:aa'),dst='b0::b0'),type_=135)" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/icmpv6(data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22')))-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_nd_sll=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_sll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=135)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=135)" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/icmpv6(data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22')))-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_nd_sll=22:22:22:22:22:22,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_sll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=135)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=135)" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/icmpv6(data=nd_neighbor(option=nd_option_sla(hw_src='aa:aa:aa:aa:aa:aa')))-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_nd_sll=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_sll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=58, hop_limit=127, traffic_class=65)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='aa:aa:aa:aa:aa:aa'),dst='b0::b0'),type_=135)" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/33_IPV6_ND_TLL.json0000664000175000017500000012506400000000000023626 0ustar00zuulzuul00000000000000[ "match: 33_IPV6_ND_TLL", { "description":"ethernet/ipv6/icmpv6(data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22')))-->'ipv6_nd_tll=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":136 } }, { "OXMTlv":{ "field":"ipv6_nd_tll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=136)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=136)" ] } ] }, { "description":"ethernet/ipv6/icmpv6(data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22')))-->'ipv6_nd_tll=22:22:22:22:22:22,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":136 } }, { "OXMTlv":{ "field":"ipv6_nd_tll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=136)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=136)" ] } ] }, { "description":"ethernet/ipv6/icmpv6(data=nd_neighbor(option=nd_option_tla(hw_src='aa:aa:aa:aa:aa:aa')))-->'ipv6_nd_tll=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":136 } }, { "OXMTlv":{ "field":"ipv6_nd_tll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=58, hop_limit=127, traffic_class=65)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='aa:aa:aa:aa:aa:aa'),dst='b0::b0'),type_=136)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv6/icmpv6(data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22')))-->'ipv6_nd_tll=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":136 } }, { "OXMTlv":{ "field":"ipv6_nd_tll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=136)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=136)" ] } ] }, { "description":"ethernet/vlan/ipv6/icmpv6(data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22')))-->'ipv6_nd_tll=22:22:22:22:22:22,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":136 } }, { "OXMTlv":{ "field":"ipv6_nd_tll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=136)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=136)" ] } ] }, { "description":"ethernet/vlan/ipv6/icmpv6(data=nd_neighbor(option=nd_option_tla(hw_src='aa:aa:aa:aa:aa:aa')))-->'ipv6_nd_tll=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":136 } }, { "OXMTlv":{ "field":"ipv6_nd_tll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=58, hop_limit=127, traffic_class=65)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='aa:aa:aa:aa:aa:aa'),dst='b0::b0'),type_=136)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv6/icmpv6(data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22')))-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_nd_tll=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":136 } }, { "OXMTlv":{ "field":"ipv6_nd_tll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=136)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=136)" ] } ] }, { "description":"ethernet/mpls/ipv6/icmpv6(data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22')))-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_nd_tll=22:22:22:22:22:22,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":136 } }, { "OXMTlv":{ "field":"ipv6_nd_tll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=136)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=136)" ] } ] }, { "description":"ethernet/mpls/ipv6/icmpv6(data=nd_neighbor(option=nd_option_tla(hw_src='aa:aa:aa:aa:aa:aa')))-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_nd_tll=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":136 } }, { "OXMTlv":{ "field":"ipv6_nd_tll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=58, hop_limit=127, traffic_class=65)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='aa:aa:aa:aa:aa:aa'),dst='b0::b0'),type_=136)" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/icmpv6(data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22')))-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_nd_tll=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":136 } }, { "OXMTlv":{ "field":"ipv6_nd_tll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=136)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=136)" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/icmpv6(data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22')))-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_nd_tll=22:22:22:22:22:22,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":136 } }, { "OXMTlv":{ "field":"ipv6_nd_tll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=136)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=136)" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/icmpv6(data=nd_neighbor(option=nd_option_tla(hw_src='aa:aa:aa:aa:aa:aa')))-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_nd_tll=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":136 } }, { "OXMTlv":{ "field":"ipv6_nd_tll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=58, hop_limit=127, traffic_class=65)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='aa:aa:aa:aa:aa:aa'),dst='b0::b0'),type_=136)" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/34_MPLS_LABEL.json0000664000175000017500000005352200000000000023460 0ustar00zuulzuul00000000000000[ "match: 34_MPLS_LABEL", { "description":"ethernet/mpls(label=100)/ipv4/tcp-->'mpls_label=100,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_label", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls(label=100)/ipv4/tcp-->'mpls_label=100,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_label", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls(label=203)/ipv4/tcp-->'mpls_label=100,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_label", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls(label=100)/ipv6/tcp-->'mpls_label=100,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_label", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls(label=100)/ipv6/tcp-->'mpls_label=100,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_label", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls(label=203)/ipv6/tcp-->'mpls_label=100,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_label", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls(label=100)/arp-->'mpls_label=100,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_label", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/mpls(label=100)/arp-->'mpls_label=100,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_label", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/mpls(label=203)/arp-->'mpls_label=100,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_label", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * 30)" ], "table-miss":[ 0 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/35_MPLS_TC.json0000664000175000017500000005332100000000000023145 0ustar00zuulzuul00000000000000[ "match: 35_MPLS_TC", { "description":"ethernet/mpls(exp=3)/ipv4/tcp-->'mpls_tc=3,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_tc", "value":3 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls(exp=3)/ipv4/tcp-->'mpls_tc=3,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_tc", "value":3 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls(exp=5)/ipv4/tcp-->'mpls_tc=3,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_tc", "value":3 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls(exp=3)/ipv6/tcp-->'mpls_tc=3,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_tc", "value":3 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls(exp=3)/ipv6/tcp-->'mpls_tc=3,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_tc", "value":3 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls(exp=5)/ipv6/tcp-->'mpls_tc=3,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_tc", "value":3 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls(exp=3)/arp-->'mpls_tc=3,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_tc", "value":3 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/mpls(exp=3)/arp-->'mpls_tc=3,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_tc", "value":3 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/mpls(exp=5)/arp-->'mpls_tc=3,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_tc", "value":3 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * 30)" ], "table-miss":[ 0 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/36_MPLS_BOS.json0000664000175000017500000005367700000000000023301 0ustar00zuulzuul00000000000000[ "match: 36_MPLS_BOS", { "description":"ethernet/mpls(bsb=1)/ipv4/tcp-->'mpls_bos=1,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_bos", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls(bsb=1)/ipv4/tcp-->'mpls_bos=1,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_bos", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls(bsb=0)/mpls(bsb=1)/ipv4/tcp-->'mpls_bos=1,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_bos", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=0, label=203, exp=5, ttl=127)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls(bsb=1)/ipv6/tcp-->'mpls_bos=1,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_bos", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls(bsb=1)/ipv6/tcp-->'mpls_bos=1,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_bos", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls(bsb=0)/mpls(bsb=1)/ipv6/tcp-->'mpls_bos=1,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_bos", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=0, label=203, exp=5, ttl=127)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls(bsb=1)/arp-->'mpls_bos=1,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_bos", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/mpls(bsb=1)/arp-->'mpls_bos=1,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_bos", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/mpls(bsb=0)/mpls(bsb=1)/arp-->'mpls_bos=1,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_bos", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=0, label=203, exp=5, ttl=127)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * 30)" ], "table-miss":[ 0 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/37_PBB_ISID.json0000664000175000017500000006325400000000000023227 0ustar00zuulzuul00000000000000[ "match: 37_PBB_ISID", { "description":"ethernet/svlan/itag(sid=100)/ethernet/svlan/vlan/ipv4/tcp-->'pbb_isid=100,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_isid", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/svlan/itag(sid=100)/ethernet/svlan/vlan/ipv4/tcp-->'pbb_isid=100,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_isid", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/svlan/itag(sid=203)/ethernet/svlan/vlan/ipv4/tcp-->'pbb_isid=100,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_isid", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/svlan/itag(sid=100)/ethernet/svlan/vlan/ipv6/tcp-->'pbb_isid=100,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_isid", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/svlan/itag(sid=100)/ethernet/svlan/vlan/ipv6/tcp-->'pbb_isid=100,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_isid", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/svlan/itag(sid=203)/ethernet/svlan/vlan/ipv6/tcp-->'pbb_isid=100,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_isid", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/svlan/itag(sid=100)/ethernet/svlan/vlan/arp-->'pbb_isid=100,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_isid", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/svlan/itag(sid=100)/ethernet/svlan/vlan/arp-->'pbb_isid=100,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_isid", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/svlan/itag(sid=203)/ethernet/svlan/vlan/arp-->'pbb_isid=100,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_isid", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * 30)" ], "table-miss":[ 0 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/37_PBB_ISID_Mask.json0000664000175000017500000006433000000000000024176 0ustar00zuulzuul00000000000000[ "match: 37_PBB_ISID (Mask)", { "description":"ethernet/svlan/itag(sid=100)/ethernet/svlan/vlan/ipv4/tcp-->'pbb_isid=96(mask=0xf0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_isid", "mask":240, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/svlan/itag(sid=100)/ethernet/svlan/vlan/ipv4/tcp-->'pbb_isid=96(mask=0xf0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_isid", "mask":240, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/svlan/itag(sid=203)/ethernet/svlan/vlan/ipv4/tcp-->'pbb_isid=96(mask=0xf0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_isid", "mask":240, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/svlan/itag(sid=100)/ethernet/svlan/vlan/ipv6/tcp-->'pbb_isid=96(mask=0xf0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_isid", "mask":240, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/svlan/itag(sid=100)/ethernet/svlan/vlan/ipv6/tcp-->'pbb_isid=96(mask=0xf0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_isid", "mask":240, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/svlan/itag(sid=203)/ethernet/svlan/vlan/ipv6/tcp-->'pbb_isid=96(mask=0xf0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_isid", "mask":240, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/svlan/itag(sid=100)/ethernet/svlan/vlan/arp-->'pbb_isid=96(mask=0xf0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_isid", "mask":240, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/svlan/itag(sid=100)/ethernet/svlan/vlan/arp-->'pbb_isid=96(mask=0xf0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_isid", "mask":240, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/svlan/itag(sid=203)/ethernet/svlan/vlan/arp-->'pbb_isid=96(mask=0xf0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_isid", "mask":240, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * 30)" ], "table-miss":[ 0 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/38_TUNNEL_ID.json0000664000175000017500000010176500000000000023376 0ustar00zuulzuul00000000000000[ "match: 38_TUNNEL_ID", { "description":"ethernet/ipv4/tcp-->'actions=set_field:12345->tunnel_id,goto_table:1','table_id:1,tunnel_id=12345,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tunnel_id", "value":12345 } } } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"tunnel_id", "value":12345 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4/tcp-->'actions=set_field:12345->tunnel_id,goto_table:1','table_id:1,tunnel_id=12345,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tunnel_id", "value":12345 } } } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"tunnel_id", "value":12345 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4/tcp-->'actions=set_field:6666->tunnel_id,goto_table:1','table_id:1,tunnel_id=12345,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tunnel_id", "value":6666 } } } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"tunnel_id", "value":12345 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/ipv6/tcp-->'actions=set_field:12345->tunnel_id,goto_table:1','table_id:1,tunnel_id=12345,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tunnel_id", "value":12345 } } } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"tunnel_id", "value":12345 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6/tcp-->'actions=set_field:12345->tunnel_id,goto_table:1','table_id:1,tunnel_id=12345,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tunnel_id", "value":12345 } } } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"tunnel_id", "value":12345 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6/tcp-->'actions=set_field:6666->tunnel_id,goto_table:1','table_id:1,tunnel_id=12345,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tunnel_id", "value":6666 } } } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"tunnel_id", "value":12345 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/arp-->'actions=set_field:12345->tunnel_id,goto_table:1','table_id:1,tunnel_id=12345,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tunnel_id", "value":12345 } } } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"tunnel_id", "value":12345 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp-->'actions=set_field:12345->tunnel_id,goto_table:1','table_id:1,tunnel_id=12345,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tunnel_id", "value":12345 } } } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"tunnel_id", "value":12345 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp-->'actions=set_field:6666->tunnel_id,goto_table:1','table_id:1,tunnel_id=12345,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tunnel_id", "value":6666 } } } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"tunnel_id", "value":12345 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/38_TUNNEL_ID_Mask.json0000664000175000017500000010312700000000000024343 0ustar00zuulzuul00000000000000[ "match: 38_TUNNEL_ID (Mask)", { "description":"ethernet/ipv4/tcp-->'actions=set_field:12345->tunnel_id,goto_table:1','table_id:1,tunnel_id=12288(mask=0xff00),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tunnel_id", "value":12345 } } } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"tunnel_id", "mask":65280, "value":12288 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4/tcp-->'actions=set_field:12345->tunnel_id,goto_table:1','table_id:1,tunnel_id=12288(mask=0xff00),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tunnel_id", "value":12345 } } } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"tunnel_id", "mask":65280, "value":12288 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4/tcp-->'actions=set_field:6666->tunnel_id,goto_table:1','table_id:1,tunnel_id=12288(mask=0xff00),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tunnel_id", "value":6666 } } } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"tunnel_id", "mask":65280, "value":12288 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/ipv6/tcp-->'actions=set_field:12345->tunnel_id,goto_table:1','table_id:1,tunnel_id=12288(mask=0xff00),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tunnel_id", "value":12345 } } } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"tunnel_id", "mask":65280, "value":12288 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6/tcp-->'actions=set_field:12345->tunnel_id,goto_table:1','table_id:1,tunnel_id=12288(mask=0xff00),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tunnel_id", "value":12345 } } } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"tunnel_id", "mask":65280, "value":12288 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6/tcp-->'actions=set_field:6666->tunnel_id,goto_table:1','table_id:1,tunnel_id=12288(mask=0xff00),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tunnel_id", "value":6666 } } } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"tunnel_id", "mask":65280, "value":12288 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/arp-->'actions=set_field:12345->tunnel_id,goto_table:1','table_id:1,tunnel_id=12288(mask=0xff00),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tunnel_id", "value":12345 } } } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"tunnel_id", "mask":65280, "value":12288 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp-->'actions=set_field:12345->tunnel_id,goto_table:1','table_id:1,tunnel_id=12288(mask=0xff00),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tunnel_id", "value":12345 } } } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"tunnel_id", "mask":65280, "value":12288 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp-->'actions=set_field:6666->tunnel_id,goto_table:1','table_id:1,tunnel_id=12288(mask=0xff00),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tunnel_id", "value":6666 } } } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"tunnel_id", "mask":65280, "value":12288 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/39_IPV6_EXTHDR.json0000664000175000017500000011424300000000000023613 0ustar00zuulzuul00000000000000[ "match: 39_IPV6_EXTHDR", { "description":"ethernet/ipv6(ext_hdrs=[hop_opts,auth]/tcp-->'ipv6_exthdr=68,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_exthdr", "value":68 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6(ext_hdrs=[hop_opts,auth])/tcp-->'ipv6_exthdr=68,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_exthdr", "value":68 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6/tcp-->'ipv6_exthdr=68,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_exthdr", "value":68 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv6(ext_hdrs=[hop_opts,auth])/tcp-->'ipv6_exthdr=68,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_exthdr", "value":68 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6(ext_hdrs=[hop_opts,auth])/tcp-->'ipv6_exthdr=68,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_exthdr", "value":68 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6/tcp-->'ipv6_exthdr=68,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_exthdr", "value":68 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv6(ext_hdrs=[hop_opts,auth])/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_exthdr=68,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_exthdr", "value":68 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6(ext_hdrs=[hop_opts,auth])/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_exthdr=68,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_exthdr", "value":68 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_exthdr=68,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_exthdr", "value":68 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(ext_hdrs=[hop_opts,auth])/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_exthdr=68,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_exthdr", "value":68 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(ext_hdrs=[hop_opts,auth])/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_exthdr=68,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_exthdr", "value":68 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_exthdr=68,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_exthdr", "value":68 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/match/39_IPV6_EXTHDR_Mask.json0000664000175000017500000011572500000000000024574 0ustar00zuulzuul00000000000000[ "match: 39_IPV6_EXTHDR (Mask)", { "description":"ethernet/ipv6(ext_hdrs=[hop_opts,auth])/tcp-->'ipv6_exthdr=64(mask=0x1f0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_exthdr", "mask":496, "value":64 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6(ext_hdrs=[hop_opts,auth])/tcp-->'ipv6_exthdr=64(mask=0x1f0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_exthdr", "mask":496, "value":64 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6/tcp-->'ipv6_exthdr=64(mask=0x1f0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_exthdr", "mask":496, "value":64 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv6(ext_hdrs=[hop_opts,auth])/tcp-->'ipv6_exthdr=64(mask=0x1f0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_exthdr", "mask":496, "value":64 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6(ext_hdrs=[hop_opts,auth])/tcp-->'ipv6_exthdr=64(mask=0x1f0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_exthdr", "mask":496, "value":64 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6/tcp-->'ipv6_exthdr=64(mask=0x1f0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_exthdr", "mask":496, "value":64 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv6(ext_hdrs=[hop_opts,auth])/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_exthdr=64(mask=0x1f0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_exthdr", "mask":496, "value":64 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6(ext_hdrs=[hop_opts,auth])/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_exthdr=64(mask=0x1f0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_exthdr", "mask":496, "value":64 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_exthdr=64(mask=0x1f0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_exthdr", "mask":496, "value":64 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(ext_hdrs=[hop_opts,auth])/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,actions=pop_pbb,goto_table:1','table_id:1,ipv6_exthdr=64(mask=0x1f0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_exthdr", "mask":496, "value":64 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(ext_hdrs=[hop_opts,auth])/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_exthdr=64(mask=0x1f0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_exthdr", "mask":496, "value":64 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_exthdr=64(mask=0x1f0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_exthdr", "mask":496, "value":64 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.2461138 os-ken-2.10.0/os_ken/tests/switch/of13/meter/0000775000175000017500000000000000000000000020616 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/meter/01_DROP_00_KBPS_00_1M.json0000664000175000017500000002114400000000000024531 0ustar00zuulzuul00000000000000[ "meter: 01_DROP_00_KBPS_00_1M", { "description":"2Mbps(ethernet/ipv4/tcp)-->'in_port=1,actions=meter:1Mbps(drop),output:2'", "prerequisite":[ { "OFPMeterMod":{ "meter_id":1, "bands":[ { "OFPMeterBandDrop":{ "rate":1000 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(proto=6)", "tcp()", "bytes(b'\\x11' * (1500 - 54))" ], "pktps":175, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":1000 } ] } } ] }, { "description":"2Mbps(ethernet/ipv6/tcp)-->'in_port=1,actions=meter:1Mbps(drop),output:2'", "prerequisite":[ { "OFPMeterMod":{ "meter_id":1, "bands":[ { "OFPMeterBandDrop":{ "rate":1000 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(nxt=6)", "tcp()", "bytes(b'\\x11' * (1500 - 74))" ], "pktps":175, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":1000 } ] } } ] }, { "description":"2Mbps(ethernet/arp)-->'in_port=1,actions=meter:1Mbps(drop),output:2'", "prerequisite":[ { "OFPMeterMod":{ "meter_id":1, "bands":[ { "OFPMeterBandDrop":{ "rate":1000 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_mac='22:22:22:22:22:22', src_mac='12:11:11:11:11:11')", "bytes(b'\\x11' * (1500 - 42))" ], "pktps":175, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":1000 } ] } } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/meter/01_DROP_00_KBPS_01_10M.json0000664000175000017500000002116400000000000024614 0ustar00zuulzuul00000000000000[ "meter: 01_DROP_00_KBPS_01_10M", { "description":"20Mbps(ethernet/ipv4/tcp)-->'in_port=1,actions=meter:10Mbps(drop),output:2'", "prerequisite":[ { "OFPMeterMod":{ "meter_id":1, "bands":[ { "OFPMeterBandDrop":{ "rate":10000 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(proto=6)", "tcp()", "bytes(b'\\x11' * (1500 - 54))" ], "pktps":1750, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":10000 } ] } } ] }, { "description":"20Mbps(ethernet/ipv6/tcp)-->'in_port=1,actions=meter:10Mbps(drop),output:2'", "prerequisite":[ { "OFPMeterMod":{ "meter_id":1, "bands":[ { "OFPMeterBandDrop":{ "rate":10000 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(nxt=6)", "tcp()", "bytes(b'\\x11' * (1500 - 74))" ], "pktps":1750, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":10000 } ] } } ] }, { "description":"20Mbps(ethernet/arp)-->'in_port=1,actions=meter:10Mbps(drop),output:2'", "prerequisite":[ { "OFPMeterMod":{ "meter_id":1, "bands":[ { "OFPMeterBandDrop":{ "rate":10000 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_mac='22:22:22:22:22:22', src_mac='12:11:11:11:11:11')", "bytes(b'\\x11' * (1500 - 42))" ], "pktps":1750, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":10000 } ] } } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/meter/01_DROP_00_KBPS_02_100M.json0000664000175000017500000002120400000000000024670 0ustar00zuulzuul00000000000000[ "meter: 01_DROP_00_KBPS_02_100M", { "description":"200Mbps(ethernet/ipv4/tcp)-->'in_port=1,actions=meter:100Mbps(drop),output:2'", "prerequisite":[ { "OFPMeterMod":{ "meter_id":1, "bands":[ { "OFPMeterBandDrop":{ "rate":100000 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(proto=6)", "tcp()", "bytes(b'\\x11' * (1500 - 54))" ], "pktps":17500, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":100000 } ] } } ] }, { "description":"200Mbps(ethernet/ipv6/tcp)-->'in_port=1,actions=meter:100Mbps(drop),output:2'", "prerequisite":[ { "OFPMeterMod":{ "meter_id":1, "bands":[ { "OFPMeterBandDrop":{ "rate":100000 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(nxt=6)", "tcp()", "bytes(b'\\x11' * (1500 - 74))" ], "pktps":17500, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":100000 } ] } } ] }, { "description":"200Mbps(ethernet/arp)-->'in_port=1,actions=meter:100Mbps(drop),output:2'", "prerequisite":[ { "OFPMeterMod":{ "meter_id":1, "bands":[ { "OFPMeterBandDrop":{ "rate":100000 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_mac='22:22:22:22:22:22', src_mac='12:11:11:11:11:11')", "bytes(b'\\x11' * (1500 - 42))" ], "pktps":17500, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":100000 } ] } } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/meter/01_DROP_01_PKTPS_00_100.json0000664000175000017500000002132200000000000024715 0ustar00zuulzuul00000000000000[ "meter: 01_DROP_01_PKTPS_00_100", { "description":"200pktps(ethernet/ipv4/tcp)-->'in_port=1,actions=meter:100pktps(drop),output:2'", "prerequisite":[ { "OFPMeterMod":{ "flags":2, "meter_id":1, "bands":[ { "OFPMeterBandDrop":{ "rate":100 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(proto=6)", "tcp()", "bytes(b'\\x11' * (1500 - 54))" ], "pktps":200, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "pktps":100 } ] } } ] }, { "description":"200pktps(ethernet/ipv6/tcp)-->'in_port=1,actions=meter:100pktps(drop),output:2'", "prerequisite":[ { "OFPMeterMod":{ "flags":2, "meter_id":1, "bands":[ { "OFPMeterBandDrop":{ "rate":100 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(nxt=6)", "tcp()", "bytes(b'\\x11' * (1500 - 74))" ], "pktps":200, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "pktps":100 } ] } } ] }, { "description":"200pktps(ethernet/arp)-->'in_port=1,actions=meter:100pktps(drop),output:2'", "prerequisite":[ { "OFPMeterMod":{ "flags":2, "meter_id":1, "bands":[ { "OFPMeterBandDrop":{ "rate":100 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_mac='22:22:22:22:22:22', src_mac='12:11:11:11:11:11')", "bytes(b'\\x11' * (1500 - 42))" ], "pktps":200, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "pktps":100 } ] } } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/meter/01_DROP_01_PKTPS_01_1000.json0000664000175000017500000002134200000000000025000 0ustar00zuulzuul00000000000000[ "meter: 01_DROP_01_PKTPS_01_1000", { "description":"2000pktps(ethernet/ipv4/tcp)-->'in_port=1,actions=meter:1000pktps(drop),output:2'", "prerequisite":[ { "OFPMeterMod":{ "flags":2, "meter_id":1, "bands":[ { "OFPMeterBandDrop":{ "rate":1000 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(proto=6)", "tcp()", "bytes(b'\\x11' * (1500 - 54))" ], "pktps":2000, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "pktps":1000 } ] } } ] }, { "description":"2000pktps(ethernet/ipv6/tcp)-->'in_port=1,actions=meter:1000pktps(drop),output:2'", "prerequisite":[ { "OFPMeterMod":{ "flags":2, "meter_id":1, "bands":[ { "OFPMeterBandDrop":{ "rate":1000 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(nxt=6)", "tcp()", "bytes(b'\\x11' * (1500 - 74))" ], "pktps":2000, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "pktps":1000 } ] } } ] }, { "description":"2000pktps(ethernet/arp)-->'in_port=1,actions=meter:1000pktps(drop),output:2'", "prerequisite":[ { "OFPMeterMod":{ "flags":2, "meter_id":1, "bands":[ { "OFPMeterBandDrop":{ "rate":1000 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_mac='22:22:22:22:22:22', src_mac='12:11:11:11:11:11')", "bytes(b'\\x11' * (1500 - 42))" ], "pktps":2000, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "pktps":1000 } ] } } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/meter/01_DROP_01_PKTPS_02_10000.json0000664000175000017500000002136200000000000025063 0ustar00zuulzuul00000000000000[ "meter: 01_DROP_01_PKTPS_02_10000", { "description":"20000pktps(ethernet/ipv4/tcp)-->'in_port=1,actions=meter:10000pktps(drop),output:2'", "prerequisite":[ { "OFPMeterMod":{ "flags":2, "meter_id":1, "bands":[ { "OFPMeterBandDrop":{ "rate":10000 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(proto=6)", "tcp()", "bytes(b'\\x11' * (1500 - 54))" ], "pktps":20000, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "pktps":10000 } ] } } ] }, { "description":"20000pktps(ethernet/ipv6/tcp)-->'in_port=1,actions=meter:10000pktps(drop),output:2'", "prerequisite":[ { "OFPMeterMod":{ "flags":2, "meter_id":1, "bands":[ { "OFPMeterBandDrop":{ "rate":10000 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(nxt=6)", "tcp()", "bytes(b'\\x11' * (1500 - 74))" ], "pktps":20000, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "pktps":10000 } ] } } ] }, { "description":"20000pktps(ethernet/arp)-->'in_port=1,actions=meter:10000pktps(drop),output:2'", "prerequisite":[ { "OFPMeterMod":{ "flags":2, "meter_id":1, "bands":[ { "OFPMeterBandDrop":{ "rate":10000 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_mac='22:22:22:22:22:22', src_mac='12:11:11:11:11:11')", "bytes(b'\\x11' * (1500 - 42))" ], "pktps":20000, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "pktps":10000 } ] } } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/meter/02_DSCP_REMARK_00_KBPS_00_1M.json0000664000175000017500000003024700000000000025564 0ustar00zuulzuul00000000000000[ "meter: 02_DSCP_REMARK_00_KBPS_00_1M", { "description":"2Mbps(ethernet/ipv4(dscp=18)/tcp)-->'in_port=1,actions=meter:1Mbps(dscp_remark:ip_dscp=20),output:2'", "prerequisite":[ { "OFPMeterMod":{ "meter_id":1, "bands":[ { "OFPMeterBandDscpRemark":{ "rate":1000, "prec_level":1 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(proto=6, tos=72)", "tcp()", "bytes(b'\\x11' * (1500 - 54))" ], "pktps":175, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } }, { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":20 } } ] }, "kbps":1000 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } }, { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":18 } } ] }, "kbps":1000 } ] } } ] }, { "description":"2Mbps(ethernet/ipv6(dscp=18)/tcp)-->'in_port=1,actions=meter:1Mbps(dscp_remark:ip_dscp=20),output:2'", "prerequisite":[ { "OFPMeterMod":{ "meter_id":1, "bands":[ { "OFPMeterBandDscpRemark":{ "rate":1000, "prec_level":1 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(nxt=6, traffic_class=72)", "tcp()", "bytes(b'\\x11' * (1500 - 74))" ], "pktps":175, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } }, { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":20 } } ] }, "kbps":1000 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } }, { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":18 } } ] }, "kbps":1000 } ] } } ] }, { "description":"2Mbps(ethernet/arp)-->'in_port=1,actions=meter:2Mbps(dscp_remark:prec_level=1),output:2'", "prerequisite":[ { "OFPMeterMod":{ "meter_id":1, "bands":[ { "OFPMeterBandDscpRemark":{ "rate":1000, "prec_level":1 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_mac='22:22:22:22:22:22', src_mac='12:11:11:11:11:11')", "bytes(b'\\x11' * (1500 - 42))" ], "pktps":175, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":2000 } ] } } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/meter/02_DSCP_REMARK_00_KBPS_01_10M.json0000664000175000017500000003027100000000000025642 0ustar00zuulzuul00000000000000[ "meter: 02_DSCP_REMARK_00_KBPS_01_10M", { "description":"20Mbps(ethernet/ipv4(dscp=18)/tcp)-->'in_port=1,actions=meter:10Mbps(dscp_remark:ip_dscp=20),output:2'", "prerequisite":[ { "OFPMeterMod":{ "meter_id":1, "bands":[ { "OFPMeterBandDscpRemark":{ "rate":10000, "prec_level":1 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(proto=6, tos=72)", "tcp()", "bytes(b'\\x11' * (1500 - 54))" ], "pktps":1750, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } }, { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":20 } } ] }, "kbps":10000 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } }, { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":18 } } ] }, "kbps":10000 } ] } } ] }, { "description":"20Mbps(ethernet/ipv6(dscp=18)/tcp)-->'in_port=1,actions=meter:10Mbps(dscp_remark:ip_dscp=20),output:2'", "prerequisite":[ { "OFPMeterMod":{ "meter_id":1, "bands":[ { "OFPMeterBandDscpRemark":{ "rate":10000, "prec_level":1 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(nxt=6, traffic_class=72)", "tcp()", "bytes(b'\\x11' * (1500 - 74))" ], "pktps":1750, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } }, { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":18 } } ] }, "kbps":10000 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } }, { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":20 } } ] }, "kbps":10000 } ] } } ] }, { "description":"20Mbps(ethernet/arp)-->'in_port=1,actions=meter:20Mbps(dscp_remark:prec_level=1),output:2'", "prerequisite":[ { "OFPMeterMod":{ "meter_id":1, "bands":[ { "OFPMeterBandDscpRemark":{ "rate":10000, "prec_level":1 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_mac='22:22:22:22:22:22', src_mac='12:11:11:11:11:11')", "bytes(b'\\x11' * (1500 - 42))" ], "pktps":1750, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":20000 } ] } } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/meter/02_DSCP_REMARK_00_KBPS_02_100M.json0000664000175000017500000003031300000000000025720 0ustar00zuulzuul00000000000000[ "meter: 02_DSCP_REMARK_00_KBPS_02_100M", { "description":"200Mbps(ethernet/ipv4(dscp=18)/tcp)-->'in_port=1,actions=meter:100Mbps(dscp_remark:ip_dscp=20),output:2'", "prerequisite":[ { "OFPMeterMod":{ "meter_id":1, "bands":[ { "OFPMeterBandDscpRemark":{ "rate":100000, "prec_level":1 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(proto=6, tos=72)", "tcp()", "bytes(b'\\x11' * (1500 - 54))" ], "pktps":17500, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } }, { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":20 } } ] }, "kbps":100000 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } }, { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":18 } } ] }, "kbps":100000 } ] } } ] }, { "description":"200Mbps(ethernet/ipv6(dscp=18)/tcp)-->'in_port=1,actions=meter:100Mbps(dscp_remark:ip_dscp=20),output:2'", "prerequisite":[ { "OFPMeterMod":{ "meter_id":1, "bands":[ { "OFPMeterBandDscpRemark":{ "rate":100000, "prec_level":1 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(nxt=6, traffic_class=72)", "tcp()", "bytes(b'\\x11' * (1500 - 74))" ], "pktps":17500, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } }, { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":20 } } ] }, "kbps":100000 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } }, { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":18 } } ] }, "kbps":100000 } ] } } ] }, { "description":"200Mbps(ethernet/arp)-->'in_port=1,actions=meter:200Mbps(dscp_remark:prec_level=1),output:2'", "prerequisite":[ { "OFPMeterMod":{ "meter_id":1, "bands":[ { "OFPMeterBandDscpRemark":{ "rate":100000, "prec_level":1 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_mac='22:22:22:22:22:22', src_mac='12:11:11:11:11:11')", "bytes(b'\\x11' * (1500 - 42))" ], "pktps":17500, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":200000 } ] } } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/meter/02_DSCP_REMARK_01_PKTPS_00_100.json0000664000175000017500000003042500000000000025750 0ustar00zuulzuul00000000000000[ "meter: 02_DSCP_REMARK_01_PKTPS_00_100", { "description":"200pktps(ethernet/ipv4(dscp=18)/tcp)-->'in_port=1,actions=meter:100pktps(dscp_remark:ip_dscp=20),output:2'", "prerequisite":[ { "OFPMeterMod":{ "flags":2, "meter_id":1, "bands":[ { "OFPMeterBandDscpRemark":{ "rate":100, "prec_level":1 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(proto=6, tos=72)", "tcp()", "bytes(b'\\x11' * (1500 - 54))" ], "pktps":200, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } }, { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":20 } } ] }, "pktps":100 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } }, { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":18 } } ] }, "pktps":100 } ] } } ] }, { "description":"200pktps(ethernet/ipv6(dscp=18)/tcp)-->'in_port=1,actions=meter:100pktps(dscp_remark:ip_dscp=20),output:2'", "prerequisite":[ { "OFPMeterMod":{ "flags":2, "meter_id":1, "bands":[ { "OFPMeterBandDscpRemark":{ "rate":100, "prec_level":1 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(nxt=6, traffic_class=72)", "tcp()", "bytes(b'\\x11' * (1500 - 74))" ], "pktps":200, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } }, { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":20 } } ] }, "pktps":100 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } }, { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":18 } } ] }, "pktps":100 } ] } } ] }, { "description":"200pktps(ethernet/arp)-->'in_port=1,actions=meter:200pktps(dscp_remark:prec_level=1),output:2'", "prerequisite":[ { "OFPMeterMod":{ "flags":2, "meter_id":1, "bands":[ { "OFPMeterBandDscpRemark":{ "rate":100, "prec_level":1 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_mac='22:22:22:22:22:22', src_mac='12:11:11:11:11:11')", "bytes(b'\\x11' * (1500 - 42))" ], "pktps":200, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "pktps":200 } ] } } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/meter/02_DSCP_REMARK_01_PKTPS_01_1000.json0000664000175000017500000003044700000000000026035 0ustar00zuulzuul00000000000000[ "meter: 02_DSCP_REMARK_01_PKTPS_01_1000", { "description":"2000pktps(ethernet/ipv4(dscp=18)/tcp)-->'in_port=1,actions=meter:1000pktps(dscp_remark:ip_dscp=20),output:2'", "prerequisite":[ { "OFPMeterMod":{ "flags":2, "meter_id":1, "bands":[ { "OFPMeterBandDscpRemark":{ "rate":1000, "prec_level":1 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(proto=6, tos=72)", "tcp()", "bytes(b'\\x11' * (1500 - 54))" ], "pktps":2000, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } }, { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":20 } } ] }, "pktps":1000 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } }, { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":18 } } ] }, "pktps":1000 } ] } } ] }, { "description":"2000pktps(ethernet/ipv6(dscp=18)/tcp)-->'in_port=1,actions=meter:1000pktps(dscp_remark:ip_dscp=20),output:2'", "prerequisite":[ { "OFPMeterMod":{ "flags":2, "meter_id":1, "bands":[ { "OFPMeterBandDscpRemark":{ "rate":1000, "prec_level":1 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(nxt=6, traffic_class=72)", "tcp()", "bytes(b'\\x11' * (1500 - 74))" ], "pktps":2000, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } }, { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":20 } } ] }, "pktps":1000 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } }, { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":18 } } ] }, "pktps":1000 } ] } } ] }, { "description":"2000pktps(ethernet/arp)-->'in_port=1,actions=meter:2000pktps(dscp_remark:prec_level=1),output:2'", "prerequisite":[ { "OFPMeterMod":{ "flags":2, "meter_id":1, "bands":[ { "OFPMeterBandDscpRemark":{ "rate":1000, "prec_level":1 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_mac='22:22:22:22:22:22', src_mac='12:11:11:11:11:11')", "bytes(b'\\x11' * (1500 - 42))" ], "pktps":2000, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "pktps":2000 } ] } } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of13/meter/02_DSCP_REMARK_01_PKTPS_02_10000.json0000664000175000017500000003047100000000000026113 0ustar00zuulzuul00000000000000[ "meter: 02_DSCP_REMARK_01_PKTPS_02_10000", { "description":"20000pktps(ethernet/ipv4(dscp=18)/tcp)-->'in_port=1,actions=meter:10000pktps(dscp_remark:ip_dscp=20),output:2'", "prerequisite":[ { "OFPMeterMod":{ "flags":2, "meter_id":1, "bands":[ { "OFPMeterBandDscpRemark":{ "rate":10000, "prec_level":1 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(proto=6, tos=72)", "tcp()", "bytes(b'\\x11' * (1500 - 54))" ], "pktps":20000, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } }, { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":20 } } ] }, "pktps":10000 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } }, { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":18 } } ] }, "pktps":10000 } ] } } ] }, { "description":"20000pktps(ethernet/ipv6(dscp=18)/tcp)-->'in_port=1,actions=meter:10000pktps(dscp_remark:ip_dscp=20),output:2'", "prerequisite":[ { "OFPMeterMod":{ "flags":2, "meter_id":1, "bands":[ { "OFPMeterBandDscpRemark":{ "rate":10000, "prec_level":1 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(nxt=6, traffic_class=72)", "tcp()", "bytes(b'\\x11' * (1500 - 74))" ], "pktps":20000, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } }, { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":20 } } ] }, "pktps":10000 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } }, { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":18 } } ] }, "pktps":10000 } ] } } ] }, { "description":"20000pktps(ethernet/arp)-->'in_port=1,actions=meter:20000pktps(dscp_remark:prec_level=1),output:2'", "prerequisite":[ { "OFPMeterMod":{ "flags":2, "meter_id":1, "bands":[ { "OFPMeterBandDscpRemark":{ "rate":10000, "prec_level":1 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_mac='22:22:22:22:22:22', src_mac='12:11:11:11:11:11')", "bytes(b'\\x11' * (1500 - 42))" ], "pktps":20000, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "pktps":20000 } ] } } ] } ] ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.0341012 os-ken-2.10.0/os_ken/tests/switch/of14/0000775000175000017500000000000000000000000017503 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003300000000000011451 xustar000000000000000027 mtime=1724334546.250114 os-ken-2.10.0/os_ken/tests/switch/of14/action/0000775000175000017500000000000000000000000020760 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/00_OUTPUT.json0000664000175000017500000001213100000000000023210 0ustar00zuulzuul00000000000000[ "action: 00_OUTPUT", { "description": "ethernet/ipv4/tcp-->'actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/ipv6/tcp-->'actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/arp-->'actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/11_COPY_TTL_OUT.json0000664000175000017500000001222600000000000024203 0ustar00zuulzuul00000000000000[ "action: 11_COPY_TTL_OUT", { "description": "ethernet/mpls(ttl=64)/ipv4(ttl=32)/tcp-->'eth_type=0x8847,actions=copy_ttl_out,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionCopyTtlOut":{} }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=32)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls(ttl=64)/ipv6(hop_limit=32)/tcp-->'eth_type=0x8847,actions=copy_ttl_out,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionCopyTtlOut":{} }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=32, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=32)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=32, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/12_COPY_TTL_IN.json0000664000175000017500000001222100000000000024036 0ustar00zuulzuul00000000000000[ "action: 12_COPY_TTL_IN", { "description": "ethernet/mpls(ttl=64)/ipv4(ttl=32)/tcp-->'eth_type=0x8847,actions=copy_ttl_in,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionCopyTtlIn":{} }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls(ttl=64)/ipv6(hop_limit=32)/tcp-->'eth_type=0x8847,actions=copy_ttl_in,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionCopyTtlIn":{} }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=32, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/15_SET_MPLS_TTL.json0000664000175000017500000001717500000000000024204 0ustar00zuulzuul00000000000000[ "action: 15_SET_MPLS_TTL", { "description": "ethernet/mpls(ttl=64)/ipv4/tcp-->'eth_type=0x8847,actions=set_mpls_ttl:127,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetMplsTtl":{ "mpls_ttl":127 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=127)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls(ttl=64)/ipv6/tcp-->'eth_type=0x8847,actions=set_mpls_ttl:127,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetMplsTtl":{ "mpls_ttl":127 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=127)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls(ttl=64)/arp-->'eth_type=0x8847,actions=set_mpls_ttl:127,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetMplsTtl":{ "mpls_ttl":127 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=127)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/16_DEC_MPLS_TTL.json0000664000175000017500000001650200000000000024136 0ustar00zuulzuul00000000000000[ "action: 16_DEC_MPLS_TTL", { "description": "ethernet/mpls(ttl=64)/ipv4/tcp-->'eth_type=0x8847,actions=dec_mpls_ttl,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionDecMplsTtl":{} }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=63)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls(ttl=64)/ipv6/tcp-->'eth_type=0x8847,actions=dec_mpls_ttl,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionDecMplsTtl":{} }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=63)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls(ttl=64)/arp-->'eth_type=0x8847,actions=dec_mpls_ttl,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionDecMplsTtl":{} }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=63)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/17_PUSH_VLAN.json0000664000175000017500000001656400000000000023575 0ustar00zuulzuul00000000000000[ "action: 17_PUSH_VLAN", { "description": "ethernet/ipv4/tcp-->'eth_type=0x0800,actions=push_vlan:0x8100,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPushVlan":{ "ethertype":33024 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/ipv6/tcp-->'eth_type=0x86dd,actions=push_vlan:0x8100,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPushVlan":{ "ethertype":33024 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/arp-->'eth_type=0x0806,actions=push_vlan:0x8100,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPushVlan":{ "ethertype":33024 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/17_PUSH_VLAN_multiple.json0000664000175000017500000001754000000000000025503 0ustar00zuulzuul00000000000000[ "action: 17_PUSH_VLAN (multiple)", { "description": "ethernet/vlan/ipv4/tcp-->'eth_type=0x0800,actions=push_vlan:0x88a8,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPushVlan":{ "ethertype":34984 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(pcp=3, cfi=0, vid=100, ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv6/tcp-->'eth_type=0x86dd,actions=push_vlan:0x88a8,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPushVlan":{ "ethertype":34984 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(pcp=3, cfi=0, vid=100, ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/arp-->'eth_type=0x0806,actions=push_vlan:0x88a8,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPushVlan":{ "ethertype":34984 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(pcp=3, cfi=0, vid=100, ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/18_POP_VLAN.json0000664000175000017500000002016300000000000023443 0ustar00zuulzuul00000000000000[ "action: 18_POP_VLAN", { "description": "ethernet/vlan(vid=100)/ipv4/tcp-->'eth_type=0x0800,vlan_vid=0,actions=pop_vlan,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"vlan_vid", "mask":4096, "value":4096 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopVlan":{} }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan(vid=100)/ipv6/tcp-->'eth_type=0x86dd,vlan_vid=0,actions=pop_vlan,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"vlan_vid", "mask":4096, "value":4096 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopVlan":{} }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan(vid=100)/arp-->'eth_type=0x0806,vlan_vid=0,actions=pop_vlan,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"vlan_vid", "mask":4096, "value":4096 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopVlan":{} }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/19_PUSH_MPLS.json0000664000175000017500000001653200000000000023605 0ustar00zuulzuul00000000000000[ "action: 19_PUSH_MPLS", { "description": "ethernet/ipv4/tcp-->'eth_type=0x0800,actions=push_mpls:0x8847,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPushMpls":{ "ethertype":34887 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/ipv6/tcp-->'eth_type=0x86dd,actions=push_mpls:0x8847,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPushMpls":{ "ethertype":34887 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/arp-->'eth_type=0x0806,actions=push_mpls:0x8847,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPushMpls":{ "ethertype":34887 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(ttl=0)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/19_PUSH_MPLS_multiple.json0000664000175000017500000001744400000000000025523 0ustar00zuulzuul00000000000000[ "action: 19_PUSH_MPLS (multiple)", { "description": "ethernet/mpls/ipv4/tcp-->'eth_type=0x8847,actions=push_mpls:0x8847,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPushMpls":{ "ethertype":34887 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=0, label=100, exp=3, ttl=64)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/ipv6/tcp-->'eth_type=0x8847,actions=push_mpls:0x8847,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPushMpls":{ "ethertype":34887 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=0, label=100, exp=3, ttl=64)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/arp-->'eth_type=0x8847,actions=push_mpls:0x8847,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPushMpls":{ "ethertype":34887 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=0, label=100, exp=3, ttl=64)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/20_POP_MPLS.json0000664000175000017500000001665600000000000023463 0ustar00zuulzuul00000000000000[ "action: 20_POP_MPLS", { "description": "ethernet/mpls/ipv4/tcp-->'eth_type=0x8847,actions=pop_mpls:0x0800,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/ipv6/tcp-->'eth_type=0x8847,actions=pop_mpls:0x86dd,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/arp-->'eth_type=0x8847,actions=pop_mpls:0x0806,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/23_SET_NW_TTL_IPv4.json0000664000175000017500000003165400000000000024614 0ustar00zuulzuul00000000000000[ "action: 23_SET_NW_TTL (IPv4)", { "description": "ethernet/ipv4(ttl=64)/tcp-->'eth_type=0x0800,actions=set_nw_ttl:32,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetNwTtl":{ "nw_ttl":32 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv4(ttl=64)/tcp-->'eth_type=0x0800,actions=set_nw_ttl:32,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetNwTtl":{ "nw_ttl":32 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/ipv4(ttl=64)/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,eth_type=0x0800,actions=set_nw_ttl:32,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetNwTtl":{ "nw_ttl":32 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/itag/ethernet/ipv4(ttl=64)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,eth_type=0x0800,actions=set_nw_ttl:32,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetNwTtl":{ "nw_ttl":32 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/23_SET_NW_TTL_IPv6.json0000664000175000017500000003212000000000000024603 0ustar00zuulzuul00000000000000[ "action: 23_SET_NW_TTL (IPv6)", { "description": "ethernet/ipv6(hop_limit=64)/tcp-->'eth_type=0x86dd,actions=set_nw_ttl:32,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetNwTtl":{ "nw_ttl":32 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=32, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv6(hop_limit=64)/tcp-->'eth_type=0x86dd,actions=set_nw_ttl:32,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetNwTtl":{ "nw_ttl":32 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=32, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/ipv6(hop_limit=64)/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,eth_type=0x86dd,actions=set_nw_ttl:32,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetNwTtl":{ "nw_ttl":32 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=32, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/itag/ethernet/ipv6(hop_limit=64)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,eth_type=0x86dd,actions=set_nw_ttl:32,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetNwTtl":{ "nw_ttl":32 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=32, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/24_DEC_NW_TTL_IPv4.json0000664000175000017500000003103400000000000024545 0ustar00zuulzuul00000000000000[ "action: 24_DEC_NW_TTL (IPv4)", { "description": "ethernet/ipv4(ttl=64)/tcp-->'eth_type=0x0800,actions=dec_nw_ttl,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionDecNwTtl":{} }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=63)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv4(ttl=64)/tcp-->'eth_type=0x0800,actions=dec_nw_ttl,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionDecNwTtl":{} }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=63)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/ipv4(ttl=64)/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,eth_type=0x0800,actions=dec_nw_ttl,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionDecNwTtl":{} }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=63)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/itag/ethernet/ipv4(ttl=64)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,eth_type=0x0800,actions=dec_nw_ttl,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionDecNwTtl":{} }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=63)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/24_DEC_NW_TTL_IPv6.json0000664000175000017500000003130000000000000024543 0ustar00zuulzuul00000000000000[ "action: 24_DEC_NW_TTL (IPv6)", { "description": "ethernet/ipv6(hop_limit=64)/tcp-->'eth_type=0x86dd,actions=dec_nw_ttl,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionDecNwTtl":{} }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=63, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv6(hop_limit=64)/tcp-->'eth_type=0x86dd,actions=dec_nw_ttl,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionDecNwTtl":{} }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=63, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/ipv6(hop_limit=64)/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,eth_type=0x86dd,actions=dec_nw_ttl,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionDecNwTtl":{} }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=63, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/itag/ethernet/ipv6(hop_limit=64)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,eth_type=0x86dd,actions=dec_nw_ttl,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionDecNwTtl":{} }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=63, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.2581143 os-ken-2.10.0/os_ken/tests/switch/of14/action/25_SET_FIELD/0000775000175000017500000000000000000000000022624 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/25_SET_FIELD/03_ETH_DST.json0000664000175000017500000002050200000000000025152 0ustar00zuulzuul00000000000000[ "action: set_field: 03_ETH_DST", { "description": "ethernet(dst='22:22:22:22:22:22')/ipv4/tcp-->'eth_dst=22:22:22:22:22:22,actions=set_field:ba:bb:bb:bb:bb:bb->eth_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_dst", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"eth_dst", "value":"ba:bb:bb:bb:bb:bb" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet(dst='22:22:22:22:22:22')/ipv6/tcp-->'eth_dst=22:22:22:22:22:22,actions=set_field:ba:bb:bb:bb:bb:bb->eth_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_dst", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"eth_dst", "value":"ba:bb:bb:bb:bb:bb" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet(dst='22:22:22:22:22:22')/arp-->'eth_dst=22:22:22:22:22:22,actions=set_field:ba:bb:bb:bb:bb:bb->eth_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_dst", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"eth_dst", "value":"ba:bb:bb:bb:bb:bb" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/25_SET_FIELD/04_ETH_SRC.json0000664000175000017500000002050200000000000025150 0ustar00zuulzuul00000000000000[ "action: set_field: 04_ETH_SRC", { "description": "ethernet(src='12:11:11:11:11:11')/ipv4/tcp-->'eth_src=12:11:11:11:11:11,actions=set_field:aa:aa:aa:aa:aa:aa->eth_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_src", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"eth_src", "value":"aa:aa:aa:aa:aa:aa" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet(src='12:11:11:11:11:11')/ipv6/tcp-->'eth_src=12:11:11:11:11:11,actions=set_field:aa:aa:aa:aa:aa:aa->eth_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_src", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"eth_src", "value":"aa:aa:aa:aa:aa:aa" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet(src='12:11:11:11:11:11')/arp-->'eth_src=12:11:11:11:11:11,actions=set_field:aa:aa:aa:aa:aa:aa->eth_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_src", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"eth_src", "value":"aa:aa:aa:aa:aa:aa" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/25_SET_FIELD/05_ETH_TYPE.json0000664000175000017500000002024400000000000025306 0ustar00zuulzuul00000000000000[ "action: set_field: 05_ETH_TYPE", { "description": "ethernet(ethertype=0x0800)/ipv4/tcp-->'eth_type=0x0800,actions=set_field:0x8848->eth_type,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"eth_type", "value":34888 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34888)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet(ethertype=0x86dd)/ipv6/tcp-->'eth_type=0x86dd,actions=set_field:0x8848->eth_type,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"eth_type", "value":34888 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34888)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet(ethertype=0x0806)/arp-->'eth_type=0x0806,actions=set_field:0x8848->eth_type,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"eth_type", "value":34888 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34888)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/25_SET_FIELD/06_VLAN_VID.json0000664000175000017500000002126200000000000025271 0ustar00zuulzuul00000000000000[ "action: set_field: 06_VLAN_VID", { "description": "ethernet/vlan(vid=100)/ipv4/tcp-->'vlan_vid=100,actions=set_field:203->vlan_vid,output:2'", "notes":"A value of VLAN_VID (4196) means '100 | OFPVID_PRESENT(0x1000)'.", "notes":"A value of VLAN_VID (4299) means '203 | OFPVID_PRESENT(0x1000)'.", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "value":4196 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"vlan_vid", "value":4299 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan(vid=100)/ipv6/tcp-->'vlan_vid=100,actions=set_field:203->vlan_vid,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "value":4196 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"vlan_vid", "value":4299 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan(vid=100)/arp-->'vlan_vid=100,actions=set_field:203->vlan_vid,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "value":4196 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"vlan_vid", "value":4299 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=203, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/25_SET_FIELD/07_VLAN_PCP.json0000664000175000017500000002240700000000000025274 0ustar00zuulzuul00000000000000[ "action: set_field: 07_VLAN_PCP", { "description": "ethernet/vlan(pcp=3)/ipv4/tcp-->'vlan_pcp=3,actions=set_field:5->vlan_pcp,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "value":4196 } }, { "OXMTlv":{ "field":"vlan_pcp", "value":3 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"vlan_pcp", "value":5 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan(pcp=3)/ipv6/tcp-->'vlan_pcp=3,actions=set_field:5->vlan_pcp,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "value":4196 } }, { "OXMTlv":{ "field":"vlan_pcp", "value":3 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"vlan_pcp", "value":5 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan(pcp=3)/arp-->'vlan_pcp=3,actions=set_field:5->vlan_pcp,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "value":4196 } }, { "OXMTlv":{ "field":"vlan_pcp", "value":3 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"vlan_pcp", "value":5 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/25_SET_FIELD/08_IP_DSCP_IPv4.json0000664000175000017500000003612400000000000026017 0ustar00zuulzuul00000000000000[ "action: set_field: 08_IP_DSCP (IPv4)", { "description": "ethernet/ipv4(tos=32)/tcp-->'ip_dscp=8,actions=set_field:16->ip_dscp,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ip_dscp", "value":16 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=64, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv4(tos=32)/tcp-->'ip_dscp=8,actions=set_field:16->ip_dscp,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ip_dscp", "value":16 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=64, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/ipv4(tos=32)/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,ip_dscp=8,actions=set_field:16->ip_dscp,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ip_dscp", "value":16 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=64, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/itag/ethernet/ipv4(tos=32)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ip_dscp=8,actions=set_field:16->ip_dscp,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ip_dscp", "value":16 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=64, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/25_SET_FIELD/08_IP_DSCP_IPv6.json0000664000175000017500000003641000000000000026017 0ustar00zuulzuul00000000000000[ "action: set_field: 08_IP_DSCP (IPv6)", { "description": "ethernet/ipv6(traffic_class=32)/tcp-->'ip_dscp=8,actions=set_field:16->ip_dscp,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ip_dscp", "value":16 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv6(traffic_class=32)/tcp-->'ip_dscp=8,actions=set_field:16->ip_dscp,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ip_dscp", "value":16 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/ipv6(traffic_class=32)/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ip_dscp=8,actions=set_field:16->ip_dscp,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ip_dscp", "value":16 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/itag/ethernet/ipv6(traffic_class=32)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ip_dscp=8,actions=set_field:16->ip_dscp,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ip_dscp", "value":16 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/25_SET_FIELD/09_IP_ECN_IPv4.json0000664000175000017500000003607300000000000025677 0ustar00zuulzuul00000000000000[ "action: set_field: 09_IP_ECN (IPv4)", { "description": "ethernet/ipv4(tos=32)/tcp-->'ip_ecn=0,actions=set_field:1->ip_ecn,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ip_ecn", "value":1 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=33, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv4(tos=32)/tcp-->'ip_ecn=0,actions=set_field:1->ip_ecn,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ip_ecn", "value":1 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=33, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/ipv4(tos=32)/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,ip_ecn=0,actions=set_field:1->ip_ecn,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ip_ecn", "value":1 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=33, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/itag/ethernet/ipv4(tos=32)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ip_ecn=0,actions=set_field:1->ip_ecn,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ip_ecn", "value":1 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=33, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/25_SET_FIELD/09_IP_ECN_IPv6.json0000664000175000017500000003635700000000000025706 0ustar00zuulzuul00000000000000[ "action: set_field: 09_IP_ECN (IPv6)", { "description": "ethernet/ipv6(traffic_class=32)/tcp-->'ip_ecn=0,actions=set_field:1->ip_ecn,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ip_ecn", "value":1 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=33)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv6(traffic_class=32)/tcp-->'ip_ecn=0,actions=set_field:1->ip_ecn,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ip_ecn", "value":1 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=33)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/ipv6(traffic_class=32)/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ip_ecn=0,actions=set_field:1->ip_ecn,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ip_ecn", "value":1 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=33)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/itag/ethernet/ipv6(traffic_class=32)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ip_ecn=0,actions=set_field:1->ip_ecn,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ip_ecn", "value":1 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=33)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/25_SET_FIELD/10_IP_PROTO_IPv4.json0000664000175000017500000003615500000000000026166 0ustar00zuulzuul00000000000000[ "action: set_field: 10_IP_PROTO (IPv4)", { "description": "ethernet/ipv4(proto=6)/tcp-->'ip_proto=6,actions=set_field:17->ip_proto,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ip_proto", "value":17 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv4(proto=6)/tcp-->'ip_proto=6,actions=set_field:17->ip_proto,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ip_proto", "value":17 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/ipv4(proto=6)/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,ip_proto=6,actions=set_field:17->ip_proto,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ip_proto", "value":17 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/itag/ethernet/ipv4(proto=6)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ip_proto=6,actions=set_field:17->ip_proto,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ip_proto", "value":17 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/25_SET_FIELD/10_IP_PROTO_IPv6.json0000664000175000017500000003636100000000000026167 0ustar00zuulzuul00000000000000[ "action: set_field: 10_IP_PROTO (IPv6)", { "description": "ethernet/ipv6(nxt=6)/tcp-->'ip_proto=6,actions=set_field:17->ip_proto,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ip_proto", "value":17 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv6(nxt=6)/tcp-->'ip_proto=6,actions=set_field:17->ip_proto,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ip_proto", "value":17 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/ipv6(nxt=6)/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ip_proto=6,actions=set_field:17->ip_proto,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ip_proto", "value":17 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/itag/ethernet/ipv6(nxt=6)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ip_proto=6,actions=set_field:17->ip_proto,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ip_proto", "value":17 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/25_SET_FIELD/11_IPV4_SRC.json0000664000175000017500000003650200000000000025257 0ustar00zuulzuul00000000000000[ "action: set_field: 11_IPV4_SRC", { "description": "ethernet/ipv4(src='192.168.10.10')/tcp-->'ipv4_src=192.168.10.10,actions=set_field:10.10.10.10->ipv4_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv4_src", "value":"10.10.10.10" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='10.10.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv4(src='192.168.10.10')/tcp-->'ipv4_src=192.168.10.10,actions=set_field:10.10.10.10->ipv4_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv4_src", "value":"10.10.10.10" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='10.10.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/ipv4(src='192.168.10.10')/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,ipv4_src=192.168.10.10,actions=set_field:10.10.10.10->ipv4_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv4_src", "value":"10.10.10.10" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='10.10.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/itag/ethernet/ipv4(src='192.168.10.10')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv4_src=192.168.10.10,actions=set_field:10.10.10.10->ipv4_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv4_src", "value":"10.10.10.10" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='10.10.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/25_SET_FIELD/12_IPV4_DST.json0000664000175000017500000003650200000000000025263 0ustar00zuulzuul00000000000000[ "action: set_field: 12_IPV4_DST", { "description": "ethernet/ipv4(dst='192.168.20.20')/tcp-->'ipv4_dst=192.168.20.20,actions=set_field:10.10.20.20->ipv4_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv4_dst", "value":"10.10.20.20" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='10.10.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv4(dst='192.168.20.20')/tcp-->'ipv4_dst=192.168.20.20,actions=set_field:10.10.20.20->ipv4_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv4_dst", "value":"10.10.20.20" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='10.10.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/ipv4(dst='192.168.20.20')/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,ipv4_dst=192.168.20.20,actions=set_field:10.10.20.20->ipv4_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv4_dst", "value":"10.10.20.20" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='10.10.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/itag/ethernet/ipv4(dst='192.168.20.20')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv4_dst=192.168.20.20,actions=set_field:10.10.20.20->ipv4_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv4_dst", "value":"10.10.20.20" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='10.10.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/25_SET_FIELD/13_TCP_SRC_IPv4.json0000664000175000017500000004031400000000000026023 0ustar00zuulzuul00000000000000[ "action: set_field: 13_TCP_SRC (IPv4)", { "description": "ethernet/ipv4/tcp(src_port=11111)-->'tcp_src=11111,actions=set_field:12345->tcp_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tcp_src", "value":12345 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv4/tcp(src_port=11111)-->'tcp_src=11111,actions=set_field:12345->tcp_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tcp_src", "value":12345 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/ipv4/tcp(src_port=11111)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,tcp_src=11111,actions=set_field:12345->tcp_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tcp_src", "value":12345 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/itag/ethernet/ipv4/tcp(src_port=11111)-->'actions=pop_pbb,goto_table:1','table_id:1,tcp_src=11111,actions=set_field:12345->tcp_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tcp_src", "value":12345 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/25_SET_FIELD/13_TCP_SRC_IPv6.json0000664000175000017500000004053000000000000026025 0ustar00zuulzuul00000000000000[ "action: set_field: 13_TCP_SRC (IPv6)", { "description": "ethernet/ipv6/tcp(src_port=11111)-->'tcp_src=11111,actions=set_field:12345->tcp_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tcp_src", "value":12345 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv6/tcp(src_port=11111)-->'tcp_src=11111,actions=set_field:12345->tcp_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tcp_src", "value":12345 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/ipv6/tcp(src_port=11111)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,tcp_src=11111,actions=set_field:12345->tcp_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tcp_src", "value":12345 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/itag/ethernet/ipv6/tcp(src_port=11111)-->'actions=pop_pbb,goto_table:1','table_id:1,tcp_src=11111,actions=set_field:12345->tcp_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tcp_src", "value":12345 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/25_SET_FIELD/14_TCP_DST_IPv4.json0000664000175000017500000004027000000000000026030 0ustar00zuulzuul00000000000000[ "action: set_field: 14_TCP_DST (IPv4)", { "description": "ethernet/ipv4/tcp(dst_port=2222)-->'tcp_dst=2222,actions=set_field:6789->tcp_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tcp_dst", "value":6789 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=6789, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv4/tcp(dst_port=2222)-->'tcp_dst=2222,actions=set_field:6789->tcp_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tcp_dst", "value":6789 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=6789, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/ipv4/tcp(dst_port=2222)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,tcp_dst=2222,actions=set_field:6789->tcp_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tcp_dst", "value":6789 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=6789, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/itag/ethernet/ipv4/tcp(dst_port=2222)-->'actions=pop_pbb,goto_table:1','table_id:1,tcp_dst=2222,actions=set_field:6789->tcp_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tcp_dst", "value":6789 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=6789, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/25_SET_FIELD/14_TCP_DST_IPv6.json0000664000175000017500000004050400000000000026032 0ustar00zuulzuul00000000000000[ "action: set_field: 14_TCP_DST (IPv6)", { "description": "ethernet/ipv6/tcp(dst_port=2222)-->'tcp_dst=2222,actions=set_field:6789->tcp_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tcp_dst", "value":6789 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=6789, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv6/tcp(dst_port=2222)-->'tcp_dst=2222,actions=set_field:6789->tcp_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tcp_dst", "value":6789 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=6789, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/ipv6/tcp(dst_port=2222)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,tcp_dst=2222,actions=set_field:6789->tcp_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tcp_dst", "value":6789 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=6789, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/itag/ethernet/ipv6/tcp(dst_port=2222)-->'actions=pop_pbb,goto_table:1','table_id:1,tcp_dst=2222,actions=set_field:6789->tcp_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tcp_dst", "value":6789 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=6789, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/25_SET_FIELD/15_UDP_SRC_IPv4.json0000664000175000017500000003777000000000000026043 0ustar00zuulzuul00000000000000[ "action: set_field: 15_UDP_SRC (IPv4)", { "description": "ethernet/ipv4/udp(src_port=11111)-->'udp_src=11111,actions=set_field:12345->udp_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"udp_src", "value":12345 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv4/udp(src_port=11111)-->'udp_src=11111,actions=set_field:12345->udp_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"udp_src", "value":12345 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/ipv4/udp(src_port=11111)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,udp_src=11111,actions=set_field:12345->udp_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"udp_src", "value":12345 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/itag/ethernet/ipv4/udp(src_port=11111)-->'actions=pop_pbb,goto_table:1','table_id:1,udp_src=11111,actions=set_field:12345->udp_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"udp_src", "value":12345 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/25_SET_FIELD/15_UDP_SRC_IPv6.json0000664000175000017500000004020400000000000026027 0ustar00zuulzuul00000000000000[ "action: set_field: 15_UDP_SRC (IPv6)", { "description": "ethernet/ipv6/udp(src_port=11111)-->'udp_src=11111,actions=set_field:12345->udp_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"udp_src", "value":12345 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv6/udp(src_port=11111)-->'udp_src=11111,actions=set_field:12345->udp_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"udp_src", "value":12345 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/ipv6/udp(src_port=11111)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,udp_src=11111,actions=set_field:12345->udp_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"udp_src", "value":12345 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/itag/ethernet/ipv6/udp(src_port=11111)-->'actions=pop_pbb,goto_table:1','table_id:1,udp_src=11111,actions=set_field:12345->udp_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"udp_src", "value":12345 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/25_SET_FIELD/16_UDP_DST_IPv4.json0000664000175000017500000003774400000000000026050 0ustar00zuulzuul00000000000000[ "action: set_field: 16_UDP_DST (IPv4)", { "description": "ethernet/ipv4/udp(dst_port=2222)-->'udp_dst=2222,actions=set_field:6789->udp_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"udp_dst", "value":6789 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=6789, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv4/udp(dst_port=2222)-->'udp_dst=2222,actions=set_field:6789->udp_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"udp_dst", "value":6789 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=6789, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/ipv4/udp(dst_port=2222)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,udp_dst=2222,actions=set_field:6789->udp_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"udp_dst", "value":6789 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=6789, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/itag/ethernet/ipv4/udp(dst_port=2222)-->'actions=pop_pbb,goto_table:1','table_id:1,udp_dst=2222,actions=set_field:6789->udp_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"udp_dst", "value":6789 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=6789, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/25_SET_FIELD/16_UDP_DST_IPv6.json0000664000175000017500000004016000000000000026034 0ustar00zuulzuul00000000000000[ "action: set_field: 16_UDP_DST (IPv6)", { "description": "ethernet/ipv6/udp(dst_port=2222)-->'udp_dst=2222,actions=set_field:6789->udp_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"udp_dst", "value":6789 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=6789, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv6/udp(dst_port=2222)-->'udp_dst=2222,actions=set_field:6789->udp_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"udp_dst", "value":6789 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=6789, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/ipv6/udp(dst_port=2222)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,udp_dst=2222,actions=set_field:6789->udp_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"udp_dst", "value":6789 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=6789, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/itag/ethernet/ipv6/udp(dst_port=2222)-->'actions=pop_pbb,goto_table:1','table_id:1,udp_dst=2222,actions=set_field:6789->udp_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"udp_dst", "value":6789 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=6789, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/25_SET_FIELD/17_SCTP_SRC_IPv4.json0000664000175000017500000003643100000000000026157 0ustar00zuulzuul00000000000000[ "action: set_field: 17_SCTP_SRC (IPv4)", { "description": "ethernet/ipv4/sctp(src_port=11111)-->'sctp_src=11111,actions=set_field:12345->sctp_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"sctp_src", "value":12345 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=12345)" ] } ] }, { "description": "ethernet/vlan/ipv4/sctp(src_port=11111)-->'sctp_src=11111,actions=set_field:12345->sctp_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"sctp_src", "value":12345 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=12345)" ] } ] }, { "description": "ethernet/mpls/ipv4/sctp(src_port=11111)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,sctp_src=11111,actions=set_field:12345->sctp_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"sctp_src", "value":12345 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=12345)" ] } ] }, { "description": "ethernet/itag/ethernet/ipv4/sctp(src_port=11111)-->'actions=pop_pbb,goto_table:1','table_id:1,sctp_src=11111,actions=set_field:12345->sctp_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"sctp_src", "value":12345 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=12345)" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/25_SET_FIELD/17_SCTP_SRC_IPv6.json0000664000175000017500000003664500000000000026170 0ustar00zuulzuul00000000000000[ "action: set_field: 17_SCTP_SRC (IPv6)", { "description": "ethernet/ipv6/udp(sctp_port=11111)-->'sctp_src=11111,actions=set_field:12345->sctp_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"sctp_src", "value":12345 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=12345)" ] } ] }, { "description": "ethernet/vlan/ipv6/sctp(src_port=11111)-->'sctp_src=11111,actions=set_field:12345->sctp_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"sctp_src", "value":12345 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=12345)" ] } ] }, { "description": "ethernet/mpls/ipv6/sctp(src_port=11111)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,sctp_src=11111,actions=set_field:12345->sctp_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"sctp_src", "value":12345 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=12345)" ] } ] }, { "description": "ethernet/itag/ethernet/ipv6/sctp(src_port=11111)-->'actions=pop_pbb,goto_table:1','table_id:1,sctp_src=11111,actions=set_field:12345->sctp_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"sctp_src", "value":12345 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=12345)" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/25_SET_FIELD/18_SCTP_DST_IPv4.json0000664000175000017500000003640500000000000026164 0ustar00zuulzuul00000000000000[ "action: set_field: 18_SCTP_DST (IPv4)", { "description": "ethernet/ipv4/sctp(dst_port=2222)-->'sctp_dst=2222,actions=set_field:6789->sctp_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"sctp_dst", "value":6789 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=6789, src_port=11111)" ] } ] }, { "description": "ethernet/vlan/ipv4/sctp(dst_port=2222)-->'sctp_dst=2222,actions=set_field:6789->sctp_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"sctp_dst", "value":6789 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=6789, src_port=11111)" ] } ] }, { "description": "ethernet/mpls/ipv4/sctp(dst_port=2222)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,sctp_dst=2222,actions=set_field:6789->sctp_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"sctp_dst", "value":6789 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=6789, src_port=11111)" ] } ] }, { "description": "ethernet/itag/ethernet/ipv4/sctp(dst_port=2222)-->'actions=pop_pbb,goto_table:1','table_id:1,sctp_dst=2222,actions=set_field:6789->sctp_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"sctp_dst", "value":6789 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=6789, src_port=11111)" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/25_SET_FIELD/18_SCTP_DST_IPv6.json0000664000175000017500000003662100000000000026166 0ustar00zuulzuul00000000000000[ "action: set_field: 18_SCTP_DST (IPv6)", { "description": "ethernet/ipv6/sctp(dst_port=2222)-->'sctp_dst=2222,actions=set_field:6789->sctp_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"sctp_dst", "value":6789 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=6789, src_port=11111)" ] } ] }, { "description": "ethernet/vlan/ipv6/sctp(dst_port=2222)-->'sctp_dst=2222,actions=set_field:6789->sctp_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"sctp_dst", "value":6789 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=6789, src_port=11111)" ] } ] }, { "description": "ethernet/mpls/ipv6/sctp(dst_port=2222)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,sctp_dst=2222,actions=set_field:6789->sctp_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"sctp_dst", "value":6789 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=6789, src_port=11111)" ] } ] }, { "description": "ethernet/itag/ethernet/ipv6/sctp(dst_port=2222)-->'actions=pop_pbb,goto_table:1','table_id:1,sctp_dst=2222,actions=set_field:6789->sctp_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"sctp_dst", "value":6789 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=6789, src_port=11111)" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/25_SET_FIELD/19_ICMPV4_TYPE.json0000664000175000017500000003576500000000000025653 0ustar00zuulzuul00000000000000[ "action: set_field: 19_ICMPV4_TYPE", { "description": "ethernet/ipv4/icmp(type=8)-->'icmpv4_type=8,actions=set_field:0->icmpv4_type,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_type", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"icmpv4_type", "value":0 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=0)" ] } ] }, { "description": "ethernet/vlan/ipv4/icmp(type=8)-->'icmpv4_type=8,actions=set_field:0->icmpv4_type,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_type", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"icmpv4_type", "value":0 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=0)" ] } ] }, { "description": "ethernet/mpls/ipv4/icmp(type=8)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,icmpv4_type=8,actions=set_field:0->icmpv4_type,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_type", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"icmpv4_type", "value":0 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=0)" ] } ] }, { "description": "ethernet/itag/ethernet/ipv4/icmp(type=8)-->'actions=pop_pbb,goto_table:1','table_id:1,icmpv4_type=8,actions=set_field:0->icmpv4_type,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_type", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"icmpv4_type", "value":0 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=0)" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/25_SET_FIELD/20_ICMPV4_CODE.json0000664000175000017500000003600100000000000025554 0ustar00zuulzuul00000000000000[ "action: set_field: 20_ICMPV4_CODE", { "description": "ethernet/ipv4/icmp(code=0)-->'icmpv4_code=0,actions=set_field:10->icmpv4_code,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"icmpv4_code", "value":10 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=10,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ] } ] }, { "description": "ethernet/vlan/ipv4/icmp(code=0)-->'icmpv4_code=0,actions=set_field:10->icmpv4_code,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"icmpv4_code", "value":10 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=10,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ] } ] }, { "description": "ethernet/mpls/ipv4/icmp(code=0)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,icmpv4_code=0,actions=set_field:10->icmpv4_code,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"icmpv4_code", "value":10 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=10,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ] } ] }, { "description": "ethernet/itag/ethernet/ipv4/icmp(code=0)-->'actions=pop_pbb,goto_table:1','table_id:1,icmpv4_code=0,actions=set_field:10->icmpv4_code,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"icmpv4_code", "value":10 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=10,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/25_SET_FIELD/21_ARP_OP.json0000664000175000017500000003336200000000000025050 0ustar00zuulzuul00000000000000[ "action: set_field: 21_ARP_OP", { "description": "ethernet/arp(opcode=1)-->'arp_op=1,actions=set_field:2->arp_op,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_op", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"arp_op", "value":2 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=2, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description": "ethernet/vlan/arp(opcode=1)-->'arp_op=1,actions=set_field:2->arp_op,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_op", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"arp_op", "value":2 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=2, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description": "ethernet/mpls/arp(opcode=1)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,arp_op=1,actions=set_field:2->arp_op,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_op", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"arp_op", "value":2 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=2, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description": "ethernet/itag/ethernet/arp(opcode=1)-->'actions=pop_pbb,goto_table:1','table_id:1,arp_op=1,actions=set_field:2->arp_op,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_op", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"arp_op", "value":2 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=2, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/25_SET_FIELD/22_ARP_SPA.json0000664000175000017500000003376300000000000025163 0ustar00zuulzuul00000000000000[ "action: set_field: 22_ARP_SPA", { "description": "ethernet/arp(src_ip='192.168.10.10')-->'arp_spa=192.168.10.10,actions=set_field:10.10.10.10->arp_spa,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"arp_spa", "value":"10.10.10.10" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='10.10.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description": "ethernet/vlan/arp(src_ip='192.168.10.10')-->'arp_spa=192.168.10.10,actions=set_field:10.10.10.10->arp_spa,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"arp_spa", "value":"10.10.10.10" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='10.10.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description": "ethernet/mpls/arp(src_ip='192.168.10.10')-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,arp_spa=192.168.10.10,actions=set_field:10.10.10.10->arp_spa,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"arp_spa", "value":"10.10.10.10" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='10.10.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description": "ethernet/itag/ethernet/arp(src_ip='192.168.10.10')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_spa=192.168.10.10,actions=set_field:10.10.10.10->arp_spa,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"arp_spa", "value":"10.10.10.10" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='10.10.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/25_SET_FIELD/23_ARP_TPA.json0000664000175000017500000003376300000000000025165 0ustar00zuulzuul00000000000000[ "action: set_field: 23_ARP_TPA", { "description": "ethernet/arp(dst_ip='192.168.20.20')-->'arp_tpa=192.168.20.20,actions=set_field:10.10.20.20->arp_tpa,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"arp_tpa", "value":"10.10.20.20" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description": "ethernet/vlan/arp(dst_ip='192.168.20.20')-->'arp_tpa=192.168.20.20,actions=set_field:10.10.20.20->arp_tpa,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"arp_tpa", "value":"10.10.20.20" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description": "ethernet/mpls/arp(dst_ip='192.168.20.20')-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,arp_tpa=192.168.20.20,actions=set_field:10.10.20.20->arp_tpa,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"arp_tpa", "value":"10.10.20.20" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description": "ethernet/itag/ethernet/arp(dst_ip='192.168.20.20')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_tpa=192.168.20.20,actions=set_field:10.10.20.20->arp_tpa,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"arp_tpa", "value":"10.10.20.20" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/25_SET_FIELD/24_ARP_SHA.json0000664000175000017500000003413700000000000025151 0ustar00zuulzuul00000000000000[ "action: set_field: 24_ARP_SHA", { "description": "ethernet/arp(src_mac='12:11:11:11:11:11')-->'arp_sha=12:11:11:11:11:11,actions=set_field:aa:aa:aa:aa:aa:aa->arp_sha,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"arp_sha", "value":"aa:aa:aa:aa:aa:aa" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description": "ethernet/vlan/arp(src_mac='12:11:11:11:11:11')-->'arp_sha=12:11:11:11:11:11,actions=set_field:aa:aa:aa:aa:aa:aa->arp_sha,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"arp_sha", "value":"aa:aa:aa:aa:aa:aa" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * 30)" ] } ] }, { "description": "ethernet/mpls/arp(src_mac='12:11:11:11:11:11')-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,arp_sha=12:11:11:11:11:11,actions=set_field:aa:aa:aa:aa:aa:aa->arp_sha,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"arp_sha", "value":"aa:aa:aa:aa:aa:aa" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description": "ethernet/itag/ethernet/arp(src_mac='12:11:11:11:11:11')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_sha=12:11:11:11:11:11,actions=set_field:aa:aa:aa:aa:aa:aa->arp_sha,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"arp_sha", "value":"aa:aa:aa:aa:aa:aa" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/25_SET_FIELD/25_ARP_THA.json0000664000175000017500000003413700000000000025153 0ustar00zuulzuul00000000000000[ "action: set_field: 25_ARP_THA", { "description": "ethernet/arp(dst_mac='22:22:22:22:22:22')-->'arp_tha=22:22:22:22:22:22,actions=set_field:ba:bb:bb:bb:bb:bb->arp_tha,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"arp_tha", "value":"ba:bb:bb:bb:bb:bb" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description": "ethernet/vlan/arp(dst_mac='22:22:22:22:22:22')-->'arp_tha=22:22:22:22:22:22,actions=set_field:ba:bb:bb:bb:bb:bb->arp_tha,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"arp_tha", "value":"ba:bb:bb:bb:bb:bb" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description": "ethernet/mpls/arp(dst_mac='22:22:22:22:22:22')-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,arp_tha=22:22:22:22:22:22,actions=set_field:ba:bb:bb:bb:bb:bb->arp_tha,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"arp_tha", "value":"ba:bb:bb:bb:bb:bb" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description": "ethernet/itag/ethernet/arp(dst_mac='22:22:22:22:22:22')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_tha=22:22:22:22:22:22,actions=set_field:ba:bb:bb:bb:bb:bb->arp_tha,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"arp_tha", "value":"ba:bb:bb:bb:bb:bb" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/25_SET_FIELD/26_IPV6_SRC.json0000664000175000017500000003653200000000000025272 0ustar00zuulzuul00000000000000[ "action: set_field: 26_IPV6_SRC", { "description": "ethernet/ipv6(src='10::10')/tcp-->'ipv6_src=10::10,actions=set_field:a0::a0->ipv6_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "value":"10::10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv6_src", "value":"a0::a0" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='a0::a0', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv6(src='10::10')/tcp-->'ipv6_src=10::10,actions=set_field:a0::a0->ipv6_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "value":"10::10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv6_src", "value":"a0::a0" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='a0::a0', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/ipv6(src='10::10')/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_src=10::10,actions=set_field:a0::a0->ipv6_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "value":"10::10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv6_src", "value":"a0::a0" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='a0::a0', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/itag/ethernet/ipv6(src='10::10')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_src=10::10,actions=set_field:a0::a0->ipv6_src,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "value":"10::10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv6_src", "value":"a0::a0" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='a0::a0', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/25_SET_FIELD/27_IPV6_DST.json0000664000175000017500000003653300000000000025277 0ustar00zuulzuul00000000000000[ "action: set_field: 27_IPV6_DST", { "description": "ethernet/ipv6(dst='20::20')/tcp-->'ipv6_dst=20::20,actions=set_field:b0::b0->ipv6_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv6_dst", "value":"b0::b0" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv6(dst='20::20')/tcp-->'ipv6_dst=20::20,actions=set_field:b0::b0->ipv6_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv6_dst", "value":"b0::b0" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/ipv6(dst='20::20')/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_dst=20::20,actions=set_field:b0::b0->ipv6_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv6_dst", "value":"b0::b0" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/itag/ethernet/ipv6(dst='20::20')/tcp--->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_dst=20::20,actions=set_field:b0::b0->ipv6_dst,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv6_dst", "value":"b0::b0" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/25_SET_FIELD/28_IPV6_FLABEL.json0000664000175000017500000003652500000000000025574 0ustar00zuulzuul00000000000000[ "action: set_field: 28_IPV6_FLABEL", { "description": "ethernet/ipv6(flow_label=100)/tcp-->'ipv6_flabel=100,actions=set_field:203->ipv6_flabel,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv6_flabel", "value":203 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=203, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/vlan/ipv6(flow_label=100)/tcp-->'ipv6_flabel=100,actions=set_field:203->ipv6_flabel,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv6_flabel", "value":203 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=203, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls/ipv6(flow_label=100)/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_flabel=100,actions=set_field:203->ipv6_flabel,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv6_flabel", "value":203 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=203, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/itag/ethernet/ipv6(flow_label=100)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_flabel=100,actions=set_field:203->ipv6_flabel,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv6_flabel", "value":203 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=203, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/25_SET_FIELD/29_ICMPV6_TYPE.json0000664000175000017500000004043500000000000025644 0ustar00zuulzuul00000000000000[ "action: set_field: 29_ICMPV6_TYPE", { "description": "ethernet/ipv6/icmpv6(type=128)-->'icmpv6_type=128,actions=set_field:135->icmpv6_type,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":128 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"icmpv6_type", "value":135 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=135)" ] } ] }, { "description": "ethernet/vlan/ipv6/icmpv6(type=128)-->'icmpv6_type=128,actions=set_field:135->icmpv6_type,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":128 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"icmpv6_type", "value":135 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=135)" ] } ] }, { "description": "ethernet/mpls/ipv6/icmpv6(type=128)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,icmpv6_type=128,actions=set_field:135->icmpv6_type,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":128 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"icmpv6_type", "value":135 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=135)" ] } ] }, { "description": "ethernet/itag/ethernet/ipv6/icmpv6(type=128)-->'actions=pop_pbb,goto_table:1','table_id:1,icmpv6_type=128,actions=set_field:135->icmpv6_type,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":128 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"icmpv6_type", "value":135 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=135)" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/25_SET_FIELD/30_ICMPV6_CODE.json0000664000175000017500000004036500000000000025567 0ustar00zuulzuul00000000000000[ "action: set_field: 30_ICMPV6_CODE", { "description": "ethernet/ipv6/icmpv6(code=0)-->'icmpv6_code=0,actions=set_field:1->icmpv6_code,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"icmpv6_code", "value":1 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=1,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ] } ] }, { "description": "ethernet/vlan/ipv6/icmpv6(code=0)-->'icmpv6_code=0,actions=set_field:1->icmpv6_code,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"icmpv6_code", "value":1 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=1,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ] } ] }, { "description": "ethernet/mpls/ipv6/icmpv6(code=0)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,icmpv6_code=0,actions=set_field:1->icmpv6_code,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"icmpv6_code", "value":1 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=1,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ] } ] }, { "description": "ethernet/itag/ethernet/ipv6/icmpv6(code=0)-->'actions=pop_pbb,goto_table:1','table_id:1,icmpv6_code=0,actions=set_field:1->icmpv6_code,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"icmpv6_code", "value":1 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=1,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/25_SET_FIELD/31_IPV6_ND_TARGET.json0000664000175000017500000004110400000000000026175 0ustar00zuulzuul00000000000000[ "action: set_field: 31_IPV6_ND_TARGET", { "description": "ethernet/ipv6/icmpv6(data=nd_neighbor(dst='20::20'))-->'ipv6_nd_target=20::20,actions=set_field:a0::a0->ipv6_nd_target,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_target", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv6_nd_target", "value":"a0::a0" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='12:11:11:11:11:11'),dst='20::20'),type_=135)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='12:11:11:11:11:11'),dst='a0::a0'),type_=135)" ] } ] }, { "description": "ethernet/vlan/ipv6/icmpv6(data=nd_neighbor(dst='20::20'))-->'ipv6_nd_target=20::20,actions=set_field:a0::a0->ipv6_nd_target,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_target", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv6_nd_target", "value":"a0::a0" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='12:11:11:11:11:11'),dst='20::20'),type_=135)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='12:11:11:11:11:11'),dst='a0::a0'),type_=135)" ] } ] }, { "description": "ethernet/mpls/ipv6/icmpv6(data=nd_neighbor(dst='20::20'))-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_nd_target=20::20,actions=set_field:a0::a0->ipv6_nd_target,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_target", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv6_nd_target", "value":"a0::a0" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='12:11:11:11:11:11'),dst='20::20'),type_=135)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='12:11:11:11:11:11'),dst='a0::a0'),type_=135)" ] } ] }, { "description": "ethernet/itag/ethernet/ipv6/icmpv6(data=nd_neighbor(dst='20::20'))-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_nd_target=20::20,actions=set_field:a0::a0->ipv6_nd_target,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_target", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv6_nd_target", "value":"a0::a0" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='12:11:11:11:11:11'),dst='20::20'),type_=135)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='12:11:11:11:11:11'),dst='a0::a0'),type_=135)" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/25_SET_FIELD/32_IPV6_ND_SLL.json0000664000175000017500000004151600000000000025651 0ustar00zuulzuul00000000000000[ "action: set_field: 32_IPV6_ND_SLL", { "description": "ethernet/ipv6/icmpv6(data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22')))-->'ipv6_nd_sll=22:22:22:22:22:22,actions=set_field:aa:aa:aa:aa:aa:aa->ipv6_nd_sll,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_sll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv6_nd_sll", "value":"aa:aa:aa:aa:aa:aa" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=135)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='aa:aa:aa:aa:aa:aa'),dst='20::20'),type_=135)" ] } ] }, { "description": "ethernet/vlan/ipv6/icmpv6(data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22')))-->'ipv6_nd_sll=12:11:11:11:11,actions=set_field:aa:aa:aa:aa:aa:aa->ipv6_nd_sll,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_sll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv6_nd_sll", "value":"aa:aa:aa:aa:aa:aa" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=135)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='aa:aa:aa:aa:aa:aa'),dst='20::20'),type_=135)" ] } ] }, { "description": "ethernet/mpls/ipv6/icmpv6(data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22')))-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_nd_sll=22:22:22:22:22:22,actions=set_field:aa:aa:aa:aa:aa:aa->ipv6_nd_sll,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_sll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv6_nd_sll", "value":"aa:aa:aa:aa:aa:aa" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=135)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='aa:aa:aa:aa:aa:aa'),dst='20::20'),type_=135)" ] } ] }, { "description": "ethernet/itag/ethernet/ipv6/icmpv6(data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22')))-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_nd_sll=22:22:22:22:22:22,actions=set_field:aa:aa:aa:aa:aa:aa->ipv6_nd_sll,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_sll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv6_nd_sll", "value":"aa:aa:aa:aa:aa:aa" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=135)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='aa:aa:aa:aa:aa:aa'),dst='20::20'),type_=135)" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/25_SET_FIELD/33_IPV6_ND_TLL.json0000664000175000017500000004152100000000000025647 0ustar00zuulzuul00000000000000[ "action: set_field: 33_IPV6_ND_TLL", { "description": "ethernet/ipv6/icmpv6(data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22')))-->'ipv6_nd_tll=22:22:22:22:22:22,actions=set_field:aa:aa:aa:aa:aa:aa->ipv6_nd_tll,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":136 } }, { "OXMTlv":{ "field":"ipv6_nd_tll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv6_nd_tll", "value":"aa:aa:aa:aa:aa:aa" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=136)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='aa:aa:aa:aa:aa:aa'),dst='20::20'),type_=136)" ] } ] }, { "description": "ethernet/vlan/ipv6/icmpv6(data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22')))-->'ipv6_nd_tll=22:22:22:22:22:22,actions=set_field:aa:aa:aa:aa:aa:aa->ipv6_nd_tll,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":136 } }, { "OXMTlv":{ "field":"ipv6_nd_tll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv6_nd_tll", "value":"aa:aa:aa:aa:aa:aa" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=136)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='aa:aa:aa:aa:aa:aa'),dst='20::20'),type_=136)" ] } ] }, { "description": "ethernet/mpls/ipv6/icmpv6(data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22')))-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_nd_tll=22:22:22:22:22:22,actions=set_field:aa:aa:aa:aa:aa:aa->ipv6_nd_tll,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":136 } }, { "OXMTlv":{ "field":"ipv6_nd_tll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv6_nd_tll", "value":"aa:aa:aa:aa:aa:aa" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=136)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='aa:aa:aa:aa:aa:aa'),dst='20::20'),type_=136)" ] } ] }, { "description": "ethernet/itag/ethernet/ipv6/icmpv6(data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22')))-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_nd_tll=22:22:22:22:22:22,actions=set_field:aa:aa:aa:aa:aa:aa->ipv6_nd_tll,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":136 } }, { "OXMTlv":{ "field":"ipv6_nd_tll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"ipv6_nd_tll", "value":"aa:aa:aa:aa:aa:aa" } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=136)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='aa:aa:aa:aa:aa:aa'),dst='20::20'),type_=136)" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/25_SET_FIELD/34_MPLS_LABEL.json0000664000175000017500000002244200000000000025503 0ustar00zuulzuul00000000000000[ "action: set_field: 34_MPLS_LABEL", { "description": "ethernet/mpls(label=100)/ipv4/tcp-->'mpls_label=100,actions=set_field:203->mpls_label,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_label", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"mpls_label", "value":203 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=203, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls(label=100)/ipv6/tcp-->'mpls_label=100,actions=set_field:203->mpls_label,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_label", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"mpls_label", "value":203 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=203, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls(label=100)/arp-->'mpls_label=100,actions=set_field:203->mpls_label,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_label", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"mpls_label", "value":203 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=203, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/25_SET_FIELD/35_MPLS_TC.json0000664000175000017500000002232700000000000025175 0ustar00zuulzuul00000000000000[ "action: set_field: 35_MPLS_TC", { "description": "ethernet/mpls(exp=3)/ipv4/tcp-->'mpls_tc=3,actions=set_field:5->mpls_tc,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_tc", "value":3 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"mpls_tc", "value":5 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=5, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls(exp=3)/ipv6/tcp-->'mpls_tc=3,actions=set_field:5->mpls_tc,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_tc", "value":3 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"mpls_tc", "value":5 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=5, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls(exp=3)/arp-->'mpls_tc=3,actions=set_field:5->mpls_tc,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_tc", "value":3 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"mpls_tc", "value":5 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=5, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/25_SET_FIELD/36_MPLS_BOS.json0000664000175000017500000002234400000000000025312 0ustar00zuulzuul00000000000000[ "action: set_field: 36_MPLS_BOS", { "description": "ethernet/mpls(bsb=1)/ipv4/tcp-->'mpls_bos=1,actions=set_field:0->mpls_bos,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_bos", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"mpls_bos", "value":0 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=0, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls(bsb=1)/ipv6/tcp-->'mpls_bos=1,actions=set_field:0->mpls_bos,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_bos", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"mpls_bos", "value":0 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=0, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/mpls(bsb=1)/arp-->'mpls_bos=1,actions=set_field:0->mpls_bos,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_bos", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"mpls_bos", "value":0 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=0, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/25_SET_FIELD/37_PBB_ISID.json0000664000175000017500000002545600000000000025257 0ustar00zuulzuul00000000000000[ "action: set_field: 37_PBB_ISID", { "description": "ethernet/svlan/itag(sid=100)/ethernet/svlan/vlan/ipv4/tcp-->'pbb_itag=100,actions=set_field:203->pbb_itag,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_isid", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"pbb_isid", "value":203 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=203)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/svlan/itag(sid=100)/ethernet/svlan/vlan/ipv6/tcp-->'pbb_itag=100,actions=set_field:203->pbb_itag,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_isid", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"pbb_isid", "value":203 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=203)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/svlan/itag(sid=100)/ethernet/svlan/vlan/arp-->'pbb_itag=100,actions=set_field:203->pbb_itag,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_isid", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"pbb_isid", "value":203 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=203)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/25_SET_FIELD/38_TUNNEL_ID.json0000664000175000017500000002651200000000000025420 0ustar00zuulzuul00000000000000[ "action: set_field: 38_TUNNEL_ID", { "description": "ethernet/ipv4/tcp-->'actions=set_field:12345->tunnel_id,goto_table:1','table_id:1,tunnel_id=12345,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tunnel_id", "value":12345 } } } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"tunnel_id", "value":12345 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/ipv6/tcp-->'actions=set_field:12345->tunnel_id,goto_table:1','table_id:1,tunnel_id=12345,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tunnel_id", "value":12345 } } } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"tunnel_id", "value":12345 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/arp-->'actions=set_field:12345->tunnel_id,goto_table:1','table_id:1,tunnel_id=12345,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tunnel_id", "value":12345 } } } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"tunnel_id", "value":12345 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/25_SET_FIELD/41_PBB_UCA.json0000664000175000017500000002545500000000000025131 0ustar00zuulzuul00000000000000[ "action: set_field: 41_PBB_UCA", { "description": "ethernet/svlan/itag(uca=0)/ethernet/svlan/vlan/ipv4/tcp-->'pbb_uca=0,actions=set_field:1->pbb_uca,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_uca", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"pbb_uca", "value":1 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(uca=0, sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(uca=1, sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/svlan/itag(uca=0)/ethernet/svlan/vlan/ipv6/tcp-->'pbb_uca=0,actions=set_field:1->pbb_uca,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_uca", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"pbb_uca", "value":1 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(uca=0, sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(uca=1, sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/svlan/itag(uca=0)/ethernet/svlan/vlan/arp-->'pbb_uca=0,actions=set_field:1->pbb_uca,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_uca", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"pbb_uca", "value":1 } } } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(uca=0, sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(uca=1, sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/26_PUSH_PBB.json0000664000175000017500000001715100000000000023431 0ustar00zuulzuul00000000000000[ "action: 26_PUSH_PBB", { "description": "ethernet/ipv4/tcp-->'eth_type=0x0800,actions=push_pbb:0x88e7,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPushPbb":{ "ethertype":35047 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag()", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/ipv6/tcp-->'eth_type=0x86dd,actions=push_pbb:0x88e7,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPushPbb":{ "ethertype":35047 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag()", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/arp-->'eth_type=0x0806,actions=push_pbb:0x88e7,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPushPbb":{ "ethertype":35047 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag()", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/26_PUSH_PBB_multiple.json0000664000175000017500000002135700000000000025347 0ustar00zuulzuul00000000000000[ "action: 26_PUSH_PBB (multiple)", { "description": "ethernet/ipv4/tcp-->'eth_type=0x0800,actions=push_pbb:0x88e7,push_pbb:0x88e7,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPushPbb":{ "ethertype":35047 } }, { "OFPActionPushPbb":{ "ethertype":35047 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag()", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag()", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/ipv6/tcp-->'eth_type=0x86dd,actions=push_pbb:0x88e7,push_pbb:0x88e7,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPushPbb":{ "ethertype":35047 } }, { "OFPActionPushPbb":{ "ethertype":35047 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag()", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag()", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/arp-->'eth_type=0x0806,actions=push_pbb:0x88e7,push_pbb:0x88e7,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPushPbb":{ "ethertype":35047 } }, { "OFPActionPushPbb":{ "ethertype":35047 } }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag()", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag()", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/action/27_POP_PBB.json0000664000175000017500000002011000000000000023276 0ustar00zuulzuul00000000000000[ "action: 27_POP_PBB", { "description": "ethernet/itag/ethernet/svlan/vlan/ipv4/tcp-->'eth_type=0x88e7,actions=pop_pbb,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/itag/ethernet/svlan/vlan/ipv6/tcp-->'eth_type=0x88e7,actions=pop_pbb,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description": "ethernet/itag/ethernet/svlan/vlan/arp-->'eth_type=0x88e7,actions=pop_pbb,output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} }, { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] } ] ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.2621145 os-ken-2.10.0/os_ken/tests/switch/of14/group/0000775000175000017500000000000000000000000020637 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/group/00_ALL.json0000664000175000017500000002732600000000000022453 0ustar00zuulzuul00000000000000[ "group: 00_ALL", { "description":"2Mbps(ethernet/ipv4/tcp)-->'in_port=1,actions=group:all(actions=output:2/actions=output:3)'", "prerequisite":[ { "OFPGroupMod":{ "group_id":0, "buckets":[ { "OFPBucket":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ] } }, { "OFPBucket":{ "actions":[ { "OFPActionOutput":{ "port":3 } } ] } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionGroup":{ "group_id":0 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(proto=6)", "tcp()", "bytes(b'\\x11' * (1500 - 54))" ], "pktps":175, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":2000 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":3 } } ] }, "kbps":2000 } ] } } ] }, { "description":"2Mbps(ethernet/ipv6/tcp)-->'in_port=1,actions=group:all(actions=output:2/actions=output:3)'", "prerequisite":[ { "OFPGroupMod":{ "group_id":0, "buckets":[ { "OFPBucket":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ] } }, { "OFPBucket":{ "actions":[ { "OFPActionOutput":{ "port":3 } } ] } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionGroup":{ "group_id":0 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(nxt=6)", "tcp()", "bytes(b'\\x11' * (1500 - 74))" ], "pktps":175, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":2000 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":3 } } ] }, "kbps":2000 } ] } } ] }, { "description":"2Mbps(ethernet/arp)-->'in_port=1,actions=group:all(actions=output:2/actions=output:3)'", "prerequisite":[ { "OFPGroupMod":{ "group_id":0, "buckets":[ { "OFPBucket":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ] } }, { "OFPBucket":{ "actions":[ { "OFPActionOutput":{ "port":3 } } ] } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionGroup":{ "group_id":0 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_mac='22:22:22:22:22:22', src_mac='12:11:11:11:11:11')", "bytes(b'\\x11' * (1500 - 42))" ], "pktps":175, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":2000 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":3 } } ] }, "kbps":2000 } ] } } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/group/01_SELECT_Ether.json0000664000175000017500000003045000000000000024142 0ustar00zuulzuul00000000000000[ "group: 01_SELECT_Ether", { "description":"2Mbps(ethernet(dst=random,src=random)/ipv4/tcp)-->'in_port=1,actions=group:select(actions=output:2/actions=output:3)'", "prerequisite":[ { "OFPGroupMod":{ "group_id":0, "type":1, "buckets":[ { "OFPBucket":{ "weight":1, "actions":[ { "OFPActionOutput":{ "port":2 } } ] } }, { "OFPBucket":{ "weight":1, "actions":[ { "OFPActionOutput":{ "port":3 } } ] } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionGroup":{ "group_id":0 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst=netaddr.EUI(randint(0, 2 ** 48 - 1)), src=netaddr.EUI(randint(0, 2 ** 48 - 1) & 0xfeffffffffff), ethertype=2048)", "ipv4(proto=6)", "tcp()", "bytes(b'\\x11' * (1500 - 54))" ], "pktps":175, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":1000 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":3 } } ] }, "kbps":1000 } ] } } ] }, { "description":"2Mbps(ethernet(dst=random,src=random)/ipv6/tcp)-->'in_port=1,actions=group:select(actions=output:2/actions=output:3)'", "prerequisite":[ { "OFPGroupMod":{ "group_id":0, "type":1, "buckets":[ { "OFPBucket":{ "weight":1, "actions":[ { "OFPActionOutput":{ "port":2 } } ] } }, { "OFPBucket":{ "weight":1, "actions":[ { "OFPActionOutput":{ "port":3 } } ] } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionGroup":{ "group_id":0 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst=netaddr.EUI(randint(0, 2 ** 48 - 1)), src=netaddr.EUI(randint(0, 2 ** 48 - 1) & 0xfeffffffffff), ethertype=34525)", "ipv6(nxt=6)", "tcp()", "bytes(b'\\x11' * (1500 - 74))" ], "pktps":175, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":1000 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":3 } } ] }, "kbps":1000 } ] } } ] }, { "description":"2Mbps(ethernet(dst=random,src=random)/arp)-->'in_port=1,actions=group:select(actions=output:2/actions=output:3)'", "prerequisite":[ { "OFPGroupMod":{ "group_id":0, "type":1, "buckets":[ { "OFPBucket":{ "weight":1, "actions":[ { "OFPActionOutput":{ "port":2 } } ] } }, { "OFPBucket":{ "weight":1, "actions":[ { "OFPActionOutput":{ "port":3 } } ] } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionGroup":{ "group_id":0 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst=netaddr.EUI(randint(0, 2 ** 48 - 1)), src=netaddr.EUI(randint(0, 2 ** 48 - 1) & 0xfeffffffffff), ethertype=2054)", "arp(dst_mac='22:22:22:22:22:22', src_mac='12:11:11:11:11:11')", "bytes(b'\\x11' * (1500 - 42))" ], "pktps":175, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":1000 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":3 } } ] }, "kbps":1000 } ] } } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/group/01_SELECT_IP.json0000664000175000017500000003117700000000000023412 0ustar00zuulzuul00000000000000[ "group: 01_SELECT_IP", { "description":"2Mbps(ethernet/ipv4(src=random,dst=random)/tcp(src_port=random,dst_port=random))-->'in_port=1,actions=group:select(actions=output:2/actions=output:3)'", "prerequisite":[ { "OFPGroupMod":{ "group_id":0, "type":1, "buckets":[ { "OFPBucket":{ "weight":1, "actions":[ { "OFPActionOutput":{ "port":2 } } ] } }, { "OFPBucket":{ "weight":1, "actions":[ { "OFPActionOutput":{ "port":3 } } ] } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionGroup":{ "group_id":0 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(proto=6, dst=netaddr.IPAddress(randint(0, 2 ** 32 - 1)), src=netaddr.IPAddress(randint(0, 2 ** 32 - 1)))", "tcp(dst_port=randint(0, 2 ** 16 - 1), src_port=randint(0, 2 ** 16 - 1))", "bytes(b'\\x11' * (1500 - 54))" ], "pktps":175, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":1000 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":3 } } ] }, "kbps":1000 } ] } } ] }, { "description":"2Mbps(ethernet/ipv6(src=random,dst=random)/tcp(src_port=random,dst_port=random))-->'in_port=1,actions=group:select(actions=output:2/actions=output:3)'", "prerequisite":[ { "OFPGroupMod":{ "group_id":0, "type":1, "buckets":[ { "OFPBucket":{ "weight":1, "actions":[ { "OFPActionOutput":{ "port":2 } } ] } }, { "OFPBucket":{ "weight":1, "actions":[ { "OFPActionOutput":{ "port":3 } } ] } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionGroup":{ "group_id":0 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(nxt=6, dst=netaddr.IPAddress(randint(0, 2 ** 128 - 1)), src=netaddr.IPAddress(randint(0, 2 ** 128 - 1)))", "tcp(dst_port=randint(0, 2 ** 16 - 1), src_port=randint(0, 2 ** 16 - 1))", "bytes(b'\\x11' * (1500 - 74))" ], "pktps":175, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":1000 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":3 } } ] }, "kbps":1000 } ] } } ] }, { "description":"2Mbps(ethernet/arp(src_ip=random,dst_ip=random)-->'in_port=1,actions=group:select(actions=output:2/actions=output:3)'", "prerequisite":[ { "OFPGroupMod":{ "group_id":0, "type":1, "buckets":[ { "OFPBucket":{ "weight":1, "actions":[ { "OFPActionOutput":{ "port":2 } } ] } }, { "OFPBucket":{ "weight":1, "actions":[ { "OFPActionOutput":{ "port":3 } } ] } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionGroup":{ "group_id":0 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_mac='22:22:22:22:22:22', src_mac='12:11:11:11:11:11', dst_ip=netaddr.IPAddress(randint(0, 2 ** 32 - 1)), src_ip=netaddr.IPAddress(randint(0, 2 ** 32 - 1)))", "bytes(b'\\x11' * (1500 - 42))" ], "pktps":175, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":1000 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":3 } } ] }, "kbps":1000 } ] } } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/group/01_SELECT_Weight_Ether.json0000664000175000017500000003054200000000000025453 0ustar00zuulzuul00000000000000[ "group: 01_SELECT_Weight_Ether", { "description":"2Mbps(ethernet(dst=random,src=random)/ipv4/tcp)-->'in_port=1,actions=group:select(weight=1,actions=output:2/weight=2,actions=output:3)'", "prerequisite":[ { "OFPGroupMod":{ "group_id":0, "type":1, "buckets":[ { "OFPBucket":{ "weight":1, "actions":[ { "OFPActionOutput":{ "port":2 } } ] } }, { "OFPBucket":{ "weight":2, "actions":[ { "OFPActionOutput":{ "port":3 } } ] } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionGroup":{ "group_id":0 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst=netaddr.EUI(randint(0, 2 ** 48 - 1)), src=netaddr.EUI(randint(0, 2 ** 48 - 1) & 0xfeffffffffff), ethertype=2048)", "ipv4(proto=6)", "tcp()", "bytes(b'\\x11' * (1500 - 54))" ], "pktps":175, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":667 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":3 } } ] }, "kbps":1333 } ] } } ] }, { "description":"2Mbps(ethernet(dst=random,src=random)/ipv6/tcp)-->'in_port=1,actions=group:select(weight=1,actions=output:2/weight=2,actions=output:3)'", "prerequisite":[ { "OFPGroupMod":{ "group_id":0, "type":1, "buckets":[ { "OFPBucket":{ "weight":1, "actions":[ { "OFPActionOutput":{ "port":2 } } ] } }, { "OFPBucket":{ "weight":2, "actions":[ { "OFPActionOutput":{ "port":3 } } ] } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionGroup":{ "group_id":0 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst=netaddr.EUI(randint(0, 2 ** 48 - 1)), src=netaddr.EUI(randint(0, 2 ** 48 - 1) & 0xfeffffffffff), ethertype=34525)", "ipv6(nxt=6)", "tcp()", "bytes(b'\\x11' * (1500 - 74))" ], "pktps":175, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":667 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":3 } } ] }, "kbps":1333 } ] } } ] }, { "description":"2Mbps(ethernet(dst=random,src=random)/arp)-->'in_port=1,actions=group:select(weight=1,actions=output:2/weight=2,actions=output:3)'", "prerequisite":[ { "OFPGroupMod":{ "group_id":0, "type":1, "buckets":[ { "OFPBucket":{ "weight":1, "actions":[ { "OFPActionOutput":{ "port":2 } } ] } }, { "OFPBucket":{ "weight":2, "actions":[ { "OFPActionOutput":{ "port":3 } } ] } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionGroup":{ "group_id":0 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst=netaddr.EUI(randint(0, 2 ** 48 - 1)), src=netaddr.EUI(randint(0, 2 ** 48 - 1) & 0xfeffffffffff), ethertype=2054)", "arp(dst_mac='22:22:22:22:22:22', src_mac='12:11:11:11:11:11')", "bytes(b'\\x11' * (1500 - 42))" ], "pktps":175, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":667 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":3 } } ] }, "kbps":1333 } ] } } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/group/01_SELECT_Weight_IP.json0000664000175000017500000003127100000000000024714 0ustar00zuulzuul00000000000000[ "group: 01_SELECT_Weight_IP", { "description":"2Mbps(ethernet/ipv4(src=random,dst=random)/tcp(src_port=random,dst_port=random))-->'in_port=1,actions=group:select(weight=1,actions=output:2/weight=2,actions=output:3)'", "prerequisite":[ { "OFPGroupMod":{ "group_id":0, "type":1, "buckets":[ { "OFPBucket":{ "weight":1, "actions":[ { "OFPActionOutput":{ "port":2 } } ] } }, { "OFPBucket":{ "weight":2, "actions":[ { "OFPActionOutput":{ "port":3 } } ] } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionGroup":{ "group_id":0 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(proto=6, dst=netaddr.IPAddress(randint(0, 2 ** 32 - 1)), src=netaddr.IPAddress(randint(0, 2 ** 32 - 1)))", "tcp(dst_port=randint(0, 2 ** 16 - 1), src_port=randint(0, 2 ** 16 - 1))", "bytes(b'\\x11' * (1500 - 54))" ], "pktps":175, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":667 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":3 } } ] }, "kbps":1333 } ] } } ] }, { "description":"2Mbps(ethernet/ipv6(src=random,dst=random)/tcp(src_port=random,dst_port=random))-->'in_port=1,actions=group:select(weight=1,actions=output:2/weight=2,actions=output:3)'", "prerequisite":[ { "OFPGroupMod":{ "group_id":0, "type":1, "buckets":[ { "OFPBucket":{ "weight":1, "actions":[ { "OFPActionOutput":{ "port":2 } } ] } }, { "OFPBucket":{ "weight":2, "actions":[ { "OFPActionOutput":{ "port":3 } } ] } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionGroup":{ "group_id":0 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(nxt=6, dst=netaddr.IPAddress(randint(0, 2 ** 128 - 1)), src=netaddr.IPAddress(randint(0, 2 ** 128 - 1)))", "tcp(dst_port=randint(0, 2 ** 16 - 1), src_port=randint(0, 2 ** 16 - 1))", "bytes(b'\\x11' * (1500 - 74))" ], "pktps":175, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":667 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":3 } } ] }, "kbps":1333 } ] } } ] }, { "description":"2Mbps(ethernet/arp(src_ip=random,dst_ip=random)-->'in_port=1,actions=group:select(weight=1,actions=output:2/weight=2,actions=output:3)'", "prerequisite":[ { "OFPGroupMod":{ "group_id":0, "type":1, "buckets":[ { "OFPBucket":{ "weight":1, "actions":[ { "OFPActionOutput":{ "port":2 } } ] } }, { "OFPBucket":{ "weight":2, "actions":[ { "OFPActionOutput":{ "port":3 } } ] } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionGroup":{ "group_id":0 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_mac='22:22:22:22:22:22', src_mac='12:11:11:11:11:11', dst_ip=netaddr.IPAddress(randint(0, 2 ** 32 - 1)), src_ip=netaddr.IPAddress(randint(0, 2 ** 32 - 1)))", "bytes(b'\\x11' * (1500 - 42))" ], "pktps":175, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":667 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":3 } } ] }, "kbps":1333 } ] } } ] } ] ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.2821157 os-ken-2.10.0/os_ken/tests/switch/of14/match/0000775000175000017500000000000000000000000020577 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/00_IN_PORT.json0000664000175000017500000004457400000000000023161 0ustar00zuulzuul00000000000000[ "match: 00_IN_PORT", { "description":"ethernet/ipv4/tcp-->'in_port=1,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4/tcp-->'in_port=1,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4/tcp-->'in_port=2,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/ipv6/tcp-->'in_port=1,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6/tcp-->'in_port=1,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6/tcp-->'in_port=2,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/arp-->'in_port=1,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp-->'in_port=1,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp-->'in_port=2,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 0 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/02_METADATA.json0000664000175000017500000006331700000000000023165 0ustar00zuulzuul00000000000000[ "match: 02_METADATA", { "description":"ethernet/ipv4/tcp-->'actions=write_metadata:255/0xffffffff,goto_table:1','table_id:1,metadata=255,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[] } }, "instructions":[ { "OFPInstructionWriteMetadata":{ "metadata":255, "metadata_mask":4294967295 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"metadata", "value":255 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4/tcp-->'actions=write_metadata:255/0xffffffff,goto_table:1','table_id:1,metadata=255,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[] } }, "instructions":[ { "OFPInstructionWriteMetadata":{ "metadata":255, "metadata_mask":4294967295 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"metadata", "value":255 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4/tcp-->'actions=write_metadata:155/0xffffffff,goto_table:1','table_id:1,metadata=255,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[] } }, "instructions":[ { "OFPInstructionWriteMetadata":{ "metadata":155, "metadata_mask":4294967295 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"metadata", "value":255 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/ipv6/tcp-->'actions=write_metadata:255/0xffffffff,goto_table:1','table_id:1,metadata=255,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[] } }, "instructions":[ { "OFPInstructionWriteMetadata":{ "metadata":255, "metadata_mask":4294967295 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"metadata", "value":255 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6/tcp-->'actions=write_metadata:255/0xffffffff,goto_table:1','table_id=1,metadata=255,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[] } }, "instructions":[ { "OFPInstructionWriteMetadata":{ "metadata":255, "metadata_mask":4294967295 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"metadata", "value":255 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6/tcp-->'actions=write_metadata:155/0xffffffff,goto_table:1','table_id:1,metadata=255,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[] } }, "instructions":[ { "OFPInstructionWriteMetadata":{ "metadata":155, "metadata_mask":4294967295 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"metadata", "value":255 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/arp-->'actions=write_metadata:255/0xffffffff,goto_table:1','table_id:1,metadata=255,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[] } }, "instructions":[ { "OFPInstructionWriteMetadata":{ "metadata":255, "metadata_mask":4294967295 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"metadata", "value":255 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp-->'actions=write_metadata:255/0xffffffff,goto_table:1','table_id:1,metadata=255,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[] } }, "instructions":[ { "OFPInstructionWriteMetadata":{ "metadata":255, "metadata_mask":4294967295 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"metadata", "value":255 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp-->'actions=write_metadata:155/0xffffffff,goto_table:1','table_id:1,metadata=255,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[] } }, "instructions":[ { "OFPInstructionWriteMetadata":{ "metadata":155, "metadata_mask":4294967295 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"metadata", "value":255 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/02_METADATA_Mask.json0000664000175000017500000006460200000000000024136 0ustar00zuulzuul00000000000000[ "match: 02_METADATA (Mask)", { "description":"ethernet/ipv4/tcp-->'actions=write_metadata:255/0xffffffff,goto_table:1','table_id:1,metadata=240(mask=0xfffffff0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[] } }, "instructions":[ { "OFPInstructionWriteMetadata":{ "metadata":255, "metadata_mask":4294967295 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"metadata", "mask":4294967280, "value":240 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4/tcp-->'actions=write_metadata:255/0xffffffff,goto_table:1','table_id:1,metadata=240(mask=0xfffffff0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[] } }, "instructions":[ { "OFPInstructionWriteMetadata":{ "metadata":255, "metadata_mask":4294967295 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"metadata", "mask":4294967280, "value":240 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4/tcp-->'actions=write_metadata:155/0xffffffff,goto_table:1','table_id:1,metadata=240(mask=0xfffffff0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[] } }, "instructions":[ { "OFPInstructionWriteMetadata":{ "metadata":155, "metadata_mask":4294967295 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"metadata", "mask":4294967280, "value":240 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/ipv6/tcp-->'actions=write_metadata:255/0xffffffff,goto_table:1','table_id:1,metadata=240(mask=0xfffffff0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[] } }, "instructions":[ { "OFPInstructionWriteMetadata":{ "metadata":255, "metadata_mask":4294967295 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"metadata", "mask":4294967280, "value":240 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6/tcp-->'actions=write_metadata:255/0xffffffff,goto_table:1','table_id:1,metadata=240(mask=0xfffffff0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[] } }, "instructions":[ { "OFPInstructionWriteMetadata":{ "metadata":255, "metadata_mask":4294967295 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"metadata", "mask":4294967280, "value":240 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6/tcp-->'actions=write_metadata:155/0xffffffff,goto_table:1','table_id:1,metadata=240(mask=0xfffffff0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[] } }, "instructions":[ { "OFPInstructionWriteMetadata":{ "metadata":155, "metadata_mask":4294967295 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"metadata", "mask":4294967280, "value":240 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/arp-->'actions=write_metadata:255/0xffffffff,goto_table:1','table_id:1,metadata=240(mask=0xfffffff0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[] } }, "instructions":[ { "OFPInstructionWriteMetadata":{ "metadata":255, "metadata_mask":4294967295 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"metadata", "mask":4294967280, "value":240 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp-->'actions=write_metadata:255/0xffffffff,goto_table:1','table_id:1,metadata=240(mask=0xfffffff0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[] } }, "instructions":[ { "OFPInstructionWriteMetadata":{ "metadata":255, "metadata_mask":4294967295 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"metadata", "mask":4294967280, "value":240 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp-->'actions=write_metadata:155/0xffffffff,goto_table:1','table_id:1,metadata=240(mask=0xfffffff0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[] } }, "instructions":[ { "OFPInstructionWriteMetadata":{ "metadata":155, "metadata_mask":4294967295 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"metadata", "mask":4294967280, "value":240 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/03_ETH_DST.json0000664000175000017500000004561700000000000023143 0ustar00zuulzuul00000000000000[ "match: 03_ETH_DST", { "description":"ethernet(dst='22:22:22:22:22:22')/ipv4/tcp-->'eth_dst=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_dst", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet(dst='22:22:22:22:22:22')/ipv4/tcp-->'eth_dst=22:22:22:22:22:22,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_dst", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet(dst='ba:bb:bb:bb:bb:bb')/ipv4/tcp-->'eth_dst=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_dst", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet(dst='22:22:22:22:22:22')/ipv6/tcp-->'eth_dst=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_dst", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet(dst='22:22:22:22:22:22')/ipv6/tcp-->'eth_dst=22:22:22:22:22:22,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_dst", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet(dst='ba:bb:bb:bb:bb:bb')/ipv6/tcp-->'eth_dst=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_dst", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet(dst='22:22:22:22:22:22')/arp-->'eth_dst=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_dst", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet(dst='22:22:22:22:22:22')/arp-->'eth_dst=22:22:22:22:22:22,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_dst", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet(dst='ba:bb:bb:bb:bb:bb')/arp-->'eth_dst=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_dst", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 0 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/03_ETH_DST_Mask.json0000664000175000017500000004732200000000000024111 0ustar00zuulzuul00000000000000[ "match: 03_ETH_DST (Mask)", { "description":"ethernet(dst='22:22:22:22:22:22')/ipv4/tcp-->'eth_dst=22:22:22:22:22:00(mask=ff:ff:ff:ff:ff:00),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_dst", "mask":"ff:ff:ff:ff:ff:00", "value":"22:22:22:22:22:00" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet(dst='22:22:22:22:22:22')/ipv4/tcp-->'eth_dst=22:22:22:22:22:00(mask=ff:ff:ff:ff:ff:00),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_dst", "mask":"ff:ff:ff:ff:ff:00", "value":"22:22:22:22:22:00" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet(dst='ba:bb:bb:bb:bb:bb')/ipv4/tcp-->'eth_dst=22:22:22:22:22:00(mask=ff:ff:ff:ff:ff:00),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_dst", "mask":"ff:ff:ff:ff:ff:00", "value":"22:22:22:22:22:00" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet(dst='22:22:22:22:22:22')/ipv6/tcp-->'eth_dst=22:22:22:22:22:00(mask=ff:ff:ff:ff:ff:00),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_dst", "mask":"ff:ff:ff:ff:ff:00", "value":"22:22:22:22:22:00" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet(dst='22:22:22:22:22:22')/ipv6/tcp-->'eth_dst=22:22:22:22:22:00(mask=ff:ff:ff:ff:ff:00),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_dst", "mask":"ff:ff:ff:ff:ff:00", "value":"22:22:22:22:22:00" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet(dst='ba:bb:bb:bb:bb:bb')/ipv6/tcp-->'eth_dst=22:22:22:22:22:00(mask=ff:ff:ff:ff:ff:00),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_dst", "mask":"ff:ff:ff:ff:ff:00", "value":"22:22:22:22:22:00" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet(dst='22:22:22:22:22:22')/arp-->'eth_dst=22:22:22:22:22:00(mask=ff:ff:ff:ff:ff:00),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_dst", "mask":"ff:ff:ff:ff:ff:00", "value":"22:22:22:22:22:00" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet(dst='22:22:22:22:22:22')/arp-->'eth_dst=22:22:22:22:22:00(mask=ff:ff:ff:ff:ff:00),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_dst", "mask":"ff:ff:ff:ff:ff:00", "value":"22:22:22:22:22:00" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet(dst='ba:bb:bb:bb:bb:bb')/arp-->'eth_dst=22:22:22:22:22:00(mask=ff:ff:ff:ff:ff:00),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_dst", "mask":"ff:ff:ff:ff:ff:00", "value":"22:22:22:22:22:00" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 0 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/04_ETH_SRC.json0000664000175000017500000004561700000000000023141 0ustar00zuulzuul00000000000000[ "match: 04_ETH_SRC", { "description":"ethernet(src='12:11:11:11:11:11')/ipv4/tcp-->'eth_src=12:11:11:11:11:11,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_src", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet(src='12:11:11:11:11:11')/ipv4/tcp-->'eth_src=12:11:11:11:11:11,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_src", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet(src='aa:aa:aa:aa:aa:aa')/ipv4/tcp-->'eth_src=12:11:11:11:11:11,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_src", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet(src='12:11:11:11:11:11')/ipv6/tcp-->'eth_src=12:11:11:11:11:11,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_src", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet(src='12:11:11:11:11:11')/ipv6/tcp-->'eth_src=12:11:11:11:11:11,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_src", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet(src='aa:aa:aa:aa:aa:aa')/ipv6/tcp-->'eth_src=12:11:11:11:11:11,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_src", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet(src='12:11:11:11:11:11')/arp-->'eth_src=12:11:11:11:11:11,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_src", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet(src='12:11:11:11:11:11')/arp-->'eth_src=12:11:11:11:11:11,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_src", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet(src='aa:aa:aa:aa:aa:aa')/arp-->'eth_src=12:11:11:11:11:11,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_src", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 0 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/04_ETH_SRC_Mask.json0000664000175000017500000004732200000000000024107 0ustar00zuulzuul00000000000000[ "match: 04_ETH_SRC (Mask)", { "description":"ethernet(src='12:11:11:11:11:11')/ipv4/tcp-->'eth_src=00:11:11:11:11:11(mask=00:ff:ff:ff:ff:ff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_src", "mask":"00:ff:ff:ff:ff:ff", "value":"00:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet(src='12:11:11:11:11:11')/ipv4/tcp-->'eth_src=00:11:11:11:11:11(mask=00:ff:ff:ff:ff:ff),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_src", "mask":"00:ff:ff:ff:ff:ff", "value":"00:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet(src='aa:aa:aa:aa:aa:aa')/ipv4/tcp-->'eth_src=00:11:11:11:11:11(mask=00:ff:ff:ff:ff:ff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_src", "mask":"00:ff:ff:ff:ff:ff", "value":"00:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet(src='12:11:11:11:11:11')/ipv6/tcp-->'eth_src=00:11:11:11:11:11(mask=00:ff:ff:ff:ff:ff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_src", "mask":"00:ff:ff:ff:ff:ff", "value":"00:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet(src='12:11:11:11:11:11')/ipv6/tcp-->'eth_src=00:11:11:11:11:11(mask=00:ff:ff:ff:ff:ff),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_src", "mask":"00:ff:ff:ff:ff:ff", "value":"00:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet(src='aa:aa:aa:aa:aa:aa')/ipv6/tcp-->'eth_src=00:11:11:11:11:11(mask=00:ff:ff:ff:ff:ff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_src", "mask":"00:ff:ff:ff:ff:ff", "value":"00:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet(src='12:11:11:11:11:11')/arp-->'eth_src=00:11:11:11:11:11(mask=00:ff:ff:ff:ff:ff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_src", "mask":"00:ff:ff:ff:ff:ff", "value":"00:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet(src='12:11:11:11:11:11')/arp-->'eth_src=00:11:11:11:11:11(mask=00:ff:ff:ff:ff:ff),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_src", "mask":"00:ff:ff:ff:ff:ff", "value":"00:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet(src='aa:aa:aa:aa:aa:aa')/arp-->'eth_src=00:11:11:11:11:11(mask=00:ff:ff:ff:ff:ff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_src", "mask":"00:ff:ff:ff:ff:ff", "value":"00:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 0 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/05_ETH_TYPE.json0000664000175000017500000004517300000000000023271 0ustar00zuulzuul00000000000000[ "match: 05_ETH_TYPE", { "description":"ethernet(ethertype=0x0800)/ipv4/tcp-->'eth_type=0x0800,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet(ethertype=0x0800)/ipv4/tcp-->'eth_type=0x0800,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet(ethertype=0x0800)/ipv4/tcp-->'eth_type=0x0806,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet(ethertype=0x86dd)/ipv6/tcp-->'eth_type=0x86dd,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet(ethertype=0x86dd)/ipv6/tcp-->'eth_type=0x86dd,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet(ethertype=0x86dd)/ipv6/tcp-->'eth_type=0x0806,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet(ethertype=0x0806)/arp-->'eth_type=0x0806,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet(ethertype=0x0806)/arp-->'eth_type=0x0806,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet(ethertype=0x0806)/arp-->'eth_type=0x0800,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 0 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/06_VLAN_VID.json0000664000175000017500000004714700000000000023256 0ustar00zuulzuul00000000000000[ "match: 06_VLAN_VID", { "description":"ethernet/vlan(vid=100)/ipv4/tcp-->'vlan_vid=100,actions=output:2'", "notes":"A value of VLAN_VID (4196) means '100 | OFPVID_PRESENT(0x1000)'.", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "value":4196 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan(vid=100)/ipv4/tcp-->'vlan_vid=100,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "value":4196 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan(vid=203)/ipv4/tcp-->'vlan_vid=100,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "value":4196 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan(vid=100)/ipv6/tcp-->'vlan_vid=100,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "value":4196 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan(vid=100)/ipv6/tcp-->'vlan_vid=100,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "value":4196 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan(vid=203)/ipv6/tcp-->'vlan_vid=100,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "value":4196 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan(vid=100)/arp-->'vlan_vid=100,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "value":4196 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/vlan(vid=100)/arp-->'vlan_vid=100,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "value":4196 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/vlan(vid=203)/arp-->'vlan_vid=100,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "value":4196 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * 30)" ], "table-miss":[ 0 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/06_VLAN_VID_Mask.json0000664000175000017500000005006600000000000024223 0ustar00zuulzuul00000000000000[ "match: 06_VLAN_VID (Mask)", { "description":"ethernet/vlan(vid=100)/ipv4/tcp-->'vlan_vid=96(mask=0xf0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "mask":240, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan(vid=100)/ipv4/tcp-->'vlan_vid=96(mask=0xf0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "mask":240, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan(vid=203)/ipv4/tcp-->'vlan_vid=96(mask=0xf0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "mask":240, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan(vid=100)/ipv6/tcp-->'vlan_vid=96(mask=0xf0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "mask":240, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan(vid=100)/ipv6/tcp-->'vlan_vid=96(mask=0xf0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "mask":240, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan(vid=203)/ipv6/tcp-->'vlan_vid=96(mask=0xf0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "mask":240, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan(vid=100)/arp-->'vlan_vid=96(mask=0xf0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "mask":240, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/vlan(vid=100)/arp-->'vlan_vid=96(mask=0xf0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "mask":240, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/vlan(vid=203)/arp-->'vlan_vid=96(mask=0xf0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "mask":240, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * 30)" ], "table-miss":[ 0 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/07_VLAN_PCP.json0000664000175000017500000005442400000000000023253 0ustar00zuulzuul00000000000000[ "match: 07_VLAN_PCP", { "description":"ethernet/vlan(pcp=3)/ipv4/tcp-->'vlan_pcp=3,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "mask":null, "value":4196 } }, { "OXMTlv":{ "field":"vlan_pcp", "value":3 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan(pcp=3)/ipv4/tcp-->'vlan_pcp=3,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "mask":null, "value":4196 } }, { "OXMTlv":{ "field":"vlan_pcp", "value":3 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan(pcp=5)/ipv4/tcp-->'vlan_pcp=3,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "mask":null, "value":4196 } }, { "OXMTlv":{ "field":"vlan_pcp", "value":3 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan(pcp=3)/ipv6/tcp-->'vlan_pcp=3,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "mask":null, "value":4196 } }, { "OXMTlv":{ "field":"vlan_pcp", "value":3 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan(pcp=3)/ipv6/tcp-->'vlan_pcp=3,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "mask":null, "value":4196 } }, { "OXMTlv":{ "field":"vlan_pcp", "value":3 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan(pcp=5)/ipv6/tcp-->'vlan_pcp=3,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "mask":null, "value":4196 } }, { "OXMTlv":{ "field":"vlan_pcp", "value":3 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan(pcp=3)/arp-->'vlan_pcp=3,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "mask":null, "value":4196 } }, { "OXMTlv":{ "field":"vlan_pcp", "value":3 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/vlan(pcp=3)/arp-->'vlan_pcp=3,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "mask":null, "value":4196 } }, { "OXMTlv":{ "field":"vlan_pcp", "value":3 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/vlan(pcp=5)/arp-->'vlan_pcp=3,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"vlan_vid", "mask":null, "value":4196 } }, { "OXMTlv":{ "field":"vlan_pcp", "value":3 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * 30)" ], "table-miss":[ 0 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/08_IP_DSCP_IPv4.json0000664000175000017500000011246700000000000023777 0ustar00zuulzuul00000000000000[ "match: 08_IP_DSCP (IPv4)", { "description":"ethernet/ipv4(tos=32)/tcp-->'ip_dscp=8,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4(tos=32)/tcp-->'ip_dscp=8,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4(tos=65)/tcp-->'ip_dscp=8,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv4(tos=32)/tcp-->'ip_dscp=8,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv4(tos=32)/tcp-->'ip_dscp=8,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv4(tos=65)/tcp-->'ip_dscp=8,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv4(tos=32)/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,ip_dscp=8,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv4(tos=32)/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,ip_dscp=8,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv4(tos=65)/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,ip_dscp=8,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv4(tos=32)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ip_dscp=8,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4(tos=32)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ip_dscp=8,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4(tos=65)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ip_dscp=8,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/08_IP_DSCP_IPv6.json0000664000175000017500000011343700000000000023777 0ustar00zuulzuul00000000000000[ "match: 08_IP_DSCP (IPv6)", { "description":"ethernet/ipv6(traffic_class=32)/tcp-->'ip_dscp=8,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6(traffic_class=32)/tcp-->'ip_dscp=8,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6(traffic_class=65)/tcp-->'ip_dscp=8,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv6(traffic_class=32)/tcp-->'ip_dscp=8,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6(traffic_class=32)/tcp-->'ip_dscp=8,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6(traffic_class=65)/tcp-->'ip_dscp=8,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv6(traffic_class=32)/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ip_dscp=8,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6(traffic_class=32)/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ip_dscp=8,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6(traffic_class=65)/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ip_dscp=8,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(traffic_class=32)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ip_dscp=8,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(traffic_class=32)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ip_dscp=8,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(traffic_class=65)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ip_dscp=8,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/09_IP_ECN_IPv4.json0000664000175000017500000011243700000000000023651 0ustar00zuulzuul00000000000000 [ "match: 09_IP_ECN (IPv4)", { "description":"ethernet/ipv4(tos=32)/tcp-->'ip_ecn=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4(tos=32)/tcp-->'ip_ecn=0,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4(tos=65)/tcp-->'ip_ecn=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv4(tos=32)/tcp-->'ip_ecn=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv4(tos=32)/tcp-->'ip_ecn=0,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv4(tos=65)/tcp-->'ip_ecn=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv4(tos=32)/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,ip_ecn=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv4(tos=32)/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,ip_ecn=0,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv4(tos=65)/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,ip_ecn=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv4(tos=32)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ip_ecn=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4(tos=32)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ip_ecn=0,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4(tos=65)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ip_ecn=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/09_IP_ECN_IPv6.json0000664000175000017500000011340600000000000023650 0ustar00zuulzuul00000000000000[ "match: 09_IP_ECN (IPv6)", { "description":"ethernet/ipv6(traffic_class=32)/tcp-->'ip_ecn=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6(traffic_class=32)/tcp-->'ip_ecn=0,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6(traffic_class=65)/tcp-->'ip_ecn=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv6(traffic_class=32)/tcp-->'ip_ecn=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6(traffic_class=32)/tcp-->'ip_ecn=0,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6(traffic_class=65)/tcp-->'ip_ecn=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv6(traffic_class=32)/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ip_ecn=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6(traffic_class=32)/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ip_ecn=0,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6(traffic_class=65)/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ip_ecn=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(traffic_class=32)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ip_ecn=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(traffic_class=32)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ip_ecn=0,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(traffic_class=65)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ip_ecn=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_ecn", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/10_IP_PROTO_IPv4.json0000664000175000017500000011254400000000000024136 0ustar00zuulzuul00000000000000[ "match: 10_IP_PROTO (IPv4)", { "description":"ethernet/ipv4(proto=6)/tcp-->'ip_proto=6,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4(proto=6)/tcp-->'ip_proto=6,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4(proto=6)/tcp-->'ip_proto=17,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv4(proto=6)/tcp-->'ip_proto=6,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv4(proto=6)/tcp-->'ip_proto=6,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv4(proto=6)/tcp-->'ip_proto=17,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv4(proto=6)/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,ip_proto=6,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv4(proto=6)/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,ip_proto=6,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv4(proto=6)/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,ip_proto=17,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv4(proto=6)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ip_proto=6,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4(proto=6)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ip_proto=6,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4(proto=6)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ip_proto=17,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/10_IP_PROTO_IPv6.json0000664000175000017500000011327400000000000024141 0ustar00zuulzuul00000000000000[ "match: 10_IP_PROTO (IPv6)", { "description":"ethernet/ipv6(nxt=6)/tcp-->'ip_proto=6,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6(nxt=6)/tcp-->'ip_proto=6,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6(nxt=6)/tcp-->'ip_proto=17,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv6(nxt=6)/tcp-->'ip_proto=6,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6(nxt=6)/tcp-->'ip_proto=6,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6(nxt=6)/tcp-->'ip_proto=17,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv6(nxt=6)/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ip_proto=6,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6(nxt=6)/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ip_proto=6,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6(nxt=6)/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ip_proto=17,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(nxt=6)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ip_proto=6,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(nxt=6)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ip_proto=6,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(nxt=6)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ip_proto=17,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/11_IPV4_SRC.json0000664000175000017500000011342500000000000023232 0ustar00zuulzuul00000000000000[ "match: 11_IPV4_SRC", { "description":"ethernet/ipv4(src='192.168.10.10')/tcp-->'ipv4_src=192.168.10.10,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4(src='192.168.10.10')/tcp-->'ipv4_src=192.168.10.10,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4(src='10.10.10.10')/tcp-->'ipv4_src=192.168.10.10,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv4(src='192.168.10.10')/tcp-->'ipv4_src=192.168.10.10,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv4(src='192.168.10.10')/tcp-->'ipv4_src=192.168.10.10,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv4(src='10.10.10.10')/tcp-->'ipv4_src=192.168.10.10,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv4(src='192.168.10.10')/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,ipv4_src=192.168.10.10,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv4(src='192.168.10.10')/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,ipv4_src=192.168.10.10,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv4(src='10.10.10.10')/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,ipv4_src=192.168.10.10,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv4(src='192.168.10.10')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv4_src=192.168.10.10,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4(src='192.168.10.10')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv4_src=192.168.10.10,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4(src='10.10.10.10')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv4_src=192.168.10.10,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/11_IPV4_SRC_Mask.json0000664000175000017500000011536400000000000024211 0ustar00zuulzuul00000000000000[ "match: 11_IPV4_SRC (Mask)", { "description":"ethernet/ipv4(src='192.168.10.10')/tcp-->'ipv4_src=192.168.10.0(mask=255.255.255.0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "mask":"255.255.255.0", "value":"192.168.10.0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4(src='192.168.10.10')/tcp-->'ipv4_src=192.168.10.0(mask=255.255.255.0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "mask":"255.255.255.0", "value":"192.168.10.0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4(src='10.10.10.10')/tcp-->'ipv4_src=192.168.10.0(mask=255.255.255.0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "mask":"255.255.255.0", "value":"192.168.10.0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv4(src='192.168.10.10')/tcp-->'ipv4_src=192.168.10.0(mask=255.255.255.0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "mask":"255.255.255.0", "value":"192.168.10.0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv4(src='192.168.10.10')/tcp-->'ipv4_src=192.168.10.0(mask=255.255.255.0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "mask":"255.255.255.0", "value":"192.168.10.0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv4(src='10.10.10.10')/tcp-->'ipv4_src=192.168.10.0(mask=255.255.255.0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "mask":"255.255.255.0", "value":"192.168.10.0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv4(src='192.168.10.10')/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,ipv4_src=192.168.10.0(mask=255.255.255.0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "mask":"255.255.255.0", "value":"192.168.10.0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv4(src='192.168.10.10')/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,ipv4_src=192.168.10.0(mask=255.255.255.0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "mask":"255.255.255.0", "value":"192.168.10.0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv4(src='10.10.10.10')/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,ipv4_src=192.168.10.0(mask=255.255.255.0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "mask":"255.255.255.0", "value":"192.168.10.0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv4(src='192.168.10.10')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv4_src=192.168.10.0(mask=255.255.255.0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "mask":"255.255.255.0", "value":"192.168.10.0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4(src='192.168.10.10')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv4_src=192.168.10.0(mask=255.255.255.0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "mask":"255.255.255.0", "value":"192.168.10.0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4(src='10.10.10.10')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv4_src=192.168.10.0(mask=255.255.255.0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_src", "mask":"255.255.255.0", "value":"192.168.10.0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/12_IPV4_DST.json0000664000175000017500000011342500000000000023236 0ustar00zuulzuul00000000000000[ "match: 12_IPV4_DST", { "description":"ethernet/ipv4(dst='192.168.20.20')/tcp-->'ipv4_dst=192.168.20.20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4(dst='192.168.20.20')/tcp-->'ipv4_dst=192.168.20.20,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4(dst='10.10.20.20')/tcp-->'ipv4_dst=192.168.20.20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv4(dst='192.168.20.20')/tcp-->'ipv4_dst=192.168.20.20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv4(dst='192.168.20.20')/tcp-->'ipv4_dst=192.168.20.20,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv4(dst='10.10.20.20')/tcp-->'ipv4_dst=192.168.20.20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv4(dst='192.168.20.20')/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,ipv4_dst=192.168.20.20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv4(dst='192.168.20.20')/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,ipv4_dst=192.168.20.20,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv4(dst='10.10.20.20')/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,ipv4_dst=192.168.20.20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv4(dst='192.168.20.20')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv4_dst=192.168.20.20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4(dst='192.168.20.20')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv4_dst=192.168.20.20,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4(dst='10.10.20.20')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv4_dst=192.168.20.20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/12_IPV4_DST_Mask.json0000664000175000017500000011536500000000000024216 0ustar00zuulzuul00000000000000 [ "match: 12_IPV4_DST (Mask)", { "description":"ethernet/ipv4(dst='192.168.20.20')/tcp-->'ipv4_dst=192.168.0.20(mask=255.255.0.255),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "mask":"255.255.0.255", "value":"192.168.0.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4(dst='192.168.20.20')/tcp-->'ipv4_dst=192.168.0.20(mask=255.255.0.255),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "mask":"255.255.0.255", "value":"192.168.0.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4(dst='10.10.20.20')/tcp-->'ipv4_dst=192.168.0.20(mask=255.255.0.255),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "mask":"255.255.0.255", "value":"192.168.0.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv4(dst='192.168.20.20')/tcp-->'ipv4_dst=192.168.0.20(mask=255.255.0.255),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "mask":"255.255.0.255", "value":"192.168.0.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv4(dst='192.168.20.20')/tcp-->'ipv4_dst=192.168.0.20(mask=255.255.0.255),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "mask":"255.255.0.255", "value":"192.168.0.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv4(dst='10.10.20.20')/tcp-->'ipv4_dst=192.168.0.20(mask=255.255.0.255),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "mask":"255.255.0.255", "value":"192.168.0.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv4(dst='192.168.20.20')/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,ipv4_dst=192.168.0.20(mask=255.255.0.255),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "mask":"255.255.0.255", "value":"192.168.0.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv4(dst='192.168.20.20')/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,ipv4_dst=192.168.0.20(mask=255.255.0.255),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "mask":"255.255.0.255", "value":"192.168.0.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv4(dst='10.10.20.20')/tcp-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,ipv4_dst=192.168.0.20(mask=255.255.0.255),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "mask":"255.255.0.255", "value":"192.168.0.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv4(dst='192.168.20.20')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv4_dst=192.168.0.20(mask=255.255.0.255),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "mask":"255.255.0.255", "value":"192.168.0.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4(dst='192.168.20.20')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv4_dst=192.168.0.20(mask=255.255.0.255),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "mask":"255.255.0.255", "value":"192.168.0.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4(dst='10.10.20.20')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv4_dst=192.168.0.20(mask=255.255.0.255),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ipv4_dst", "mask":"255.255.0.255", "value":"192.168.0.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/13_TCP_SRC_IPv4.json0000664000175000017500000012112700000000000024000 0ustar00zuulzuul00000000000000[ "match: 13_TCP_SRC (IPv4)", { "description":"ethernet/ipv4/tcp(src_port=11111)-->'tcp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4/tcp(src_port=11111)-->'tcp_src=11111,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4/tcp(src_port=12345)-->'tcp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv4/tcp(src_port=11111)-->'tcp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv4/tcp(src_port=11111)-->'tcp_src=11111,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv4/tcp(src_port=12345)-->'tcp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv4/tcp(src_port=11111)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,tcp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv4/tcp(src_port=11111)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,tcp_src=11111,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv4/tcp(src_port=12345)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,tcp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv4/tcp(src_port=11111)-->'actions=pop_pbb,goto_table:1','table_id:1,tcp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4/tcp(src_port=11111)-->'actions=pop_pbb,goto_table:1','table_id:1,tcp_src=11111,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4/tcp(src_port=12345)-->'actions=pop_pbb,goto_table:1','table_id:1,tcp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/13_TCP_SRC_IPv6.json0000664000175000017500000012170700000000000024006 0ustar00zuulzuul00000000000000[ "match: 13_TCP_SRC (IPv6)", { "description":"ethernet/ipv6/tcp(src_port=11111)-->'tcp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6/tcp(src_port=11111)-->'tcp_src=11111,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6/tcp(src_port=12345)-->'tcp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv6/tcp(src_port=11111)-->'tcp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6/tcp(src_port=11111)-->'tcp_src=11111,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6/tcp(src_port=12345)-->'tcp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv6/tcp(src_port=11111)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,tcp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6/tcp(src_port=11111)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,tcp_src=11111,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6/tcp(src_port=12345)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,tcp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/tcp(src_port=11111)-->'actions=pop_pbb,goto_table:1','table_id:1,tcp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/tcp(src_port=11111)-->'actions=pop_pbb,goto_table:1','table_id:1,tcp_src=11111,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/tcp(src_port=12345)-->'actions=pop_pbb,goto_table:1','table_id:1,tcp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/14_TCP_DST_IPv4.json0000664000175000017500000012106300000000000024003 0ustar00zuulzuul00000000000000[ "match: 14_TCP_DST (IPv4)", { "description":"ethernet/ipv4/tcp(dst_port=2222)-->'tcp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4/tcp(dst_port=2222)-->'tcp_dst=2222,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4/tcp(dst_port=6789)-->'tcp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv4/tcp(dst_port=2222)-->'tcp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv4/tcp(dst_port=2222)-->'tcp_dst=2222,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv4/tcp(dst_port=6789)-->'tcp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv4/tcp(dst_port=2222)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,tcp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv4/tcp(dst_port=2222)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,tcp_dst=2222,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv4/tcp(dst_port=6789)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,tcp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv4/tcp(dst_port=2222)-->'actions=pop_pbb,goto_table:1','table_id:1,tcp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4/tcp(dst_port=2222)-->'actions=pop_pbb,goto_table:1','table_id:1,tcp_dst=2222,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4/tcp(dst_port=6789)-->'actions=pop_pbb,goto_table:1','table_id:1,tcp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/14_TCP_DST_IPv6.json0000664000175000017500000012164300000000000024011 0ustar00zuulzuul00000000000000[ "match: 14_TCP_DST (IPv6)", { "description":"ethernet/ipv6/tcp(dst_port=2222)-->'tcp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6/tcp(dst_port=2222)-->'tcp_dst=2222,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6/tcp(dst_port=6789)-->'tcp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv6/tcp(dst_port=2222)-->'tcp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6/tcp(dst_port=2222)-->'tcp_dst=2222,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6/tcp(dst_port=6789)-->'tcp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv6/tcp(dst_port=2222)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,tcp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6/tcp(dst_port=2222)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,tcp_dst=2222,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6/tcp(dst_port=6789)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,tcp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/tcp(dst_port=2222)-->'actions=pop_pbb,goto_table:1','table_id:1,tcp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/tcp(dst_port=2222)-->'actions=pop_pbb,goto_table:1','table_id:1,tcp_dst=2222,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/tcp(dst_port=6789)-->'actions=pop_pbb,goto_table:1','table_id:1,tcp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":6 } }, { "OXMTlv":{ "field":"tcp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/15_UDP_SRC_IPv4.json0000664000175000017500000012010700000000000024001 0ustar00zuulzuul00000000000000[ "match: 15_UDP_SRC (IPv4)", { "description":"ethernet/ipv4/udp(src_port=11111)-->'udp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4/udp(src_port=11111)-->'udp_src=11111,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4/udp(src_port=12345)-->'udp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=17, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "udp(dst_port=6789, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv4/udp(src_port=11111)-->'udp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv4/udp(src_port=11111)-->'udp_src=11111,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv4/udp(src_port=12345)-->'udp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=17, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "udp(dst_port=6789, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv4/udp(src_port=11111)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,udp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv4/udp(src_port=11111)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,udp_src=11111,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv4/udp(src_port=12345)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,udp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv4(tos=65, proto=17, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "udp(dst_port=6789, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv4/udp(src_port=11111)-->'actions=pop_pbb,goto_table:1','table_id:1,udp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4/udp(src_port=11111)-->'actions=pop_pbb,goto_table:1','table_id:1,udp_src=11111,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4/udp(src_port=12345)-->'actions=pop_pbb,goto_table:1','table_id:1,udp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=17, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "udp(dst_port=6789, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/15_UDP_SRC_IPv6.json0000664000175000017500000012066700000000000024016 0ustar00zuulzuul00000000000000[ "match: 15_UDP_SRC (IPv6)", { "description":"ethernet/ipv6/udp(src_port=11111)-->'udp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6/udp(src_port=11111)-->'udp_src=11111,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6/udp(src_port=12345)-->'udp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=17, hop_limit=127, traffic_class=65)", "udp(dst_port=6789, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv6/udp(src_port=11111)-->'udp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6/udp(src_port=11111)-->'udp_src=11111,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6/udp(src_port=12345)-->'udp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=17, hop_limit=127, traffic_class=65)", "udp(dst_port=6789, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv6/udp(src_port=11111)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,udp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6/udp(src_port=11111)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,udp_src=11111,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6/udp(src_port=12345)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,udp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=17, hop_limit=127, traffic_class=65)", "udp(dst_port=6789, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/udp(src_port=11111)-->'actions=pop_pbb,goto_table:1','table_id:1,udp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/udp(src_port=11111)-->'actions=pop_pbb,goto_table:1','table_id:1,udp_src=11111,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/udp(src_port=12345)-->'actions=pop_pbb,goto_table:1','table_id:1,udp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=17, hop_limit=127, traffic_class=65)", "udp(dst_port=6789, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/16_UDP_DST_IPv4.json0000664000175000017500000012004300000000000024004 0ustar00zuulzuul00000000000000[ "match: 16_UDP_DST (IPv4)", { "description":"ethernet/ipv4/udp(dst_port=2222)-->'udp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4/udp(dst_port=2222)-->'udp_dst=2222,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4/udp(dst_port=6789)-->'udp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=17, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "udp(dst_port=6789, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv4/udp(dst_port=2222)-->'udp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv4/udp(dst_port=2222)-->'udp_dst=2222,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv4/udp(dst_port=6789)-->'udp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=17, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "udp(dst_port=6789, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv4/udp(dst_port=2222)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,udp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv4/udp(dst_port=2222)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,udp_dst=2222,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv4/udp(dst_port=6789)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,udp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv4(tos=65, proto=17, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "udp(dst_port=6789, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv4/udp(dst_port=2222)-->'actions=pop_pbb,goto_table:1','table_id:1,udp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4/udp(dst_port=2222)-->'actions=pop_pbb,goto_table:1','table_id:1,udp_dst=2222,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=17, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4/udp(dst_port=6789)-->'actions=pop_pbb,goto_table:1','table_id:1,udp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=17, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "udp(dst_port=6789, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/16_UDP_DST_IPv6.json0000664000175000017500000012062300000000000024012 0ustar00zuulzuul00000000000000[ "match: 16_UDP_DST (IPv6)", { "description":"ethernet/ipv6/udp(dst_port=2222)-->'udp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6/udp(dst_port=2222)-->'udp_dst=2222,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6/udp(dst_port=6789)-->'udp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=17, hop_limit=127, traffic_class=65)", "udp(dst_port=6789, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv6/udp(dst_port=2222)-->'udp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6/udp(dst_port=2222)-->'udp_dst=2222,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6/udp(dst_port=6789)-->'udp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=17, hop_limit=127, traffic_class=65)", "udp(dst_port=6789, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv6/udp(dst_port=2222)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,udp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6/udp(dst_port=2222)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,udp_dst=2222,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6/udp(dst_port=6789)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,udp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=17, hop_limit=127, traffic_class=65)", "udp(dst_port=6789, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/udp(dst_port=2222)-->'actions=pop_pbb,goto_table:1','table_id:1,udp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/udp(dst_port=2222)-->'actions=pop_pbb,goto_table:1','table_id:1,udp_dst=2222,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=17, hop_limit=64, traffic_class=32)", "udp(dst_port=2222, src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/udp(dst_port=6789)-->'actions=pop_pbb,goto_table:1','table_id:1,udp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":17 } }, { "OXMTlv":{ "field":"udp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=17, hop_limit=127, traffic_class=65)", "udp(dst_port=6789, src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/17_SCTP_SRC_IPv4.json0000664000175000017500000011441400000000000024130 0ustar00zuulzuul00000000000000[ "match: 17_SCTP_SRC (IPv4)", { "description":"ethernet/ipv4/sctp(src_port=11111)-->'sctp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/ipv4/sctp(src_port=11111)-->'sctp_src=11111,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/ipv4/sctp(src_port=12345)-->'sctp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=132, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=6789, src_port=12345)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv4/sctp(src_port=11111)-->'sctp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/vlan/ipv4/sctp(src_port=11111)-->'sctp_src=11111,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/vlan/ipv4/sctp(src_port=12345)-->'sctp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=132, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=6789, src_port=12345)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv4/sctp(src_port=11111)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,sctp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/mpls/ipv4/sctp(src_port=11111)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,sctp_src=11111,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/mpls/ipv4/sctp(src_port=12345)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,sctp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv4(tos=65, proto=132, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=6789, src_port=12345)" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv4/sctp(src_port=11111)-->'actions=pop_pbb,goto_table:1','table_id:1,sctp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4/sctp(src_port=11111)-->'actions=pop_pbb,goto_table:1','table_id:1,sctp_src=11111,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4/sctp(src_port=12345)-->'actions=pop_pbb,goto_table:1','table_id:1,sctp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=132, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=6789, src_port=12345)" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/17_SCTP_SRC_IPv6.json0000664000175000017500000011517400000000000024136 0ustar00zuulzuul00000000000000[ "match: 17_SCTP_SRC (IPv6)", { "description":"ethernet/ipv6/sctp(src_port=11111)-->'sctp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/ipv6/sctp(src_port=11111)-->'sctp_src=11111,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/ipv6/sctp(src_port=12345)-->'sctp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=132, hop_limit=127, traffic_class=65)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=6789, src_port=12345)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv6/sctp(src_port=11111)-->'sctp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/vlan/ipv6/sctp(src_port=11111)-->'sctp_src=11111,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/vlan/ipv6/sctp(src_port=12345)-->'sctp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=132, hop_limit=127, traffic_class=65)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=6789, src_port=12345)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv6/sctp(src_port=11111)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,sctp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/mpls/ipv6/sctp(src_port=11111)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,sctp_src=11111,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/mpls/ipv6/sctp(src_port=12345)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,sctp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=132, hop_limit=127, traffic_class=65)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=6789, src_port=12345)" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/sctp(src_port=11111)-->'actions=pop_pbb,goto_table:1','table_id:1,sctp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/sctp(src_port=11111)-->'actions=pop_pbb,goto_table:1','table_id:1,sctp_src=11111,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/sctp(src_port=12345)-->'actions=pop_pbb,goto_table:1','table_id:1,sctp_src=11111,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_src", "value":11111 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=132, hop_limit=127, traffic_class=65)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=6789, src_port=12345)" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/18_SCTP_DST_IPv4.json0000664000175000017500000011435000000000000024133 0ustar00zuulzuul00000000000000[ "match: 18_SCTP_DST (IPv4)", { "description":"ethernet/ipv4/sctp(dst_port=2222)-->'sctp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/ipv4/sctp(dst_port=2222)-->'sctp_dst=2222,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/ipv4/sctp(dst_port=6789)-->'sctp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=132, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=6789, src_port=12345)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv4/sctp(dst_port=2222)-->'sctp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/vlan/ipv4/sctp(dst_port=2222)-->'sctp_dst=2222,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/vlan/ipv4/sctp(dst_port=6789)-->'sctp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=132, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=6789, src_port=12345)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv4/sctp(dst_port=2222)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,sctp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/mpls/ipv4/sctp(dst_port=2222)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,sctp_dst=2222,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/mpls/ipv4/sctp(dst_port=6789)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,sctp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv4(tos=65, proto=132, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=6789, src_port=12345)" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv4/sctp(dst_port=2222)-->'actions=pop_pbb,goto_table:1','table_id:1,sctp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4/sctp(dst_port=2222)-->'actions=pop_pbb,goto_table:1','table_id:1,sctp_dst=2222,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=132, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4/sctp(dst_port=6789)-->'actions=pop_pbb,goto_table:1','table_id:1,sctp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=132, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=6789, src_port=12345)" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/18_SCTP_DST_IPv6.json0000664000175000017500000011513000000000000024132 0ustar00zuulzuul00000000000000[ "match: 18_SCTP_DST (IPv6)", { "description":"ethernet/ipv6/sctp(dst_port=2222)-->'sctp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/ipv6/sctp(dst_port=2222)-->'sctp_dst=2222,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/ipv6/sctp(dst_port=6789)-->'sctp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=132, hop_limit=127, traffic_class=65)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=6789, src_port=12345)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv6/sctp(dst_port=2222)-->'sctp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/vlan/ipv6/sctp(dst_port=2222)-->'sctp_dst=2222,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/vlan/ipv6/sctp(dst_port=6789)-->'sctp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=132, hop_limit=127, traffic_class=65)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=6789, src_port=12345)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv6/sctp(dst_port=2222)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,sctp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/mpls/ipv6/sctp(dst_port=2222)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,sctp_dst=2222,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/mpls/ipv6/sctp(dst_port=6789)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,sctp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=132, hop_limit=127, traffic_class=65)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=6789, src_port=12345)" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/sctp(dst_port=2222)-->'actions=pop_pbb,goto_table:1','table_id:1,sctp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/sctp(dst_port=2222)-->'actions=pop_pbb,goto_table:1','table_id:1,sctp_dst=2222,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=132, hop_limit=64, traffic_class=32)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=2222, src_port=11111)" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/sctp(dst_port=6789)-->'actions=pop_pbb,goto_table:1','table_id:1,sctp_dst=2222,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":132 } }, { "OXMTlv":{ "field":"sctp_dst", "value":2222 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=132, hop_limit=127, traffic_class=65)", "sctp(chunks=[chunk_data(payload_data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef')], dst_port=6789, src_port=12345)" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/19_ICMPV4_TYPE.json0000664000175000017500000011406400000000000023614 0ustar00zuulzuul00000000000000[ "match: 19_ICMPV4_TYPE", { "description":"ethernet/ipv4/icmp(type=8)-->'icmpv4_type=8,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_type", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ] } ] }, { "description":"ethernet/ipv4/icmp(type=8)-->'icmpv4_type=8,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_type", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ] } ] }, { "description":"ethernet/ipv4/icmp(type=3)-->'icmpv4_type=8,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_type", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=1, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "icmp(code=1,csum=0,data=dest_unreach(data=b'\\xd3]\\xb7\\xe3\\x9e\\xbb\\xf3\\xd6\\x9bq\\xd7\\x9f\\x82\\x18\\xa3\\x92Y\\xa7\\xa2\\x9a\\xab\\xb2\\xdb\\xaf\\xc3\\x1c\\xb3\\x00\\x10\\x83\\x10Q\\x87 \\x92\\x8b'),type_=3)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv4/icmp(type=8)-->'icmpv4_type=8,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_type", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ] } ] }, { "description":"ethernet/vlan/ipv4/icmp(type=8)-->'icmpv4_type=8,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_type", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ] } ] }, { "description":"ethernet/vlan/ipv4/icmp(type=3)-->'icmpv4_type=8,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_type", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=1, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "icmp(code=1,csum=0,data=dest_unreach(data=b'\\xd3]\\xb7\\xe3\\x9e\\xbb\\xf3\\xd6\\x9bq\\xd7\\x9f\\x82\\x18\\xa3\\x92Y\\xa7\\xa2\\x9a\\xab\\xb2\\xdb\\xaf\\xc3\\x1c\\xb3\\x00\\x10\\x83\\x10Q\\x87 \\x92\\x8b'),type_=3)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv4/icmp(type=8)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,icmpv4_type=8,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_type", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ] } ] }, { "description":"ethernet/mpls/ipv4/icmp(type=8)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,icmpv4_type=8,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_type", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ] } ] }, { "description":"ethernet/mpls/ipv4/icmp(type=3)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,icmpv4_type=8,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_type", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv4(tos=65, proto=1, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "icmp(code=1,csum=0,data=dest_unreach(data=b'\\xd3]\\xb7\\xe3\\x9e\\xbb\\xf3\\xd6\\x9bq\\xd7\\x9f\\x82\\x18\\xa3\\x92Y\\xa7\\xa2\\x9a\\xab\\xb2\\xdb\\xaf\\xc3\\x1c\\xb3\\x00\\x10\\x83\\x10Q\\x87 \\x92\\x8b'),type_=3)" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv4/icmp(type=8)-->'actions=pop_pbb,goto_table:1','table_id:1,icmpv4_type=8,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_type", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4/icmp(type=8)-->'actions=pop_pbb,goto_table:1','table_id:1,icmpv4_type=8,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_type", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4/icmp(type=3)-->'actions=pop_pbb,goto_table:1','table_id:1,icmpv4_type=8,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_type", "value":8 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=1, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "icmp(code=1,csum=0,data=dest_unreach(data=b'\\xd3]\\xb7\\xe3\\x9e\\xbb\\xf3\\xd6\\x9bq\\xd7\\x9f\\x82\\x18\\xa3\\x92Y\\xa7\\xa2\\x9a\\xab\\xb2\\xdb\\xaf\\xc3\\x1c\\xb3\\x00\\x10\\x83\\x10Q\\x87 \\x92\\x8b'),type_=3)" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/20_ICMPV4_CODE.json0000664000175000017500000011406400000000000023535 0ustar00zuulzuul00000000000000[ "match: 20_ICMPV4_CODE", { "description":"ethernet/ipv4/icmp(code=0)-->'icmpv4_code=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ] } ] }, { "description":"ethernet/ipv4/icmp(code=0)-->'icmpv4_code=0,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ] } ] }, { "description":"ethernet/ipv4/icmp(code=1)-->'icmpv4_code=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=1, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "icmp(code=1,csum=0,data=dest_unreach(data=b'\\xd3]\\xb7\\xe3\\x9e\\xbb\\xf3\\xd6\\x9bq\\xd7\\x9f\\x82\\x18\\xa3\\x92Y\\xa7\\xa2\\x9a\\xab\\xb2\\xdb\\xaf\\xc3\\x1c\\xb3\\x00\\x10\\x83\\x10Q\\x87 \\x92\\x8b'),type_=3)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv4/icmp(code=0)-->'icmpv4_code=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ] } ] }, { "description":"ethernet/vlan/ipv4/icmp(code=0)-->'icmpv4_code=0,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ] } ] }, { "description":"ethernet/vlan/ipv4/icmp(code=1)-->'icmpv4_code=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=1, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "icmp(code=1,csum=0,data=dest_unreach(data=b'\\xd3]\\xb7\\xe3\\x9e\\xbb\\xf3\\xd6\\x9bq\\xd7\\x9f\\x82\\x18\\xa3\\x92Y\\xa7\\xa2\\x9a\\xab\\xb2\\xdb\\xaf\\xc3\\x1c\\xb3\\x00\\x10\\x83\\x10Q\\x87 \\x92\\x8b'),type_=3)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv4/icmp(code=0)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,icmpv4_code=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ] } ] }, { "description":"ethernet/mpls/ipv4/icmp(code=0)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,icmpv4_code=0,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ] } ] }, { "description":"ethernet/mpls/ipv4/icmp(code=1)-->'actions=pop_mpls:0x0800,goto_table:1','table_id:1,icmpv4_code=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2048 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv4(tos=65, proto=1, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "icmp(code=1,csum=0,data=dest_unreach(data=b'\\xd3]\\xb7\\xe3\\x9e\\xbb\\xf3\\xd6\\x9bq\\xd7\\x9f\\x82\\x18\\xa3\\x92Y\\xa7\\xa2\\x9a\\xab\\xb2\\xdb\\xaf\\xc3\\x1c\\xb3\\x00\\x10\\x83\\x10Q\\x87 \\x92\\x8b'),type_=3)" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv4/icmp(code=0)-->'actions=pop_pbb,goto_table:1','table_id:1,icmpv4_code=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4/icmp(code=0)-->'actions=pop_pbb,goto_table:1','table_id:1,icmpv4_code=0,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=1, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "icmp(code=0,csum=0,data=echo(data=b'\\x01\\x23\\x45\\x67\\x89\\xab\\xcd\\xef'),type_=8)" ] } ] }, { "description":"ethernet/itag/ethernet/ipv4/icmp(code=1)-->'actions=pop_pbb,goto_table:1','table_id:1,icmpv4_code=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_proto", "value":1 } }, { "OXMTlv":{ "field":"icmpv4_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2048)", "ipv4(tos=65, proto=1, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "icmp(code=1,csum=0,data=dest_unreach(data=b'\\xd3]\\xb7\\xe3\\x9e\\xbb\\xf3\\xd6\\x9bq\\xd7\\x9f\\x82\\x18\\xa3\\x92Y\\xa7\\xa2\\x9a\\xab\\xb2\\xdb\\xaf\\xc3\\x1c\\xb3\\x00\\x10\\x83\\x10Q\\x87 \\x92\\x8b'),type_=3)" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/21_ARP_OP.json0000664000175000017500000010375000000000000023022 0ustar00zuulzuul00000000000000[ "match: 21_ARP_OP", { "description":"ethernet/arp(opcode=1)-->'arp_op=1,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_op", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp(opcode=1)-->'arp_op=1,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_op", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp(opcode=2)-->'arp_op=1,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_op", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/arp(opcode=1)-->'arp_op=1,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_op", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/vlan/arp(opcode=1)-->'arp_op=1,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_op", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/vlan/arp(opcode=2)-->'arp_op=1,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_op", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * 30)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/arp(opcode=1)-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_op=1,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_op", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/mpls/arp(opcode=1)-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_op=1,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_op", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/mpls/arp(opcode=2)-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_op=1,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_op", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/arp(opcode=1)-->'actions=pop_pbb,goto_table:1','table_id:1,arp_op=1,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_op", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/itag/ethernet/arp(opcode=1)-->'actions=pop_pbb,goto_table:1','table_id:1,arp_op=1,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_op", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/itag/ethernet/arp(opcode=2)-->'actions=pop_pbb,goto_table:1','table_id:1,arp_op=1,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_op", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/22_ARP_SPA.json0000664000175000017500000010473100000000000023130 0ustar00zuulzuul00000000000000[ "match: 22_ARP_SPA", { "description":"ethernet/arp(src_ip='192.168.10.10')-->'arp_spa=192.168.10.10,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp(src_ip='192.168.10.10')-->'arp_spa=192.168.10.10,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp(src_ip='10.10.10.10')-->'arp_spa=192.168.10.10,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/arp(src_ip='192.168.10.10')-->'arp_spa=192.168.10.10,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/vlan/arp(src_ip='192.168.10.10')-->'arp_spa=192.168.10.10,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/vlan/arp(src_ip='10.10.10.10')-->'arp_spa=192.168.10.10,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * 30)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/arp(src_ip='192.168.10.10')-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_spa=192.168.10.10,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/mpls/arp(src_ip='192.168.10.10')-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_spa=192.168.10.10,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/mpls/arp(src_ip='10.10.10.10')-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_spa=192.168.10.10,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/arp(src_ip='192.168.10.10')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_spa=192.168.10.10,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/itag/ethernet/arp(src_ip='192.168.10.10')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_spa=192.168.10.10,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/itag/ethernet/arp(src_ip='10.10.10.10')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_spa=192.168.10.10,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "value":"192.168.10.10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/22_ARP_SPA_Mask.json0000664000175000017500000010667000000000000024107 0ustar00zuulzuul00000000000000[ "match: 22_ARP_SPA (Mask)", { "description":"ethernet/arp(src_ip='192.168.10.10')-->'arp_spa=192.168.10.0(mask=255.255.255.0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "mask":"255.255.255.0", "value":"192.168.10.0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp(src_ip='192.168.10.10')-->'arp_spa=192.168.10.0(mask=255.255.255.0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "mask":"255.255.255.0", "value":"192.168.10.0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp(src_ip='10.10.10.10')-->'arp_spa=192.168.10.0(mask=255.255.255.0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "mask":"255.255.255.0", "value":"192.168.10.0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/arp(src_ip='192.168.10.10')-->'arp_spa=192.168.10.0(mask=255.255.255.0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "mask":"255.255.255.0", "value":"192.168.10.0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/vlan/arp(src_ip='192.168.10.10')-->'arp_spa=192.168.10.0(mask=255.255.255.0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "mask":"255.255.255.0", "value":"192.168.10.0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/vlan/arp(src_ip='10.10.10.10')-->'arp_spa=192.168.10.0(mask=255.255.255.0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "mask":"255.255.255.0", "value":"192.168.10.0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * 30)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/arp(src_ip='192.168.10.10')-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_spa=192.168.10.0(mask=255.255.255.0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "mask":"255.255.255.0", "value":"192.168.10.0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/mpls/arp(src_ip='192.168.10.10')-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_spa=192.168.10.0(mask=255.255.255.0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "mask":"255.255.255.0", "value":"192.168.10.0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/mpls/arp(src_ip='10.10.10.10')-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_spa=192.168.10.0(mask=255.255.255.0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "mask":"255.255.255.0", "value":"192.168.10.0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/arp(src_ip='192.168.10.10')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_spa=192.168.10.0(mask=255.255.255.0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "mask":"255.255.255.0", "value":"192.168.10.0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/itag/ethernet/arp(src_ip='192.168.10.10')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_spa=192.168.10.0(mask=255.255.255.0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "mask":"255.255.255.0", "value":"192.168.10.0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/itag/ethernet/arp(src_ip='10.10.10.10')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_spa=192.168.10.0(mask=255.255.255.0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_spa", "mask":"255.255.255.0", "value":"192.168.10.0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/23_ARP_TPA.json0000664000175000017500000010473100000000000023132 0ustar00zuulzuul00000000000000[ "match: 23_ARP_TPA", { "description":"ethernet/arp(dst_ip='192.168.20.20')-->'arp_tpa=192.168.20.20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp(dst_ip='192.168.20.20')-->'arp_tpa=192.168.20.20,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp(dst_ip='10.10.20.20')-->'arp_tpa=192.168.20.20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/arp(dst_ip='192.168.20.20')-->'arp_tpa=192.168.20.20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/vlan/arp(dst_ip='192.168.20.20')-->'arp_tpa=192.168.20.20,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/vlan/arp(dst_ip='10.10.20.20')-->'arp_tpa=192.168.20.20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * 30)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/arp(dst_ip='192.168.20.20')-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_tpa=192.168.20.20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/mpls/arp(dst_ip='192.168.20.20')-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_tpa=192.168.20.20,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/mpls/arp(dst_ip='10.10.20.20')-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_tpa=192.168.20.20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/arp(dst_ip='192.168.20.20')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_tpa=192.168.20.20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/itag/ethernet/arp(dst_ip='192.168.20.20')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_tpa=192.168.20.20,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/itag/ethernet/arp(dst_ip='10.10.20.20')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_tpa=192.168.20.20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "value":"192.168.20.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/23_ARP_TPA_Mask.json0000664000175000017500000010667000000000000024111 0ustar00zuulzuul00000000000000[ "match: 23_ARP_TPA (Mask)", { "description":"ethernet/arp(dst_ip='192.168.20.20')-->'arp_tpa=192.168.0.20(mask=255.255.0.255),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "mask":"255.255.0.255", "value":"192.168.0.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp(dst_ip='192.168.20.20')-->'arp_tpa=192.168.0.20(mask=255.255.0.255),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "mask":"255.255.0.255", "value":"192.168.0.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp(dst_ip='10.10.20.20')-->'arp_tpa=192.168.0.20(mask=255.255.0.255),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "mask":"255.255.0.255", "value":"192.168.0.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/arp(dst_ip='192.168.20.20')-->'arp_tpa=192.168.0.20(mask=255.255.0.255),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "mask":"255.255.0.255", "value":"192.168.0.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/vlan/arp(dst_ip='192.168.20.20')-->'arp_tpa=192.168.0.20(mask=255.255.0.255),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "mask":"255.255.0.255", "value":"192.168.0.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/vlan/arp(dst_ip='10.10.20.20')-->'arp_tpa=192.168.0.20(mask=255.255.0.255),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "mask":"255.255.0.255", "value":"192.168.0.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * 30)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/arp(dst_ip='192.168.20.20')-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_tpa=192.168.0.20(mask=255.255.0.255),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "mask":"255.255.0.255", "value":"192.168.0.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/mpls/arp(dst_ip='192.168.20.20')-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_tpa=192.168.0.20(mask=255.255.0.255),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "mask":"255.255.0.255", "value":"192.168.0.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/mpls/arp(dst_ip='10.10.20.20')-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_tpa=192.168.0.20(mask=255.255.0.255),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "mask":"255.255.0.255", "value":"192.168.0.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/arp(dst_ip='192.168.20.20')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_tpa=192.168.0.20(mask=255.255.0.255),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "mask":"255.255.0.255", "value":"192.168.0.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/itag/ethernet/arp(dst_ip='192.168.20.20')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_tpa=192.168.0.20(mask=255.255.0.255),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "mask":"255.255.0.255", "value":"192.168.0.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/itag/ethernet/arp(dst_ip='10.10.20.20')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_tpa=192.168.0.20(mask=255.255.0.255),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tpa", "mask":"255.255.0.255", "value":"192.168.0.20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/24_ARP_SHA.json0000664000175000017500000010517500000000000023125 0ustar00zuulzuul00000000000000[ "match: 24_ARP_SHA", { "description":"ethernet/arp(src_mac='12:11:11:11:11:11')-->'arp_sha=12:11:11:11:11:11,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp(src_mac='12:11:11:11:11:11')-->'arp_sha=12:11:11:11:11:11,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp(src_mac='aa:aa:aa:aa:aa:aa')-->'arp_sha=12:11:11:11:11:11,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/arp(src_mac='12:11:11:11:11:11')-->'arp_sha=12:11:11:11:11:11,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/vlan/arp(src_mac='12:11:11:11:11:11')-->'arp_sha=12:11:11:11:11:11,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/vlan/arp(src_mac='aa:aa:aa:aa:aa:aa')-->'arp_sha=12:11:11:11:11:11,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * 30)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/arp(src_mac='12:11:11:11:11:11')-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_sha=12:11:11:11:11:11,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/mpls/arp(src_mac='12:11:11:11:11:11')-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_sha=12:11:11:11:11:11,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/mpls/arp(src_mac='aa:aa:aa:aa:aa:aa')-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_sha=12:11:11:11:11:11,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/arp(src_mac='12:11:11:11:11:11')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_sha=12:11:11:11:11:11,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/itag/ethernet/arp(src_mac='12:11:11:11:11:11')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_sha=12:11:11:11:11:11,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/itag/ethernet/arp(src_mac='aa:aa:aa:aa:aa:aa')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_sha=12:11:11:11:11:11,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "value":"12:11:11:11:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/24_ARP_SHA_Mask.json0000664000175000017500000010732400000000000024076 0ustar00zuulzuul00000000000000[ "match: 24_ARP_SHA (Mask)", { "description":"ethernet/arp(src_mac='12:11:11:11:11:11')-->'arp_sha=12:11:11:00:11:11(mask=ff:ff:ff:00:ff:ff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "mask":"ff:ff:ff:00:ff:ff", "value":"12:11:11:00:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp(src_mac='12:11:11:11:11:11')-->'arp_sha=12:11:11:00:11:11(mask=ff:ff:ff:00:ff:ff),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "mask":"ff:ff:ff:00:ff:ff", "value":"12:11:11:00:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp(src_mac='aa:aa:aa:aa:aa:aa')-->'arp_sha=12:11:11:00:11:11(mask=ff:ff:ff:00:ff:ff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "mask":"ff:ff:ff:00:ff:ff", "value":"12:11:11:00:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/arp(src_mac='12:11:11:11:11:11')-->'arp_sha=12:11:11:00:11:11(mask=ff:ff:ff:00:ff:ff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "mask":"ff:ff:ff:00:ff:ff", "value":"12:11:11:00:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/vlan/arp(src_mac='12:11:11:11:11:11')-->'arp_sha=12:11:11:00:11:11(mask=ff:ff:ff:00:ff:ff),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "mask":"ff:ff:ff:00:ff:ff", "value":"12:11:11:00:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/vlan/arp(src_mac='aa:aa:aa:aa:aa:aa')-->'arp_sha=12:11:11:00:11:11(mask=ff:ff:ff:00:ff:ff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "mask":"ff:ff:ff:00:ff:ff", "value":"12:11:11:00:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * 30)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/arp(src_mac='12:11:11:11:11:11')-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_sha=12:11:11:00:11:11(mask=ff:ff:ff:00:ff:ff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "mask":"ff:ff:ff:00:ff:ff", "value":"12:11:11:00:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/mpls/arp(src_mac='12:11:11:11:11:11')-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_sha=12:11:11:00:11:11(mask=ff:ff:ff:00:ff:ff),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "mask":"ff:ff:ff:00:ff:ff", "value":"12:11:11:00:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/mpls/arp(src_mac='aa:aa:aa:aa:aa:aa')-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_sha=12:11:11:00:11:11(mask=ff:ff:ff:00:ff:ff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "mask":"ff:ff:ff:00:ff:ff", "value":"12:11:11:00:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/arp(src_mac='12:11:11:11:11:11')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_sha=12:11:11:00:11:11(mask=ff:ff:ff:00:ff:ff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "mask":"ff:ff:ff:00:ff:ff", "value":"12:11:11:00:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/itag/ethernet/arp(src_mac='12:11:11:11:11:11')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_sha=12:11:11:00:11:11(mask=ff:ff:ff:00:ff:ff),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "mask":"ff:ff:ff:00:ff:ff", "value":"12:11:11:00:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/itag/ethernet/arp(src_mac='aa:aa:aa:aa:aa:aa')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_sha=12:11:11:00:11:11(mask=ff:ff:ff:00:ff:ff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_sha", "mask":"ff:ff:ff:00:ff:ff", "value":"12:11:11:00:11:11" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/25_ARP_THA.json0000664000175000017500000010517500000000000023127 0ustar00zuulzuul00000000000000[ "match: 25_ARP_THA", { "description":"ethernet/arp(dst_mac='22:22:22:22:22:22')-->'arp_tha=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp(dst_mac='22:22:22:22:22:22')-->'arp_tha=22:22:22:22:22:22,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp(dst_mac='ba:bb:bb:bb:bb:bb')-->'arp_tha=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/arp(dst_mac='22:22:22:22:22:22')-->'arp_tha=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/vlan/arp(dst_mac='22:22:22:22:22:22')-->'arp_tha=22:22:22:22:22:22,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/vlan/arp(dst_mac='ba:bb:bb:bb:bb:bb')-->'arp_tha=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * 30)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/arp(dst_mac='22:22:22:22:22:22')-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_tha=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/mpls/arp(dst_mac='22:22:22:22:22:22')-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_tha=22:22:22:22:22:22,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/mpls/arp(dst_mac='ba:bb:bb:bb:bb:bb')-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_tha=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/arp(dst_mac='22:22:22:22:22:22')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_tha=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/itag/ethernet/arp(dst_mac='22:22:22:22:22:22')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_tha=22:22:22:22:22:22,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/itag/ethernet/arp(dst_mac='ba:bb:bb:bb:bb:bb')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_tha=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/25_ARP_THA_Mask.json0000664000175000017500000010732400000000000024100 0ustar00zuulzuul00000000000000[ "match: 25_ARP_THA (Mask)", { "description":"ethernet/arp(dst_mac='22:22:22:22:22:22')-->'arp_tha=22:22:00:22:22:22(mask=ff:ff:00:ff:ff:ff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "mask":"ff:ff:00:ff:ff:ff", "value":"22:22:00:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp(dst_mac='22:22:22:22:22:22')-->'arp_tha=22:22:00:22:22:22(mask=ff:ff:00:ff:ff:ff),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "mask":"ff:ff:00:ff:ff:ff", "value":"22:22:00:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp(dst_mac='ba:bb:bb:bb:bb:bb')-->'arp_tha=22:22:00:22:22:22(mask=ff:ff:00:ff:ff:ff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "mask":"ff:ff:00:ff:ff:ff", "value":"22:22:00:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/arp(dst_mac='22:22:22:22:22:22')-->'arp_tha=22:22:00:22:22:22(mask=ff:ff:00:ff:ff:ff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "mask":"ff:ff:00:ff:ff:ff", "value":"22:22:00:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/vlan/arp(dst_mac='22:22:22:22:22:22')-->'arp_tha=22:22:00:22:22:22(mask=ff:ff:00:ff:ff:ff),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "mask":"ff:ff:00:ff:ff:ff", "value":"22:22:00:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/vlan/arp(dst_mac='ba:bb:bb:bb:bb:bb')-->'arp_tha=22:22:00:22:22:22(mask=ff:ff:00:ff:ff:ff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "mask":"ff:ff:00:ff:ff:ff", "value":"22:22:00:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * 30)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/arp(dst_mac='22:22:22:22:22:22')-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_tha=22:22:00:22:22:22(mask=ff:ff:00:ff:ff:ff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "mask":"ff:ff:00:ff:ff:ff", "value":"22:22:00:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/mpls/arp(dst_mac='22:22:22:22:22:22')-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_tha=22:22:00:22:22:22(mask=ff:ff:00:ff:ff:ff),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "mask":"ff:ff:00:ff:ff:ff", "value":"22:22:00:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/mpls/arp(dst_mac='ba:bb:bb:bb:bb:bb')-->'actions=pop_mpls:0x0806,goto_table:1','table_id:1,arp_tha=22:22:00:22:22:22(mask=ff:ff:00:ff:ff:ff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":2054 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "mask":"ff:ff:00:ff:ff:ff", "value":"22:22:00:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/arp(dst_mac='22:22:22:22:22:22')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_tha=22:22:00:22:22:22(mask=ff:ff:00:ff:ff:ff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "mask":"ff:ff:00:ff:ff:ff", "value":"22:22:00:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/itag/ethernet/arp(dst_mac='22:22:22:22:22:22')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_tha=22:22:00:22:22:22(mask=ff:ff:00:ff:ff:ff),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "mask":"ff:ff:00:ff:ff:ff", "value":"22:22:00:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/itag/ethernet/arp(dst_mac='ba:bb:bb:bb:bb:bb')-->'actions=pop_pbb,goto_table:1','table_id:1,arp_tha=22:22:00:22:22:22(mask=ff:ff:00:ff:ff:ff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":2054 } }, { "OXMTlv":{ "field":"arp_tha", "mask":"ff:ff:00:ff:ff:ff", "value":"22:22:00:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/26_IPV6_SRC.json0000664000175000017500000011362100000000000023240 0ustar00zuulzuul00000000000000[ "match: 26_IPV6_SRC", { "description":"ethernet/ipv6(src='10::10')/tcp-->'ipv6_src=10::10,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "value":"10::10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6(src='10::10')/tcp-->'ipv6_src=10::10,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "value":"10::10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6(src='a0::a0')/tcp-->'ipv6_src=10::10,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "value":"10::10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv6(src='10::10')/tcp-->'ipv6_src=10::10,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "value":"10::10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6(src='10::10')/tcp-->'ipv6_src=10::10,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "value":"10::10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6(src='a0::a0')/tcp-->'ipv6_src=10::10,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "value":"10::10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv6(src='10::10')/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_src=10::10,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "value":"10::10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6(src='10::10')/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_src=10::10,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "value":"10::10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6(src='a0::a0')/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_src=10::10,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "value":"10::10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(src='10::10')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_src=10::10,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "value":"10::10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(src='10::10')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_src=10::10,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "value":"10::10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(src='a0::a0')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_src=10::10,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "value":"10::10" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/26_IPV6_SRC_Mask.json0000664000175000017500000011663000000000000024216 0ustar00zuulzuul00000000000000[ "match: 26_IPV6_SRC (Mask)", { "description":"ethernet/ipv6(src='10::10')/tcp-->'ipv6_src=10::0(mask=ffff:ffff:ffff:ffff:ffff:ffff:ffff:0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "mask":"ffff:ffff:ffff:ffff:ffff:ffff:ffff:0", "value":"10::0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6(src='10::10')/tcp-->'ipv6_src=10::0(mask=ffff:ffff:ffff:ffff:ffff:ffff:ffff:0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "mask":"ffff:ffff:ffff:ffff:ffff:ffff:ffff:0", "value":"10::0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6(src='a0::a0')/tcp-->'ipv6_src=10::0(mask=ffff:ffff:ffff:ffff:ffff:ffff:ffff:0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "mask":"ffff:ffff:ffff:ffff:ffff:ffff:ffff:0", "value":"10::0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv6(src='10::10')/tcp-->'ipv6_src=10::0(mask=ffff:ffff:ffff:ffff:ffff:ffff:ffff:0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "mask":"ffff:ffff:ffff:ffff:ffff:ffff:ffff:0", "value":"10::0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6(src='10::10')/tcp-->'ipv6_src=10::0(mask=ffff:ffff:ffff:ffff:ffff:ffff:ffff:0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "mask":"ffff:ffff:ffff:ffff:ffff:ffff:ffff:0", "value":"10::0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6(src='a0::a0')/tcp-->'ipv6_src=10::0(mask=ffff:ffff:ffff:ffff:ffff:ffff:ffff:0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "mask":"ffff:ffff:ffff:ffff:ffff:ffff:ffff:0", "value":"10::0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv6(src='10::10')/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_src=10::0(mask=ffff:ffff:ffff:ffff:ffff:ffff:ffff:0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "mask":"ffff:ffff:ffff:ffff:ffff:ffff:ffff:0", "value":"10::0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6(src='10::10')/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_src=10::0(mask=ffff:ffff:ffff:ffff:ffff:ffff:ffff:0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "mask":"ffff:ffff:ffff:ffff:ffff:ffff:ffff:0", "value":"10::0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6(src='a0::a0')/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_src=10::0(mask=ffff:ffff:ffff:ffff:ffff:ffff:ffff:0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "mask":"ffff:ffff:ffff:ffff:ffff:ffff:ffff:0", "value":"10::0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(src='10::10')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_src=10::0(mask=ffff:ffff:ffff:ffff:ffff:ffff:ffff:0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "mask":"ffff:ffff:ffff:ffff:ffff:ffff:ffff:0", "value":"10::0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(src='10::10')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_src=10::0(mask=ffff:ffff:ffff:ffff:ffff:ffff:ffff:0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "mask":"ffff:ffff:ffff:ffff:ffff:ffff:ffff:0", "value":"10::0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(src='a0::a0')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_src=10::0(mask=ffff:ffff:ffff:ffff:ffff:ffff:ffff:0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_src", "mask":"ffff:ffff:ffff:ffff:ffff:ffff:ffff:0", "value":"10::0" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/27_IPV6_DST.json0000664000175000017500000011362100000000000023244 0ustar00zuulzuul00000000000000[ "match: 27_IPV6_DST", { "description":"ethernet/ipv6(dst='20::20')/tcp-->'ipv6_dst=20::20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6(dst='20::20')/tcp-->'ipv6_dst=20::20,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6(dst='b0::b0')/tcp-->'ipv6_dst=20::20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv6(dst='20::20')/tcp-->'ipv6_dst=20::20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6(dst='20::20')/tcp-->'ipv6_dst=20::20,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6(dst='b0::b0')/tcp-->'ipv6_dst=20::20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv6(dst='20::20')/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_dst=20::20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6(dst='20::20')/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_dst=20::20,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6(dst='b0::b0')/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_dst=20::20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(dst='20::20')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_dst=20::20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(dst='20::20')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_dst=20::20,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(dst='b0::b0')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_dst=20::20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/27_IPV6_DST_Mask.json0000664000175000017500000011663000000000000024222 0ustar00zuulzuul00000000000000[ "match: 27_IPV6_DST (Mask)", { "description":"ethernet/ipv6(dst='20::20')/tcp-->'ipv6_dst=0::20(mask=0:ffff:ffff:ffff:ffff:ffff:ffff:ffff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "mask":"0:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "value":"0::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6(dst='20::20')/tcp-->'ipv6_dst=0::20(mask=0:ffff:ffff:ffff:ffff:ffff:ffff:ffff),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "mask":"0:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "value":"0::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6(dst='b0::b0')/tcp-->'ipv6_dst=0::20(mask=0:ffff:ffff:ffff:ffff:ffff:ffff:ffff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "mask":"0:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "value":"0::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv6(dst='20::20')/tcp-->'ipv6_dst=0::20(mask=0:ffff:ffff:ffff:ffff:ffff:ffff:ffff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "mask":"0:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "value":"0::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6(dst='20::20')/tcp-->'ipv6_dst=0::20(mask=0:ffff:ffff:ffff:ffff:ffff:ffff:ffff),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "mask":"0:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "value":"0::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6(dst='b0::b0')/tcp-->'ipv6_dst=0::20(mask=0:ffff:ffff:ffff:ffff:ffff:ffff:ffff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "mask":"0:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "value":"0::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv6(dst='20::20')/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_dst=0::20(mask=0:ffff:ffff:ffff:ffff:ffff:ffff:ffff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "mask":"0:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "value":"0::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6(dst='20::20')/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_dst=0::20(mask=0:ffff:ffff:ffff:ffff:ffff:ffff:ffff),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "mask":"0:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "value":"0::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6(dst='b0::b0')/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_dst=0::20(mask=0:ffff:ffff:ffff:ffff:ffff:ffff:ffff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "mask":"0:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "value":"0::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(dst='20::20')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_dst=0::20(mask=0:ffff:ffff:ffff:ffff:ffff:ffff:ffff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "mask":"0:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "value":"0::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(dst='20::20')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_dst=0::20(mask=0:ffff:ffff:ffff:ffff:ffff:ffff:ffff),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "mask":"0:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "value":"0::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(dst='b0::b0')/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_dst=0::20(mask=0:ffff:ffff:ffff:ffff:ffff:ffff:ffff),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_dst", "mask":"0:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "value":"0::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/28_IPV6_FLABEL.json0000664000175000017500000011362400000000000023543 0ustar00zuulzuul00000000000000[ "match: 28_IPV6_FLABEL", { "description":"ethernet/ipv6(flow_label=100)/tcp-->'ipv6_flabel=100,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6(flow_label=100)/tcp-->'ipv6_flabel=100,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6(flow_label=203)/tcp-->'ipv6_flabel=100,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv6(flow_label=100)/tcp-->'ipv6_flabel=100,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6(flow_label=100)/tcp-->'ipv6_flabel=100,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6(flow_label=203)/tcp-->'ipv6_flabel=100,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv6(flow_label=100)/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_flabel=100,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6(flow_label=100)/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_flabel=100,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6(flow_label=203)/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_flabel=100,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(flow_label=100)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_flabel=100,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(flow_label=100)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_flabel=100,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(flow_label=203)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_flabel=100,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/28_IPV6_FLABEL_Mask.json0000664000175000017500000011535700000000000024523 0ustar00zuulzuul00000000000000[ "match: 28_IPV6_FLABEL (Mask)", { "description":"ethernet/ipv6(flow_label=100)/tcp-->'ipv6_flabel=96(mask=0x000ffff0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "mask":1048560, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6(flow_label=100)/tcp-->'ipv6_flabel=96(mask=0x000ffff0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "mask":1048560, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6(flow_label=203)/tcp-->'ipv6_flabel=96(mask=0x000ffff0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "mask":1048560, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv6(flow_label=100)/tcp-->'ipv6_flabel=96(mask=0x000ffff0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "mask":1048560, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6(flow_label=100)/tcp-->'ipv6_flabel=96(mask=0x000ffff0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "mask":1048560, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6(flow_label=203)/tcp-->'ipv6_flabel=96(mask=0x000ffff0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "mask":1048560, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv6(flow_label=100)/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_flabel=96(mask=0x000ffff0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "mask":1048560, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6(flow_label=100)/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_flabel=96(mask=0x000ffff0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "mask":1048560, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6(flow_label=203)/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_flabel=96(mask=0x000ffff0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "mask":1048560, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(flow_label=100)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_flabel=96(mask=0x000ffff0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "mask":1048560, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(flow_label=100)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_flabel=96(mask=0x000ffff0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "mask":1048560, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(flow_label=203)/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_flabel=96(mask=0x000ffff0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_flabel", "mask":1048560, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/29_ICMPV6_TYPE.json0000664000175000017500000012045000000000000023613 0ustar00zuulzuul00000000000000[ "match: 29_ICMPV6_TYPE", { "description":"ethernet/ipv6/icmpv6(type=128)-->'icmpv6_type=128,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":128 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ] } ] }, { "description":"ethernet/ipv6/icmpv6(type=128)-->'icmpv6_type=128,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":128 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ] } ] }, { "description":"ethernet/ipv6/icmpv6(type=135)-->'icmpv6_type=128,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":128 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=58, hop_limit=127, traffic_class=65)", "icmpv6(code=1,data=nd_neighbor(option=nd_option_sla(hw_src='aa:aa:aa:aa:aa:aa'),dst='a0::a0'),type_=135)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv6/icmpv6(type=128)-->'icmpv6_type=128,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":128 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ] } ] }, { "description":"ethernet/vlan/ipv6/icmpv6(type=128)-->'icmpv6_type=128,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":128 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ] } ] }, { "description":"ethernet/vlan/ipv6/icmpv6(type=135)-->'icmpv6_type=128,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":128 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=58, hop_limit=127, traffic_class=65)", "icmpv6(code=1,data=nd_neighbor(option=nd_option_sla(hw_src='aa:aa:aa:aa:aa:aa'),dst='a0::a0'),type_=135)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv6/icmpv6(type=128)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,icmpv6_type=128,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":128 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ] } ] }, { "description":"ethernet/mpls/ipv6/icmpv6(type=128)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,icmpv6_type=128,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":128 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ] } ] }, { "description":"ethernet/mpls/ipv6/icmpv6(type=135)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,icmpv6_type=128,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":128 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=58, hop_limit=127, traffic_class=65)", "icmpv6(code=1,data=nd_neighbor(option=nd_option_sla(hw_src='aa:aa:aa:aa:aa:aa'),dst='a0::a0'),type_=135)" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/icmpv6(type=128)-->'actions=pop_pbb,goto_table:1','table_id:1,icmpv6_type=128,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":128 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/icmpv6(type=128)-->'actions=pop_pbb,goto_table:1','table_id:1,icmpv6_type=128,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":128 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/icmpv6(type=135)-->'actions=pop_pbb,goto_table:1','table_id:1,icmpv6_type=128,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":128 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=58, hop_limit=127, traffic_class=65)", "icmpv6(code=1,data=nd_neighbor(option=nd_option_sla(hw_src='aa:aa:aa:aa:aa:aa'),dst='a0::a0'),type_=135)" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/30_ICMPV6_CODE.json0000664000175000017500000012034000000000000023532 0ustar00zuulzuul00000000000000[ "match: 30_ICMPV6_CODE", { "description":"ethernet/ipv6/icmpv6(code=0)-->'icmpv6_code=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ] } ] }, { "description":"ethernet/ipv6/icmpv6(code=0)-->'icmpv6_code=0,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ] } ] }, { "description":"ethernet/ipv6/icmpv6(code=1)-->'icmpv6_code=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=58, hop_limit=127, traffic_class=65)", "icmpv6(code=1,data=nd_neighbor(option=nd_option_sla(hw_src='aa:aa:aa:aa:aa:aa'),dst='a0::a0'),type_=135)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv6/icmpv6(code=0)-->'icmpv6_code=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ] } ] }, { "description":"ethernet/vlan/ipv6/icmpv6(code=0)-->'icmpv6_code=0,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ] } ] }, { "description":"ethernet/vlan/ipv6/icmpv6(code=1)-->'icmpv6_code=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=58, hop_limit=127, traffic_class=65)", "icmpv6(code=1,data=nd_neighbor(option=nd_option_sla(hw_src='aa:aa:aa:aa:aa:aa'),dst='a0::a0'),type_=135)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv6/icmpv6(code=0)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,icmpv6_code=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ] } ] }, { "description":"ethernet/mpls/ipv6/icmpv6(code=0)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,icmpv6_code=0,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ] } ] }, { "description":"ethernet/mpls/ipv6/icmpv6(code=1)-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,icmpv6_code=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=58, hop_limit=127, traffic_class=65)", "icmpv6(code=1,data=nd_neighbor(option=nd_option_sla(hw_src='aa:aa:aa:aa:aa:aa'),dst='a0::a0'),type_=135)" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/icmpv6(code=0)-->'actions=pop_pbb,goto_table:1','table_id:1,icmpv6_code=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/icmpv6(code=0)-->'actions=pop_pbb,goto_table:1','table_id:1,icmpv6_code=0,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=icmpv6echo(data=b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123'),type_=128)" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/icmpv6(code=1)-->'actions=pop_pbb,goto_table:1','table_id:1,icmpv6_code=0,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_code", "value":0 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=58, hop_limit=127, traffic_class=65)", "icmpv6(code=1,data=nd_neighbor(option=nd_option_sla(hw_src='aa:aa:aa:aa:aa:aa'),dst='a0::a0'),type_=135)" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/31_IPV6_ND_TARGET.json0000664000175000017500000012370700000000000024162 0ustar00zuulzuul00000000000000[ "match: 31_IPV6_ND_TARGET", { "description":"ethernet/ipv6/icmpv6(data=nd_neighbor(dst='20::20'))-->'ipv6_nd_target=20::20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_target", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='12:11:11:11:11:11'),dst='20::20'),type_=135)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='12:11:11:11:11:11'),dst='20::20'),type_=135)" ] } ] }, { "description":"ethernet/ipv6/icmpv6(data=nd_neighbor(dst='20::20'))-->'ipv6_nd_target=20::20,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_target", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='12:11:11:11:11:11'),dst='20::20'),type_=135)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='12:11:11:11:11:11'),dst='20::20'),type_=135)" ] } ] }, { "description":"ethernet/ipv6/icmpv6(data=nd_neighbor(dst='b0::b0'))-->'ipv6_nd_target=20::20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_target", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=58, hop_limit=127, traffic_class=65)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='aa:aa:aa:aa:aa:aa'),dst='b0::b0'),type_=135)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv6/icmpv6(data=nd_neighbor(dst='20::20'))-->'ipv6_nd_target=20::20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_target", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='12:11:11:11:11:11'),dst='20::20'),type_=135)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='12:11:11:11:11:11'),dst='20::20'),type_=135)" ] } ] }, { "description":"ethernet/vlan/ipv6/icmpv6(data=nd_neighbor(dst='20::20'))-->'ipv6_nd_target=20::20,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_target", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='12:11:11:11:11:11'),dst='20::20'),type_=135)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='12:11:11:11:11:11'),dst='20::20'),type_=135)" ] } ] }, { "description":"ethernet/vlan/ipv6/icmpv6(data=nd_neighbor(dst='b0::b0'))-->'ipv6_nd_target=20::20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_target", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=58, hop_limit=127, traffic_class=65)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='aa:aa:aa:aa:aa:aa'),dst='b0::b0'),type_=135)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv6/icmpv6(data=nd_neighbor(dst='20::20'))-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_nd_target=20::20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_target", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='12:11:11:11:11:11'),dst='20::20'),type_=135)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='12:11:11:11:11:11'),dst='20::20'),type_=135)" ] } ] }, { "description":"ethernet/mpls/ipv6/icmpv6(data=nd_neighbor(dst='20::20'))-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_nd_target=20::20,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_target", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='12:11:11:11:11:11'),dst='20::20'),type_=135)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='12:11:11:11:11:11'),dst='20::20'),type_=135)" ] } ] }, { "description":"ethernet/mpls/ipv6/icmpv6(data=nd_neighbor(dst='b0::b0'))-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_nd_target=20::20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_target", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=58, hop_limit=127, traffic_class=65)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='aa:aa:aa:aa:aa:aa'),dst='b0::b0'),type_=135)" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/icmpv6(data=nd_neighbor(dst='20::20'))-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_nd_target=20::20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_target", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='12:11:11:11:11:11'),dst='20::20'),type_=135)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='12:11:11:11:11:11'),dst='20::20'),type_=135)" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/icmpv6(data=nd_neighbor(dst='20::20'))-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_nd_target=20::20,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_target", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='12:11:11:11:11:11'),dst='20::20'),type_=135)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='12:11:11:11:11:11'),dst='20::20'),type_=135)" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/icmpv6(data=nd_neighbor(dst='b0::b0'))-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_nd_target=20::20,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_target", "value":"20::20" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=58, hop_limit=127, traffic_class=65)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='aa:aa:aa:aa:aa:aa'),dst='b0::b0'),type_=135)" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/32_IPV6_ND_SLL.json0000664000175000017500000012506400000000000023625 0ustar00zuulzuul00000000000000[ "match: 32_IPV6_ND_SLL", { "description":"ethernet/ipv6/icmpv6(data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22')))-->'ipv6_nd_sll=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_sll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=135)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=135)" ] } ] }, { "description":"ethernet/ipv6/icmpv6(data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22')))-->'ipv6_nd_sll=22:22:22:22:22:22,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_sll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=135)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=135)" ] } ] }, { "description":"ethernet/ipv6/icmpv6(data=nd_neighbor(option=nd_option_sla(hw_src='aa:aa:aa:aa:aa:aa')))-->'ipv6_nd_sll=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_sll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=58, hop_limit=127, traffic_class=65)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='aa:aa:aa:aa:aa:aa'),dst='b0::b0'),type_=135)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv6/icmpv6(data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22')))-->'ipv6_nd_sll=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_sll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=135)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=135)" ] } ] }, { "description":"ethernet/vlan/ipv6/icmpv6(data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22')))-->'ipv6_nd_sll=22:22:22:22:22:22,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_sll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=135)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=135)" ] } ] }, { "description":"ethernet/vlan/ipv6/icmpv6(data=nd_neighbor(option=nd_option_sla(hw_src='aa:aa:aa:aa:aa:aa')))-->'ipv6_nd_sll=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_sll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=58, hop_limit=127, traffic_class=65)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='aa:aa:aa:aa:aa:aa'),dst='b0::b0'),type_=135)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv6/icmpv6(data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22')))-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_nd_sll=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_sll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=135)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=135)" ] } ] }, { "description":"ethernet/mpls/ipv6/icmpv6(data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22')))-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_nd_sll=22:22:22:22:22:22,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_sll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=135)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=135)" ] } ] }, { "description":"ethernet/mpls/ipv6/icmpv6(data=nd_neighbor(option=nd_option_sla(hw_src='aa:aa:aa:aa:aa:aa')))-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_nd_sll=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_sll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=58, hop_limit=127, traffic_class=65)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='aa:aa:aa:aa:aa:aa'),dst='b0::b0'),type_=135)" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/icmpv6(data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22')))-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_nd_sll=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_sll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=135)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=135)" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/icmpv6(data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22')))-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_nd_sll=22:22:22:22:22:22,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_sll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=135)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=135)" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/icmpv6(data=nd_neighbor(option=nd_option_sla(hw_src='aa:aa:aa:aa:aa:aa')))-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_nd_sll=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":135 } }, { "OXMTlv":{ "field":"ipv6_nd_sll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=58, hop_limit=127, traffic_class=65)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_sla(hw_src='aa:aa:aa:aa:aa:aa'),dst='b0::b0'),type_=135)" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/33_IPV6_ND_TLL.json0000664000175000017500000012506400000000000023627 0ustar00zuulzuul00000000000000[ "match: 33_IPV6_ND_TLL", { "description":"ethernet/ipv6/icmpv6(data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22')))-->'ipv6_nd_tll=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":136 } }, { "OXMTlv":{ "field":"ipv6_nd_tll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=136)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=136)" ] } ] }, { "description":"ethernet/ipv6/icmpv6(data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22')))-->'ipv6_nd_tll=22:22:22:22:22:22,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":136 } }, { "OXMTlv":{ "field":"ipv6_nd_tll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=136)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=136)" ] } ] }, { "description":"ethernet/ipv6/icmpv6(data=nd_neighbor(option=nd_option_tla(hw_src='aa:aa:aa:aa:aa:aa')))-->'ipv6_nd_tll=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":136 } }, { "OXMTlv":{ "field":"ipv6_nd_tll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=58, hop_limit=127, traffic_class=65)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='aa:aa:aa:aa:aa:aa'),dst='b0::b0'),type_=136)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv6/icmpv6(data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22')))-->'ipv6_nd_tll=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":136 } }, { "OXMTlv":{ "field":"ipv6_nd_tll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=136)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=136)" ] } ] }, { "description":"ethernet/vlan/ipv6/icmpv6(data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22')))-->'ipv6_nd_tll=22:22:22:22:22:22,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":136 } }, { "OXMTlv":{ "field":"ipv6_nd_tll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=136)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=136)" ] } ] }, { "description":"ethernet/vlan/ipv6/icmpv6(data=nd_neighbor(option=nd_option_tla(hw_src='aa:aa:aa:aa:aa:aa')))-->'ipv6_nd_tll=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":136 } }, { "OXMTlv":{ "field":"ipv6_nd_tll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=58, hop_limit=127, traffic_class=65)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='aa:aa:aa:aa:aa:aa'),dst='b0::b0'),type_=136)" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv6/icmpv6(data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22')))-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_nd_tll=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":136 } }, { "OXMTlv":{ "field":"ipv6_nd_tll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=136)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=136)" ] } ] }, { "description":"ethernet/mpls/ipv6/icmpv6(data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22')))-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_nd_tll=22:22:22:22:22:22,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":136 } }, { "OXMTlv":{ "field":"ipv6_nd_tll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=136)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=136)" ] } ] }, { "description":"ethernet/mpls/ipv6/icmpv6(data=nd_neighbor(option=nd_option_tla(hw_src='aa:aa:aa:aa:aa:aa')))-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_nd_tll=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":136 } }, { "OXMTlv":{ "field":"ipv6_nd_tll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=58, hop_limit=127, traffic_class=65)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='aa:aa:aa:aa:aa:aa'),dst='b0::b0'),type_=136)" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/icmpv6(data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22')))-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_nd_tll=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":136 } }, { "OXMTlv":{ "field":"ipv6_nd_tll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=136)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=136)" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/icmpv6(data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22')))-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_nd_tll=22:22:22:22:22:22,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":136 } }, { "OXMTlv":{ "field":"ipv6_nd_tll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=136)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=58, hop_limit=64, traffic_class=32)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='22:22:22:22:22:22'),dst='20::20'),type_=136)" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/icmpv6(data=nd_neighbor(option=nd_option_tla(hw_src='aa:aa:aa:aa:aa:aa')))-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_nd_tll=22:22:22:22:22:22,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_proto", "value":58 } }, { "OXMTlv":{ "field":"icmpv6_type", "value":136 } }, { "OXMTlv":{ "field":"ipv6_nd_tll", "value":"22:22:22:22:22:22" } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=58, hop_limit=127, traffic_class=65)", "icmpv6(code=0,data=nd_neighbor(option=nd_option_tla(hw_src='aa:aa:aa:aa:aa:aa'),dst='b0::b0'),type_=136)" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/34_MPLS_LABEL.json0000664000175000017500000005352200000000000023461 0ustar00zuulzuul00000000000000[ "match: 34_MPLS_LABEL", { "description":"ethernet/mpls(label=100)/ipv4/tcp-->'mpls_label=100,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_label", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls(label=100)/ipv4/tcp-->'mpls_label=100,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_label", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls(label=203)/ipv4/tcp-->'mpls_label=100,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_label", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls(label=100)/ipv6/tcp-->'mpls_label=100,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_label", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls(label=100)/ipv6/tcp-->'mpls_label=100,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_label", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls(label=203)/ipv6/tcp-->'mpls_label=100,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_label", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls(label=100)/arp-->'mpls_label=100,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_label", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/mpls(label=100)/arp-->'mpls_label=100,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_label", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/mpls(label=203)/arp-->'mpls_label=100,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_label", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * 30)" ], "table-miss":[ 0 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/35_MPLS_TC.json0000664000175000017500000005332100000000000023146 0ustar00zuulzuul00000000000000[ "match: 35_MPLS_TC", { "description":"ethernet/mpls(exp=3)/ipv4/tcp-->'mpls_tc=3,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_tc", "value":3 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls(exp=3)/ipv4/tcp-->'mpls_tc=3,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_tc", "value":3 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls(exp=5)/ipv4/tcp-->'mpls_tc=3,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_tc", "value":3 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls(exp=3)/ipv6/tcp-->'mpls_tc=3,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_tc", "value":3 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls(exp=3)/ipv6/tcp-->'mpls_tc=3,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_tc", "value":3 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls(exp=5)/ipv6/tcp-->'mpls_tc=3,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_tc", "value":3 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls(exp=3)/arp-->'mpls_tc=3,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_tc", "value":3 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/mpls(exp=3)/arp-->'mpls_tc=3,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_tc", "value":3 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/mpls(exp=5)/arp-->'mpls_tc=3,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_tc", "value":3 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * 30)" ], "table-miss":[ 0 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/36_MPLS_BOS.json0000664000175000017500000005367700000000000023302 0ustar00zuulzuul00000000000000[ "match: 36_MPLS_BOS", { "description":"ethernet/mpls(bsb=1)/ipv4/tcp-->'mpls_bos=1,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_bos", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls(bsb=1)/ipv4/tcp-->'mpls_bos=1,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_bos", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls(bsb=0)/mpls(bsb=1)/ipv4/tcp-->'mpls_bos=1,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_bos", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=0, label=203, exp=5, ttl=127)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls(bsb=1)/ipv6/tcp-->'mpls_bos=1,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_bos", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls(bsb=1)/ipv6/tcp-->'mpls_bos=1,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_bos", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls(bsb=0)/mpls(bsb=1)/ipv6/tcp-->'mpls_bos=1,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_bos", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=0, label=203, exp=5, ttl=127)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls(bsb=1)/arp-->'mpls_bos=1,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_bos", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/mpls(bsb=1)/arp-->'mpls_bos=1,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_bos", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/mpls(bsb=0)/mpls(bsb=1)/arp-->'mpls_bos=1,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } }, { "OXMTlv":{ "field":"mpls_bos", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=0, label=203, exp=5, ttl=127)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * 30)" ], "table-miss":[ 0 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/37_PBB_ISID.json0000664000175000017500000006325400000000000023230 0ustar00zuulzuul00000000000000[ "match: 37_PBB_ISID", { "description":"ethernet/svlan/itag(sid=100)/ethernet/svlan/vlan/ipv4/tcp-->'pbb_isid=100,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_isid", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/svlan/itag(sid=100)/ethernet/svlan/vlan/ipv4/tcp-->'pbb_isid=100,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_isid", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/svlan/itag(sid=203)/ethernet/svlan/vlan/ipv4/tcp-->'pbb_isid=100,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_isid", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/svlan/itag(sid=100)/ethernet/svlan/vlan/ipv6/tcp-->'pbb_isid=100,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_isid", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/svlan/itag(sid=100)/ethernet/svlan/vlan/ipv6/tcp-->'pbb_isid=100,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_isid", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/svlan/itag(sid=203)/ethernet/svlan/vlan/ipv6/tcp-->'pbb_isid=100,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_isid", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/svlan/itag(sid=100)/ethernet/svlan/vlan/arp-->'pbb_isid=100,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_isid", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/svlan/itag(sid=100)/ethernet/svlan/vlan/arp-->'pbb_isid=100,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_isid", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/svlan/itag(sid=203)/ethernet/svlan/vlan/arp-->'pbb_isid=100,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_isid", "value":100 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * 30)" ], "table-miss":[ 0 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/37_PBB_ISID_Mask.json0000664000175000017500000006433000000000000024177 0ustar00zuulzuul00000000000000[ "match: 37_PBB_ISID (Mask)", { "description":"ethernet/svlan/itag(sid=100)/ethernet/svlan/vlan/ipv4/tcp-->'pbb_isid=96(mask=0xf0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_isid", "mask":240, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/svlan/itag(sid=100)/ethernet/svlan/vlan/ipv4/tcp-->'pbb_isid=96(mask=0xf0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_isid", "mask":240, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/svlan/itag(sid=203)/ethernet/svlan/vlan/ipv4/tcp-->'pbb_isid=96(mask=0xf0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_isid", "mask":240, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/svlan/itag(sid=100)/ethernet/svlan/vlan/ipv6/tcp-->'pbb_isid=96(mask=0xf0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_isid", "mask":240, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/svlan/itag(sid=100)/ethernet/svlan/vlan/ipv6/tcp-->'pbb_isid=96(mask=0xf0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_isid", "mask":240, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/svlan/itag(sid=203)/ethernet/svlan/vlan/ipv6/tcp-->'pbb_isid=96(mask=0xf0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_isid", "mask":240, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/svlan/itag(sid=100)/ethernet/svlan/vlan/arp-->'pbb_isid=96(mask=0xf0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_isid", "mask":240, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/svlan/itag(sid=100)/ethernet/svlan/vlan/arp-->'pbb_isid=96(mask=0xf0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_isid", "mask":240, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/svlan/itag(sid=203)/ethernet/svlan/vlan/arp-->'pbb_isid=96(mask=0xf0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_isid", "mask":240, "value":96 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * 30)" ], "table-miss":[ 0 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/38_TUNNEL_ID.json0000664000175000017500000010176500000000000023377 0ustar00zuulzuul00000000000000[ "match: 38_TUNNEL_ID", { "description":"ethernet/ipv4/tcp-->'actions=set_field:12345->tunnel_id,goto_table:1','table_id:1,tunnel_id=12345,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tunnel_id", "value":12345 } } } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"tunnel_id", "value":12345 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4/tcp-->'actions=set_field:12345->tunnel_id,goto_table:1','table_id:1,tunnel_id=12345,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tunnel_id", "value":12345 } } } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"tunnel_id", "value":12345 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4/tcp-->'actions=set_field:6666->tunnel_id,goto_table:1','table_id:1,tunnel_id=12345,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tunnel_id", "value":6666 } } } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"tunnel_id", "value":12345 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/ipv6/tcp-->'actions=set_field:12345->tunnel_id,goto_table:1','table_id:1,tunnel_id=12345,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tunnel_id", "value":12345 } } } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"tunnel_id", "value":12345 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6/tcp-->'actions=set_field:12345->tunnel_id,goto_table:1','table_id:1,tunnel_id=12345,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tunnel_id", "value":12345 } } } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"tunnel_id", "value":12345 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6/tcp-->'actions=set_field:6666->tunnel_id,goto_table:1','table_id:1,tunnel_id=12345,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tunnel_id", "value":6666 } } } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"tunnel_id", "value":12345 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/arp-->'actions=set_field:12345->tunnel_id,goto_table:1','table_id:1,tunnel_id=12345,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tunnel_id", "value":12345 } } } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"tunnel_id", "value":12345 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp-->'actions=set_field:12345->tunnel_id,goto_table:1','table_id:1,tunnel_id=12345,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tunnel_id", "value":12345 } } } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"tunnel_id", "value":12345 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp-->'actions=set_field:6666->tunnel_id,goto_table:1','table_id:1,tunnel_id=12345,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tunnel_id", "value":6666 } } } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"tunnel_id", "value":12345 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/38_TUNNEL_ID_Mask.json0000664000175000017500000010312700000000000024344 0ustar00zuulzuul00000000000000[ "match: 38_TUNNEL_ID (Mask)", { "description":"ethernet/ipv4/tcp-->'actions=set_field:12345->tunnel_id,goto_table:1','table_id:1,tunnel_id=12288(mask=0xff00),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tunnel_id", "value":12345 } } } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"tunnel_id", "mask":65280, "value":12288 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4/tcp-->'actions=set_field:12345->tunnel_id,goto_table:1','table_id:1,tunnel_id=12288(mask=0xff00),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tunnel_id", "value":12345 } } } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"tunnel_id", "mask":65280, "value":12288 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv4/tcp-->'actions=set_field:6666->tunnel_id,goto_table:1','table_id:1,tunnel_id=12288(mask=0xff00),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tunnel_id", "value":6666 } } } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"tunnel_id", "mask":65280, "value":12288 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/ipv6/tcp-->'actions=set_field:12345->tunnel_id,goto_table:1','table_id:1,tunnel_id=12288(mask=0xff00),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tunnel_id", "value":12345 } } } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"tunnel_id", "mask":65280, "value":12288 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6/tcp-->'actions=set_field:12345->tunnel_id,goto_table:1','table_id:1,tunnel_id=12288(mask=0xff00),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tunnel_id", "value":12345 } } } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"tunnel_id", "mask":65280, "value":12288 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6/tcp-->'actions=set_field:6666->tunnel_id,goto_table:1','table_id:1,tunnel_id=12288(mask=0xff00),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tunnel_id", "value":6666 } } } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"tunnel_id", "mask":65280, "value":12288 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/arp-->'actions=set_field:12345->tunnel_id,goto_table:1','table_id:1,tunnel_id=12288(mask=0xff00),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tunnel_id", "value":12345 } } } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"tunnel_id", "mask":65280, "value":12288 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp-->'actions=set_field:12345->tunnel_id,goto_table:1','table_id:1,tunnel_id=12288(mask=0xff00),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tunnel_id", "value":12345 } } } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"tunnel_id", "mask":65280, "value":12288 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ] } ] }, { "description":"ethernet/arp-->'actions=set_field:6666->tunnel_id,goto_table:1','table_id:1,tunnel_id=12288(mask=0xff00),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionSetField":{ "field":{ "OXMTlv":{ "field":"tunnel_id", "value":6666 } } } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"tunnel_id", "mask":65280, "value":12288 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * (60 - 42))" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/39_IPV6_EXTHDR.json0000664000175000017500000011424300000000000023614 0ustar00zuulzuul00000000000000[ "match: 39_IPV6_EXTHDR", { "description":"ethernet/ipv6(ext_hdrs=[hop_opts,auth]/tcp-->'ipv6_exthdr=68,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_exthdr", "value":68 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6(ext_hdrs=[hop_opts,auth])/tcp-->'ipv6_exthdr=68,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_exthdr", "value":68 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6/tcp-->'ipv6_exthdr=68,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_exthdr", "value":68 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv6(ext_hdrs=[hop_opts,auth])/tcp-->'ipv6_exthdr=68,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_exthdr", "value":68 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6(ext_hdrs=[hop_opts,auth])/tcp-->'ipv6_exthdr=68,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_exthdr", "value":68 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6/tcp-->'ipv6_exthdr=68,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_exthdr", "value":68 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv6(ext_hdrs=[hop_opts,auth])/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_exthdr=68,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_exthdr", "value":68 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6(ext_hdrs=[hop_opts,auth])/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_exthdr=68,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_exthdr", "value":68 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_exthdr=68,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_exthdr", "value":68 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(ext_hdrs=[hop_opts,auth])/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_exthdr=68,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_exthdr", "value":68 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(ext_hdrs=[hop_opts,auth])/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_exthdr=68,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_exthdr", "value":68 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_exthdr=68,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_exthdr", "value":68 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/39_IPV6_EXTHDR_Mask.json0000664000175000017500000011572500000000000024575 0ustar00zuulzuul00000000000000[ "match: 39_IPV6_EXTHDR (Mask)", { "description":"ethernet/ipv6(ext_hdrs=[hop_opts,auth])/tcp-->'ipv6_exthdr=64(mask=0x1f0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_exthdr", "mask":496, "value":64 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6(ext_hdrs=[hop_opts,auth])/tcp-->'ipv6_exthdr=64(mask=0x1f0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_exthdr", "mask":496, "value":64 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/ipv6/tcp-->'ipv6_exthdr=64(mask=0x1f0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_exthdr", "mask":496, "value":64 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/vlan/ipv6(ext_hdrs=[hop_opts,auth])/tcp-->'ipv6_exthdr=64(mask=0x1f0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_exthdr", "mask":496, "value":64 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6(ext_hdrs=[hop_opts,auth])/tcp-->'ipv6_exthdr=64(mask=0x1f0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_exthdr", "mask":496, "value":64 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=33024)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/vlan/ipv6/tcp-->'ipv6_exthdr=64(mask=0x1f0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_exthdr", "mask":496, "value":64 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=33024)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/mpls/ipv6(ext_hdrs=[hop_opts,auth])/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_exthdr=64(mask=0x1f0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_exthdr", "mask":496, "value":64 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6(ext_hdrs=[hop_opts,auth])/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_exthdr=64(mask=0x1f0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_exthdr", "mask":496, "value":64 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34887)", "mpls(bsb=1, label=100, exp=3, ttl=64)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/mpls/ipv6/tcp-->'actions=pop_mpls:0x86dd,goto_table:1','table_id:1,ipv6_exthdr=64(mask=0x1f0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34887 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopMpls":{ "ethertype":34525 } } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_exthdr", "mask":496, "value":64 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34887)", "mpls(bsb=1, label=203, exp=5, ttl=127)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(ext_hdrs=[hop_opts,auth])/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,actions=pop_pbb,goto_table:1','table_id:1,ipv6_exthdr=64(mask=0x1f0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_exthdr", "mask":496, "value":64 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6(ext_hdrs=[hop_opts,auth])/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_exthdr=64(mask=0x1f0),actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_exthdr", "mask":496, "value":64 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=35047)", "itag(sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(dst='20::20',ext_hdrs=[hop_opts(nxt=51), auth(nxt=6)],flow_label=100, src='10::10', nxt=0, hop_limit=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/itag/ethernet/ipv6/tcp-->'actions=pop_pbb,goto_table:1','table_id:1,ipv6_exthdr=64(mask=0x1f0),actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionPopPbb":{} } ], "type":4 } }, { "OFPInstructionGotoTable":{ "table_id":1 } } ] } }, { "OFPFlowMod":{ "table_id":1, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ipv6_exthdr", "mask":496, "value":64 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=35047)", "itag(sid=203)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 1 ] } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/match/41_PBB_UCA.json0000664000175000017500000006331400000000000023100 0ustar00zuulzuul00000000000000[ "match: 41_PBB_UCA", { "description":"ethernet/svlan/itag(uca=1)/ethernet/svlan/vlan/ipv4/tcp-->'pbb_uca=1,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_uca", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(uca=1, sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(uca=1, sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/svlan/itag(uca=1)/ethernet/svlan/vlan/ipv4/tcp-->'pbb_uca=1,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_uca", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(uca=1, sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(uca=1, sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2048)", "ipv4(tos=32, proto=6, src='192.168.10.10', dst='192.168.20.20', ttl=64)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/svlan/itag(uca=0)/ethernet/svlan/vlan/ipv4/tcp-->'pbb_uca=1,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_uca", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(uca=0, sid=100)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2048)", "ipv4(tos=65, proto=6, src='10.10.10.10', dst='10.10.20.20', ttl=127)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/svlan/itag(uca=1)/ethernet/svlan/vlan/ipv6/tcp-->'pbb_uca=1,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_uca", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(uca=1, sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(uca=1, sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/svlan/itag(uca=1)/ethernet/svlan/vlan/ipv6/tcp-->'pbb_uca=1,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_uca", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(uca=1, sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(uca=1, sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=34525)", "ipv6(dst='20::20', flow_label=100, src='10::10', nxt=6, hop_limit=64, traffic_class=32)", "tcp(dst_port=2222, option=bytes(b'\\x00' * 4), src_port=11111)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ] } ] }, { "description":"ethernet/svlan/itag(uca=0)/ethernet/svlan/vlan/ipv6/tcp-->'pbb_uca=1,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_uca", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(uca=0, sid=100)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=5, cfi=0, vid=203, ethertype=34525)", "ipv6(dst='b0::b0', flow_label=203, src='a0::a0', nxt=6, hop_limit=127, traffic_class=65)", "tcp(dst_port=6789, option=bytes(b'\\x01' * 4), src_port=12345)", "b'\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f'" ], "table-miss":[ 0 ] } ] }, { "description":"ethernet/svlan/itag(uca=1)/ethernet/svlan/vlan/arp-->'pbb_uca=1,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_uca", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(uca=1, sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "egress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(uca=1, sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/svlan/itag(uca=1)/ethernet/svlan/vlan/arp-->'pbb_uca=1,actions=output:CONTROLLER'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_uca", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "max_len":65535, "port":4294967293 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(uca=1, sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ], "PACKET_IN":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(uca=1, sid=100)", "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=3, cfi=0, vid=100, ethertype=2054)", "arp(dst_ip='192.168.20.20',dst_mac='22:22:22:22:22:22', opcode=1, src_ip='192.168.10.10',src_mac='12:11:11:11:11:11')", "bytes(b'\\x00' * 30)" ] } ] }, { "description":"ethernet/svlan/itag(uca=0)/ethernet/svlan/vlan/arp-->'pbb_uca=1,actions=output:2'", "prerequisite":[ { "OFPFlowMod":{ "table_id":0, "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"eth_type", "value":35047 } }, { "OXMTlv":{ "field":"pbb_uca", "value":1 } } ] } }, "instructions":[ { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":[ "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34984)", "svlan(ethertype=35047, vid=10)", "itag(uca=0, sid=100)", "ethernet(dst='ba:bb:bb:bb:bb:bb', src='aa:aa:aa:aa:aa:aa', ethertype=34984)", "svlan(ethertype=33024, vid=10)", "vlan(pcp=5, cfi=0, vid=203, ethertype=2054)", "arp(dst_ip='10.10.20.20',dst_mac='ba:bb:bb:bb:bb:bb', opcode=2, src_ip='10.10.10.10',src_mac='aa:aa:aa:aa:aa:aa')", "bytes(b'\\x00' * 30)" ], "table-miss":[ 0 ] } ] } ] ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.2821157 os-ken-2.10.0/os_ken/tests/switch/of14/meter/0000775000175000017500000000000000000000000020617 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/meter/01_DROP_00_KBPS_00_1M.json0000664000175000017500000002114400000000000024532 0ustar00zuulzuul00000000000000[ "meter: 01_DROP_00_KBPS_00_1M", { "description":"2Mbps(ethernet/ipv4/tcp)-->'in_port=1,actions=meter:1Mbps(drop),output:2'", "prerequisite":[ { "OFPMeterMod":{ "meter_id":1, "bands":[ { "OFPMeterBandDrop":{ "rate":1000 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(proto=6)", "tcp()", "bytes(b'\\x11' * (1500 - 54))" ], "pktps":175, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":1000 } ] } } ] }, { "description":"2Mbps(ethernet/ipv6/tcp)-->'in_port=1,actions=meter:1Mbps(drop),output:2'", "prerequisite":[ { "OFPMeterMod":{ "meter_id":1, "bands":[ { "OFPMeterBandDrop":{ "rate":1000 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(nxt=6)", "tcp()", "bytes(b'\\x11' * (1500 - 74))" ], "pktps":175, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":1000 } ] } } ] }, { "description":"2Mbps(ethernet/arp)-->'in_port=1,actions=meter:1Mbps(drop),output:2'", "prerequisite":[ { "OFPMeterMod":{ "meter_id":1, "bands":[ { "OFPMeterBandDrop":{ "rate":1000 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_mac='22:22:22:22:22:22', src_mac='12:11:11:11:11:11')", "bytes(b'\\x11' * (1500 - 42))" ], "pktps":175, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":1000 } ] } } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/meter/01_DROP_00_KBPS_01_10M.json0000664000175000017500000002116400000000000024615 0ustar00zuulzuul00000000000000[ "meter: 01_DROP_00_KBPS_01_10M", { "description":"20Mbps(ethernet/ipv4/tcp)-->'in_port=1,actions=meter:10Mbps(drop),output:2'", "prerequisite":[ { "OFPMeterMod":{ "meter_id":1, "bands":[ { "OFPMeterBandDrop":{ "rate":10000 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(proto=6)", "tcp()", "bytes(b'\\x11' * (1500 - 54))" ], "pktps":1750, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":10000 } ] } } ] }, { "description":"20Mbps(ethernet/ipv6/tcp)-->'in_port=1,actions=meter:10Mbps(drop),output:2'", "prerequisite":[ { "OFPMeterMod":{ "meter_id":1, "bands":[ { "OFPMeterBandDrop":{ "rate":10000 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(nxt=6)", "tcp()", "bytes(b'\\x11' * (1500 - 74))" ], "pktps":1750, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":10000 } ] } } ] }, { "description":"20Mbps(ethernet/arp)-->'in_port=1,actions=meter:10Mbps(drop),output:2'", "prerequisite":[ { "OFPMeterMod":{ "meter_id":1, "bands":[ { "OFPMeterBandDrop":{ "rate":10000 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_mac='22:22:22:22:22:22', src_mac='12:11:11:11:11:11')", "bytes(b'\\x11' * (1500 - 42))" ], "pktps":1750, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":10000 } ] } } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/meter/01_DROP_00_KBPS_02_100M.json0000664000175000017500000002120400000000000024671 0ustar00zuulzuul00000000000000[ "meter: 01_DROP_00_KBPS_02_100M", { "description":"200Mbps(ethernet/ipv4/tcp)-->'in_port=1,actions=meter:100Mbps(drop),output:2'", "prerequisite":[ { "OFPMeterMod":{ "meter_id":1, "bands":[ { "OFPMeterBandDrop":{ "rate":100000 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(proto=6)", "tcp()", "bytes(b'\\x11' * (1500 - 54))" ], "pktps":17500, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":100000 } ] } } ] }, { "description":"200Mbps(ethernet/ipv6/tcp)-->'in_port=1,actions=meter:100Mbps(drop),output:2'", "prerequisite":[ { "OFPMeterMod":{ "meter_id":1, "bands":[ { "OFPMeterBandDrop":{ "rate":100000 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(nxt=6)", "tcp()", "bytes(b'\\x11' * (1500 - 74))" ], "pktps":17500, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":100000 } ] } } ] }, { "description":"200Mbps(ethernet/arp)-->'in_port=1,actions=meter:100Mbps(drop),output:2'", "prerequisite":[ { "OFPMeterMod":{ "meter_id":1, "bands":[ { "OFPMeterBandDrop":{ "rate":100000 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_mac='22:22:22:22:22:22', src_mac='12:11:11:11:11:11')", "bytes(b'\\x11' * (1500 - 42))" ], "pktps":17500, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":100000 } ] } } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/meter/01_DROP_01_PKTPS_00_100.json0000664000175000017500000002132200000000000024716 0ustar00zuulzuul00000000000000[ "meter: 01_DROP_01_PKTPS_00_100", { "description":"200pktps(ethernet/ipv4/tcp)-->'in_port=1,actions=meter:100pktps(drop),output:2'", "prerequisite":[ { "OFPMeterMod":{ "flags":2, "meter_id":1, "bands":[ { "OFPMeterBandDrop":{ "rate":100 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(proto=6)", "tcp()", "bytes(b'\\x11' * (1500 - 54))" ], "pktps":200, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "pktps":100 } ] } } ] }, { "description":"200pktps(ethernet/ipv6/tcp)-->'in_port=1,actions=meter:100pktps(drop),output:2'", "prerequisite":[ { "OFPMeterMod":{ "flags":2, "meter_id":1, "bands":[ { "OFPMeterBandDrop":{ "rate":100 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(nxt=6)", "tcp()", "bytes(b'\\x11' * (1500 - 74))" ], "pktps":200, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "pktps":100 } ] } } ] }, { "description":"200pktps(ethernet/arp)-->'in_port=1,actions=meter:100pktps(drop),output:2'", "prerequisite":[ { "OFPMeterMod":{ "flags":2, "meter_id":1, "bands":[ { "OFPMeterBandDrop":{ "rate":100 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_mac='22:22:22:22:22:22', src_mac='12:11:11:11:11:11')", "bytes(b'\\x11' * (1500 - 42))" ], "pktps":200, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "pktps":100 } ] } } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/meter/01_DROP_01_PKTPS_01_1000.json0000664000175000017500000002134200000000000025001 0ustar00zuulzuul00000000000000[ "meter: 01_DROP_01_PKTPS_01_1000", { "description":"2000pktps(ethernet/ipv4/tcp)-->'in_port=1,actions=meter:1000pktps(drop),output:2'", "prerequisite":[ { "OFPMeterMod":{ "flags":2, "meter_id":1, "bands":[ { "OFPMeterBandDrop":{ "rate":1000 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(proto=6)", "tcp()", "bytes(b'\\x11' * (1500 - 54))" ], "pktps":2000, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "pktps":1000 } ] } } ] }, { "description":"2000pktps(ethernet/ipv6/tcp)-->'in_port=1,actions=meter:1000pktps(drop),output:2'", "prerequisite":[ { "OFPMeterMod":{ "flags":2, "meter_id":1, "bands":[ { "OFPMeterBandDrop":{ "rate":1000 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(nxt=6)", "tcp()", "bytes(b'\\x11' * (1500 - 74))" ], "pktps":2000, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "pktps":1000 } ] } } ] }, { "description":"2000pktps(ethernet/arp)-->'in_port=1,actions=meter:1000pktps(drop),output:2'", "prerequisite":[ { "OFPMeterMod":{ "flags":2, "meter_id":1, "bands":[ { "OFPMeterBandDrop":{ "rate":1000 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_mac='22:22:22:22:22:22', src_mac='12:11:11:11:11:11')", "bytes(b'\\x11' * (1500 - 42))" ], "pktps":2000, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "pktps":1000 } ] } } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/meter/01_DROP_01_PKTPS_02_10000.json0000664000175000017500000002136200000000000025064 0ustar00zuulzuul00000000000000[ "meter: 01_DROP_01_PKTPS_02_10000", { "description":"20000pktps(ethernet/ipv4/tcp)-->'in_port=1,actions=meter:10000pktps(drop),output:2'", "prerequisite":[ { "OFPMeterMod":{ "flags":2, "meter_id":1, "bands":[ { "OFPMeterBandDrop":{ "rate":10000 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(proto=6)", "tcp()", "bytes(b'\\x11' * (1500 - 54))" ], "pktps":20000, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "pktps":10000 } ] } } ] }, { "description":"20000pktps(ethernet/ipv6/tcp)-->'in_port=1,actions=meter:10000pktps(drop),output:2'", "prerequisite":[ { "OFPMeterMod":{ "flags":2, "meter_id":1, "bands":[ { "OFPMeterBandDrop":{ "rate":10000 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(nxt=6)", "tcp()", "bytes(b'\\x11' * (1500 - 74))" ], "pktps":20000, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "pktps":10000 } ] } } ] }, { "description":"20000pktps(ethernet/arp)-->'in_port=1,actions=meter:10000pktps(drop),output:2'", "prerequisite":[ { "OFPMeterMod":{ "flags":2, "meter_id":1, "bands":[ { "OFPMeterBandDrop":{ "rate":10000 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_mac='22:22:22:22:22:22', src_mac='12:11:11:11:11:11')", "bytes(b'\\x11' * (1500 - 42))" ], "pktps":20000, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "pktps":10000 } ] } } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/meter/02_DSCP_REMARK_00_KBPS_00_1M.json0000664000175000017500000003024700000000000025565 0ustar00zuulzuul00000000000000[ "meter: 02_DSCP_REMARK_00_KBPS_00_1M", { "description":"2Mbps(ethernet/ipv4(dscp=18)/tcp)-->'in_port=1,actions=meter:1Mbps(dscp_remark:ip_dscp=20),output:2'", "prerequisite":[ { "OFPMeterMod":{ "meter_id":1, "bands":[ { "OFPMeterBandDscpRemark":{ "rate":1000, "prec_level":1 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(proto=6, tos=72)", "tcp()", "bytes(b'\\x11' * (1500 - 54))" ], "pktps":175, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } }, { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":20 } } ] }, "kbps":1000 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } }, { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":18 } } ] }, "kbps":1000 } ] } } ] }, { "description":"2Mbps(ethernet/ipv6(dscp=18)/tcp)-->'in_port=1,actions=meter:1Mbps(dscp_remark:ip_dscp=20),output:2'", "prerequisite":[ { "OFPMeterMod":{ "meter_id":1, "bands":[ { "OFPMeterBandDscpRemark":{ "rate":1000, "prec_level":1 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(nxt=6, traffic_class=72)", "tcp()", "bytes(b'\\x11' * (1500 - 74))" ], "pktps":175, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } }, { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":20 } } ] }, "kbps":1000 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } }, { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":18 } } ] }, "kbps":1000 } ] } } ] }, { "description":"2Mbps(ethernet/arp)-->'in_port=1,actions=meter:2Mbps(dscp_remark:prec_level=1),output:2'", "prerequisite":[ { "OFPMeterMod":{ "meter_id":1, "bands":[ { "OFPMeterBandDscpRemark":{ "rate":1000, "prec_level":1 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_mac='22:22:22:22:22:22', src_mac='12:11:11:11:11:11')", "bytes(b'\\x11' * (1500 - 42))" ], "pktps":175, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":2000 } ] } } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/meter/02_DSCP_REMARK_00_KBPS_01_10M.json0000664000175000017500000003027100000000000025643 0ustar00zuulzuul00000000000000[ "meter: 02_DSCP_REMARK_00_KBPS_01_10M", { "description":"20Mbps(ethernet/ipv4(dscp=18)/tcp)-->'in_port=1,actions=meter:10Mbps(dscp_remark:ip_dscp=20),output:2'", "prerequisite":[ { "OFPMeterMod":{ "meter_id":1, "bands":[ { "OFPMeterBandDscpRemark":{ "rate":10000, "prec_level":1 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(proto=6, tos=72)", "tcp()", "bytes(b'\\x11' * (1500 - 54))" ], "pktps":1750, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } }, { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":20 } } ] }, "kbps":10000 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } }, { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":18 } } ] }, "kbps":10000 } ] } } ] }, { "description":"20Mbps(ethernet/ipv6(dscp=18)/tcp)-->'in_port=1,actions=meter:10Mbps(dscp_remark:ip_dscp=20),output:2'", "prerequisite":[ { "OFPMeterMod":{ "meter_id":1, "bands":[ { "OFPMeterBandDscpRemark":{ "rate":10000, "prec_level":1 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(nxt=6, traffic_class=72)", "tcp()", "bytes(b'\\x11' * (1500 - 74))" ], "pktps":1750, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } }, { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":18 } } ] }, "kbps":10000 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } }, { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":20 } } ] }, "kbps":10000 } ] } } ] }, { "description":"20Mbps(ethernet/arp)-->'in_port=1,actions=meter:20Mbps(dscp_remark:prec_level=1),output:2'", "prerequisite":[ { "OFPMeterMod":{ "meter_id":1, "bands":[ { "OFPMeterBandDscpRemark":{ "rate":10000, "prec_level":1 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_mac='22:22:22:22:22:22', src_mac='12:11:11:11:11:11')", "bytes(b'\\x11' * (1500 - 42))" ], "pktps":1750, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":20000 } ] } } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/meter/02_DSCP_REMARK_00_KBPS_02_100M.json0000664000175000017500000003031300000000000025721 0ustar00zuulzuul00000000000000[ "meter: 02_DSCP_REMARK_00_KBPS_02_100M", { "description":"200Mbps(ethernet/ipv4(dscp=18)/tcp)-->'in_port=1,actions=meter:100Mbps(dscp_remark:ip_dscp=20),output:2'", "prerequisite":[ { "OFPMeterMod":{ "meter_id":1, "bands":[ { "OFPMeterBandDscpRemark":{ "rate":100000, "prec_level":1 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(proto=6, tos=72)", "tcp()", "bytes(b'\\x11' * (1500 - 54))" ], "pktps":17500, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } }, { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":20 } } ] }, "kbps":100000 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } }, { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":18 } } ] }, "kbps":100000 } ] } } ] }, { "description":"200Mbps(ethernet/ipv6(dscp=18)/tcp)-->'in_port=1,actions=meter:100Mbps(dscp_remark:ip_dscp=20),output:2'", "prerequisite":[ { "OFPMeterMod":{ "meter_id":1, "bands":[ { "OFPMeterBandDscpRemark":{ "rate":100000, "prec_level":1 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(nxt=6, traffic_class=72)", "tcp()", "bytes(b'\\x11' * (1500 - 74))" ], "pktps":17500, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } }, { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":20 } } ] }, "kbps":100000 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } }, { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":18 } } ] }, "kbps":100000 } ] } } ] }, { "description":"200Mbps(ethernet/arp)-->'in_port=1,actions=meter:200Mbps(dscp_remark:prec_level=1),output:2'", "prerequisite":[ { "OFPMeterMod":{ "meter_id":1, "bands":[ { "OFPMeterBandDscpRemark":{ "rate":100000, "prec_level":1 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_mac='22:22:22:22:22:22', src_mac='12:11:11:11:11:11')", "bytes(b'\\x11' * (1500 - 42))" ], "pktps":17500, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "kbps":200000 } ] } } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/meter/02_DSCP_REMARK_01_PKTPS_00_100.json0000664000175000017500000003042500000000000025751 0ustar00zuulzuul00000000000000[ "meter: 02_DSCP_REMARK_01_PKTPS_00_100", { "description":"200pktps(ethernet/ipv4(dscp=18)/tcp)-->'in_port=1,actions=meter:100pktps(dscp_remark:ip_dscp=20),output:2'", "prerequisite":[ { "OFPMeterMod":{ "flags":2, "meter_id":1, "bands":[ { "OFPMeterBandDscpRemark":{ "rate":100, "prec_level":1 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(proto=6, tos=72)", "tcp()", "bytes(b'\\x11' * (1500 - 54))" ], "pktps":200, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } }, { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":20 } } ] }, "pktps":100 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } }, { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":18 } } ] }, "pktps":100 } ] } } ] }, { "description":"200pktps(ethernet/ipv6(dscp=18)/tcp)-->'in_port=1,actions=meter:100pktps(dscp_remark:ip_dscp=20),output:2'", "prerequisite":[ { "OFPMeterMod":{ "flags":2, "meter_id":1, "bands":[ { "OFPMeterBandDscpRemark":{ "rate":100, "prec_level":1 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(nxt=6, traffic_class=72)", "tcp()", "bytes(b'\\x11' * (1500 - 74))" ], "pktps":200, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } }, { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":20 } } ] }, "pktps":100 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } }, { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":18 } } ] }, "pktps":100 } ] } } ] }, { "description":"200pktps(ethernet/arp)-->'in_port=1,actions=meter:200pktps(dscp_remark:prec_level=1),output:2'", "prerequisite":[ { "OFPMeterMod":{ "flags":2, "meter_id":1, "bands":[ { "OFPMeterBandDscpRemark":{ "rate":100, "prec_level":1 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_mac='22:22:22:22:22:22', src_mac='12:11:11:11:11:11')", "bytes(b'\\x11' * (1500 - 42))" ], "pktps":200, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "pktps":200 } ] } } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/meter/02_DSCP_REMARK_01_PKTPS_01_1000.json0000664000175000017500000003044700000000000026036 0ustar00zuulzuul00000000000000[ "meter: 02_DSCP_REMARK_01_PKTPS_01_1000", { "description":"2000pktps(ethernet/ipv4(dscp=18)/tcp)-->'in_port=1,actions=meter:1000pktps(dscp_remark:ip_dscp=20),output:2'", "prerequisite":[ { "OFPMeterMod":{ "flags":2, "meter_id":1, "bands":[ { "OFPMeterBandDscpRemark":{ "rate":1000, "prec_level":1 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(proto=6, tos=72)", "tcp()", "bytes(b'\\x11' * (1500 - 54))" ], "pktps":2000, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } }, { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":20 } } ] }, "pktps":1000 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } }, { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":18 } } ] }, "pktps":1000 } ] } } ] }, { "description":"2000pktps(ethernet/ipv6(dscp=18)/tcp)-->'in_port=1,actions=meter:1000pktps(dscp_remark:ip_dscp=20),output:2'", "prerequisite":[ { "OFPMeterMod":{ "flags":2, "meter_id":1, "bands":[ { "OFPMeterBandDscpRemark":{ "rate":1000, "prec_level":1 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(nxt=6, traffic_class=72)", "tcp()", "bytes(b'\\x11' * (1500 - 74))" ], "pktps":2000, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } }, { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":20 } } ] }, "pktps":1000 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } }, { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":18 } } ] }, "pktps":1000 } ] } } ] }, { "description":"2000pktps(ethernet/arp)-->'in_port=1,actions=meter:2000pktps(dscp_remark:prec_level=1),output:2'", "prerequisite":[ { "OFPMeterMod":{ "flags":2, "meter_id":1, "bands":[ { "OFPMeterBandDscpRemark":{ "rate":1000, "prec_level":1 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_mac='22:22:22:22:22:22', src_mac='12:11:11:11:11:11')", "bytes(b'\\x11' * (1500 - 42))" ], "pktps":2000, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "pktps":2000 } ] } } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/of14/meter/02_DSCP_REMARK_01_PKTPS_02_10000.json0000664000175000017500000003047100000000000026114 0ustar00zuulzuul00000000000000[ "meter: 02_DSCP_REMARK_01_PKTPS_02_10000", { "description":"20000pktps(ethernet/ipv4(dscp=18)/tcp)-->'in_port=1,actions=meter:10000pktps(dscp_remark:ip_dscp=20),output:2'", "prerequisite":[ { "OFPMeterMod":{ "flags":2, "meter_id":1, "bands":[ { "OFPMeterBandDscpRemark":{ "rate":10000, "prec_level":1 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2048)", "ipv4(proto=6, tos=72)", "tcp()", "bytes(b'\\x11' * (1500 - 54))" ], "pktps":20000, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } }, { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":20 } } ] }, "pktps":10000 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } }, { "OXMTlv":{ "field":"eth_type", "value":2048 } }, { "OXMTlv":{ "field":"ip_dscp", "value":18 } } ] }, "pktps":10000 } ] } } ] }, { "description":"20000pktps(ethernet/ipv6(dscp=18)/tcp)-->'in_port=1,actions=meter:10000pktps(dscp_remark:ip_dscp=20),output:2'", "prerequisite":[ { "OFPMeterMod":{ "flags":2, "meter_id":1, "bands":[ { "OFPMeterBandDscpRemark":{ "rate":10000, "prec_level":1 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=34525)", "ipv6(nxt=6, traffic_class=72)", "tcp()", "bytes(b'\\x11' * (1500 - 74))" ], "pktps":20000, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } }, { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":20 } } ] }, "pktps":10000 }, { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } }, { "OXMTlv":{ "field":"eth_type", "value":34525 } }, { "OXMTlv":{ "field":"ip_dscp", "value":18 } } ] }, "pktps":10000 } ] } } ] }, { "description":"20000pktps(ethernet/arp)-->'in_port=1,actions=meter:20000pktps(dscp_remark:prec_level=1),output:2'", "prerequisite":[ { "OFPMeterMod":{ "flags":2, "meter_id":1, "bands":[ { "OFPMeterBandDscpRemark":{ "rate":10000, "prec_level":1 } } ] } }, { "OFPFlowMod":{ "match":{ "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":1 } } ] } }, "instructions":[ { "OFPInstructionMeter":{ "meter_id":1 } }, { "OFPInstructionActions":{ "actions":[ { "OFPActionOutput":{ "port":2 } } ], "type":4 } } ] } } ], "tests":[ { "ingress":{ "packets":{ "data":[ "ethernet(dst='22:22:22:22:22:22', src='12:11:11:11:11:11', ethertype=2054)", "arp(dst_mac='22:22:22:22:22:22', src_mac='12:11:11:11:11:11')", "bytes(b'\\x11' * (1500 - 42))" ], "pktps":20000, "duration_time":30 } }, "egress":{ "throughput":[ { "OFPMatch":{ "oxm_fields":[ { "OXMTlv":{ "field":"in_port", "value":2 } } ] }, "pktps":20000 } ] } } ] } ] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/run_mininet.py0000775000175000017500000000260200000000000021636 0ustar00zuulzuul00000000000000#!/usr/bin/env python3 import sys from mininet.cli import CLI from mininet.net import Mininet from mininet.node import RemoteController from mininet.node import OVSSwitch from mininet.node import UserSwitch from oslo_config import cfg from os_ken import version from os_ken.ofproto.ofproto_common import OFP_TCP_PORT if '__main__' == __name__: opts = [ cfg.StrOpt('switch', default='ovs', help='test switch [ovs|cpqd]'), cfg.StrOpt('protocols', default='OpenFlow13', help='"protocols" option for ovs-vsctl (e.g. OpenFlow13)') ] conf = cfg.ConfigOpts() conf.register_cli_opts(opts) conf(project='os_ken', version='run_mininet.py %s' % version) conf(sys.argv[1:]) switch_type = {'ovs': OVSSwitch, 'cpqd': UserSwitch} switch = switch_type.get(conf.switch, None) if switch is None: raise ValueError('Invalid switch type. [%s]', conf.switch) net = Mininet(switch=switch, controller=RemoteController) c0 = net.addController('c0', port=OFP_TCP_PORT) s1 = net.addSwitch('s1') s2 = net.addSwitch('s2') net.addLink(s1, s2) net.addLink(s1, s2) net.addLink(s1, s2) net.start() if conf.switch == 'ovs': s1.cmd('ovs-vsctl set Bridge s1 protocols=%s' % conf.protocols) s2.cmd('ovs-vsctl set Bridge s2 protocols=%s' % conf.protocols) CLI(net) net.stop() ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/switch/tester.py0000664000175000017500000016307500000000000020626 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone 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. import binascii import inspect import json import logging import math import netaddr import os import signal import sys import time import traceback from random import randint from os_ken import cfg from os_ken.base import app_manager from os_ken.controller import handler from os_ken.controller import ofp_event from os_ken.controller.handler import set_ev_cls from os_ken.exception import OSKenException from os_ken.lib import dpid as dpid_lib from os_ken.lib import hub from os_ken.lib import stringify from os_ken.lib.packet import packet from os_ken.ofproto import ofproto_parser from os_ken.ofproto import ofproto_protocol from os_ken.ofproto import ofproto_v1_0 from os_ken.ofproto import ofproto_v1_2 from os_ken.ofproto import ofproto_v1_3 from os_ken.ofproto import ofproto_v1_4 from os_ken.ofproto import ofproto_v1_5 # import all packet libraries. PKT_LIB_PATH = 'os_ken.lib.packet' CLSNAME_ALIASES = { ('os_ken.lib.packet.ipv6', 'option'): 'ipv6option', ('os_ken.lib.packet.icmpv6', 'echo'): 'icmpv6echo', ('os_ken.lib.packet.bgp', 'StreamParser'): '', ('os_ken.lib.packet.bgp', 'StringifyMixin'): '', ('os_ken.lib.packet.dhcp', 'option'): 'dhcpoption', ('os_ken.lib.packet.dhcp', 'options'): 'dhcpoptions', ('os_ken.lib.packet.ospf', 'StringifyMixin'): '' } for modname, moddef in sys.modules.copy().items(): if not modname.startswith(PKT_LIB_PATH) or not moddef: continue for (clsname, clsdef, ) in inspect.getmembers(moddef): if not inspect.isclass(clsdef): continue clsname_alias = CLSNAME_ALIASES.get((modname, clsname)) if clsname_alias == '': continue elif clsname_alias is not None: exec('from %s import %s as %s' % (modname, clsname, clsname_alias)) else: assert clsname not in globals(), ( "%s.%s already defined" % (modname, clsname)) exec('from %s import %s' % (modname, clsname)) """ Required test network: +-------------------+ +----------| target sw | The switch to be tested | +-------------------+ +------------+ (1) (2) (3) | controller | | | | +------------+ (1) (2) (3) | +-------------------+ +----------| tester sw | OpenFlow Switch +-------------------+ (X) : port number Tests send a packet from port 1 of the tester sw. If the packet matched with a flow entry of the target sw, the target sw resends the packet from port 2 (or the port which connected with the controller), according to the flow entry. Then the tester sw receives the packet and sends a PacketIn message. If the packet did not match, the target sw drops the packet. If you want to use the other port number which differ from above chart, you can specify the port number in the options when this tool is started. For details of this options, please refer to the Help command. Also, if you describe the name of an option argument (e.g. "target_send_port_1") in test files, this tool sets the argument value in the port number. e.g.) "OFPActionOutput":{ "port":"target_send_port_1" } """ CONF = cfg.CONF # Default settings. INTERVAL = 1 # sec WAIT_TIMER = 3 # sec CONTINUOUS_THREAD_INTVL = float(0.01) # sec CONTINUOUS_PROGRESS_SPAN = 3 # sec THROUGHPUT_PRIORITY = ofproto_v1_3.OFP_DEFAULT_PRIORITY + 1 THROUGHPUT_COOKIE = THROUGHPUT_PRIORITY THROUGHPUT_THRESHOLD = float(0.10) # expected throughput plus/minus 10 % # Default settings for 'ingress: packets' DEFAULT_DURATION_TIME = 30 DEFAULT_PKTPS = 1000 # Test file format. KEY_DESC = 'description' KEY_PREREQ = 'prerequisite' KEY_FLOW = 'OFPFlowMod' KEY_METER = 'OFPMeterMod' KEY_GROUP = 'OFPGroupMod' KEY_TESTS = 'tests' KEY_INGRESS = 'ingress' KEY_EGRESS = 'egress' KEY_PKT_IN = 'PACKET_IN' KEY_TBL_MISS = 'table-miss' KEY_PACKETS = 'packets' KEY_DATA = 'data' KEY_KBPS = 'kbps' KEY_PKTPS = 'pktps' KEY_DURATION_TIME = 'duration_time' KEY_THROUGHPUT = 'throughput' KEY_MATCH = 'OFPMatch' # Test state. STATE_INIT_FLOW = 0 STATE_FLOW_INSTALL = 1 STATE_FLOW_EXIST_CHK = 2 STATE_TARGET_PKT_COUNT = 3 STATE_TESTER_PKT_COUNT = 4 STATE_FLOW_MATCH_CHK = 5 STATE_NO_PKTIN_REASON = 6 STATE_GET_MATCH_COUNT = 7 STATE_SEND_BARRIER = 8 STATE_FLOW_UNMATCH_CHK = 9 STATE_INIT_METER = 10 STATE_METER_INSTALL = 11 STATE_METER_EXIST_CHK = 12 STATE_INIT_THROUGHPUT_FLOW = 13 STATE_THROUGHPUT_FLOW_INSTALL = 14 STATE_THROUGHPUT_FLOW_EXIST_CHK = 15 STATE_GET_THROUGHPUT = 16 STATE_THROUGHPUT_CHK = 17 STATE_INIT_GROUP = 18 STATE_GROUP_INSTALL = 19 STATE_GROUP_EXIST_CHK = 20 STATE_DISCONNECTED = 99 # Test result. TEST_OK = 'OK' TEST_ERROR = 'ERROR' OSKEN_INTERNAL_ERROR = '- (OSKen internal error.)' TEST_FILE_ERROR = '%(file)s : Test file format error (%(detail)s)' NO_TEST_FILE = 'Test file (*.json) is not found.' INVALID_PATH = '%(path)s : No such file or directory.' # Test result details. FAILURE = 0 ERROR = 1 TIMEOUT = 2 RCV_ERR = 3 MSG = {STATE_INIT_FLOW: {TIMEOUT: 'Failed to initialize flow tables: barrier request timeout.', RCV_ERR: 'Failed to initialize flow tables: %(err_msg)s'}, STATE_INIT_THROUGHPUT_FLOW: {TIMEOUT: 'Failed to initialize flow tables of tester_sw: ' 'barrier request timeout.', RCV_ERR: 'Failed to initialize flow tables of tester_sw: ' '%(err_msg)s'}, STATE_FLOW_INSTALL: {TIMEOUT: 'Failed to add flows: barrier request timeout.', RCV_ERR: 'Failed to add flows: %(err_msg)s'}, STATE_THROUGHPUT_FLOW_INSTALL: {TIMEOUT: 'Failed to add flows to tester_sw: barrier request timeout.', RCV_ERR: 'Failed to add flows to tester_sw: %(err_msg)s'}, STATE_METER_INSTALL: {TIMEOUT: 'Failed to add meters: barrier request timeout.', RCV_ERR: 'Failed to add meters: %(err_msg)s'}, STATE_GROUP_INSTALL: {TIMEOUT: 'Failed to add groups: barrier request timeout.', RCV_ERR: 'Failed to add groups: %(err_msg)s'}, STATE_FLOW_EXIST_CHK: {FAILURE: 'Added incorrect flows: %(flows)s', TIMEOUT: 'Failed to add flows: flow stats request timeout.', RCV_ERR: 'Failed to add flows: %(err_msg)s'}, STATE_METER_EXIST_CHK: {FAILURE: 'Added incorrect meters: %(meters)s', TIMEOUT: 'Failed to add meters: meter config stats request timeout.', RCV_ERR: 'Failed to add meters: %(err_msg)s'}, STATE_GROUP_EXIST_CHK: {FAILURE: 'Added incorrect groups: %(groups)s', TIMEOUT: 'Failed to add groups: group desc stats request timeout.', RCV_ERR: 'Failed to add groups: %(err_msg)s'}, STATE_TARGET_PKT_COUNT: {TIMEOUT: 'Failed to request port stats from target: request timeout.', RCV_ERR: 'Failed to request port stats from target: %(err_msg)s'}, STATE_TESTER_PKT_COUNT: {TIMEOUT: 'Failed to request port stats from tester: request timeout.', RCV_ERR: 'Failed to request port stats from tester: %(err_msg)s'}, STATE_FLOW_MATCH_CHK: {FAILURE: 'Received incorrect %(pkt_type)s: %(detail)s', TIMEOUT: '', # for check no packet-in reason. RCV_ERR: 'Failed to send packet: %(err_msg)s'}, STATE_NO_PKTIN_REASON: {FAILURE: 'Receiving timeout: %(detail)s'}, STATE_GET_MATCH_COUNT: {TIMEOUT: 'Failed to request table stats: request timeout.', RCV_ERR: 'Failed to request table stats: %(err_msg)s'}, STATE_SEND_BARRIER: {TIMEOUT: 'Failed to send packet: barrier request timeout.', RCV_ERR: 'Failed to send packet: %(err_msg)s'}, STATE_FLOW_UNMATCH_CHK: {FAILURE: 'Table-miss error: increment in matched_count.', ERROR: 'Table-miss error: no change in lookup_count.', TIMEOUT: 'Failed to request table stats: request timeout.', RCV_ERR: 'Failed to request table stats: %(err_msg)s'}, STATE_THROUGHPUT_FLOW_EXIST_CHK: {FAILURE: 'Added incorrect flows to tester_sw: %(flows)s', TIMEOUT: 'Failed to add flows to tester_sw: ' 'flow stats request timeout.', RCV_ERR: 'Failed to add flows to tester_sw: %(err_msg)s'}, STATE_GET_THROUGHPUT: {TIMEOUT: 'Failed to request flow stats: request timeout.', RCV_ERR: 'Failed to request flow stats: %(err_msg)s'}, STATE_THROUGHPUT_CHK: {FAILURE: 'Received unexpected throughput: %(detail)s'}, STATE_DISCONNECTED: {ERROR: 'Disconnected from switch'}} ERR_MSG = 'OFPErrorMsg[type=0x%02x, code=0x%02x]' class TestMessageBase(OSKenException): def __init__(self, state, message_type, **argv): msg = MSG[state][message_type] % argv super(TestMessageBase, self).__init__(msg=msg) class TestFailure(TestMessageBase): def __init__(self, state, **argv): super(TestFailure, self).__init__(state, FAILURE, **argv) class TestTimeout(TestMessageBase): def __init__(self, state): super(TestTimeout, self).__init__(state, TIMEOUT) class TestReceiveError(TestMessageBase): def __init__(self, state, err_msg): argv = {'err_msg': ERR_MSG % (err_msg.type, err_msg.code)} super(TestReceiveError, self).__init__(state, RCV_ERR, **argv) class TestError(TestMessageBase): def __init__(self, state, **argv): super(TestError, self).__init__(state, ERROR, **argv) class OfTester(app_manager.OSKenApp): """ OpenFlow Switch Tester. """ tester_ver = None target_ver = None def __init__(self): super(OfTester, self).__init__() self._set_logger() self.interval = CONF['test-switch']['interval'] self.target_dpid = self._convert_dpid(CONF['test-switch']['target']) self.target_send_port_1 = CONF['test-switch']['target_send_port_1'] self.target_send_port_2 = CONF['test-switch']['target_send_port_2'] self.target_recv_port = CONF['test-switch']['target_recv_port'] self.tester_dpid = self._convert_dpid(CONF['test-switch']['tester']) self.tester_send_port = CONF['test-switch']['tester_send_port'] self.tester_recv_port_1 = CONF['test-switch']['tester_recv_port_1'] self.tester_recv_port_2 = CONF['test-switch']['tester_recv_port_2'] self.logger.info('target_dpid=%s', dpid_lib.dpid_to_str(self.target_dpid)) self.logger.info('tester_dpid=%s', dpid_lib.dpid_to_str(self.tester_dpid)) def __get_version(opt): vers = { 'openflow10': ofproto_v1_0.OFP_VERSION, 'openflow13': ofproto_v1_3.OFP_VERSION, 'openflow14': ofproto_v1_4.OFP_VERSION, 'openflow15': ofproto_v1_5.OFP_VERSION } ver = vers.get(opt.lower()) if ver is None: self.logger.error( '%s is not supported. ' 'Supported versions are %s.', opt, list(vers.keys())) self._test_end() return ver target_opt = CONF['test-switch']['target_version'] self.logger.info('target ofp version=%s', target_opt) OfTester.target_ver = __get_version(target_opt) tester_opt = CONF['test-switch']['tester_version'] self.logger.info('tester ofp version=%s', tester_opt) OfTester.tester_ver = __get_version(tester_opt) # set app_supported_versions later. ofproto_protocol.set_app_supported_versions( [OfTester.target_ver, OfTester.tester_ver]) test_dir = CONF['test-switch']['dir'] self.logger.info('Test files directory = %s', test_dir) self.target_sw = OpenFlowSw(DummyDatapath(), self.logger) self.tester_sw = OpenFlowSw(DummyDatapath(), self.logger) self.state = STATE_INIT_FLOW self.sw_waiter = None self.waiter = None self.send_msg_xids = [] self.rcv_msgs = [] self.ingress_event = None self.ingress_threads = [] self.thread_msg = None self.test_thread = hub.spawn( self._test_sequential_execute, test_dir) def _set_logger(self): self.logger.propagate = False s_hdlr = logging.StreamHandler() self.logger.addHandler(s_hdlr) if CONF.log_file: f_hdlr = logging.handlers.WatchedFileHandler(CONF.log_file) self.logger.addHandler(f_hdlr) def _convert_dpid(self, dpid_str): try: return int(dpid_str, 16) except ValueError as err: self.logger.error('Invarid dpid parameter. %s', err) self._test_end() def close(self): if self.test_thread is not None: hub.kill(self.test_thread) if self.ingress_event: self.ingress_event.set() hub.joinall([self.test_thread]) self._test_end('--- Test terminated ---') @set_ev_cls(ofp_event.EventOFPStateChange, [handler.MAIN_DISPATCHER, handler.DEAD_DISPATCHER]) def dispatcher_change(self, ev): assert ev.datapath is not None if ev.state == handler.MAIN_DISPATCHER: self._register_sw(ev.datapath) elif ev.state == handler.DEAD_DISPATCHER: self._unregister_sw(ev.datapath) def _register_sw(self, dp): vers = { ofproto_v1_0.OFP_VERSION: 'openflow10', ofproto_v1_3.OFP_VERSION: 'openflow13', ofproto_v1_4.OFP_VERSION: 'openflow14', ofproto_v1_5.OFP_VERSION: 'openflow15' } if dp.id == self.target_dpid: if dp.ofproto.OFP_VERSION != OfTester.target_ver: msg = 'Join target SW, but ofp version is not %s.' % \ vers[OfTester.target_ver] else: self.target_sw.dp = dp msg = 'Join target SW.' elif dp.id == self.tester_dpid: if dp.ofproto.OFP_VERSION != OfTester.tester_ver: msg = 'Join tester SW, but ofp version is not %s.' % \ vers[OfTester.tester_ver] else: self.tester_sw.dp = dp msg = 'Join tester SW.' else: msg = 'Connect unknown SW.' if dp.id: self.logger.info('dpid=%s : %s', dpid_lib.dpid_to_str(dp.id), msg) if not (isinstance(self.target_sw.dp, DummyDatapath) or isinstance(self.tester_sw.dp, DummyDatapath)): if self.sw_waiter is not None: self.sw_waiter.set() def _unregister_sw(self, dp): if dp.id == self.target_dpid: self.target_sw.dp = DummyDatapath() msg = 'Leave target SW.' elif dp.id == self.tester_dpid: self.tester_sw.dp = DummyDatapath() msg = 'Leave tester SW.' else: msg = 'Disconnect unknown SW.' if dp.id: self.logger.info('dpid=%s : %s', dpid_lib.dpid_to_str(dp.id), msg) def _test_sequential_execute(self, test_dir): """ Execute OpenFlow Switch test. """ # Parse test pattern from test files. tests = TestPatterns(test_dir, self.logger) if not tests: self.logger.warning(NO_TEST_FILE) self._test_end() test_report = {} self.logger.info('--- Test start ---') test_keys = list(tests.keys()) test_keys.sort() for file_name in test_keys: report = self._test_file_execute(tests[file_name]) for result, descriptions in report.items(): test_report.setdefault(result, []) test_report[result].extend(descriptions) self._test_end(msg='--- Test end ---', report=test_report) def _test_file_execute(self, testfile): report = {} for i, test in enumerate(testfile.tests): desc = testfile.description if i == 0 else None result = self._test_execute(test, desc) report.setdefault(result, []) report[result].append([testfile.description, test.description]) hub.sleep(self.interval) return report def _test_execute(self, test, description): if isinstance(self.target_sw.dp, DummyDatapath) or \ isinstance(self.tester_sw.dp, DummyDatapath): self.logger.info('waiting for switches connection...') self.sw_waiter = hub.Event() self.sw_waiter.wait() self.sw_waiter = None if description: self.logger.info('%s', description) self.thread_msg = None # Test execute. try: # Initialize. self._test(STATE_INIT_METER) self._test(STATE_INIT_GROUP) self._test(STATE_INIT_FLOW, self.target_sw) self._test(STATE_INIT_THROUGHPUT_FLOW, self.tester_sw) # Install flows. for flow in test.prerequisite: if isinstance( flow, self.target_sw.dp.ofproto_parser.OFPFlowMod): self._test(STATE_FLOW_INSTALL, self.target_sw, flow) self._test(STATE_FLOW_EXIST_CHK, self.target_sw.send_flow_stats, flow) elif isinstance( flow, self.target_sw.dp.ofproto_parser.OFPMeterMod): self._test(STATE_METER_INSTALL, self.target_sw, flow) self._test(STATE_METER_EXIST_CHK, self.target_sw.send_meter_config_stats, flow) elif isinstance( flow, self.target_sw.dp.ofproto_parser.OFPGroupMod): self._test(STATE_GROUP_INSTALL, self.target_sw, flow) self._test(STATE_GROUP_EXIST_CHK, self.target_sw.send_group_desc_stats, flow) # Do tests. for pkt in test.tests: # Get stats before sending packet(s). if KEY_EGRESS in pkt or KEY_PKT_IN in pkt: target_pkt_count = [self._test(STATE_TARGET_PKT_COUNT, True)] tester_pkt_count = [self._test(STATE_TESTER_PKT_COUNT, False)] elif KEY_THROUGHPUT in pkt: # install flows for throughput analysis for throughput in pkt[KEY_THROUGHPUT]: flow = throughput[KEY_FLOW] self._test(STATE_THROUGHPUT_FLOW_INSTALL, self.tester_sw, flow) self._test(STATE_THROUGHPUT_FLOW_EXIST_CHK, self.tester_sw.send_flow_stats, flow) start = self._test(STATE_GET_THROUGHPUT) elif KEY_TBL_MISS in pkt: before_stats = self._test(STATE_GET_MATCH_COUNT) # Send packet(s). if KEY_INGRESS in pkt: self._one_time_packet_send(pkt) elif KEY_PACKETS in pkt: self._continuous_packet_send(pkt) # Check a result. if KEY_EGRESS in pkt or KEY_PKT_IN in pkt: result = self._test(STATE_FLOW_MATCH_CHK, pkt) if result == TIMEOUT: target_pkt_count.append(self._test( STATE_TARGET_PKT_COUNT, True)) tester_pkt_count.append(self._test( STATE_TESTER_PKT_COUNT, False)) test_type = (KEY_EGRESS if KEY_EGRESS in pkt else KEY_PKT_IN) self._test(STATE_NO_PKTIN_REASON, test_type, target_pkt_count, tester_pkt_count) elif KEY_THROUGHPUT in pkt: end = self._test(STATE_GET_THROUGHPUT) self._test(STATE_THROUGHPUT_CHK, pkt[KEY_THROUGHPUT], start, end) elif KEY_TBL_MISS in pkt: self._test(STATE_SEND_BARRIER) hub.sleep(INTERVAL) self._test(STATE_FLOW_UNMATCH_CHK, before_stats, pkt) result = [TEST_OK] result_type = TEST_OK except (TestFailure, TestError, TestTimeout, TestReceiveError) as err: result = [TEST_ERROR, str(err)] result_type = str(err).split(':', 1)[0] finally: self.ingress_event = None for tid in self.ingress_threads: hub.kill(tid) self.ingress_threads = [] # Output test result. self.logger.info(' %-100s %s', test.description, result[0]) if 1 < len(result): self.logger.info(' %s', result[1]) if result[1] == OSKEN_INTERNAL_ERROR\ or result == 'An unknown exception': self.logger.error(traceback.format_exc()) hub.sleep(0) return result_type def _test_end(self, msg=None, report=None): self.test_thread = None if msg: self.logger.info(msg) if report: self._output_test_report(report) pid = os.getpid() os.kill(pid, signal.SIGTERM) def _output_test_report(self, report): self.logger.info('%s--- Test report ---', os.linesep) error_count = 0 for result_type in sorted(list(report.keys())): test_descriptions = report[result_type] if result_type == TEST_OK: continue error_count += len(test_descriptions) self.logger.info('%s(%d)', result_type, len(test_descriptions)) for file_desc, test_desc in test_descriptions: self.logger.info(' %-40s %s', file_desc, test_desc) self.logger.info('%s%s(%d) / %s(%d)', os.linesep, TEST_OK, len(report.get(TEST_OK, [])), TEST_ERROR, error_count) def _test(self, state, *args): test = {STATE_INIT_FLOW: self._test_initialize_flow, STATE_INIT_THROUGHPUT_FLOW: self._test_initialize_flow, STATE_INIT_METER: self.target_sw.del_meters, STATE_INIT_GROUP: self.target_sw.del_groups, STATE_FLOW_INSTALL: self._test_msg_install, STATE_THROUGHPUT_FLOW_INSTALL: self._test_msg_install, STATE_METER_INSTALL: self._test_msg_install, STATE_GROUP_INSTALL: self._test_msg_install, STATE_FLOW_EXIST_CHK: self._test_exist_check, STATE_THROUGHPUT_FLOW_EXIST_CHK: self._test_exist_check, STATE_METER_EXIST_CHK: self._test_exist_check, STATE_GROUP_EXIST_CHK: self._test_exist_check, STATE_TARGET_PKT_COUNT: self._test_get_packet_count, STATE_TESTER_PKT_COUNT: self._test_get_packet_count, STATE_FLOW_MATCH_CHK: self._test_flow_matching_check, STATE_NO_PKTIN_REASON: self._test_no_pktin_reason_check, STATE_GET_MATCH_COUNT: self._test_get_match_count, STATE_SEND_BARRIER: self._test_send_barrier, STATE_FLOW_UNMATCH_CHK: self._test_flow_unmatching_check, STATE_GET_THROUGHPUT: self._test_get_throughput, STATE_THROUGHPUT_CHK: self._test_throughput_check} self.send_msg_xids = [] self.rcv_msgs = [] self.state = state return test[state](*args) def _test_initialize_flow(self, datapath): # Note: Because DELETE and DELETE_STRICT commands in OpenFlow 1.0 # can not be filtered by the cookie value, this tool deletes all # flow entries of the tester switch temporarily and inserts default # flow entry immediately. xid = datapath.del_flows() self.send_msg_xids.append(xid) xid = datapath.add_flow( in_port=self.tester_recv_port_1, out_port=datapath.dp.ofproto.OFPP_CONTROLLER) self.send_msg_xids.append(xid) xid = datapath.send_barrier_request() self.send_msg_xids.append(xid) self._wait() assert len(self.rcv_msgs) == 1 msg = self.rcv_msgs[0] assert isinstance(msg, datapath.dp.ofproto_parser.OFPBarrierReply) def _test_msg_install(self, datapath, message): xid = datapath.send_msg(message) self.send_msg_xids.append(xid) xid = datapath.send_barrier_request() self.send_msg_xids.append(xid) self._wait() assert len(self.rcv_msgs) == 1 msg = self.rcv_msgs[0] assert isinstance(msg, datapath.dp.ofproto_parser.OFPBarrierReply) def _test_exist_check(self, method, message): ofp = method.__self__.dp.ofproto parser = method.__self__.dp.ofproto_parser method_dict = { OpenFlowSw.send_flow_stats.__name__: { 'reply': parser.OFPFlowStatsReply, 'compare': self._compare_flow } } if ofp.OFP_VERSION >= ofproto_v1_2.OFP_VERSION: method_dict[OpenFlowSw.send_group_desc_stats.__name__] = { 'reply': parser.OFPGroupDescStatsReply, 'compare': self._compare_group } if ofp.OFP_VERSION >= ofproto_v1_3.OFP_VERSION: method_dict[OpenFlowSw.send_meter_config_stats.__name__] = { 'reply': parser.OFPMeterConfigStatsReply, 'compare': self._compare_meter } xid = method() self.send_msg_xids.append(xid) self._wait() ng_stats = [] for msg in self.rcv_msgs: assert isinstance(msg, method_dict[method.__name__]['reply']) for stats in msg.body: result, stats = method_dict[method.__name__]['compare']( stats, message) if result: return else: ng_stats.append(stats) error_dict = { OpenFlowSw.send_flow_stats.__name__: { 'flows': ', '.join(ng_stats) } } if ofp.OFP_VERSION >= ofproto_v1_2.OFP_VERSION: error_dict[OpenFlowSw.send_group_desc_stats.__name__] = { 'groups': ', '.join(ng_stats) } if ofp.OFP_VERSION >= ofproto_v1_3.OFP_VERSION: error_dict[OpenFlowSw.send_meter_config_stats.__name__] = { 'meters': ', '.join(ng_stats) } raise TestFailure(self.state, **error_dict[method.__name__]) def _test_get_packet_count(self, is_target): sw = self.target_sw if is_target else self.tester_sw xid = sw.send_port_stats() self.send_msg_xids.append(xid) self._wait() result = {} for msg in self.rcv_msgs: for stats in msg.body: result[stats.port_no] = {'rx': stats.rx_packets, 'tx': stats.tx_packets} return result def _test_flow_matching_check(self, pkt): self.logger.debug("egress:[%s]", packet.Packet(pkt.get(KEY_EGRESS))) self.logger.debug("packet_in:[%s]", packet.Packet(pkt.get(KEY_PKT_IN))) # receive a PacketIn message. try: self._wait() except TestTimeout: return TIMEOUT assert len(self.rcv_msgs) == 1 msg = self.rcv_msgs[0] # Compare a received message with OFPPacketIn # # We compare names of classes instead of classes themselves # due to OVS bug. The code below should be as follows: # # assert isinstance(msg, msg.datapath.ofproto_parser.OFPPacketIn) # # At this moment, OVS sends Packet-In messages of of13 even if # OVS is configured to use of14, so the above code causes an # assertion. assert msg.__class__.__name__ == 'OFPPacketIn' self.logger.debug("dpid=%s : receive_packet[%s]", dpid_lib.dpid_to_str(msg.datapath.id), packet.Packet(msg.data)) # check the SW which sended PacketIn and output packet. pkt_in_src_model = (self.tester_sw if KEY_EGRESS in pkt else self.target_sw) model_pkt = (pkt[KEY_EGRESS] if KEY_EGRESS in pkt else pkt[KEY_PKT_IN]) if hasattr(msg.datapath.ofproto, "OFPR_NO_MATCH"): invalid_packet_in_reason = [msg.datapath.ofproto.OFPR_NO_MATCH] else: invalid_packet_in_reason = [msg.datapath.ofproto.OFPR_TABLE_MISS] if hasattr(msg.datapath.ofproto, "OFPR_INVALID_TTL"): invalid_packet_in_reason.append( msg.datapath.ofproto.OFPR_INVALID_TTL) if msg.datapath.id != pkt_in_src_model.dp.id: pkt_type = 'packet-in' err_msg = 'SW[dpid=%s]' % dpid_lib.dpid_to_str(msg.datapath.id) elif msg.reason in invalid_packet_in_reason: pkt_type = 'packet-in' err_msg = 'OFPPacketIn[reason=%d]' % msg.reason elif repr(msg.data) != repr(model_pkt): pkt_type = 'packet' err_msg = self._diff_packets(packet.Packet(model_pkt), packet.Packet(msg.data)) else: return TEST_OK raise TestFailure(self.state, pkt_type=pkt_type, detail=err_msg) def _test_no_pktin_reason_check(self, test_type, target_pkt_count, tester_pkt_count): before_target_receive = target_pkt_count[ 0][self.target_recv_port]['rx'] before_target_send = target_pkt_count[0][self.target_send_port_1]['tx'] before_tester_receive = tester_pkt_count[ 0][self.tester_recv_port_1]['rx'] before_tester_send = tester_pkt_count[0][self.tester_send_port]['tx'] after_target_receive = target_pkt_count[1][self.target_recv_port]['rx'] after_target_send = target_pkt_count[1][self.target_send_port_1]['tx'] after_tester_receive = tester_pkt_count[ 1][self.tester_recv_port_1]['rx'] after_tester_send = tester_pkt_count[1][self.tester_send_port]['tx'] if after_tester_send == before_tester_send: log_msg = 'no change in tx_packets on tester.' elif after_target_receive == before_target_receive: log_msg = 'no change in rx_packets on target.' elif test_type == KEY_EGRESS: if after_target_send == before_target_send: log_msg = 'no change in tx_packets on target.' elif after_tester_receive == before_tester_receive: log_msg = 'no change in rx_packets on tester.' else: log_msg = 'increment in rx_packets in tester.' else: assert test_type == KEY_PKT_IN log_msg = 'no packet-in.' raise TestFailure(self.state, detail=log_msg) def _test_get_match_count(self): xid = self.target_sw.send_table_stats() self.send_msg_xids.append(xid) self._wait() result = {} for msg in self.rcv_msgs: for stats in msg.body: result[stats.table_id] = {'lookup': stats.lookup_count, 'matched': stats.matched_count} return result def _test_send_barrier(self): # Wait OFPBarrierReply. xid = self.tester_sw.send_barrier_request() self.send_msg_xids.append(xid) self._wait() assert len(self.rcv_msgs) == 1 msg = self.rcv_msgs[0] assert isinstance( msg, self.tester_sw.dp.ofproto_parser.OFPBarrierReply) def _test_flow_unmatching_check(self, before_stats, pkt): # Check matched packet count. rcv_msgs = self._test_get_match_count() lookup = False for target_tbl_id in pkt[KEY_TBL_MISS]: before = before_stats[target_tbl_id] after = rcv_msgs[target_tbl_id] if before['lookup'] < after['lookup']: lookup = True if before['matched'] < after['matched']: raise TestFailure(self.state) if not lookup: raise TestError(self.state) def _one_time_packet_send(self, pkt): self.logger.debug("send_packet:[%s]", packet.Packet(pkt[KEY_INGRESS])) xid = self.tester_sw.send_packet_out(pkt[KEY_INGRESS]) self.send_msg_xids.append(xid) def _continuous_packet_send(self, pkt): assert self.ingress_event is None pkt_text = pkt[KEY_PACKETS]['packet_text'] pkt_bin = pkt[KEY_PACKETS]['packet_binary'] pktps = pkt[KEY_PACKETS][KEY_PKTPS] duration_time = pkt[KEY_PACKETS][KEY_DURATION_TIME] randomize = pkt[KEY_PACKETS]['randomize'] self.logger.debug("send_packet:[%s]", packet.Packet(pkt_bin)) self.logger.debug("pktps:[%d]", pktps) self.logger.debug("duration_time:[%d]", duration_time) arg = {'packet_text': pkt_text, 'packet_binary': pkt_bin, 'thread_counter': 0, 'dot_span': int(CONTINUOUS_PROGRESS_SPAN / CONTINUOUS_THREAD_INTVL), 'packet_counter': float(0), 'packet_counter_inc': pktps * CONTINUOUS_THREAD_INTVL, 'randomize': randomize} try: self.ingress_event = hub.Event() tid = hub.spawn(self._send_packet_thread, arg) self.ingress_threads.append(tid) self.ingress_event.wait(duration_time) if self.thread_msg is not None: raise self.thread_msg # pylint: disable=E0702 finally: sys.stdout.write("\r\n") sys.stdout.flush() def _send_packet_thread(self, arg): """ Send several packets continuously. """ if self.ingress_event is None or self.ingress_event._cond: return # display dots to express progress of sending packets if not arg['thread_counter'] % arg['dot_span']: sys.stdout.write(".") sys.stdout.flush() arg['thread_counter'] += 1 # pile up float values and # use integer portion as the number of packets this thread sends arg['packet_counter'] += arg['packet_counter_inc'] count = int(arg['packet_counter']) arg['packet_counter'] -= count hub.sleep(CONTINUOUS_THREAD_INTVL) tid = hub.spawn(self._send_packet_thread, arg) self.ingress_threads.append(tid) hub.sleep(0) for _ in range(count): if arg['randomize']: msg = eval('/'.join(arg['packet_text'])) msg.serialize() data = msg.data else: data = arg['packet_binary'] try: self.tester_sw.send_packet_out(data) except Exception as err: self.thread_msg = err self.ingress_event.set() break def _compare_flow(self, stats1, stats2): def __reasm_match(match): """ reassemble match_fields. """ match_fields = match.to_jsondict() # For only OpenFlow1.0 match_fields['OFPMatch'].pop('wildcards', None) return match_fields attr_list = ['cookie', 'priority', 'hard_timeout', 'idle_timeout', 'match'] if self.target_sw.dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION: attr_list += ['actions'] else: attr_list += ['table_id', 'instructions'] for attr in attr_list: value1 = getattr(stats1, attr) value2 = getattr(stats2, attr) if attr in ['actions', 'instructions']: value1 = sorted(value1, key=lambda x: x.type) value2 = sorted(value2, key=lambda x: x.type) elif attr == 'match': value1 = __reasm_match(value1) value2 = __reasm_match(value2) if str(value1) != str(value2): return False, 'flow_stats(%s != %s)' % (value1, value2) return True, None @classmethod def _compare_meter(cls, stats1, stats2): """compare the message used to install and the message got from the switch.""" attr_list = ['flags', 'meter_id', 'bands'] for attr in attr_list: value1 = getattr(stats1, attr) value2 = getattr(stats2, attr) if str(value1) != str(value2): return False, 'meter_stats(%s != %s)' % (value1, value2) return True, None @classmethod def _compare_group(cls, stats1, stats2): attr_list = ['type', 'group_id', 'buckets'] for attr in attr_list: value1 = getattr(stats1, attr) value2 = getattr(stats2, attr) if str(value1) != str(value2): return False, 'group_stats(%s != %s)' % (value1, value2) return True, None @classmethod def _diff_packets(cls, model_pkt, rcv_pkt): msg = [] for rcv_p in rcv_pkt.protocols: if not isinstance(rcv_p, bytes): model_protocols = model_pkt.get_protocols(type(rcv_p)) if len(model_protocols) == 1: model_p = model_protocols[0] diff = [] for attr in rcv_p.__dict__: if attr.startswith('_'): continue if callable(attr): continue if hasattr(rcv_p.__class__, attr): continue rcv_attr = repr(getattr(rcv_p, attr)) model_attr = repr(getattr(model_p, attr)) if rcv_attr != model_attr: diff.append('%s=%s' % (attr, rcv_attr)) if diff: msg.append('%s(%s)' % (rcv_p.__class__.__name__, ','.join(diff))) else: if (not model_protocols or not str(rcv_p) in str(model_protocols)): msg.append(str(rcv_p)) else: model_p = '' for p in model_pkt.protocols: if isinstance(p, bytes): model_p = p break if model_p != rcv_p: msg.append('str(%s)' % repr(rcv_p)) if msg: return '/'.join(msg) else: return ('Encounter an error during packet comparison.' ' it is malformed.') def _test_get_throughput(self): xid = self.tester_sw.send_flow_stats() self.send_msg_xids.append(xid) self._wait() assert len(self.rcv_msgs) == 1 flow_stats = self.rcv_msgs[0].body self.logger.debug(flow_stats) result = {} for stat in flow_stats: if stat.cookie != THROUGHPUT_COOKIE: continue result[str(stat.match)] = (stat.byte_count, stat.packet_count) return time.time(), result def _test_throughput_check(self, throughputs, start, end): msgs = [] elapsed_sec = end[0] - start[0] for throughput in throughputs: match = str(throughput[KEY_FLOW].match) # get oxm_fields of OFPMatch fields = dict(throughput[KEY_FLOW].match._fields2) if match not in start[1] or match not in end[1]: raise TestError(self.state, match=match) increased_bytes = end[1][match][0] - start[1][match][0] increased_packets = end[1][match][1] - start[1][match][1] if throughput[KEY_PKTPS]: key = KEY_PKTPS conv = 1 measured_value = increased_packets unit = 'pktps' elif throughput[KEY_KBPS]: key = KEY_KBPS conv = 1024 / 8 # Kilobits -> bytes measured_value = increased_bytes unit = 'kbps' else: raise OSKenException( 'An invalid key exists that is neither "%s" nor "%s".' % (KEY_KBPS, KEY_PKTPS)) expected_value = throughput[key] * elapsed_sec * conv margin = expected_value * THROUGHPUT_THRESHOLD self.logger.debug("measured_value:[%s]", measured_value) self.logger.debug("expected_value:[%s]", expected_value) self.logger.debug("margin:[%s]", margin) if math.fabs(measured_value - expected_value) > margin: msgs.append('{0} {1:.2f}{2}'.format(fields, measured_value / elapsed_sec / conv, unit)) if msgs: raise TestFailure(self.state, detail=', '.join(msgs)) def _wait(self): """ Wait until specific OFP message received or timer is exceeded. """ assert self.waiter is None self.waiter = hub.Event() self.rcv_msgs = [] timeout = False timer = hub.Timeout(WAIT_TIMER) try: self.waiter.wait() except hub.Timeout as t: if t is not timer: raise OSKenException('Internal error. Not my timeout.') timeout = True finally: timer.cancel() self.waiter = None if timeout: raise TestTimeout(self.state) if (self.rcv_msgs and isinstance( self.rcv_msgs[0], self.rcv_msgs[0].datapath.ofproto_parser.OFPErrorMsg)): raise TestReceiveError(self.state, self.rcv_msgs[0]) @set_ev_cls([ofp_event.EventOFPFlowStatsReply, ofp_event.EventOFPMeterConfigStatsReply, ofp_event.EventOFPTableStatsReply, ofp_event.EventOFPPortStatsReply, ofp_event.EventOFPGroupDescStatsReply], handler.MAIN_DISPATCHER) def stats_reply_handler(self, ev): # keys: stats reply event classes # values: states in which the events should be processed ofp = ev.msg.datapath.ofproto event_states = { ofp_event.EventOFPFlowStatsReply: [STATE_FLOW_EXIST_CHK, STATE_THROUGHPUT_FLOW_EXIST_CHK, STATE_GET_THROUGHPUT], ofp_event.EventOFPTableStatsReply: [STATE_GET_MATCH_COUNT, STATE_FLOW_UNMATCH_CHK], ofp_event.EventOFPPortStatsReply: [STATE_TARGET_PKT_COUNT, STATE_TESTER_PKT_COUNT], } if ofp.OFP_VERSION >= ofproto_v1_2.OFP_VERSION: event_states[ofp_event.EventOFPGroupDescStatsReply] = [ STATE_GROUP_EXIST_CHK ] if ofp.OFP_VERSION >= ofproto_v1_3.OFP_VERSION: event_states[ofp_event.EventOFPMeterConfigStatsReply] = [ STATE_METER_EXIST_CHK ] if self.state in event_states[ev.__class__]: if self.waiter and ev.msg.xid in self.send_msg_xids: self.rcv_msgs.append(ev.msg) if not ev.msg.flags: self.waiter.set() hub.sleep(0) @set_ev_cls(ofp_event.EventOFPBarrierReply, handler.MAIN_DISPATCHER) def barrier_reply_handler(self, ev): state_list = [STATE_INIT_FLOW, STATE_INIT_THROUGHPUT_FLOW, STATE_INIT_METER, STATE_INIT_GROUP, STATE_FLOW_INSTALL, STATE_THROUGHPUT_FLOW_INSTALL, STATE_METER_INSTALL, STATE_GROUP_INSTALL, STATE_SEND_BARRIER] if self.state in state_list: if self.waiter and ev.msg.xid in self.send_msg_xids: self.rcv_msgs.append(ev.msg) self.waiter.set() hub.sleep(0) @set_ev_cls(ofp_event.EventOFPPacketIn, handler.MAIN_DISPATCHER) def packet_in_handler(self, ev): state_list = [STATE_FLOW_MATCH_CHK] if self.state in state_list: if self.waiter: self.rcv_msgs.append(ev.msg) self.waiter.set() hub.sleep(0) @set_ev_cls(ofp_event.EventOFPErrorMsg, [handler.HANDSHAKE_DISPATCHER, handler.CONFIG_DISPATCHER, handler.MAIN_DISPATCHER]) def error_msg_handler(self, ev): if ev.msg.xid in self.send_msg_xids: self.rcv_msgs.append(ev.msg) if self.waiter: self.waiter.set() hub.sleep(0) class OpenFlowSw(object): def __init__(self, dp, logger): super(OpenFlowSw, self).__init__() self.dp = dp self.logger = logger self.tester_send_port = CONF['test-switch']['tester_send_port'] def send_msg(self, msg): if isinstance(self.dp, DummyDatapath): raise TestError(STATE_DISCONNECTED) msg.xid = None self.dp.set_xid(msg) self.dp.send_msg(msg) return msg.xid def add_flow(self, in_port=None, out_port=None): """ Add flow. """ ofp = self.dp.ofproto parser = self.dp.ofproto_parser match = parser.OFPMatch(in_port=in_port) actions = [parser.OFPActionOutput(out_port)] if ofp.OFP_VERSION == ofproto_v1_0.OFP_VERSION: mod = parser.OFPFlowMod( self.dp, match=match, cookie=0, command=ofp.OFPFC_ADD, actions=actions) else: inst = [parser.OFPInstructionActions( ofp.OFPIT_APPLY_ACTIONS, actions)] mod = parser.OFPFlowMod( self.dp, cookie=0, command=ofp.OFPFC_ADD, match=match, instructions=inst) return self.send_msg(mod) def del_flows(self, cookie=0): """ Delete all flow except default flow by using the cookie value. Note: In OpenFlow 1.0, DELETE and DELETE_STRICT commands can not be filtered by the cookie value and this value is ignored. """ ofp = self.dp.ofproto parser = self.dp.ofproto_parser cookie_mask = 0 if cookie: cookie_mask = 0xffffffffffffffff if ofp.OFP_VERSION == ofproto_v1_0.OFP_VERSION: match = parser.OFPMatch() mod = parser.OFPFlowMod(self.dp, match, cookie, ofp.OFPFC_DELETE) else: mod = parser.OFPFlowMod( self.dp, cookie=cookie, cookie_mask=cookie_mask, table_id=ofp.OFPTT_ALL, command=ofp.OFPFC_DELETE, out_port=ofp.OFPP_ANY, out_group=ofp.OFPG_ANY) return self.send_msg(mod) def del_meters(self): """ Delete all meter entries. """ ofp = self.dp.ofproto parser = self.dp.ofproto_parser if ofp.OFP_VERSION < ofproto_v1_3.OFP_VERSION: return None mod = parser.OFPMeterMod(self.dp, command=ofp.OFPMC_DELETE, flags=0, meter_id=ofp.OFPM_ALL) return self.send_msg(mod) def del_groups(self): """ Delete all group entries. """ ofp = self.dp.ofproto parser = self.dp.ofproto_parser if ofp.OFP_VERSION < ofproto_v1_2.OFP_VERSION: return None mod = parser.OFPGroupMod(self.dp, command=ofp.OFPGC_DELETE, type_=0, group_id=ofp.OFPG_ALL) return self.send_msg(mod) def send_barrier_request(self): """ send a BARRIER_REQUEST message.""" parser = self.dp.ofproto_parser req = parser.OFPBarrierRequest(self.dp) return self.send_msg(req) def send_port_stats(self): """ Get port stats.""" ofp = self.dp.ofproto parser = self.dp.ofproto_parser flags = 0 if ofp.OFP_VERSION == ofproto_v1_0.OFP_VERSION: port = ofp.OFPP_NONE else: port = ofp.OFPP_ANY req = parser.OFPPortStatsRequest(self.dp, flags, port) return self.send_msg(req) def send_flow_stats(self): """ Get all flow. """ ofp = self.dp.ofproto parser = self.dp.ofproto_parser if ofp.OFP_VERSION == ofproto_v1_0.OFP_VERSION: req = parser.OFPFlowStatsRequest( self.dp, 0, parser.OFPMatch(), 0xff, ofp.OFPP_NONE) else: req = parser.OFPFlowStatsRequest( self.dp, 0, ofp.OFPTT_ALL, ofp.OFPP_ANY, ofp.OFPG_ANY, 0, 0, parser.OFPMatch()) return self.send_msg(req) def send_meter_config_stats(self): """ Get all meter. """ ofp = self.dp.ofproto parser = self.dp.ofproto_parser if ofp.OFP_VERSION < ofproto_v1_3.OFP_VERSION: return None stats = parser.OFPMeterConfigStatsRequest(self.dp) return self.send_msg(stats) def send_group_desc_stats(self): """ Get all group. """ ofp = self.dp.ofproto parser = self.dp.ofproto_parser if ofp.OFP_VERSION < ofproto_v1_2.OFP_VERSION: return None stats = parser.OFPGroupDescStatsRequest(self.dp) return self.send_msg(stats) def send_table_stats(self): """ Get table stats. """ parser = self.dp.ofproto_parser req = parser.OFPTableStatsRequest(self.dp, 0) return self.send_msg(req) def send_packet_out(self, data): """ send a PacketOut message.""" ofp = self.dp.ofproto parser = self.dp.ofproto_parser actions = [parser.OFPActionOutput(self.tester_send_port)] out = parser.OFPPacketOut( datapath=self.dp, buffer_id=ofp.OFP_NO_BUFFER, data=data, in_port=ofp.OFPP_CONTROLLER, actions=actions) return self.send_msg(out) class TestPatterns(dict): """ List of Test class objects. """ def __init__(self, test_dir, logger): super(TestPatterns, self).__init__() self.logger = logger # Parse test pattern from test files. self._get_tests(test_dir) def _get_tests(self, path): if not os.path.exists(path): msg = INVALID_PATH % {'path': path} self.logger.warning(msg) return if os.path.isdir(path): # Directory for test_path in os.listdir(path): test_path = path + (test_path if path[-1:] == '/' else '/%s' % test_path) self._get_tests(test_path) elif os.path.isfile(path): # File (dummy, ext) = os.path.splitext(path) if ext == '.json': test = TestFile(path, self.logger) self[test.description] = test class TestFile(stringify.StringifyMixin): """Test File object include Test objects.""" def __init__(self, path, logger): super(TestFile, self).__init__() self.logger = logger self.description = None self.tests = [] self._get_tests(path) def _normalize_test_json(self, val): def __replace_port_name(k, v): for port_name in [ 'target_recv_port', 'target_send_port_1', 'target_send_port_2', 'tester_send_port', 'tester_recv_port_1', 'tester_recv_port_2']: if v[k] == port_name: v[k] = CONF['test-switch'][port_name] if isinstance(val, dict): for k, v in val.items(): if k == "OFPActionOutput": if 'port' in v: __replace_port_name("port", v) elif k == "OXMTlv": if v.get("field", "") == "in_port": __replace_port_name("value", v) self._normalize_test_json(v) elif isinstance(val, list): for v in val: self._normalize_test_json(v) def _get_tests(self, path): with open(path, 'r') as fhandle: buf = fhandle.read() try: json_list = json.loads(buf) for test_json in json_list: if isinstance(test_json, str): self.description = test_json else: self._normalize_test_json(test_json) self.tests.append(Test(test_json)) except (ValueError, TypeError) as e: result = (TEST_FILE_ERROR % {'file': path, 'detail': str(e)}) self.logger.warning(result) class Test(stringify.StringifyMixin): def __init__(self, test_json): super(Test, self).__init__() (self.description, self.prerequisite, self.tests) = self._parse_test(test_json) @classmethod def _parse_test(cls, buf): def __test_pkt_from_json(test): data = eval('/'.join(test)) data.serialize() return bytes(data.data) # create Datapath instance using user-specified versions target_dp = DummyDatapath(OfTester.target_ver) tester_dp = DummyDatapath(OfTester.tester_ver) # parse 'description' description = buf.get(KEY_DESC) # parse 'prerequisite' prerequisite = [] if KEY_PREREQ not in buf: raise ValueError('a test requires a "%s" block' % KEY_PREREQ) for flow in buf[KEY_PREREQ]: msg = ofproto_parser.ofp_msg_from_jsondict( target_dp, flow) msg.serialize() prerequisite.append(msg) # parse 'tests' tests = [] if KEY_TESTS not in buf: raise ValueError('a test requires a "%s" block.' % KEY_TESTS) for test in buf[KEY_TESTS]: if len(test) != 2: raise ValueError( '"%s" block requires "%s" field and one of "%s" or "%s"' ' or "%s" field.' % (KEY_TESTS, KEY_INGRESS, KEY_EGRESS, KEY_PKT_IN, KEY_TBL_MISS)) test_pkt = {} # parse 'ingress' if KEY_INGRESS not in test: raise ValueError('a test requires "%s" field.' % KEY_INGRESS) if isinstance(test[KEY_INGRESS], list): test_pkt[KEY_INGRESS] = __test_pkt_from_json(test[KEY_INGRESS]) elif isinstance(test[KEY_INGRESS], dict): test_pkt[KEY_PACKETS] = { 'packet_text': test[KEY_INGRESS][KEY_PACKETS][KEY_DATA], 'packet_binary': __test_pkt_from_json( test[KEY_INGRESS][KEY_PACKETS][KEY_DATA]), KEY_DURATION_TIME: test[KEY_INGRESS][KEY_PACKETS].get( KEY_DURATION_TIME, DEFAULT_DURATION_TIME), KEY_PKTPS: test[KEY_INGRESS][KEY_PACKETS].get( KEY_PKTPS, DEFAULT_PKTPS), 'randomize': True in [ line.find('randint') != -1 for line in test[KEY_INGRESS][KEY_PACKETS][KEY_DATA]]} else: raise ValueError('invalid format: "%s" field' % KEY_INGRESS) # parse 'egress' or 'PACKET_IN' or 'table-miss' if KEY_EGRESS in test: if isinstance(test[KEY_EGRESS], list): test_pkt[KEY_EGRESS] = __test_pkt_from_json( test[KEY_EGRESS]) elif isinstance(test[KEY_EGRESS], dict): throughputs = [] for throughput in test[KEY_EGRESS][KEY_THROUGHPUT]: one = {} mod = { "OFPFlowMod": { 'cookie': THROUGHPUT_COOKIE, 'priority': THROUGHPUT_PRIORITY, 'match': { 'OFPMatch': throughput[KEY_MATCH] } } } msg = ofproto_parser.ofp_msg_from_jsondict( tester_dp, mod) one[KEY_FLOW] = msg one[KEY_KBPS] = throughput.get(KEY_KBPS) one[KEY_PKTPS] = throughput.get(KEY_PKTPS) if not bool(one[KEY_KBPS]) != bool(one[KEY_PKTPS]): raise ValueError( '"%s" requires either "%s" or "%s".' % ( KEY_THROUGHPUT, KEY_KBPS, KEY_PKTPS)) throughputs.append(one) test_pkt[KEY_THROUGHPUT] = throughputs else: raise ValueError('invalid format: "%s" field' % KEY_EGRESS) elif KEY_PKT_IN in test: test_pkt[KEY_PKT_IN] = __test_pkt_from_json(test[KEY_PKT_IN]) elif KEY_TBL_MISS in test: test_pkt[KEY_TBL_MISS] = test[KEY_TBL_MISS] tests.append(test_pkt) return description, prerequisite, tests class DummyDatapath(ofproto_protocol.ProtocolDesc): def __init__(self, version=None): super(DummyDatapath, self).__init__(version) def set_xid(self, _): pass def send_msg(self, _): pass ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.2821157 os-ken-2.10.0/os_ken/tests/unit/0000775000175000017500000000000000000000000016410 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/__init__.py0000664000175000017500000000032600000000000020522 0ustar00zuulzuul00000000000000 # Note: The following import statement is defined in order to resolve # the conflict of the module names between 'os_ken.lib.ovs' and 'ovs'. # The latter is the official Python package of Open vSwitch. import ovs ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.2861161 os-ken-2.10.0/os_ken/tests/unit/cmd/0000775000175000017500000000000000000000000017153 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/cmd/__init__.py0000664000175000017500000000124600000000000021267 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013 YAMAMOTO Takashi # # 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. ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/cmd/dummy_app.py0000664000175000017500000000137400000000000021525 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013 YAMAMOTO Takashi # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. from os_ken.base import app_manager class DummyApp(app_manager.OSKenApp): pass ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/cmd/dummy_openflow_app.py0000664000175000017500000000153300000000000023433 0ustar00zuulzuul00000000000000# Copyright (C) 2013,2014 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013,2014 YAMAMOTO Takashi # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. from os_ken.base import app_manager from os_ken.ofproto import ofproto_v1_3 class DummyOpenFlowApp(app_manager.OSKenApp): OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/cmd/test_manager.py0000664000175000017500000000415100000000000022177 0ustar00zuulzuul00000000000000# Copyright (C) 2013,2014 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013,2014 YAMAMOTO Takashi # # 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. import unittest from unittest import mock from importlib import reload from os_ken.cmd.manager import main class Test_Manager(unittest.TestCase): """Test osken-manager command """ def __init__(self, methodName): super(Test_Manager, self).__init__(methodName) def setUp(self): pass def tearDown(self): pass @mock.patch('sys.argv', new=['osken-manager', '--version']) def test_version(self): self.assertRaises(SystemExit, main) @mock.patch('sys.argv', new=['osken-manager', '--help']) def test_help(self): self.assertRaises(SystemExit, main) @staticmethod def _reset_globals(): # hack to reset globals like SERVICE_BRICKS. # assumption: this is the only test which actually starts OSKenApp. import os_ken.base.app_manager import os_ken.ofproto.ofproto_protocol reload(os_ken.base.app_manager) reload(os_ken.ofproto.ofproto_protocol) @mock.patch('sys.argv', new=['osken-manager', '--verbose', 'os_ken.tests.unit.cmd.dummy_app']) def test_no_services(self): self._reset_globals() main() self._reset_globals() @mock.patch('sys.argv', new=['osken-manager', '--verbose', 'os_ken.tests.unit.cmd.dummy_openflow_app']) def test_openflow_app(self): self._reset_globals() main() self._reset_globals() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.2861161 os-ken-2.10.0/os_ken/tests/unit/controller/0000775000175000017500000000000000000000000020573 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/controller/__init__.py0000664000175000017500000000000000000000000022672 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/controller/cert.crt0000664000175000017500000000233100000000000022241 0ustar00zuulzuul00000000000000-----BEGIN CERTIFICATE----- MIIDaDCCAlCgAwIBAgIJAKL09YuU92JPMA0GCSqGSIb3DQEBCwUAMEgxCzAJBgNV BAYTAkpQMRMwEQYDVQQIDApTb21lLVN0YXRlMSQwIgYDVQQKDBtSeXUgU0ROIEZy YW1ld29yayBDb21tdW5pdHkwIBcNMTkwMzI1MDE1NzQzWhgPMjI5MzAxMDYwMTU3 NDNaMEgxCzAJBgNVBAYTAkpQMRMwEQYDVQQIDApTb21lLVN0YXRlMSQwIgYDVQQK DBtSeXUgU0ROIEZyYW1ld29yayBDb21tdW5pdHkwggEiMA0GCSqGSIb3DQEBAQUA A4IBDwAwggEKAoIBAQDLT29+6JwD75wH7gPVxU52hrysBfxE6WjyT/nT+aSIQmZu SU6/5hECOnV4YdyB7rxFu2WO2SD5PgeoHPBpTqtxrdTWoVOWVljnNcqEwSCS7bl9 nbgX8uxCacg9qbFNJJRBAS0XQ2bSsD0GoOnhj3Olrz1u0wRIUqrR3A5giMbYwQPr S4cmkxfgp2uV+WCHk40WxZnGgWzIRhO11GK9CAGncncPYhj+23w+GFaHIf00TdV2 JEvwLFuLf1EaewZ7rz8zf1sLHAxqx20A6VdledEpNAzt1L8goPhk1mHvRgUC7E2v FnSt1ePCJsVrvccudMdPBXSMfgJC2gmfdQefdSXRAgMBAAGjUzBRMB0GA1UdDgQW BBRjlXSQ2rVjwOr1io6iJyidmjCNfzAfBgNVHSMEGDAWgBRjlXSQ2rVjwOr1io6i JyidmjCNfzAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCC1Uvo 4PdC5YQSXkAhrxgVhexp87VVkoWwpno75hvfoCjtSkb7+cskvQbPM14zbjIUrsli qmTkjXyTUe8q5U06OitMAyM6qUvS0nFDi5aPQYV6N0XmJ+rV18prfQORyHvEmEyv nqHVPoQkmGPpJ8aOVrTlECyxG7wLI2UxBEB3Atk51QHzbGGLKW7g5tHY6J5cMe/9 ydeClJk2/AXkoqWkbtJrbw46alH97CajuLn/4D9B/Rm+M1Kg48gze5zJ7+WrB0Jl pAhRqMM3upaOlXdeYDdNDgE0j/ulZGY2UssFIoHylcrb4QKQXjwqRXYhuuucJQJ3 vsY4y1D/qps9llRL -----END CERTIFICATE----- ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/controller/cert.key0000664000175000017500000000324400000000000022245 0ustar00zuulzuul00000000000000-----BEGIN PRIVATE KEY----- MIIEuwIBADANBgkqhkiG9w0BAQEFAASCBKUwggShAgEAAoIBAQDLT29+6JwD75wH 7gPVxU52hrysBfxE6WjyT/nT+aSIQmZuSU6/5hECOnV4YdyB7rxFu2WO2SD5Pgeo HPBpTqtxrdTWoVOWVljnNcqEwSCS7bl9nbgX8uxCacg9qbFNJJRBAS0XQ2bSsD0G oOnhj3Olrz1u0wRIUqrR3A5giMbYwQPrS4cmkxfgp2uV+WCHk40WxZnGgWzIRhO1 1GK9CAGncncPYhj+23w+GFaHIf00TdV2JEvwLFuLf1EaewZ7rz8zf1sLHAxqx20A 6VdledEpNAzt1L8goPhk1mHvRgUC7E2vFnSt1ePCJsVrvccudMdPBXSMfgJC2gmf dQefdSXRAgMBAAECggEAcvPsB6Z/qB4Pa9Bg7LqNnaia/uy3cUND6lXb3MW3CK/6 eHsMgqYTkd3502IJqpGQdCD70CPmZ+Zxr9UE/ZXUjAcMY3p952/U/o3EfwEvaMPu 8B6AG1Jn0Tk8VdkffY2kIYkHtLKQbanmJ1xOQRG6AsEti/7V2gqbuOKiYmSTgbPG Upw9JNdtR6bZrGrrEXJbPCrSCej47MDyE+nt4zMIsqmY5IlbTMHcTKVDGeKbT9qT 7/Uyg+Tb62eber9iQhE0OteLt2GwrJR5yZ5QKNKM4SPqwYlOvQ9z289eZMVU3uwI 1NI1YRM5EMsdWrzFye7H/T/jsCaWrO0zmI/I4BMfEQKBgQDtUgPyY4PgVXVZ/hha l5pi66GQ79+6LJP3SHb3I6p0iULq3oV+onG0Ezvx2vc21sbuLEazNlJoXzEzSIVM /RjNJ9FsD/ENEuJedkspwtZZ4O4ZH6wKyHg/LCUly59ER37Ql/XwIX7adKCn7Z4d 9xN3aQmPtLna/aIZ8HyptRpT9QKBgQDbUB67YXiIFY+k5cwtK0m8T3rY4WNpEwzr Y/1l+0EvXqCousU9MnLveyY8EcLDh5SnM0CvH4mFS8xL/r/kcUO9cHwuM+KZ77KN Ukp9CRT9raxDZY/F0FVuET4LrJNnekCMsOnMxO51il/AHcul7886sEirkB1dsXND nkh9h8g87QJ/cRikyN6j+kS/qCNvd7zH1lx0op2uAQs9eJsQFrbohKDlQwjIlZDU nvyLlLbFGV1BcD+pcb5xh0vWJppo7EexihNvug/e0FwvhNTa/QvdGvgWf+KYGotu wqxHB7wCKofn54CDs+xCh9kMtvqGX8FfhYiJBfMan0I//hydTEMCSQKBgEiv6E+g gYtQ4hf8FczOsRSZnxSstv8HUlvd+wlG2hbyHPtvU5nx04gt38E+/bdCg3FbGlAw eqrUMXTqjP0Q0SvDUVUa2zq76AjQwmFoli1x10tLKPieEQJ28oJ6Ayzjpus6Y3L7 vjD02MFa3rkznxJLhPpfvGvmOVaq6km4rBQNAoGBALQGfaRiAtp6lSubi4Etdwtg Tps2o1SBXfzENpq6s99k+UdCBLh90uzuA897GClsUYeuAYUyxQP3otIZUuSjq/Ht JHYwT9QxOkSYrNCfQW/nF0CJjZ6TcvcFp8SdyUUbwCR2rkDK7LlMzxkfU3cCrwMP q51oIVlKjIxg86JJXrRQ -----END PRIVATE KEY----- ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/controller/test_controller.py0000664000175000017500000001374400000000000024400 0ustar00zuulzuul00000000000000# Copyright (C) 2015 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2015 Stratosphere Inc. # # 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. # vim: tabstop=4 shiftwidth=4 softtabstop=4 import json import os import ssl import sys import warnings import logging import random import testtools import unittest from unittest import mock from os_ken.base import app_manager # To suppress cyclic import from os_ken.controller import controller from os_ken.controller import handler from os_ken.lib import hub from os_ken.ofproto import ofproto_v1_3_parser from os_ken.ofproto import ofproto_v1_2_parser from os_ken.ofproto import ofproto_v1_0_parser hub.patch() LOG = logging.getLogger('test_controller') class TestUtils(testtools.TestCase): """ Test cases for utilities defined in controller module. """ def test_split_addr_with_ipv4(self): addr, port = controller._split_addr('127.0.0.1:6653') self.assertEqual('127.0.0.1', addr) self.assertEqual(6653, port) def test_split_addr_with_ipv6(self): addr, port = controller._split_addr('[::1]:6653') self.assertEqual('::1', addr) self.assertEqual(6653, port) def test_split_addr_with_invalid_addr(self): self.assertRaises(ValueError, controller._split_addr, '127.0.0.1') def test_split_addr_with_invalid_ipv4_addr(self): self.assertRaises(ValueError, controller._split_addr, 'xxx.xxx.xxx.xxx:6653') def test_split_addr_with_invalid_ipv6_addr(self): self.assertRaises(ValueError, controller._split_addr, '[::xxxx]:6653') def test_split_addr_with_non_bracketed_ipv6_addr(self): self.assertRaises(ValueError, controller._split_addr, '::1:6653') class Test_Datapath(unittest.TestCase): """ Test cases for controller.Datapath """ def _test_ports_accessibility(self, ofproto_parser, msgs_len): with mock.patch('os_ken.controller.controller.Datapath.set_state'): # Ignore warnings with warnings.catch_warnings(record=True) as msgs: warnings.simplefilter('always') # Test target sock_mock = mock.Mock() addr_mock = mock.Mock() dp = controller.Datapath(sock_mock, addr_mock) dp.ofproto_parser = ofproto_parser # Create dp.ports = {} # Update port_mock = mock.Mock() dp.ports[0] = port_mock # Read & Delete del dp.ports[0] self.assertEqual(len(msgs), msgs_len) for msg in msgs: self.assertTrue(issubclass(msg.category, UserWarning)) def test_ports_accessibility_v13(self): self._test_ports_accessibility(ofproto_v1_3_parser, 0) def test_ports_accessibility_v12(self): self._test_ports_accessibility(ofproto_v1_2_parser, 0) def test_ports_accessibility_v10(self): self._test_ports_accessibility(ofproto_v1_0_parser, 0) @mock.patch("os_ken.base.app_manager", spec=app_manager) def test_recv_loop(self, app_manager_mock): # Prepare test data test_messages = [ "4-6-ofp_features_reply.packet", "4-14-ofp_echo_reply.packet", "4-14-ofp_echo_reply.packet", "4-4-ofp_packet_in.packet", "4-14-ofp_echo_reply.packet", "4-14-ofp_echo_reply.packet", ] this_dir = os.path.dirname(sys.modules[__name__].__file__) packet_data_dir = os.path.join(this_dir, '../../packet_data/of13') json_dir = os.path.join(this_dir, '../ofproto/json/of13') packet_buf = bytearray() expected_json = list() for msg in test_messages: # Construct the received packet buffer as one packet data in order # to test the case of the OpenFlow messages composed in one packet. packet_data_file = os.path.join(packet_data_dir, msg) packet_buf += open(packet_data_file, 'rb').read() json_data_file = os.path.join(json_dir, msg + '.json') expected_json.append(json.load(open(json_data_file))) # Prepare mock for socket class SocketMock(mock.MagicMock): buf = bytearray() random = None def recv(self, bufsize): size = self.random.randint(1, bufsize) out = self.buf[:size] self.buf = self.buf[size:] return out # Prepare mock ofp_brick_mock = mock.MagicMock(spec=app_manager.OSKenApp) app_manager_mock.lookup_service_brick.return_value = ofp_brick_mock sock_mock = SocketMock() sock_mock.buf = packet_buf sock_mock.random = random.Random('OSKen SDN Framework') addr_mock = mock.MagicMock() # Prepare test target dp = controller.Datapath(sock_mock, addr_mock) dp.set_state(handler.MAIN_DISPATCHER) ofp_brick_mock.reset_mock() # Test dp._recv_loop() # Assert calls output_json = list() for call in ofp_brick_mock.send_event_to_observers.call_args_list: args, kwargs = call ev, state = args if not hasattr(ev, 'msg'): continue output_json.append(ev.msg.to_jsondict()) self.assertEqual(state, handler.MAIN_DISPATCHER) self.assertEqual(kwargs, {}) self.assertEqual(expected_json, output_json) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.2861161 os-ken-2.10.0/os_ken/tests/unit/lib/0000775000175000017500000000000000000000000017156 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/lib/__init__.py0000664000175000017500000000000000000000000021255 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/lib/test_sockaddr.py0000664000175000017500000000325200000000000022363 0ustar00zuulzuul00000000000000# Copyright 2020 Red Hat, Inc. # # 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. import unittest import platform import sys from os_ken.lib import sockaddr system = platform.system() class Test_sockaddr(unittest.TestCase): def setUp(self): pass def tearDown(self): pass def test_sockaddr_linux_sa_in4(self): if system != 'Linux' or sys.byteorder != 'little': return addr = '127.0.0.1' expected_result = (b'\x02\x00\x00\x00' b'\x7f\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00') self.assertEqual(expected_result, sockaddr.sa_in4(addr)) def test_sockaddr_linux_sa_in6(self): if system != 'Linux' or sys.byteorder != 'little': return addr = 'dead:beef::1' expected_result = (b'\n\x00\x00\x00\x00\x00\x00\x00\xde\xad\xbe\xef' b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00') self.assertEqual(expected_result, sockaddr.sa_in6(addr)) def test_sockaddr_sa_to_ss(self): addr = b'\x01' expected_result = b'\x01' + 127 * b'\x00' self.assertEqual(expected_result, sockaddr.sa_to_ss(addr)) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.2901163 os-ken-2.10.0/os_ken/tests/unit/ofproto/0000775000175000017500000000000000000000000020100 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/__init__.py0000664000175000017500000000000000000000000022177 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.0381014 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/0000775000175000017500000000000000000000000021051 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.2941165 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of10/0000775000175000017500000000000000000000000021616 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of10/1-1-ofp_packet_out.packet.json0000664000175000017500000000061100000000000027253 0ustar00zuulzuul00000000000000{ "OFPPacketOut": { "actions": [ { "OFPActionOutput": { "max_len": 65535, "port": 65532 } } ], "buffer_id": 4294967295, "data": "8guk0D9w8gukffjqCABFAABU+BoAAP8Br4sKAAABCgAAAggAAgj3YAAAMdYCAAAAAACrjS0xAAAAABAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vAAAAAAAAAAA=", "in_port": 65533 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of10/1-2-ofp_flow_mod.packet.json0000664000175000017500000000146200000000000026731 0ustar00zuulzuul00000000000000{ "OFPFlowMod": { "actions": [ { "OFPActionOutput": { "max_len": 65535, "port": 6 } } ], "buffer_id": 65535, "command": 0, "cookie": 0, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "match": { "OFPMatch": { "dl_dst": "f2:0b:a4:7d:f8:ea", "dl_src": "00:00:00:00:00:00", "dl_type": 0, "dl_vlan": 0, "dl_vlan_pcp": 0, "in_port": 0, "nw_dst": "0.0.0.0", "nw_proto": 0, "nw_src": "0.0.0.0", "nw_tos": 0, "tp_dst": 0, "tp_src": 0, "wildcards": 4194295 } }, "out_port": 65532, "priority": 123 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of10/1-4-ofp_packet_in.packet.json0000664000175000017500000000027300000000000027061 0ustar00zuulzuul00000000000000{ "OFPPacketIn": { "buffer_id": 2, "data": "////////8gukffjqCAYAAQgABgQAAfILpH346goAAAEAAAAAAAAKAAAD", "in_port": 99, "reason": 1, "total_len": 42 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of10/1-5-features_request.packet.json0000664000175000017500000000004000000000000027637 0ustar00zuulzuul00000000000000{ "OFPFeaturesRequest": {} } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of10/1-6-ofp_switch_features.packet.json0000664000175000017500000000160500000000000030325 0ustar00zuulzuul00000000000000{ "OFPSwitchFeatures": { "actions": 2115, "capabilities": 169, "datapath_id": 1095522080376, "n_buffers": 0, "n_tables": 255, "ports": { "6": { "OFPPhyPort": { "advertised": 640, "config": 0, "curr": 648, "hw_addr": "f2:0b:a4:7d:f8:ea", "name": "Port6", "peer": 648, "port_no": 6, "state": 2, "supported": 648 } }, "7": { "OFPPhyPort": { "advertised": 640, "config": 0, "curr": 648, "hw_addr": "f2:0b:a4:d0:3f:70", "name": "Port7", "peer": 648, "port_no": 7, "state": 16, "supported": 648 } } } } } ././@PaxHeader0000000000000000000000000000021400000000000011452 xustar0000000000000000118 path=os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of10/libofproto-OFP10-ofp_packet_out_packet_library.packet.json 22 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of10/libofproto-OFP10-ofp_packet_out_packet_library.pac0000664000175000017500000000311400000000000033317 0ustar00zuulzuul00000000000000{ "OFPPacketOut": { "actions": [ { "OFPActionOutput": { "max_len": 65535, "port": 65532 } } ], "buffer_id": 4294967295, "data": { "Packet": { "protocols": [ { "ethernet": { "dst": "f2:0b:a4:d0:3f:70", "ethertype": 2048, "src": "f2:0b:a4:7d:f8:ea" } }, { "ipv4": { "csum": 44939, "dst": "10.0.0.2", "flags": 0, "header_length": 5, "identification": 63514, "offset": 0, "option": null, "proto": 1, "src": "10.0.0.1", "tos": 0, "total_length": 84, "ttl": 255, "version": 4 } }, { "icmp": { "code": 0, "csum": 520, "data": { "echo": { "data": "MdYCAAAAAACrjS0xAAAAABAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vAAAAAAAAAAA=", "id": 63328, "seq": 0 } }, "type": 8 } } ] } }, "in_port": 65533 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of10/ovs-ofctl-of10-action_dec_mpls_ttl.packet.json0000664000175000017500000000165400000000000032450 0ustar00zuulzuul00000000000000{ "OFPFlowMod": { "actions": [ { "NXActionDecMplsTtl": { "subtype": 26, "vendor": 8992 } } ], "buffer_id": 4294967295, "command": 0, "cookie": 0, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "match": { "OFPMatch": { "dl_dst": "00:00:00:00:00:00", "dl_src": "00:00:00:00:00:00", "dl_type": 34887, "dl_vlan": 0, "dl_vlan_pcp": 0, "in_port": 0, "nw_dst": "0.0.0.0", "nw_proto": 0, "nw_src": "0.0.0.0", "nw_tos": 0, "tp_dst": 0, "tp_src": 0, "wildcards": 3678447 } }, "out_port": 65535, "priority": 100 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of10/ovs-ofctl-of10-action_dec_nw_ttl.packet.json0000664000175000017500000000165000000000000032115 0ustar00zuulzuul00000000000000{ "OFPFlowMod": { "actions": [ { "NXActionDecTtl": { "subtype": 18, "vendor": 8992 } } ], "buffer_id": 4294967295, "command": 0, "cookie": 0, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "match": { "OFPMatch": { "dl_dst": "00:00:00:00:00:00", "dl_src": "00:00:00:00:00:00", "dl_type": 34887, "dl_vlan": 0, "dl_vlan_pcp": 0, "in_port": 0, "nw_dst": "0.0.0.0", "nw_proto": 0, "nw_src": "0.0.0.0", "nw_tos": 0, "tp_dst": 0, "tp_src": 0, "wildcards": 3678447 } }, "out_port": 65535, "priority": 100 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of10/ovs-ofctl-of10-action_pop_mpls.packet.json0000664000175000017500000000172000000000000031622 0ustar00zuulzuul00000000000000{ "OFPFlowMod": { "actions": [ { "NXActionPopMpls": { "ethertype": 2048, "subtype": 24, "vendor": 8992 } } ], "buffer_id": 4294967295, "command": 0, "cookie": 0, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "match": { "OFPMatch": { "dl_dst": "00:00:00:00:00:00", "dl_src": "00:00:00:00:00:00", "dl_type": 34887, "dl_vlan": 0, "dl_vlan_pcp": 0, "in_port": 0, "nw_dst": "0.0.0.0", "nw_proto": 0, "nw_src": "0.0.0.0", "nw_tos": 0, "tp_dst": 0, "tp_src": 0, "wildcards": 3678447 } }, "out_port": 65535, "priority": 100 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of10/ovs-ofctl-of10-action_push_mpls.packet.json0000664000175000017500000000172100000000000032004 0ustar00zuulzuul00000000000000{ "OFPFlowMod": { "actions": [ { "NXActionPushMpls": { "ethertype": 34887, "subtype": 23, "vendor": 8992 } } ], "buffer_id": 4294967295, "command": 0, "cookie": 0, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "match": { "OFPMatch": { "dl_dst": "00:00:00:00:00:00", "dl_src": "00:00:00:00:00:00", "dl_type": 2048, "dl_vlan": 0, "dl_vlan_pcp": 0, "in_port": 0, "nw_dst": "0.0.0.0", "nw_proto": 0, "nw_src": "0.0.0.0", "nw_tos": 0, "tp_dst": 0, "tp_src": 0, "wildcards": 3678447 } }, "out_port": 65535, "priority": 100 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of10/ovs-ofctl-of10-action_set_mpls_label.packet.json0000664000175000017500000000171700000000000032764 0ustar00zuulzuul00000000000000{ "OFPFlowMod": { "actions": [ { "NXActionSetMplsLabel": { "label": 10, "subtype": 30, "vendor": 8992 } } ], "buffer_id": 4294967295, "command": 0, "cookie": 0, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "match": { "OFPMatch": { "dl_dst": "00:00:00:00:00:00", "dl_src": "00:00:00:00:00:00", "dl_type": 34887, "dl_vlan": 0, "dl_vlan_pcp": 0, "in_port": 0, "nw_dst": "0.0.0.0", "nw_proto": 0, "nw_src": "0.0.0.0", "nw_tos": 0, "tp_dst": 0, "tp_src": 0, "wildcards": 3678447 } }, "out_port": 65535, "priority": 100 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of10/ovs-ofctl-of10-action_set_mpls_tc.packet.json0000664000175000017500000000171100000000000032305 0ustar00zuulzuul00000000000000{ "OFPFlowMod": { "actions": [ { "NXActionSetMplsTc": { "subtype": 31, "tc": 10, "vendor": 8992 } } ], "buffer_id": 4294967295, "command": 0, "cookie": 0, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "match": { "OFPMatch": { "dl_dst": "00:00:00:00:00:00", "dl_src": "00:00:00:00:00:00", "dl_type": 34887, "dl_vlan": 0, "dl_vlan_pcp": 0, "in_port": 0, "nw_dst": "0.0.0.0", "nw_proto": 0, "nw_src": "0.0.0.0", "nw_tos": 0, "tp_dst": 0, "tp_src": 0, "wildcards": 3678447 } }, "out_port": 65535, "priority": 100 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of10/ovs-ofctl-of10-action_set_mpls_ttl.packet.json0000664000175000017500000000171400000000000032505 0ustar00zuulzuul00000000000000{ "OFPFlowMod": { "actions": [ { "NXActionSetMplsTtl": { "subtype": 25, "ttl": 127, "vendor": 8992 } } ], "buffer_id": 4294967295, "command": 0, "cookie": 0, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "match": { "OFPMatch": { "dl_dst": "00:00:00:00:00:00", "dl_src": "00:00:00:00:00:00", "dl_type": 34887, "dl_vlan": 0, "dl_vlan_pcp": 0, "in_port": 0, "nw_dst": "0.0.0.0", "nw_proto": 0, "nw_src": "0.0.0.0", "nw_tos": 0, "tp_dst": 0, "tp_src": 0, "wildcards": 3678447 } }, "out_port": 65535, "priority": 100 } } ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.3021169 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/0000775000175000017500000000000000000000000021620 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/3-0-ofp_desc_stats_reply.packet.json0000664000175000017500000000043100000000000030467 0ustar00zuulzuul00000000000000{ "OFPStatsReply": { "body": { "OFPDescStats": { "dp_desc": "dp", "hw_desc": "hw", "mfr_desc": "mfr", "serial_num": "serial", "sw_desc": "sw" } }, "flags": 0, "type": 0 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/3-1-ofp_packet_out.packet.json0000664000175000017500000000074000000000000027262 0ustar00zuulzuul00000000000000{ "OFPPacketOut": { "actions": [ { "OFPActionOutput": { "len": 16, "max_len": 65535, "port": 4294967292, "type": 0 } } ], "actions_len": 16, "buffer_id": 4294967295, "data": "8guk0D9w8gukffjqCABFAABU+BoAAP8Br4sKAAABCgAAAggAAgj3YAAAMdYCAAAAAACrjS0xAAAAABAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vAAAAAAAAAAA=", "in_port": 4294967293 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/3-10-ofp_hello.packet.json0000664000175000017500000000002600000000000026304 0ustar00zuulzuul00000000000000{ "OFPHello": {} } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/3-11-ofp_flow_stats_request.packet.json0000664000175000017500000000047400000000000031146 0ustar00zuulzuul00000000000000{ "OFPFlowStatsRequest": { "cookie": 0, "cookie_mask": 0, "flags": 0, "match": { "OFPMatch": { "length": 4, "oxm_fields": [], "type": 1 } }, "out_group": 4294967295, "out_port": 4294967295, "table_id": 0 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/3-12-ofp_flow_stats_reply.packet.json0000664000175000017500000001142200000000000030605 0ustar00zuulzuul00000000000000{ "OFPStatsReply": { "body": [ { "OFPFlowStats": { "byte_count": 0, "cookie": 0, "duration_nsec": 115277000, "duration_sec": 358, "hard_timeout": 0, "idle_timeout": 0, "instructions": [], "length": 56, "match": { "OFPMatch": { "length": 4, "oxm_fields": [], "type": 1 } }, "packet_count": 0, "priority": 65535, "table_id": 0 } }, { "OFPFlowStats": { "byte_count": 0, "cookie": 0, "duration_nsec": 115055000, "duration_sec": 358, "hard_timeout": 0, "idle_timeout": 0, "instructions": [ { "OFPInstructionActions": { "actions": [ { "OFPActionOutput": { "len": 16, "max_len": 0, "port": 4294967290, "type": 0 } } ], "len": 24, "type": 4 } } ], "length": 88, "match": { "OFPMatch": { "length": 10, "oxm_fields": [ { "OXMTlv": { "field": "eth_type", "mask": null, "value": 2054 } } ], "type": 1 } }, "packet_count": 0, "priority": 65534, "table_id": 0 } }, { "OFPFlowStats": { "byte_count": 238, "cookie": 0, "duration_nsec": 511582000, "duration_sec": 316220, "hard_timeout": 0, "idle_timeout": 0, "instructions": [ { "OFPInstructionGotoTable": { "len": 8, "table_id": 1, "type": 1 } } ], "length": 80, "match": { "OFPMatch": { "length": 22, "oxm_fields": [ { "OXMTlv": { "field": "in_port", "mask": null, "value": 6 } }, { "OXMTlv": { "field": "eth_src", "mask": null, "value": "f2:0b:a4:7d:f8:ea" } } ], "type": 1 } }, "packet_count": 3, "priority": 123, "table_id": 0 } }, { "OFPFlowStats": { "byte_count": 98, "cookie": 0, "duration_nsec": 980901000, "duration_sec": 313499, "hard_timeout": 0, "idle_timeout": 0, "instructions": [ { "OFPInstructionActions": { "actions": [ { "OFPActionOutput": { "len": 16, "max_len": 65535, "port": 4294967293, "type": 0 } } ], "len": 24, "type": 3 } } ], "length": 80, "match": { "OFPMatch": { "length": 4, "oxm_fields": [], "type": 1 } }, "packet_count": 1, "priority": 0, "table_id": 0 } } ], "flags": 0, "type": 1 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/3-13-ofp_echo_request.packet.json0000664000175000017500000000007100000000000027672 0ustar00zuulzuul00000000000000{ "OFPEchoRequest": { "data": "aG9nZQ==" } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/3-14-ofp_echo_reply.packet.json0000664000175000017500000000006700000000000027343 0ustar00zuulzuul00000000000000{ "OFPEchoReply": { "data": "aG9nZQ==" } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/3-15-ofp_error_msg.packet.json0000664000175000017500000000013500000000000027206 0ustar00zuulzuul00000000000000{ "OFPErrorMsg": { "code": 11, "data": "ZnVnYWZ1Z2E=", "type": 2 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/3-16-ofp_experimenter.packet.json0000664000175000017500000000016700000000000027724 0ustar00zuulzuul00000000000000{ "OFPExperimenter": { "data": "bmF6bw==", "exp_type": 123456789, "experimenter": 98765432 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/3-17-ofp_barrier_request.packet.json0000664000175000017500000000003700000000000030410 0ustar00zuulzuul00000000000000{ "OFPBarrierRequest": {} } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/3-18-ofp_barrier_reply.packet.json0000664000175000017500000000003500000000000030052 0ustar00zuulzuul00000000000000{ "OFPBarrierReply": {} } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/3-19-ofp_role_request.packet.json0000664000175000017500000000013500000000000027724 0ustar00zuulzuul00000000000000{ "OFPRoleRequest": { "generation_id": 17294086455919964160, "role": 2 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/3-2-ofp_flow_mod.packet.json0000664000175000017500000000421100000000000026730 0ustar00zuulzuul00000000000000{ "OFPFlowMod": { "buffer_id": 65535, "command": 0, "cookie": 0, "cookie_mask": 0, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "instructions": [ { "OFPInstructionActions": { "actions": [ { "OFPActionSetField": { "field": { "OXMTlv": { "field": "vlan_vid", "mask": null, "value": 258 } }, "len": 16, "type": 25 } }, { "OFPActionOutput": { "len": 16, "max_len": 65535, "port": 6, "type": 0 } } ], "len": 40, "type": 3 } }, { "OFPInstructionActions": { "actions": [ { "OFPActionSetField": { "field": { "OXMTlv": { "field": "eth_src", "mask": null, "value": "01:02:03:04:05:06" } }, "len": 16, "type": 25 } } ], "len": 24, "type": 4 } } ], "match": { "OFPMatch": { "length": 14, "oxm_fields": [ { "OXMTlv": { "field": "eth_dst", "mask": null, "value": "f2:0b:a4:7d:f8:ea" } } ], "type": 1 } }, "out_group": 4294967295, "out_port": 4294967295, "priority": 123, "table_id": 1 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/3-20-ofp_role_reply.packet.json0000664000175000017500000000013300000000000027355 0ustar00zuulzuul00000000000000{ "OFPRoleReply": { "generation_id": 17294086455919964160, "role": 3 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/3-21-ofp_group_mod.packet.json0000664000175000017500000000112000000000000027172 0ustar00zuulzuul00000000000000{ "OFPGroupMod": { "buckets": [ { "OFPBucket": { "actions": [ { "OFPActionOutput": { "len": 16, "max_len": 65535, "port": 2, "type": 0 } } ], "len": 32, "watch_group": 1, "watch_port": 1, "weight": 1 } } ], "command": 0, "group_id": 1, "type": 0 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/3-22-ofp_port_mod.packet.json0000664000175000017500000000022200000000000027025 0ustar00zuulzuul00000000000000{ "OFPPortMod": { "advertise": 4096, "config": 0, "hw_addr": "00-11-00-00-11-11", "mask": 0, "port_no": 1 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/3-23-ofp_table_mod.packet.json0000664000175000017500000000010600000000000027132 0ustar00zuulzuul00000000000000{ "OFPTableMod": { "config": 0, "table_id": 255 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/3-24-ofp_desc_stats_request.packet.json0000664000175000017500000000006600000000000031116 0ustar00zuulzuul00000000000000{ "OFPDescStatsRequest": { "flags": 0 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/3-25-ofp_aggregate_stats_request.packet.json0000664000175000017500000000050300000000000032123 0ustar00zuulzuul00000000000000{ "OFPAggregateStatsRequest": { "cookie": 0, "cookie_mask": 0, "flags": 0, "match": { "OFPMatch": { "length": 4, "oxm_fields": [], "type": 1 } }, "out_group": 4294967295, "out_port": 4294967295, "table_id": 255 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/3-26-ofp_aggregate_stats_reply.packet.json0000664000175000017500000000034400000000000031572 0ustar00zuulzuul00000000000000{ "OFPStatsReply": { "body": { "OFPAggregateStatsReply": { "byte_count": 574, "flow_count": 6, "packet_count": 7 } }, "flags": 0, "type": 2 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/3-27-ofp_table_stats_request.packet.json0000664000175000017500000000006700000000000031273 0ustar00zuulzuul00000000000000{ "OFPTableStatsRequest": { "flags": 0 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/3-28-ofp_table_stats_reply.packet.json0000664000175000017500000053111300000000000030740 0ustar00zuulzuul00000000000000{ "OFPStatsReply": { "body": [ { "OFPTableStats": { "active_count": 4, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 4, "match": 68719476733, "matched_count": 4, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "\u79c1\u306e\u30c6\u30fc\u30d6\u30eb", "table_id": 0, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 2, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 3, "match": 68719476733, "matched_count": 3, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x01", "table_id": 1, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x02", "table_id": 2, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x03", "table_id": 3, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x04", "table_id": 4, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x05", "table_id": 5, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x06", "table_id": 6, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x07", "table_id": 7, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x08", "table_id": 8, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x09", "table_id": 9, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x0a", "table_id": 10, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x0b", "table_id": 11, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x0c", "table_id": 12, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x0d", "table_id": 13, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x0e", "table_id": 14, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x0f", "table_id": 15, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x10", "table_id": 16, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x11", "table_id": 17, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x12", "table_id": 18, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x13", "table_id": 19, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x14", "table_id": 20, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x15", "table_id": 21, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x16", "table_id": 22, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x17", "table_id": 23, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x18", "table_id": 24, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x19", "table_id": 25, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x1a", "table_id": 26, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x1b", "table_id": 27, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x1c", "table_id": 28, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x1d", "table_id": 29, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x1e", "table_id": 30, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x1f", "table_id": 31, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x20", "table_id": 32, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x21", "table_id": 33, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x22", "table_id": 34, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x23", "table_id": 35, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x24", "table_id": 36, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x25", "table_id": 37, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x26", "table_id": 38, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x27", "table_id": 39, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x28", "table_id": 40, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x29", "table_id": 41, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x2a", "table_id": 42, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x2b", "table_id": 43, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x2c", "table_id": 44, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x2d", "table_id": 45, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x2e", "table_id": 46, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x2f", "table_id": 47, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x30", "table_id": 48, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x31", "table_id": 49, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x32", "table_id": 50, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x33", "table_id": 51, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x34", "table_id": 52, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x35", "table_id": 53, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x36", "table_id": 54, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x37", "table_id": 55, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x38", "table_id": 56, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x39", "table_id": 57, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x3a", "table_id": 58, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x3b", "table_id": 59, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x3c", "table_id": 60, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x3d", "table_id": 61, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x3e", "table_id": 62, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x3f", "table_id": 63, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x40", "table_id": 64, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x41", "table_id": 65, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x42", "table_id": 66, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x43", "table_id": 67, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x44", "table_id": 68, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x45", "table_id": 69, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x46", "table_id": 70, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x47", "table_id": 71, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x48", "table_id": 72, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x49", "table_id": 73, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x4a", "table_id": 74, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x4b", "table_id": 75, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x4c", "table_id": 76, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x4d", "table_id": 77, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x4e", "table_id": 78, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x4f", "table_id": 79, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x50", "table_id": 80, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x51", "table_id": 81, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x52", "table_id": 82, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x53", "table_id": 83, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x54", "table_id": 84, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x55", "table_id": 85, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x56", "table_id": 86, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x57", "table_id": 87, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x58", "table_id": 88, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x59", "table_id": 89, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x5a", "table_id": 90, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x5b", "table_id": 91, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x5c", "table_id": 92, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x5d", "table_id": 93, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x5e", "table_id": 94, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x5f", "table_id": 95, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x60", "table_id": 96, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x61", "table_id": 97, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x62", "table_id": 98, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x63", "table_id": 99, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x64", "table_id": 100, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x65", "table_id": 101, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x66", "table_id": 102, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x67", "table_id": 103, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x68", "table_id": 104, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x69", "table_id": 105, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x6a", "table_id": 106, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x6b", "table_id": 107, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x6c", "table_id": 108, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x6d", "table_id": 109, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x6e", "table_id": 110, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x6f", "table_id": 111, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x70", "table_id": 112, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x71", "table_id": 113, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x72", "table_id": 114, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x73", "table_id": 115, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x74", "table_id": 116, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x75", "table_id": 117, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x76", "table_id": 118, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x77", "table_id": 119, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x78", "table_id": 120, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x79", "table_id": 121, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x7a", "table_id": 122, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x7b", "table_id": 123, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x7c", "table_id": 124, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x7d", "table_id": 125, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x7e", "table_id": 126, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x7f", "table_id": 127, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x80", "table_id": 128, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x81", "table_id": 129, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x82", "table_id": 130, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x83", "table_id": 131, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x84", "table_id": 132, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x85", "table_id": 133, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x86", "table_id": 134, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x87", "table_id": 135, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x88", "table_id": 136, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x89", "table_id": 137, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x8a", "table_id": 138, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x8b", "table_id": 139, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x8c", "table_id": 140, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x8d", "table_id": 141, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x8e", "table_id": 142, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x8f", "table_id": 143, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x90", "table_id": 144, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x91", "table_id": 145, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x92", "table_id": 146, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x93", "table_id": 147, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x94", "table_id": 148, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x95", "table_id": 149, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x96", "table_id": 150, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x97", "table_id": 151, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x98", "table_id": 152, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x99", "table_id": 153, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x9a", "table_id": 154, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x9b", "table_id": 155, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x9c", "table_id": 156, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x9d", "table_id": 157, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x9e", "table_id": 158, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x9f", "table_id": 159, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xa0", "table_id": 160, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xa1", "table_id": 161, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xa2", "table_id": 162, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xa3", "table_id": 163, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xa4", "table_id": 164, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xa5", "table_id": 165, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xa6", "table_id": 166, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xa7", "table_id": 167, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xa8", "table_id": 168, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xa9", "table_id": 169, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xaa", "table_id": 170, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xab", "table_id": 171, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xac", "table_id": 172, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xad", "table_id": 173, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xae", "table_id": 174, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xaf", "table_id": 175, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xb0", "table_id": 176, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xb1", "table_id": 177, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xb2", "table_id": 178, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xb3", "table_id": 179, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xb4", "table_id": 180, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xb5", "table_id": 181, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xb6", "table_id": 182, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xb7", "table_id": 183, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xb8", "table_id": 184, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xb9", "table_id": 185, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xba", "table_id": 186, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xbb", "table_id": 187, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xbc", "table_id": 188, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xbd", "table_id": 189, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xbe", "table_id": 190, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xbf", "table_id": 191, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xc0", "table_id": 192, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xc1", "table_id": 193, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xc2", "table_id": 194, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xc3", "table_id": 195, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xc4", "table_id": 196, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xc5", "table_id": 197, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xc6", "table_id": 198, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xc7", "table_id": 199, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xc8", "table_id": 200, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xc9", "table_id": 201, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xca", "table_id": 202, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xcb", "table_id": 203, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xcc", "table_id": 204, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xcd", "table_id": 205, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xce", "table_id": 206, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xcf", "table_id": 207, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xd0", "table_id": 208, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xd1", "table_id": 209, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xd2", "table_id": 210, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xd3", "table_id": 211, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xd4", "table_id": 212, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xd5", "table_id": 213, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xd6", "table_id": 214, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xd7", "table_id": 215, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xd8", "table_id": 216, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xd9", "table_id": 217, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xda", "table_id": 218, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xdb", "table_id": 219, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xdc", "table_id": 220, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xdd", "table_id": 221, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xde", "table_id": 222, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xdf", "table_id": 223, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xe0", "table_id": 224, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xe1", "table_id": 225, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xe2", "table_id": 226, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xe3", "table_id": 227, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xe4", "table_id": 228, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xe5", "table_id": 229, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xe6", "table_id": 230, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xe7", "table_id": 231, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xe8", "table_id": 232, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xe9", "table_id": 233, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xea", "table_id": 234, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xeb", "table_id": 235, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xec", "table_id": 236, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xed", "table_id": 237, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xee", "table_id": 238, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xef", "table_id": 239, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xf0", "table_id": 240, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xf1", "table_id": 241, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xf2", "table_id": 242, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xf3", "table_id": 243, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xf4", "table_id": 244, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xf5", "table_id": 245, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xf6", "table_id": 246, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xf7", "table_id": 247, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xf8", "table_id": 248, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xf9", "table_id": 249, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xfa", "table_id": 250, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xfb", "table_id": 251, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xfc", "table_id": 252, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xfd", "table_id": 253, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } }, { "OFPTableStats": { "active_count": 0, "apply_actions": 67082241, "apply_setfields": 0, "config": 0, "instructions": 62, "lookup_count": 0, "match": 68719476733, "matched_count": 0, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0xfe", "table_id": 254, "wildcards": 68719476733, "write_actions": 67082241, "write_setfields": 0 } } ], "flags": 0, "type": 3 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/3-29-ofp_port_stats_request.packet.json0000664000175000017500000000012300000000000031163 0ustar00zuulzuul00000000000000{ "OFPPortStatsRequest": { "flags": 0, "port_no": 4294967295 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/3-3-ofp_flow_mod.packet.json0000664000175000017500000000201100000000000026725 0ustar00zuulzuul00000000000000{ "OFPFlowMod": { "buffer_id": 65535, "command": 0, "cookie": 0, "cookie_mask": 0, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "instructions": [ { "OFPInstructionGotoTable": { "len": 8, "table_id": 1, "type": 1 } } ], "match": { "OFPMatch": { "length": 22, "oxm_fields": [ { "OXMTlv": { "field": "in_port", "mask": null, "value": 6 } }, { "OXMTlv": { "field": "eth_src", "mask": null, "value": "f2:0b:a4:7d:f8:ea" } } ], "type": 1 } }, "out_group": 4294967295, "out_port": 4294967295, "priority": 123, "table_id": 0 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/3-30-ofp_port_stats_reply.packet.json0000664000175000017500000000202700000000000030623 0ustar00zuulzuul00000000000000{ "OFPStatsReply": { "body": [ { "OFPPortStats": { "collisions": 0, "port_no": 7, "rx_bytes": 0, "rx_crc_err": 0, "rx_dropped": 0, "rx_errors": 0, "rx_frame_err": 0, "rx_over_err": 0, "rx_packets": 0, "tx_bytes": 336, "tx_dropped": 0, "tx_errors": 0, "tx_packets": 4 } }, { "OFPPortStats": { "collisions": 0, "port_no": 6, "rx_bytes": 336, "rx_crc_err": 0, "rx_dropped": 0, "rx_errors": 0, "rx_frame_err": 0, "rx_over_err": 0, "rx_packets": 4, "tx_bytes": 336, "tx_dropped": 0, "tx_errors": 0, "tx_packets": 4 } } ], "flags": 0, "type": 4 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/3-31-ofp_group_features_stats_request.packet.json0000664000175000017500000000007700000000000033232 0ustar00zuulzuul00000000000000{ "OFPGroupFeaturesStatsRequest": { "flags": 0 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/3-32-ofp_group_features_stats_reply.packet.json0000664000175000017500000000076300000000000032700 0ustar00zuulzuul00000000000000{ "OFPStatsReply": { "body": { "OFPGroupFeaturesStats": { "actions": [ 67082241, 67082241, 67082241, 67082241 ], "capabilities": 5, "length": 40, "max_groups": [ 16777216, 16777216, 16777216, 16777216 ], "types": 15 } }, "flags": 0, "type": 8 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/3-33-ofp_group_desc_stats_request.packet.json0000664000175000017500000000007300000000000032330 0ustar00zuulzuul00000000000000{ "OFPGroupDescStatsRequest": { "flags": 0 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/3-34-ofp_group_desc_stats_reply.packet.json0000664000175000017500000000164300000000000032000 0ustar00zuulzuul00000000000000{ "OFPStatsReply": { "body": [ { "OFPGroupDescStats": { "buckets": [ { "OFPBucket": { "actions": [ { "OFPActionOutput": { "len": 16, "max_len": 65535, "port": 2, "type": 0 } } ], "len": 32, "watch_group": 1, "watch_port": 1, "weight": 1 } } ], "group_id": 1, "length": 40, "type": 0 } } ], "flags": 0, "type": 7 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/3-35-ofp_queue_get_config_request.packet.json0000664000175000017500000000010300000000000032264 0ustar00zuulzuul00000000000000{ "OFPQueueGetConfigRequest": { "port": 4294967295 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/3-36-ofp_queue_get_config_reply.packet.json0000664000175000017500000000253200000000000031740 0ustar00zuulzuul00000000000000{ "OFPQueueGetConfigReply": { "port": 4294967295, "queues": [ { "OFPPacketQueue": { "len": 48, "port": 77, "properties": [ { "OFPQueuePropMinRate": { "len": 16, "property": 1, "rate": 10 } }, { "OFPQueuePropMaxRate": { "len": 16, "property": 2, "rate": 900 } } ], "queue_id": 99 } }, { "OFPPacketQueue": { "len": 48, "port": 77, "properties": [ { "OFPQueuePropMinRate": { "len": 16, "property": 1, "rate": 100 } }, { "OFPQueuePropMaxRate": { "len": 16, "property": 2, "rate": 200 } } ], "queue_id": 88 } } ] } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/3-37-ofp_queue_stats_request.packet.json0000664000175000017500000000016200000000000031325 0ustar00zuulzuul00000000000000{ "OFPQueueStatsRequest": { "flags": 0, "port_no": 4294967295, "queue_id": 4294967295 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/3-38-ofp_queue_stats_reply.packet.json0000664000175000017500000000135200000000000030773 0ustar00zuulzuul00000000000000{ "OFPStatsReply": { "body": [ { "OFPQueueStats": { "port_no": 7, "queue_id": 1, "tx_bytes": 0, "tx_errors": 0, "tx_packets": 0 } }, { "OFPQueueStats": { "port_no": 6, "queue_id": 1, "tx_bytes": 0, "tx_errors": 0, "tx_packets": 0 } }, { "OFPQueueStats": { "port_no": 7, "queue_id": 2, "tx_bytes": 0, "tx_errors": 0, "tx_packets": 0 } } ], "flags": 0, "type": 5 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/3-39-ofp_port_status.packet.json0000664000175000017500000000071500000000000027610 0ustar00zuulzuul00000000000000{ "OFPPortStatus": { "desc": { "OFPPort": { "advertised": 10240, "config": 0, "curr": 10248, "curr_speed": 5000, "hw_addr": "f2:0b:a4:d0:3f:70", "max_speed": 5000, "name": "\u79c1\u306e\u30dd\u30fc\u30c8", "peer": 10248, "port_no": 7, "state": 4, "supported": 10248 } }, "reason": 0 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/3-4-ofp_packet_in.packet.json0000664000175000017500000000416700000000000027073 0ustar00zuulzuul00000000000000{ "OFPPacketIn": { "buffer_id": 2, "data": "////////8gukffjqCAYAAQgABgQAAfILpH346goAAAEAAAAAAAAKAAAD", "match": { "OFPMatch": { "length": 80, "oxm_fields": [ { "OXMTlv": { "field": "in_port", "mask": null, "value": 6 } }, { "OXMTlv": { "field": "eth_type", "mask": null, "value": 2054 } }, { "OXMTlv": { "field": "eth_dst", "mask": null, "value": "ff:ff:ff:ff:ff:ff" } }, { "OXMTlv": { "field": "eth_src", "mask": null, "value": "f2:0b:a4:7d:f8:ea" } }, { "OXMTlv": { "field": "arp_op", "mask": null, "value": 1 } }, { "OXMTlv": { "field": "arp_spa", "mask": null, "value": "10.0.0.1" } }, { "OXMTlv": { "field": "arp_tpa", "mask": null, "value": "10.0.0.3" } }, { "OXMTlv": { "field": "arp_sha", "mask": null, "value": "f2:0b:a4:7d:f8:ea" } }, { "OXMTlv": { "field": "arp_tha", "mask": null, "value": "00:00:00:00:00:00" } } ], "type": 1 } }, "reason": 1, "table_id": 1, "total_len": 42 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/3-40-ofp_flow_removed.packet.json0000664000175000017500000000117100000000000027676 0ustar00zuulzuul00000000000000{ "OFPFlowRemoved": { "byte_count": 86, "cookie": 0, "duration_nsec": 48825000, "duration_sec": 3, "hard_timeout": 0, "idle_timeout": 3, "match": { "OFPMatch": { "length": 14, "oxm_fields": [ { "OXMTlv": { "field": "eth_dst", "mask": null, "value": "f2:0b:a4:7d:f8:ea" } } ], "type": 1 } }, "packet_count": 1, "priority": 65535, "reason": 0, "table_id": 0 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/3-41-ofp_error_msg_experimenter.packet.json0000664000175000017500000000023600000000000031776 0ustar00zuulzuul00000000000000{ "OFPErrorMsg": { "code": null, "data": "amlra2VuIGRhdGE=", "exp_type": 60000, "experimenter": 999999, "type": 65535 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/3-5-ofp_features_request.packet.json0000664000175000017500000000004000000000000030507 0ustar00zuulzuul00000000000000{ "OFPFeaturesRequest": {} } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/3-59-ofp_packet_in.packet.json0000664000175000017500000001633700000000000027167 0ustar00zuulzuul00000000000000{ "OFPPacketIn": { "buffer_id": 4026531840, "data": "", "match": { "OFPMatch": { "length": 294, "oxm_fields": [ { "OXMTlv": { "field": "in_port", "mask": null, "value": 84281096 } }, { "OXMTlv": { "field": "in_phy_port", "mask": null, "value": 16909060 } }, { "OXMTlv": { "field": "metadata", "mask": null, "value": 283686952306183 } }, { "OXMTlv": { "field": "eth_type", "mask": null, "value": 2054 } }, { "OXMTlv": { "field": "eth_dst", "mask": null, "value": "ff:ff:ff:ff:ff:ff" } }, { "OXMTlv": { "field": "eth_src", "mask": null, "value": "f2:0b:a4:7d:f8:ea" } }, { "OXMTlv": { "field": "vlan_vid", "mask": null, "value": 999 } }, { "OXMTlv": { "field": "ip_dscp", "mask": null, "value": 9 } }, { "OXMTlv": { "field": "ip_ecn", "mask": null, "value": 3 } }, { "OXMTlv": { "field": "ip_proto", "mask": null, "value": 99 } }, { "OXMTlv": { "field": "ipv4_src", "mask": null, "value": "1.2.3.4" } }, { "OXMTlv": { "field": "ipv4_dst", "mask": null, "value": "1.2.3.4" } }, { "OXMTlv": { "field": "tcp_src", "mask": null, "value": 8080 } }, { "OXMTlv": { "field": "tcp_dst", "mask": null, "value": 18080 } }, { "OXMTlv": { "field": "udp_src", "mask": null, "value": 28080 } }, { "OXMTlv": { "field": "udp_dst", "mask": null, "value": 55936 } }, { "OXMTlv": { "field": "sctp_src", "mask": null, "value": 48080 } }, { "OXMTlv": { "field": "sctp_dst", "mask": null, "value": 59328 } }, { "OXMTlv": { "field": "icmpv4_type", "mask": null, "value": 100 } }, { "OXMTlv": { "field": "icmpv4_code", "mask": null, "value": 101 } }, { "OXMTlv": { "field": "arp_op", "mask": null, "value": 1 } }, { "OXMTlv": { "field": "arp_spa", "mask": null, "value": "10.0.0.1" } }, { "OXMTlv": { "field": "arp_tpa", "mask": null, "value": "10.0.0.3" } }, { "OXMTlv": { "field": "arp_sha", "mask": null, "value": "f2:0b:a4:7d:f8:ea" } }, { "OXMTlv": { "field": "arp_tha", "mask": null, "value": "00:00:00:00:00:00" } }, { "OXMTlv": { "field": "ipv6_src", "mask": null, "value": "fe80::f00b:a4ff:fe48:28a5" } }, { "OXMTlv": { "field": "ipv6_dst", "mask": null, "value": "fe80::f00b:a4ff:fe05:b7dc" } }, { "OXMTlv": { "field": "ipv6_flabel", "mask": null, "value": 541473 } }, { "OXMTlv": { "field": "icmpv6_type", "mask": null, "value": 200 } }, { "OXMTlv": { "field": "icmpv6_code", "mask": null, "value": 201 } }, { "OXMTlv": { "field": "ipv6_nd_target", "mask": null, "value": "fe80::a60:6eff:fe7f:74e7" } }, { "OXMTlv": { "field": "ipv6_nd_sll", "mask": null, "value": "00:00:00:00:02:9a" } }, { "OXMTlv": { "field": "ipv6_nd_tll", "mask": null, "value": "00:00:00:00:02:2b" } }, { "OXMTlv": { "field": "mpls_label", "mask": null, "value": 624485 } }, { "OXMTlv": { "field": "mpls_tc", "mask": null, "value": 5 } } ], "type": 1 } }, "reason": 0, "table_id": 200, "total_len": 0 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/3-6-ofp_features_reply.packet.json0000664000175000017500000000200000000000000030151 0ustar00zuulzuul00000000000000{ "OFPSwitchFeatures": { "capabilities": 79, "datapath_id": 9210263729383, "n_buffers": 0, "n_tables": 255, "ports": { "6": { "OFPPort": { "advertised": 10240, "config": 0, "curr": 10248, "curr_speed": 5000, "hw_addr": "f2:0b:a4:7d:f8:ea", "max_speed": 5000, "name": "Port6", "peer": 10248, "port_no": 6, "state": 4, "supported": 10248 } }, "7": { "OFPPort": { "advertised": 10240, "config": 0, "curr": 10248, "curr_speed": 5000, "hw_addr": "f2:0b:a4:d0:3f:70", "max_speed": 5000, "name": "Port7", "peer": 10248, "port_no": 7, "state": 4, "supported": 10248 } } } } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/3-60-ofp_flow_mod.packet.json0000664000175000017500000001661500000000000027027 0ustar00zuulzuul00000000000000{ "OFPFlowMod": { "buffer_id": 65535, "command": 0, "cookie": 0, "cookie_mask": 0, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "instructions": [], "match": { "OFPMatch": { "length": 294, "oxm_fields": [ { "OXMTlv": { "field": "in_port", "mask": null, "value": 84281096 } }, { "OXMTlv": { "field": "in_phy_port", "mask": null, "value": 16909060 } }, { "OXMTlv": { "field": "metadata", "mask": null, "value": 283686952306183 } }, { "OXMTlv": { "field": "eth_type", "mask": null, "value": 2054 } }, { "OXMTlv": { "field": "eth_dst", "mask": null, "value": "ff:ff:ff:ff:ff:ff" } }, { "OXMTlv": { "field": "eth_src", "mask": null, "value": "f2:0b:a4:7d:f8:ea" } }, { "OXMTlv": { "field": "vlan_vid", "mask": null, "value": 999 } }, { "OXMTlv": { "field": "ip_dscp", "mask": null, "value": 9 } }, { "OXMTlv": { "field": "ip_ecn", "mask": null, "value": 3 } }, { "OXMTlv": { "field": "ip_proto", "mask": null, "value": 99 } }, { "OXMTlv": { "field": "ipv4_src", "mask": null, "value": "1.2.3.4" } }, { "OXMTlv": { "field": "ipv4_dst", "mask": null, "value": "1.2.3.4" } }, { "OXMTlv": { "field": "tcp_src", "mask": null, "value": 8080 } }, { "OXMTlv": { "field": "tcp_dst", "mask": null, "value": 18080 } }, { "OXMTlv": { "field": "udp_src", "mask": null, "value": 28080 } }, { "OXMTlv": { "field": "udp_dst", "mask": null, "value": 55936 } }, { "OXMTlv": { "field": "sctp_src", "mask": null, "value": 48080 } }, { "OXMTlv": { "field": "sctp_dst", "mask": null, "value": 59328 } }, { "OXMTlv": { "field": "icmpv4_type", "mask": null, "value": 100 } }, { "OXMTlv": { "field": "icmpv4_code", "mask": null, "value": 101 } }, { "OXMTlv": { "field": "arp_op", "mask": null, "value": 1 } }, { "OXMTlv": { "field": "arp_spa", "mask": null, "value": "10.0.0.1" } }, { "OXMTlv": { "field": "arp_tpa", "mask": null, "value": "10.0.0.3" } }, { "OXMTlv": { "field": "arp_sha", "mask": null, "value": "f2:0b:a4:7d:f8:ea" } }, { "OXMTlv": { "field": "arp_tha", "mask": null, "value": "00:00:00:00:00:00" } }, { "OXMTlv": { "field": "ipv6_src", "mask": null, "value": "fe80::f00b:a4ff:fe48:28a5" } }, { "OXMTlv": { "field": "ipv6_dst", "mask": null, "value": "fe80::f00b:a4ff:fe05:b7dc" } }, { "OXMTlv": { "field": "ipv6_flabel", "mask": null, "value": 541473 } }, { "OXMTlv": { "field": "icmpv6_type", "mask": null, "value": 200 } }, { "OXMTlv": { "field": "icmpv6_code", "mask": null, "value": 201 } }, { "OXMTlv": { "field": "ipv6_nd_target", "mask": null, "value": "fe80::a60:6eff:fe7f:74e7" } }, { "OXMTlv": { "field": "ipv6_nd_sll", "mask": null, "value": "00:00:00:00:02:9a" } }, { "OXMTlv": { "field": "ipv6_nd_tll", "mask": null, "value": "00:00:00:00:02:2b" } }, { "OXMTlv": { "field": "mpls_label", "mask": null, "value": 624485 } }, { "OXMTlv": { "field": "mpls_tc", "mask": null, "value": 5 } } ], "type": 1 } }, "out_group": 4294967295, "out_port": 4294967295, "priority": 123, "table_id": 1 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/3-61-ofp_group_stats_request.packet.json0000664000175000017500000000012500000000000031331 0ustar00zuulzuul00000000000000{ "OFPGroupStatsRequest": { "flags": 0, "group_id": 4294967292 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/3-62-ofp_group_stats_reply.packet.json0000664000175000017500000000106600000000000031002 0ustar00zuulzuul00000000000000{ "OFPStatsReply": { "body": [ { "OFPGroupStats": { "bucket_counters": [ { "OFPBucketCounter": { "byte_count": 2345, "packet_count": 234 } } ], "byte_count": 12345, "group_id": 1, "length": 48, "packet_count": 123, "ref_count": 2 } } ], "flags": 0, "type": 6 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/3-7-ofp_set_config.packet.json0000664000175000017500000000011300000000000027244 0ustar00zuulzuul00000000000000{ "OFPSetConfig": { "flags": 0, "miss_send_len": 128 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/3-8-ofp_get_config_request.packet.json0000664000175000017500000000004100000000000031001 0ustar00zuulzuul00000000000000{ "OFPGetConfigRequest": {} } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/3-9-ofp_get_config_reply.packet.json0000664000175000017500000000012000000000000030443 0ustar00zuulzuul00000000000000{ "OFPGetConfigReply": { "flags": 0, "miss_send_len": 128 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/lib-ofctl-ofp_group_stats_request.packet.json0000664000175000017500000000011400000000000032614 0ustar00zuulzuul00000000000000{ "OFPGroupStatsRequest": { "flags": 0, "group_id": 1 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/lib-ofctl-ofp_port_stats_request.packet.json0000664000175000017500000000011200000000000032442 0ustar00zuulzuul00000000000000{ "OFPPortStatsRequest": { "flags": 0, "port_no": 7 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/lib-ofctl-ofp_queue_get_config_request.packet.json0000664000175000017500000000010300000000000033550 0ustar00zuulzuul00000000000000{ "OFPQueueGetConfigRequest": { "port": 4294967295 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/lib-ofctl-ofp_queue_stats_request.packet1.json0000664000175000017500000000015100000000000032666 0ustar00zuulzuul00000000000000{ "OFPQueueStatsRequest": { "flags": 0, "port_no": 7, "queue_id": 4294967295 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/lib-ofctl-ofp_queue_stats_request.packet2.json0000664000175000017500000000014000000000000032665 0ustar00zuulzuul00000000000000{ "OFPQueueStatsRequest": { "flags": 0, "port_no": 7, "queue_id": 1 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/lib-ofctl-ofp_queue_stats_request.packet3.json0000664000175000017500000000015100000000000032670 0ustar00zuulzuul00000000000000{ "OFPQueueStatsRequest": { "flags": 0, "port_no": 4294967295, "queue_id": 1 } } ././@PaxHeader0000000000000000000000000000021400000000000011452 xustar0000000000000000118 path=os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/libofproto-OFP12-ofp_packet_out_packet_library.packet.json 22 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of12/libofproto-OFP12-ofp_packet_out_packet_library.pac0000664000175000017500000000324300000000000033326 0ustar00zuulzuul00000000000000{ "OFPPacketOut": { "actions": [ { "OFPActionOutput": { "len": 16, "max_len": 65535, "port": 4294967292, "type": 0 } } ], "actions_len": 16, "buffer_id": 4294967295, "data": { "Packet": { "protocols": [ { "ethernet": { "dst": "f2:0b:a4:d0:3f:70", "ethertype": 2048, "src": "f2:0b:a4:7d:f8:ea" } }, { "ipv4": { "csum": 44939, "dst": "10.0.0.2", "flags": 0, "header_length": 5, "identification": 63514, "offset": 0, "option": null, "proto": 1, "src": "10.0.0.1", "tos": 0, "total_length": 84, "ttl": 255, "version": 4 } }, { "icmp": { "code": 0, "csum": 520, "data": { "echo": { "data": "MdYCAAAAAACrjS0xAAAAABAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vAAAAAAAAAAA=", "id": 63328, "seq": 0 } }, "type": 8 } } ] } }, "in_port": 4294967293 } } ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.3301187 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/0000775000175000017500000000000000000000000021621 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-0-ofp_desc_reply.packet.json0000664000175000017500000000043500000000000027257 0ustar00zuulzuul00000000000000{ "OFPDescStatsReply": { "body": { "OFPDescStats": { "dp_desc": "dp", "hw_desc": "hw", "mfr_desc": "mfr", "serial_num": "serial", "sw_desc": "sw" } }, "flags": 0, "type": 0 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-1-ofp_packet_out.packet.json0000664000175000017500000000074000000000000027264 0ustar00zuulzuul00000000000000{ "OFPPacketOut": { "actions": [ { "OFPActionOutput": { "len": 16, "max_len": 65535, "port": 4294967292, "type": 0 } } ], "actions_len": 16, "buffer_id": 4294967295, "data": "8guk0D9w8gukffjqCABFAABU+BoAAP8Br4sKAAABCgAAAggAAgj3YAAAMdYCAAAAAACrjS0xAAAAABAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vAAAAAAAAAAA=", "in_port": 4294967293 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-10-ofp_hello.packet.json0000664000175000017500000000055000000000000026310 0ustar00zuulzuul00000000000000{ "OFPHello": { "elements": [ { "OFPHelloElemVersionBitmap": { "length": 8, "type": 1, "versions": [ 1, 2, 3, 9, 10, 30 ] } } ] } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-11-ofp_flow_stats_request.packet.json0000664000175000017500000000051500000000000031144 0ustar00zuulzuul00000000000000{ "OFPFlowStatsRequest": { "cookie": 0, "cookie_mask": 0, "flags": 0, "match": { "OFPMatch": { "length": 4, "oxm_fields": [], "type": 1 } }, "out_group": 4294967295, "out_port": 4294967295, "table_id": 0, "type": 1 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-12-ofp_flow_stats_reply.packet.json0000664000175000017500000002754400000000000030623 0ustar00zuulzuul00000000000000{ "OFPFlowStatsReply": { "body": [ { "OFPFlowStats": { "byte_count": 0, "cookie": 0, "duration_nsec": 115277000, "duration_sec": 358, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "instructions": [], "length": 56, "match": { "OFPMatch": { "length": 4, "oxm_fields": [], "type": 1 } }, "packet_count": 0, "priority": 65535, "table_id": 0 } }, { "OFPFlowStats": { "byte_count": 0, "cookie": 0, "duration_nsec": 115055000, "duration_sec": 358, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "instructions": [ { "OFPInstructionActions": { "actions": [ { "OFPActionOutput": { "len": 16, "max_len": 0, "port": 4294967290, "type": 0 } } ], "len": 24, "type": 4 } } ], "length": 88, "match": { "OFPMatch": { "length": 10, "oxm_fields": [ { "OXMTlv": { "field": "eth_type", "mask": null, "value": 2054 } } ], "type": 1 } }, "packet_count": 0, "priority": 65534, "table_id": 0 } }, { "OFPFlowStats": { "byte_count": 238, "cookie": 0, "duration_nsec": 511582000, "duration_sec": 316220, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "instructions": [ { "OFPInstructionGotoTable": { "len": 8, "table_id": 1, "type": 1 } } ], "length": 80, "match": { "OFPMatch": { "length": 22, "oxm_fields": [ { "OXMTlv": { "field": "in_port", "mask": null, "value": 6 } }, { "OXMTlv": { "field": "eth_src", "mask": null, "value": "f2:0b:a4:7d:f8:ea" } } ], "type": 1 } }, "packet_count": 3, "priority": 123, "table_id": 0 } }, { "OFPFlowStats": { "byte_count": 98, "cookie": 0, "duration_nsec": 980901000, "duration_sec": 313499, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "instructions": [ { "OFPInstructionActions": { "actions": [ { "OFPActionSetField": { "field": { "OXMTlv": { "field": "vlan_vid", "mask": null, "value": 258 } }, "len": 16, "type": 25 } }, { "OFPActionCopyTtlOut": { "len": 8, "type": 11 } }, { "OFPActionCopyTtlIn": { "len": 8, "type": 12 } }, { "OFPActionCopyTtlIn": { "len": 8, "type": 12 } }, { "OFPActionPopPbb": { "len": 8, "type": 27 } }, { "OFPActionPushPbb": { "ethertype": 4660, "len": 8, "type": 26 } }, { "OFPActionPopMpls": { "ethertype": 39030, "len": 8, "type": 20 } }, { "OFPActionPushMpls": { "ethertype": 34887, "len": 8, "type": 19 } }, { "OFPActionPopVlan": { "len": 8, "type": 18 } }, { "OFPActionPushVlan": { "ethertype": 33024, "len": 8, "type": 17 } }, { "OFPActionDecMplsTtl": { "len": 8, "type": 16 } }, { "OFPActionSetMplsTtl": { "len": 8, "mpls_ttl": 10, "type": 15 } }, { "OFPActionDecNwTtl": { "len": 8, "type": 24 } }, { "OFPActionSetNwTtl": { "len": 8, "nw_ttl": 10, "type": 23 } }, { "OFPActionSetQueue": { "len": 8, "queue_id": 3, "type": 21 } }, { "OFPActionGroup": { "group_id": 99, "len": 8, "type": 22 } }, { "OFPActionOutput": { "len": 16, "max_len": 65535, "port": 6, "type": 0 } }, { "OFPActionExperimenterUnknown": { "len": 16, "data": "ZXhwX2RhdGE=", "experimenter": 98765432, "type": 65535 } }, { "NXActionUnknown": { "len": 16, "data": "cF9kYXRh", "experimenter": 8992, "type": 65535, "subtype": 25976 } } ], "len": 192, "type": 3 } }, { "OFPInstructionActions": { "actions": [ { "OFPActionSetField": { "field": { "OXMTlv": { "field": "eth_src", "mask": null, "value": "01:02:03:04:05:06" } }, "len": 16, "type": 25 } }, { "OFPActionSetField": { "field": { "OXMTlv": { "field": "pbb_uca", "mask": null, "value": 1 } }, "len": 16, "type": 25 } } ], "len": 40, "type": 4 } }, { "OFPInstructionActions": { "actions": [ { "OFPActionOutput": { "len": 16, "max_len": 65535, "port": 4294967293, "type": 0 } } ], "len": 24, "type": 3 } } ], "length": 312, "match": { "OFPMatch": { "length": 4, "oxm_fields": [], "type": 1 } }, "packet_count": 1, "priority": 0, "table_id": 0 } } ], "flags": 0, "type": 1 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-13-ofp_echo_request.packet.json0000664000175000017500000000007100000000000027674 0ustar00zuulzuul00000000000000{ "OFPEchoRequest": { "data": "aG9nZQ==" } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-14-ofp_echo_reply.packet.json0000664000175000017500000000006700000000000027345 0ustar00zuulzuul00000000000000{ "OFPEchoReply": { "data": "aG9nZQ==" } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-15-ofp_error_msg.packet.json0000664000175000017500000000013500000000000027210 0ustar00zuulzuul00000000000000{ "OFPErrorMsg": { "code": 11, "data": "ZnVnYWZ1Z2E=", "type": 2 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-16-ofp_experimenter.packet.json0000664000175000017500000000016700000000000027726 0ustar00zuulzuul00000000000000{ "OFPExperimenter": { "data": "bmF6bw==", "exp_type": 123456789, "experimenter": 98765432 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-17-ofp_barrier_request.packet.json0000664000175000017500000000003700000000000030412 0ustar00zuulzuul00000000000000{ "OFPBarrierRequest": {} } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-18-ofp_barrier_reply.packet.json0000664000175000017500000000003500000000000030054 0ustar00zuulzuul00000000000000{ "OFPBarrierReply": {} } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-19-ofp_role_request.packet.json0000664000175000017500000000013500000000000027726 0ustar00zuulzuul00000000000000{ "OFPRoleRequest": { "generation_id": 17294086455919964160, "role": 2 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-2-ofp_flow_mod.packet.json0000664000175000017500000001341500000000000026740 0ustar00zuulzuul00000000000000{ "OFPFlowMod": { "buffer_id": 65535, "command": 0, "cookie": 0, "cookie_mask": 0, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "instructions": [ { "OFPInstructionActions": { "actions": [ { "OFPActionSetField": { "field": { "OXMTlv": { "field": "vlan_vid", "mask": null, "value": 258 } }, "len": 16, "type": 25 } }, { "OFPActionCopyTtlOut": { "len": 8, "type": 11 } }, { "OFPActionCopyTtlIn": { "len": 8, "type": 12 } }, { "OFPActionCopyTtlIn": { "len": 8, "type": 12 } }, { "OFPActionPopPbb": { "len": 8, "type": 27 } }, { "OFPActionPushPbb": { "ethertype": 4660, "len": 8, "type": 26 } }, { "OFPActionPopMpls": { "ethertype": 39030, "len": 8, "type": 20 } }, { "OFPActionPushMpls": { "ethertype": 34887, "len": 8, "type": 19 } }, { "OFPActionPopVlan": { "len": 8, "type": 18 } }, { "OFPActionPushVlan": { "ethertype": 33024, "len": 8, "type": 17 } }, { "OFPActionDecMplsTtl": { "len": 8, "type": 16 } }, { "OFPActionSetMplsTtl": { "len": 8, "mpls_ttl": 10, "type": 15 } }, { "OFPActionDecNwTtl": { "len": 8, "type": 24 } }, { "OFPActionSetNwTtl": { "len": 8, "nw_ttl": 10, "type": 23 } }, { "OFPActionExperimenterUnknown": { "data": "AAECAwQFBgc=", "experimenter": 101, "len": 16, "type": 65535 } }, { "OFPActionSetQueue": { "len": 8, "queue_id": 3, "type": 21 } }, { "OFPActionGroup": { "group_id": 99, "len": 8, "type": 22 } }, { "OFPActionOutput": { "len": 16, "max_len": 65535, "port": 6, "type": 0 } } ], "len": 176, "type": 3 } }, { "OFPInstructionActions": { "actions": [ { "OFPActionSetField": { "field": { "OXMTlv": { "field": "eth_src", "mask": null, "value": "01:02:03:04:05:06" } }, "len": 16, "type": 25 } }, { "OFPActionSetField": { "field": { "OXMTlv": { "field": "pbb_uca", "mask": null, "value": 1 } }, "len": 16, "type": 25 } } ], "len": 40, "type": 4 } } ], "match": { "OFPMatch": { "length": 14, "oxm_fields": [ { "OXMTlv": { "field": "eth_dst", "mask": null, "value": "f2:0b:a4:7d:f8:ea" } } ], "type": 1 } }, "out_group": 4294967295, "out_port": 4294967295, "priority": 123, "table_id": 1 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-20-ofp_role_reply.packet.json0000664000175000017500000000013300000000000027357 0ustar00zuulzuul00000000000000{ "OFPRoleReply": { "generation_id": 17294086455919964160, "role": 3 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-21-ofp_group_mod.packet.json0000664000175000017500000000112000000000000027174 0ustar00zuulzuul00000000000000{ "OFPGroupMod": { "buckets": [ { "OFPBucket": { "actions": [ { "OFPActionOutput": { "len": 16, "max_len": 65535, "port": 2, "type": 0 } } ], "len": 32, "watch_group": 1, "watch_port": 1, "weight": 1 } } ], "command": 0, "group_id": 1, "type": 0 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-22-ofp_port_mod.packet.json0000664000175000017500000000022200000000000027027 0ustar00zuulzuul00000000000000{ "OFPPortMod": { "advertise": 4096, "config": 0, "hw_addr": "00:11:00:00:11:11", "mask": 0, "port_no": 1 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-23-ofp_table_mod.packet.json0000664000175000017500000000010600000000000027134 0ustar00zuulzuul00000000000000{ "OFPTableMod": { "config": 0, "table_id": 255 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-24-ofp_desc_request.packet.json0000664000175000017500000000010700000000000027676 0ustar00zuulzuul00000000000000{ "OFPDescStatsRequest": { "flags": 0, "type": 0 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-25-ofp_aggregate_stats_request.packet.json0000664000175000017500000000052400000000000032130 0ustar00zuulzuul00000000000000{ "OFPAggregateStatsRequest": { "cookie": 0, "cookie_mask": 0, "flags": 0, "match": { "OFPMatch": { "length": 4, "oxm_fields": [], "type": 1 } }, "out_group": 4294967295, "out_port": 4294967295, "table_id": 255, "type": 2 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-26-ofp_aggregate_stats_reply.packet.json0000664000175000017500000000035000000000000031571 0ustar00zuulzuul00000000000000{ "OFPAggregateStatsReply": { "body": { "OFPAggregateStats": { "byte_count": 574, "flow_count": 6, "packet_count": 7 } }, "flags": 0, "type": 2 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-27-ofp_table_stats_request.packet.json0000664000175000017500000000011000000000000031262 0ustar00zuulzuul00000000000000{ "OFPTableStatsRequest": { "flags": 0, "type": 3 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-28-ofp_table_stats_reply.packet.json0000664000175000017500000000075600000000000030746 0ustar00zuulzuul00000000000000{ "OFPTableStatsReply": { "body": [ { "OFPTableStats": { "active_count": 4, "lookup_count": 4, "matched_count": 4, "table_id": 0 } }, { "OFPTableStats": { "active_count": 4, "lookup_count": 4, "matched_count": 4, "table_id": 1 } } ], "flags": 0, "type": 3 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-29-ofp_port_stats_request.packet.json0000664000175000017500000000014400000000000031170 0ustar00zuulzuul00000000000000{ "OFPPortStatsRequest": { "flags": 0, "port_no": 4294967295, "type": 4 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-3-ofp_flow_mod.packet.json0000664000175000017500000000201100000000000026727 0ustar00zuulzuul00000000000000{ "OFPFlowMod": { "buffer_id": 65535, "command": 0, "cookie": 0, "cookie_mask": 0, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "instructions": [ { "OFPInstructionGotoTable": { "len": 8, "table_id": 1, "type": 1 } } ], "match": { "OFPMatch": { "length": 22, "oxm_fields": [ { "OXMTlv": { "field": "in_port", "mask": null, "value": 6 } }, { "OXMTlv": { "field": "eth_src", "mask": null, "value": "f2:0b:a4:7d:f8:ea" } } ], "type": 1 } }, "out_group": 4294967295, "out_port": 4294967295, "priority": 123, "table_id": 0 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-30-ofp_port_stats_reply.packet.json0000664000175000017500000000224500000000000030627 0ustar00zuulzuul00000000000000{ "OFPPortStatsReply": { "body": [ { "OFPPortStats": { "collisions": 0, "duration_nsec": 0, "duration_sec": 0, "port_no": 7, "rx_bytes": 0, "rx_crc_err": 0, "rx_dropped": 0, "rx_errors": 0, "rx_frame_err": 0, "rx_over_err": 0, "rx_packets": 0, "tx_bytes": 336, "tx_dropped": 0, "tx_errors": 0, "tx_packets": 4 } }, { "OFPPortStats": { "collisions": 0, "duration_nsec": 0, "duration_sec": 0, "port_no": 6, "rx_bytes": 336, "rx_crc_err": 0, "rx_dropped": 0, "rx_errors": 0, "rx_frame_err": 0, "rx_over_err": 0, "rx_packets": 4, "tx_bytes": 336, "tx_dropped": 0, "tx_errors": 0, "tx_packets": 4 } } ], "flags": 0, "type": 4 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-31-ofp_group_features_request.packet.json0000664000175000017500000000012000000000000032003 0ustar00zuulzuul00000000000000{ "OFPGroupFeaturesStatsRequest": { "flags": 0, "type": 8 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-32-ofp_group_features_reply.packet.json0000664000175000017500000000074600000000000031465 0ustar00zuulzuul00000000000000{ "OFPGroupFeaturesStatsReply": { "body": { "OFPGroupFeaturesStats": { "actions": [ 67082241, 67082241, 67082241, 67082241 ], "capabilities": 5, "max_groups": [ 16777216, 16777216, 16777216, 16777216 ], "types": 15 } }, "flags": 0, "type": 8 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-33-ofp_group_desc_request.packet.json0000664000175000017500000000011400000000000031110 0ustar00zuulzuul00000000000000{ "OFPGroupDescStatsRequest": { "flags": 0, "type": 7 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-34-ofp_group_desc_reply.packet.json0000664000175000017500000000165400000000000030566 0ustar00zuulzuul00000000000000{ "OFPGroupDescStatsReply": { "body": [ { "OFPGroupDescStats": { "buckets": [ { "OFPBucket": { "actions": [ { "OFPActionOutput": { "len": 16, "max_len": 65535, "port": 2, "type": 0 } } ], "len": 32, "watch_group": 1, "watch_port": 1, "weight": 1 } } ], "group_id": 1, "length": 40, "type": 0 } } ], "flags": 0, "type": 7 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-35-ofp_queue_get_config_request.packet.json0000664000175000017500000000010300000000000032266 0ustar00zuulzuul00000000000000{ "OFPQueueGetConfigRequest": { "port": 4294967295 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-36-ofp_queue_get_config_reply.packet.json0000664000175000017500000000562700000000000031752 0ustar00zuulzuul00000000000000{ "OFPQueueGetConfigReply": { "port": 4294967295, "queues": [ { "OFPPacketQueue": { "len": 64, "port": 77, "properties": [ { "OFPQueuePropMinRate": { "len": 16, "property": 1, "rate": 10 } }, { "OFPQueuePropMaxRate": { "len": 16, "property": 2, "rate": 900 } }, { "OFPQueuePropExperimenter": { "data": [], "experimenter": 999, "len": 16, "property": 65535 } } ], "queue_id": 99 } }, { "OFPPacketQueue": { "len": 65, "port": 77, "properties": [ { "OFPQueuePropMinRate": { "len": 16, "property": 1, "rate": 100 } }, { "OFPQueuePropMaxRate": { "len": 16, "property": 2, "rate": 200 } }, { "OFPQueuePropExperimenter": { "experimenter": 999, "data": [ 1 ], "len": 17, "property": 65535 } } ], "queue_id": 88 } }, { "OFPPacketQueue": { "len": 66, "port": 77, "properties": [ { "OFPQueuePropMinRate": { "len": 16, "property": 1, "rate": 200 } }, { "OFPQueuePropMaxRate": { "len": 16, "property": 2, "rate": 400 } }, { "OFPQueuePropExperimenter": { "experimenter": 999, "data": [ 1, 2 ], "len": 18, "property": 65535 } } ], "queue_id": 77 } } ] } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-37-ofp_queue_stats_request.packet.json0000664000175000017500000000020300000000000031323 0ustar00zuulzuul00000000000000{ "OFPQueueStatsRequest": { "flags": 0, "port_no": 4294967295, "queue_id": 4294967295, "type": 5 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-38-ofp_queue_stats_reply.packet.json0000664000175000017500000000167600000000000031006 0ustar00zuulzuul00000000000000{ "OFPQueueStatsReply": { "body": [ { "OFPQueueStats": { "duration_nsec": 0, "duration_sec": 0, "port_no": 7, "queue_id": 1, "tx_bytes": 0, "tx_errors": 0, "tx_packets": 0 } }, { "OFPQueueStats": { "duration_nsec": 0, "duration_sec": 0, "port_no": 6, "queue_id": 1, "tx_bytes": 0, "tx_errors": 0, "tx_packets": 0 } }, { "OFPQueueStats": { "duration_nsec": 0, "duration_sec": 0, "port_no": 7, "queue_id": 2, "tx_bytes": 0, "tx_errors": 0, "tx_packets": 0 } } ], "flags": 0, "type": 5 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-39-ofp_port_status.packet.json0000664000175000017500000000071500000000000027612 0ustar00zuulzuul00000000000000{ "OFPPortStatus": { "desc": { "OFPPort": { "advertised": 10240, "config": 0, "curr": 10248, "curr_speed": 5000, "hw_addr": "f2:0b:a4:d0:3f:70", "max_speed": 5000, "name": "\u79c1\u306e\u30dd\u30fc\u30c8", "peer": 10248, "port_no": 7, "state": 4, "supported": 10248 } }, "reason": 0 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-4-ofp_packet_in.packet.json0000664000175000017500000000423000000000000027064 0ustar00zuulzuul00000000000000{ "OFPPacketIn": { "buffer_id": 2, "cookie": 283686884868096, "data": "////////8gukffjqCAYAAQgABgQAAfILpH346goAAAEAAAAAAAAKAAAD", "match": { "OFPMatch": { "length": 80, "oxm_fields": [ { "OXMTlv": { "field": "in_port", "mask": null, "value": 6 } }, { "OXMTlv": { "field": "eth_type", "mask": null, "value": 2054 } }, { "OXMTlv": { "field": "eth_dst", "mask": null, "value": "ff:ff:ff:ff:ff:ff" } }, { "OXMTlv": { "field": "eth_src", "mask": null, "value": "f2:0b:a4:7d:f8:ea" } }, { "OXMTlv": { "field": "arp_op", "mask": null, "value": 1 } }, { "OXMTlv": { "field": "arp_spa", "mask": null, "value": "10.0.0.1" } }, { "OXMTlv": { "field": "arp_tpa", "mask": null, "value": "10.0.0.3" } }, { "OXMTlv": { "field": "arp_sha", "mask": null, "value": "f2:0b:a4:7d:f8:ea" } }, { "OXMTlv": { "field": "arp_tha", "mask": null, "value": "00:00:00:00:00:00" } } ], "type": 1 } }, "reason": 1, "table_id": 1, "total_len": 42 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-40-ofp_flow_removed.packet.json0000664000175000017500000000117100000000000027700 0ustar00zuulzuul00000000000000{ "OFPFlowRemoved": { "byte_count": 86, "cookie": 0, "duration_nsec": 48825000, "duration_sec": 3, "hard_timeout": 0, "idle_timeout": 3, "match": { "OFPMatch": { "length": 14, "oxm_fields": [ { "OXMTlv": { "field": "eth_dst", "mask": null, "value": "f2:0b:a4:7d:f8:ea" } } ], "type": 1 } }, "packet_count": 1, "priority": 65535, "reason": 0, "table_id": 0 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-41-ofp_error_msg_experimenter.packet.json0000664000175000017500000000023600000000000032000 0ustar00zuulzuul00000000000000{ "OFPErrorMsg": { "code": null, "data": "amlra2VuIGRhdGE=", "exp_type": 60000, "experimenter": 999999, "type": 65535 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-42-ofp_get_async_request.packet.json0000664000175000017500000000004000000000000030730 0ustar00zuulzuul00000000000000{ "OFPGetAsyncRequest": {} } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-43-ofp_get_async_reply.packet.json0000664000175000017500000000032500000000000030402 0ustar00zuulzuul00000000000000{ "OFPGetAsyncReply": { "flow_removed_mask": [ 15, 3 ], "packet_in_mask": [ 5, 1 ], "port_status_mask": [ 7, 3 ] } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-44-ofp_set_async.packet.json0000664000175000017500000000032000000000000027177 0ustar00zuulzuul00000000000000{ "OFPSetAsync": { "flow_removed_mask": [ 15, 3 ], "packet_in_mask": [ 5, 1 ], "port_status_mask": [ 7, 3 ] } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-45-ofp_meter_mod.packet.json0000664000175000017500000000136100000000000027171 0ustar00zuulzuul00000000000000{ "OFPMeterMod": { "bands": [ { "OFPMeterBandDrop": { "burst_size": 10, "len": 16, "rate": 1000, "type": 1 } }, { "OFPMeterBandDscpRemark": { "burst_size": 10, "len": 16, "prec_level": 1, "rate": 1000, "type": 2 } }, { "OFPMeterBandExperimenter": { "burst_size": 10, "experimenter": 999, "len": 16, "rate": 1000, "type": 65535 } } ], "command": 0, "flags": 14, "meter_id": 100 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-46-ofp_flow_mod.packet.json0000664000175000017500000000235400000000000027030 0ustar00zuulzuul00000000000000{ "OFPFlowMod": { "buffer_id": 65535, "command": 0, "cookie": 0, "cookie_mask": 0, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "instructions": [ { "OFPInstructionMeter": { "len": 8, "meter_id": 1, "type": 6 } }, { "OFPInstructionActions": { "actions": [ { "OFPActionOutput": { "len": 16, "max_len": 65535, "port": 6, "type": 0 } } ], "len": 24, "type": 3 } } ], "match": { "OFPMatch": { "length": 14, "oxm_fields": [ { "OXMTlv": { "field": "eth_dst", "mask": null, "value": "f2:0b:a4:7d:f8:ea" } } ], "type": 1 } }, "out_group": 4294967295, "out_port": 4294967295, "priority": 123, "table_id": 1 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-47-ofp_meter_config_request.packet.json0000664000175000017500000000015500000000000031431 0ustar00zuulzuul00000000000000{ "OFPMeterConfigStatsRequest": { "flags": 0, "meter_id": 4294967295, "type": 10 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-48-ofp_meter_config_reply.packet.json0000664000175000017500000000106200000000000031073 0ustar00zuulzuul00000000000000{ "OFPMeterConfigStatsReply": { "body": [ { "OFPMeterConfigStats": { "bands": [ { "OFPMeterBandDrop": { "burst_size": 10, "len": 16, "rate": 1000, "type": 1 } } ], "flags": 14, "length": 24, "meter_id": 100 } } ], "flags": 0, "type": 10 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-49-ofp_meter_stats_request.packet.json0000664000175000017500000000014600000000000031324 0ustar00zuulzuul00000000000000{ "OFPMeterStatsRequest": { "flags": 0, "meter_id": 4294967295, "type": 9 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-5-ofp_features_request.packet.json0000664000175000017500000000004000000000000030511 0ustar00zuulzuul00000000000000{ "OFPFeaturesRequest": {} } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-50-ofp_meter_stats_reply.packet.json0000664000175000017500000000120600000000000030755 0ustar00zuulzuul00000000000000{ "OFPMeterStatsReply": { "body": [ { "OFPMeterStats": { "band_stats": [ { "OFPMeterBandStats": { "byte_band_count": 0, "packet_band_count": 0 } } ], "byte_in_count": 0, "duration_nsec": 480000, "duration_sec": 0, "flow_count": 0, "len": 56, "meter_id": 100, "packet_in_count": 0 } } ], "flags": 0, "type": 9 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-51-ofp_meter_features_request.packet.json0000664000175000017500000000012100000000000031766 0ustar00zuulzuul00000000000000{ "OFPMeterFeaturesStatsRequest": { "flags": 0, "type": 11 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-52-ofp_meter_features_reply.packet.json0000664000175000017500000000054400000000000031443 0ustar00zuulzuul00000000000000{ "OFPMeterFeaturesStatsReply": { "body": [ { "OFPMeterFeaturesStats": { "band_types": 2147483654, "capabilities": 15, "max_bands": 255, "max_color": 0, "max_meter": 16777216 } } ], "flags": 0, "type": 11 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-53-ofp_port_desc_request.packet.json0000664000175000017500000000011400000000000030742 0ustar00zuulzuul00000000000000{ "OFPPortDescStatsRequest": { "flags": 0, "type": 13 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-54-ofp_port_desc_reply.packet.json0000664000175000017500000000166200000000000030417 0ustar00zuulzuul00000000000000{ "OFPPortDescStatsReply": { "body": [ { "OFPPort": { "advertised": 10240, "config": 0, "curr": 10248, "curr_speed": 5000, "hw_addr": "f2:0b:a4:d0:3f:70", "max_speed": 5000, "name": "Port7", "peer": 10248, "port_no": 7, "state": 4, "supported": 10248 } }, { "OFPPort": { "advertised": 10240, "config": 0, "curr": 10248, "curr_speed": 5000, "hw_addr": "f2:0b:a4:7d:f8:ea", "max_speed": 5000, "name": "Port6", "peer": 10248, "port_no": 6, "state": 4, "supported": 10248 } } ], "flags": 0, "type": 13 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-55-ofp_table_features_request.packet.json0000664000175000017500000223551700000000000031772 0ustar00zuulzuul00000000000000{ "OFPTableFeaturesStatsRequest": { "body": [ { "OFPTableFeaturesStats": { "config": 0, "length": 1168, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x00", "properties": [ { "OFPTableFeaturePropInstructions": { "instruction_ids": [ { "OFPInstructionId": { "len": 4, "type": 1 } }, { "OFPInstructionId": { "len": 4, "type": 2 } }, { "OFPInstructionId": { "len": 4, "type": 3 } }, { "OFPInstructionId": { "len": 4, "type": 4 } }, { "OFPInstructionId": { "len": 4, "type": 5 } }, { "OFPInstructionId": { "len": 4, "type": 6 } } ], "length": 28, "type": 0 } }, { "OFPTableFeaturePropNextTables": { "length": 258, "table_ids": [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254 ], "type": 2 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 4 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 6 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 8 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 10 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 12 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 14 } }, { "OFPTableFeaturePropExperimenter": { "data": [], "exp_type": 0, "experimenter": 101, "length": 12, "type": 65534 } }, { "OFPTableFeaturePropExperimenter": { "data": [ 1 ], "exp_type": 1, "experimenter": 101, "length": 16, "type": 65534 } }, { "OFPTableFeaturePropExperimenter": { "data": [ 1, 2 ], "exp_type": 2, "experimenter": 101, "length": 20, "type": 65534 } } ], "table_id": 0 } }, { "OFPTableFeaturesStats": { "config": 0, "length": 1112, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x01", "properties": [ { "OFPTableFeaturePropInstructions": { "instruction_ids": [ { "OFPInstructionId": { "len": 4, "type": 1 } }, { "OFPInstructionId": { "len": 4, "type": 2 } }, { "OFPInstructionId": { "len": 4, "type": 3 } }, { "OFPInstructionId": { "len": 4, "type": 4 } }, { "OFPInstructionId": { "len": 4, "type": 5 } }, { "OFPInstructionId": { "len": 4, "type": 6 } } ], "length": 28, "type": 0 } }, { "OFPTableFeaturePropNextTables": { "length": 257, "table_ids": [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254 ], "type": 2 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 4 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 6 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 8 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 10 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 12 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 14 } } ], "table_id": 1 } }, { "OFPTableFeaturesStats": { "config": 0, "length": 1104, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x02", "properties": [ { "OFPTableFeaturePropInstructions": { "instruction_ids": [ { "OFPInstructionId": { "len": 4, "type": 1 } }, { "OFPInstructionId": { "len": 4, "type": 2 } }, { "OFPInstructionId": { "len": 4, "type": 3 } }, { "OFPInstructionId": { "len": 4, "type": 4 } }, { "OFPInstructionId": { "len": 4, "type": 5 } }, { "OFPInstructionId": { "len": 4, "type": 6 } } ], "length": 28, "type": 0 } }, { "OFPTableFeaturePropNextTables": { "length": 256, "table_ids": [ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254 ], "type": 2 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 4 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 6 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 8 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 10 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 12 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 14 } } ], "table_id": 2 } }, { "OFPTableFeaturesStats": { "config": 0, "length": 1104, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x03", "properties": [ { "OFPTableFeaturePropInstructions": { "instruction_ids": [ { "OFPInstructionId": { "len": 4, "type": 1 } }, { "OFPInstructionId": { "len": 4, "type": 2 } }, { "OFPInstructionId": { "len": 4, "type": 3 } }, { "OFPInstructionId": { "len": 4, "type": 4 } }, { "OFPInstructionId": { "len": 4, "type": 5 } }, { "OFPInstructionId": { "len": 4, "type": 6 } } ], "length": 28, "type": 0 } }, { "OFPTableFeaturePropNextTables": { "length": 255, "table_ids": [ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254 ], "type": 2 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 4 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 6 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 8 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 10 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 12 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 14 } } ], "table_id": 3 } }, { "OFPTableFeaturesStats": { "config": 0, "length": 1104, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x04", "properties": [ { "OFPTableFeaturePropInstructions": { "instruction_ids": [ { "OFPInstructionId": { "len": 4, "type": 1 } }, { "OFPInstructionId": { "len": 4, "type": 2 } }, { "OFPInstructionId": { "len": 4, "type": 3 } }, { "OFPInstructionId": { "len": 4, "type": 4 } }, { "OFPInstructionId": { "len": 4, "type": 5 } }, { "OFPInstructionId": { "len": 4, "type": 6 } } ], "length": 28, "type": 0 } }, { "OFPTableFeaturePropNextTables": { "length": 254, "table_ids": [ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254 ], "type": 2 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 4 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 6 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 8 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 10 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 12 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 14 } } ], "table_id": 4 } }, { "OFPTableFeaturesStats": { "config": 0, "length": 1104, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x05", "properties": [ { "OFPTableFeaturePropInstructions": { "instruction_ids": [ { "OFPInstructionId": { "len": 4, "type": 1 } }, { "OFPInstructionId": { "len": 4, "type": 2 } }, { "OFPInstructionId": { "len": 4, "type": 3 } }, { "OFPInstructionId": { "len": 4, "type": 4 } }, { "OFPInstructionId": { "len": 4, "type": 5 } }, { "OFPInstructionId": { "len": 4, "type": 6 } } ], "length": 28, "type": 0 } }, { "OFPTableFeaturePropNextTables": { "length": 253, "table_ids": [ 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254 ], "type": 2 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 4 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 6 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 8 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 10 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 12 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 14 } } ], "table_id": 5 } }, { "OFPTableFeaturesStats": { "config": 0, "length": 1104, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x06", "properties": [ { "OFPTableFeaturePropInstructions": { "instruction_ids": [ { "OFPInstructionId": { "len": 4, "type": 1 } }, { "OFPInstructionId": { "len": 4, "type": 2 } }, { "OFPInstructionId": { "len": 4, "type": 3 } }, { "OFPInstructionId": { "len": 4, "type": 4 } }, { "OFPInstructionId": { "len": 4, "type": 5 } }, { "OFPInstructionId": { "len": 4, "type": 6 } } ], "length": 28, "type": 0 } }, { "OFPTableFeaturePropNextTables": { "length": 252, "table_ids": [ 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254 ], "type": 2 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 4 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 6 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 8 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 10 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 12 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 14 } } ], "table_id": 6 } }, { "OFPTableFeaturesStats": { "config": 0, "length": 1104, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x07", "properties": [ { "OFPTableFeaturePropInstructions": { "instruction_ids": [ { "OFPInstructionId": { "len": 4, "type": 1 } }, { "OFPInstructionId": { "len": 4, "type": 2 } }, { "OFPInstructionId": { "len": 4, "type": 3 } }, { "OFPInstructionId": { "len": 4, "type": 4 } }, { "OFPInstructionId": { "len": 4, "type": 5 } }, { "OFPInstructionId": { "len": 4, "type": 6 } } ], "length": 28, "type": 0 } }, { "OFPTableFeaturePropNextTables": { "length": 251, "table_ids": [ 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254 ], "type": 2 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 4 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 6 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 8 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 10 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 12 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 14 } } ], "table_id": 7 } }, { "OFPTableFeaturesStats": { "config": 0, "length": 1104, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x08", "properties": [ { "OFPTableFeaturePropInstructions": { "instruction_ids": [ { "OFPInstructionId": { "len": 4, "type": 1 } }, { "OFPInstructionId": { "len": 4, "type": 2 } }, { "OFPInstructionId": { "len": 4, "type": 3 } }, { "OFPInstructionId": { "len": 4, "type": 4 } }, { "OFPInstructionId": { "len": 4, "type": 5 } }, { "OFPInstructionId": { "len": 4, "type": 6 } } ], "length": 28, "type": 0 } }, { "OFPTableFeaturePropNextTables": { "length": 250, "table_ids": [ 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254 ], "type": 2 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 4 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 6 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 8 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 10 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 12 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 14 } } ], "table_id": 8 } }, { "OFPTableFeaturesStats": { "config": 0, "length": 1104, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x09", "properties": [ { "OFPTableFeaturePropInstructions": { "instruction_ids": [ { "OFPInstructionId": { "len": 4, "type": 1 } }, { "OFPInstructionId": { "len": 4, "type": 2 } }, { "OFPInstructionId": { "len": 4, "type": 3 } }, { "OFPInstructionId": { "len": 4, "type": 4 } }, { "OFPInstructionId": { "len": 4, "type": 5 } }, { "OFPInstructionId": { "len": 4, "type": 6 } } ], "length": 28, "type": 0 } }, { "OFPTableFeaturePropNextTables": { "length": 249, "table_ids": [ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254 ], "type": 2 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 4 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 6 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 8 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 10 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 12 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 14 } } ], "table_id": 9 } } ], "flags": 1, "type": 12 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-56-ofp_table_features_reply.packet.json0000664000175000017500000223554200000000000031434 0ustar00zuulzuul00000000000000{ "OFPTableFeaturesStatsReply": { "body": [ { "OFPTableFeaturesStats": { "config": 0, "length": 1168, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "\u79c1\u306e\u30c6\u30fc\u30d6\u30eb", "properties": [ { "OFPTableFeaturePropInstructions": { "instruction_ids": [ { "OFPInstructionId": { "len": 4, "type": 1 } }, { "OFPInstructionId": { "len": 4, "type": 2 } }, { "OFPInstructionId": { "len": 4, "type": 3 } }, { "OFPInstructionId": { "len": 4, "type": 4 } }, { "OFPInstructionId": { "len": 4, "type": 5 } }, { "OFPInstructionId": { "len": 4, "type": 6 } } ], "length": 28, "type": 0 } }, { "OFPTableFeaturePropNextTables": { "length": 258, "table_ids": [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254 ], "type": 2 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 4 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 6 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 8 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 10 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 12 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 14 } }, { "OFPTableFeaturePropExperimenter": { "data": [], "exp_type": 0, "experimenter": 101, "length": 12, "type": 65534 } }, { "OFPTableFeaturePropExperimenter": { "data": [ 1 ], "exp_type": 1, "experimenter": 101, "length": 16, "type": 65534 } }, { "OFPTableFeaturePropExperimenter": { "data": [ 1, 2 ], "exp_type": 2, "experimenter": 101, "length": 20, "type": 65534 } } ], "table_id": 0 } }, { "OFPTableFeaturesStats": { "config": 0, "length": 1112, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x01", "properties": [ { "OFPTableFeaturePropInstructions": { "instruction_ids": [ { "OFPInstructionId": { "len": 4, "type": 1 } }, { "OFPInstructionId": { "len": 4, "type": 2 } }, { "OFPInstructionId": { "len": 4, "type": 3 } }, { "OFPInstructionId": { "len": 4, "type": 4 } }, { "OFPInstructionId": { "len": 4, "type": 5 } }, { "OFPInstructionId": { "len": 4, "type": 6 } } ], "length": 28, "type": 0 } }, { "OFPTableFeaturePropNextTables": { "length": 257, "table_ids": [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254 ], "type": 2 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 4 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 6 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 8 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 10 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 12 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 14 } } ], "table_id": 1 } }, { "OFPTableFeaturesStats": { "config": 0, "length": 1104, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x02", "properties": [ { "OFPTableFeaturePropInstructions": { "instruction_ids": [ { "OFPInstructionId": { "len": 4, "type": 1 } }, { "OFPInstructionId": { "len": 4, "type": 2 } }, { "OFPInstructionId": { "len": 4, "type": 3 } }, { "OFPInstructionId": { "len": 4, "type": 4 } }, { "OFPInstructionId": { "len": 4, "type": 5 } }, { "OFPInstructionId": { "len": 4, "type": 6 } } ], "length": 28, "type": 0 } }, { "OFPTableFeaturePropNextTables": { "length": 256, "table_ids": [ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254 ], "type": 2 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 4 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 6 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 8 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 10 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 12 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 14 } } ], "table_id": 2 } }, { "OFPTableFeaturesStats": { "config": 0, "length": 1104, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x03", "properties": [ { "OFPTableFeaturePropInstructions": { "instruction_ids": [ { "OFPInstructionId": { "len": 4, "type": 1 } }, { "OFPInstructionId": { "len": 4, "type": 2 } }, { "OFPInstructionId": { "len": 4, "type": 3 } }, { "OFPInstructionId": { "len": 4, "type": 4 } }, { "OFPInstructionId": { "len": 4, "type": 5 } }, { "OFPInstructionId": { "len": 4, "type": 6 } } ], "length": 28, "type": 0 } }, { "OFPTableFeaturePropNextTables": { "length": 255, "table_ids": [ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254 ], "type": 2 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 4 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 6 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 8 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 10 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 12 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 14 } } ], "table_id": 3 } }, { "OFPTableFeaturesStats": { "config": 0, "length": 1104, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x04", "properties": [ { "OFPTableFeaturePropInstructions": { "instruction_ids": [ { "OFPInstructionId": { "len": 4, "type": 1 } }, { "OFPInstructionId": { "len": 4, "type": 2 } }, { "OFPInstructionId": { "len": 4, "type": 3 } }, { "OFPInstructionId": { "len": 4, "type": 4 } }, { "OFPInstructionId": { "len": 4, "type": 5 } }, { "OFPInstructionId": { "len": 4, "type": 6 } } ], "length": 28, "type": 0 } }, { "OFPTableFeaturePropNextTables": { "length": 254, "table_ids": [ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254 ], "type": 2 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 4 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 6 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 8 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 10 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 12 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 14 } } ], "table_id": 4 } }, { "OFPTableFeaturesStats": { "config": 0, "length": 1104, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x05", "properties": [ { "OFPTableFeaturePropInstructions": { "instruction_ids": [ { "OFPInstructionId": { "len": 4, "type": 1 } }, { "OFPInstructionId": { "len": 4, "type": 2 } }, { "OFPInstructionId": { "len": 4, "type": 3 } }, { "OFPInstructionId": { "len": 4, "type": 4 } }, { "OFPInstructionId": { "len": 4, "type": 5 } }, { "OFPInstructionId": { "len": 4, "type": 6 } } ], "length": 28, "type": 0 } }, { "OFPTableFeaturePropNextTables": { "length": 253, "table_ids": [ 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254 ], "type": 2 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 4 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 6 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 8 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 10 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 12 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 14 } } ], "table_id": 5 } }, { "OFPTableFeaturesStats": { "config": 0, "length": 1104, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x06", "properties": [ { "OFPTableFeaturePropInstructions": { "instruction_ids": [ { "OFPInstructionId": { "len": 4, "type": 1 } }, { "OFPInstructionId": { "len": 4, "type": 2 } }, { "OFPInstructionId": { "len": 4, "type": 3 } }, { "OFPInstructionId": { "len": 4, "type": 4 } }, { "OFPInstructionId": { "len": 4, "type": 5 } }, { "OFPInstructionId": { "len": 4, "type": 6 } } ], "length": 28, "type": 0 } }, { "OFPTableFeaturePropNextTables": { "length": 252, "table_ids": [ 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254 ], "type": 2 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 4 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 6 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 8 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 10 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 12 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 14 } } ], "table_id": 6 } }, { "OFPTableFeaturesStats": { "config": 0, "length": 1104, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x07", "properties": [ { "OFPTableFeaturePropInstructions": { "instruction_ids": [ { "OFPInstructionId": { "len": 4, "type": 1 } }, { "OFPInstructionId": { "len": 4, "type": 2 } }, { "OFPInstructionId": { "len": 4, "type": 3 } }, { "OFPInstructionId": { "len": 4, "type": 4 } }, { "OFPInstructionId": { "len": 4, "type": 5 } }, { "OFPInstructionId": { "len": 4, "type": 6 } } ], "length": 28, "type": 0 } }, { "OFPTableFeaturePropNextTables": { "length": 251, "table_ids": [ 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254 ], "type": 2 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 4 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 6 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 8 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 10 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 12 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 14 } } ], "table_id": 7 } }, { "OFPTableFeaturesStats": { "config": 0, "length": 1104, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x08", "properties": [ { "OFPTableFeaturePropInstructions": { "instruction_ids": [ { "OFPInstructionId": { "len": 4, "type": 1 } }, { "OFPInstructionId": { "len": 4, "type": 2 } }, { "OFPInstructionId": { "len": 4, "type": 3 } }, { "OFPInstructionId": { "len": 4, "type": 4 } }, { "OFPInstructionId": { "len": 4, "type": 5 } }, { "OFPInstructionId": { "len": 4, "type": 6 } } ], "length": 28, "type": 0 } }, { "OFPTableFeaturePropNextTables": { "length": 250, "table_ids": [ 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254 ], "type": 2 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 4 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 6 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 8 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 10 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 12 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 14 } } ], "table_id": 8 } }, { "OFPTableFeaturesStats": { "config": 0, "length": 1104, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x09", "properties": [ { "OFPTableFeaturePropInstructions": { "instruction_ids": [ { "OFPInstructionId": { "len": 4, "type": 1 } }, { "OFPInstructionId": { "len": 4, "type": 2 } }, { "OFPInstructionId": { "len": 4, "type": 3 } }, { "OFPInstructionId": { "len": 4, "type": 4 } }, { "OFPInstructionId": { "len": 4, "type": 5 } }, { "OFPInstructionId": { "len": 4, "type": 6 } } ], "length": 28, "type": 0 } }, { "OFPTableFeaturePropNextTables": { "length": 249, "table_ids": [ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254 ], "type": 2 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 4 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 6 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 8 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 10 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 12 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 14 } } ], "table_id": 9 } } ], "flags": 1, "type": 12 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-57-ofp_group_stats_request.packet.json0000664000175000017500000000014600000000000031343 0ustar00zuulzuul00000000000000{ "OFPGroupStatsRequest": { "flags": 0, "group_id": 4294967292, "type": 6 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-58-ofp_group_stats_reply.packet.json0000664000175000017500000000120500000000000031004 0ustar00zuulzuul00000000000000{ "OFPGroupStatsReply": { "body": [ { "OFPGroupStats": { "bucket_stats": [ { "OFPBucketCounter": { "byte_count": 2345, "packet_count": 234 } } ], "byte_count": 12345, "duration_nsec": 609036000, "duration_sec": 9, "group_id": 1, "length": 56, "packet_count": 123, "ref_count": 2 } } ], "flags": 0, "type": 6 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-59-ofp_packet_in.packet.json0000664000175000017500000002120300000000000027155 0ustar00zuulzuul00000000000000{ "OFPPacketIn": { "buffer_id": 4026531840, "cookie": 283686884868096, "data": "", "match": { "OFPMatch": { "length": 351, "oxm_fields": [ { "OXMTlv": { "field": "in_port", "mask": null, "value": 84281096 } }, { "OXMTlv": { "field": "in_phy_port", "mask": null, "value": 16909060 } }, { "OXMTlv": { "field": "metadata", "mask": null, "value": 283686952306183 } }, { "OXMTlv": { "field": "eth_type", "mask": null, "value": 2054 } }, { "OXMTlv": { "field": "eth_dst", "mask": null, "value": "ff:ff:ff:ff:ff:ff" } }, { "OXMTlv": { "field": "eth_src", "mask": null, "value": "f2:0b:a4:7d:f8:ea" } }, { "OXMTlv": { "field": "vlan_vid", "mask": null, "value": 999 } }, { "OXMTlv": { "field": "ip_dscp", "mask": null, "value": 9 } }, { "OXMTlv": { "field": "ip_ecn", "mask": null, "value": 3 } }, { "OXMTlv": { "field": "ip_proto", "mask": null, "value": 99 } }, { "OXMTlv": { "field": "ipv4_src", "mask": null, "value": "1.2.3.4" } }, { "OXMTlv": { "field": "ipv4_dst", "mask": null, "value": "1.2.3.4" } }, { "OXMTlv": { "field": "tcp_src", "mask": null, "value": 8080 } }, { "OXMTlv": { "field": "tcp_dst", "mask": null, "value": 18080 } }, { "OXMTlv": { "field": "udp_src", "mask": null, "value": 28080 } }, { "OXMTlv": { "field": "udp_dst", "mask": null, "value": 55936 } }, { "OXMTlv": { "field": "sctp_src", "mask": null, "value": 48080 } }, { "OXMTlv": { "field": "sctp_dst", "mask": null, "value": 59328 } }, { "OXMTlv": { "field": "icmpv4_type", "mask": null, "value": 100 } }, { "OXMTlv": { "field": "icmpv4_code", "mask": null, "value": 101 } }, { "OXMTlv": { "field": "arp_op", "mask": null, "value": 1 } }, { "OXMTlv": { "field": "arp_spa", "mask": null, "value": "10.0.0.1" } }, { "OXMTlv": { "field": "arp_tpa", "mask": null, "value": "10.0.0.3" } }, { "OXMTlv": { "field": "arp_sha", "mask": null, "value": "f2:0b:a4:7d:f8:ea" } }, { "OXMTlv": { "field": "arp_tha", "mask": null, "value": "00:00:00:00:00:00" } }, { "OXMTlv": { "field": "ipv6_src", "mask": null, "value": "fe80::f00b:a4ff:fe48:28a5" } }, { "OXMTlv": { "field": "ipv6_dst", "mask": null, "value": "fe80::f00b:a4ff:fe05:b7dc" } }, { "OXMTlv": { "field": "ipv6_flabel", "mask": null, "value": 541473 } }, { "OXMTlv": { "field": "icmpv6_type", "mask": null, "value": 200 } }, { "OXMTlv": { "field": "icmpv6_code", "mask": null, "value": 201 } }, { "OXMTlv": { "field": "ipv6_nd_target", "mask": null, "value": "fe80::a60:6eff:fe7f:74e7" } }, { "OXMTlv": { "field": "ipv6_nd_sll", "mask": null, "value": "00:00:00:00:02:9a" } }, { "OXMTlv": { "field": "ipv6_nd_tll", "mask": null, "value": "00:00:00:00:02:2b" } }, { "OXMTlv": { "field": "mpls_label", "mask": null, "value": 624485 } }, { "OXMTlv": { "field": "mpls_tc", "mask": null, "value": 5 } }, { "OXMTlv": { "field": "mpls_bos", "mask": null, "value": 1 } }, { "OXMTlv": { "field": "pbb_isid", "mask": null, "value": 11259375 } }, { "OXMTlv": { "field": "tunnel_id", "mask": null, "value": 651061555542690057 } }, { "OXMTlv": { "field": "ipv6_exthdr", "mask": null, "value": 500 } }, { "OXMTlv": { "field": "pbb_uca", "mask": null, "value": 1 } }, { "OXMTlv": { "field": "tun_ipv4_src", "mask": null, "value": "1.2.3.4" } }, { "OXMTlv": { "field": "tun_ipv4_dst", "mask": null, "value": "1.2.3.4" } } ], "type": 1 } }, "reason": 0, "table_id": 200, "total_len": 0 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-6-ofp_features_reply.packet.json0000664000175000017500000000024700000000000030166 0ustar00zuulzuul00000000000000{ "OFPSwitchFeatures": { "auxiliary_id": 99, "capabilities": 79, "datapath_id": 9210263729383, "n_buffers": 0, "n_tables": 255 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-60-ofp_flow_mod.packet.json0000664000175000017500000002142000000000000027017 0ustar00zuulzuul00000000000000{ "OFPFlowMod": { "buffer_id": 65535, "command": 0, "cookie": 0, "cookie_mask": 0, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "instructions": [], "match": { "OFPMatch": { "length": 351, "oxm_fields": [ { "OXMTlv": { "field": "in_port", "mask": null, "value": 84281096 } }, { "OXMTlv": { "field": "in_phy_port", "mask": null, "value": 16909060 } }, { "OXMTlv": { "field": "metadata", "mask": null, "value": 283686952306183 } }, { "OXMTlv": { "field": "eth_type", "mask": null, "value": 2054 } }, { "OXMTlv": { "field": "eth_dst", "mask": null, "value": "ff:ff:ff:ff:ff:ff" } }, { "OXMTlv": { "field": "eth_src", "mask": null, "value": "f2:0b:a4:7d:f8:ea" } }, { "OXMTlv": { "field": "vlan_vid", "mask": null, "value": 999 } }, { "OXMTlv": { "field": "ip_dscp", "mask": null, "value": 9 } }, { "OXMTlv": { "field": "ip_ecn", "mask": null, "value": 3 } }, { "OXMTlv": { "field": "ip_proto", "mask": null, "value": 99 } }, { "OXMTlv": { "field": "ipv4_src", "mask": null, "value": "1.2.3.4" } }, { "OXMTlv": { "field": "ipv4_dst", "mask": null, "value": "1.2.3.4" } }, { "OXMTlv": { "field": "tcp_src", "mask": null, "value": 8080 } }, { "OXMTlv": { "field": "tcp_dst", "mask": null, "value": 18080 } }, { "OXMTlv": { "field": "udp_src", "mask": null, "value": 28080 } }, { "OXMTlv": { "field": "udp_dst", "mask": null, "value": 55936 } }, { "OXMTlv": { "field": "sctp_src", "mask": null, "value": 48080 } }, { "OXMTlv": { "field": "sctp_dst", "mask": null, "value": 59328 } }, { "OXMTlv": { "field": "icmpv4_type", "mask": null, "value": 100 } }, { "OXMTlv": { "field": "icmpv4_code", "mask": null, "value": 101 } }, { "OXMTlv": { "field": "arp_op", "mask": null, "value": 1 } }, { "OXMTlv": { "field": "arp_spa", "mask": null, "value": "10.0.0.1" } }, { "OXMTlv": { "field": "arp_tpa", "mask": null, "value": "10.0.0.3" } }, { "OXMTlv": { "field": "arp_sha", "mask": null, "value": "f2:0b:a4:7d:f8:ea" } }, { "OXMTlv": { "field": "arp_tha", "mask": null, "value": "00:00:00:00:00:00" } }, { "OXMTlv": { "field": "ipv6_src", "mask": null, "value": "fe80::f00b:a4ff:fe48:28a5" } }, { "OXMTlv": { "field": "ipv6_dst", "mask": null, "value": "fe80::f00b:a4ff:fe05:b7dc" } }, { "OXMTlv": { "field": "ipv6_flabel", "mask": null, "value": 541473 } }, { "OXMTlv": { "field": "icmpv6_type", "mask": null, "value": 200 } }, { "OXMTlv": { "field": "icmpv6_code", "mask": null, "value": 201 } }, { "OXMTlv": { "field": "ipv6_nd_target", "mask": null, "value": "fe80::a60:6eff:fe7f:74e7" } }, { "OXMTlv": { "field": "ipv6_nd_sll", "mask": null, "value": "00:00:00:00:02:9a" } }, { "OXMTlv": { "field": "ipv6_nd_tll", "mask": null, "value": "00:00:00:00:02:2b" } }, { "OXMTlv": { "field": "mpls_label", "mask": null, "value": 624485 } }, { "OXMTlv": { "field": "mpls_tc", "mask": null, "value": 5 } }, { "OXMTlv": { "field": "mpls_bos", "mask": null, "value": 1 } }, { "OXMTlv": { "field": "pbb_isid", "mask": null, "value": 11259375 } }, { "OXMTlv": { "field": "tunnel_id", "mask": null, "value": 651061555542690057 } }, { "OXMTlv": { "field": "ipv6_exthdr", "mask": null, "value": 500 } }, { "OXMTlv": { "field": "pbb_uca", "mask": null, "value": 1 } }, { "OXMTlv": { "field": "tun_ipv4_src", "mask": null, "value": "1.2.3.4" } }, { "OXMTlv": { "field": "tun_ipv4_dst", "mask": null, "value": "1.2.3.4" } } ], "type": 1 } }, "out_group": 4294967295, "out_port": 4294967295, "priority": 123, "table_id": 1 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-61-ofp_experimenter_request.packet.json0000664000175000017500000000026100000000000031471 0ustar00zuulzuul00000000000000{ "OFPExperimenterStatsRequest": { "data": "aG9nZWhvZ2U=", "exp_type": 3405678728, "experimenter": 3735928495, "flags": 0, "type": 65535 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-62-ofp_experimenter_reply.packet.json0000664000175000017500000000042700000000000031141 0ustar00zuulzuul00000000000000{ "OFPExperimenterStatsReply": { "body": { "OFPExperimenterMultipart": { "data": "dGVzdGRhdGE5OTk5OTk5OQ==", "exp_type": 3405674359, "experimenter": 3735928495 } }, "flags": 0, "type": 65535 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-63-onf_flow_monitor_request.packet.json0000664000175000017500000002765400000000000031517 0ustar00zuulzuul00000000000000{ "ONFFlowMonitorStatsRequest": { "body": [ { "ONFFlowMonitorRequest": { "flags": 15, "id": 100000000, "match": { "OFPMatch": { "length": 4, "oxm_fields": [], "type": 1 } }, "match_len": 0, "out_port": 22, "table_id": 33 } }, { "ONFFlowMonitorRequest": { "flags": 49, "id": 999, "match": { "OFPMatch": { "length": 351, "oxm_fields": [ { "OXMTlv": { "field": "in_port", "mask": null, "value": 84281096 } }, { "OXMTlv": { "field": "in_phy_port", "mask": null, "value": 16909060 } }, { "OXMTlv": { "field": "metadata", "mask": null, "value": 283686952306183 } }, { "OXMTlv": { "field": "eth_type", "mask": null, "value": 2054 } }, { "OXMTlv": { "field": "eth_dst", "mask": null, "value": "ff:ff:ff:ff:ff:ff" } }, { "OXMTlv": { "field": "eth_src", "mask": null, "value": "f2:0b:a4:7d:f8:ea" } }, { "OXMTlv": { "field": "vlan_vid", "mask": null, "value": 999 } }, { "OXMTlv": { "field": "ip_dscp", "mask": null, "value": 9 } }, { "OXMTlv": { "field": "ip_ecn", "mask": null, "value": 3 } }, { "OXMTlv": { "field": "ip_proto", "mask": null, "value": 99 } }, { "OXMTlv": { "field": "ipv4_src", "mask": null, "value": "1.2.3.4" } }, { "OXMTlv": { "field": "ipv4_dst", "mask": null, "value": "1.2.3.4" } }, { "OXMTlv": { "field": "tcp_src", "mask": null, "value": 8080 } }, { "OXMTlv": { "field": "tcp_dst", "mask": null, "value": 18080 } }, { "OXMTlv": { "field": "udp_src", "mask": null, "value": 28080 } }, { "OXMTlv": { "field": "udp_dst", "mask": null, "value": 55936 } }, { "OXMTlv": { "field": "sctp_src", "mask": null, "value": 48080 } }, { "OXMTlv": { "field": "sctp_dst", "mask": null, "value": 59328 } }, { "OXMTlv": { "field": "icmpv4_type", "mask": null, "value": 100 } }, { "OXMTlv": { "field": "icmpv4_code", "mask": null, "value": 101 } }, { "OXMTlv": { "field": "arp_op", "mask": null, "value": 1 } }, { "OXMTlv": { "field": "arp_spa", "mask": null, "value": "10.0.0.1" } }, { "OXMTlv": { "field": "arp_tpa", "mask": null, "value": "10.0.0.3" } }, { "OXMTlv": { "field": "arp_sha", "mask": null, "value": "f2:0b:a4:7d:f8:ea" } }, { "OXMTlv": { "field": "arp_tha", "mask": null, "value": "00:00:00:00:00:00" } }, { "OXMTlv": { "field": "ipv6_src", "mask": null, "value": "fe80::f00b:a4ff:fe48:28a5" } }, { "OXMTlv": { "field": "ipv6_dst", "mask": null, "value": "fe80::f00b:a4ff:fe05:b7dc" } }, { "OXMTlv": { "field": "ipv6_flabel", "mask": null, "value": 541473 } }, { "OXMTlv": { "field": "icmpv6_type", "mask": null, "value": 200 } }, { "OXMTlv": { "field": "icmpv6_code", "mask": null, "value": 201 } }, { "OXMTlv": { "field": "ipv6_nd_target", "mask": null, "value": "fe80::a60:6eff:fe7f:74e7" } }, { "OXMTlv": { "field": "ipv6_nd_sll", "mask": null, "value": "00:00:00:00:02:9a" } }, { "OXMTlv": { "field": "ipv6_nd_tll", "mask": null, "value": "00:00:00:00:02:2b" } }, { "OXMTlv": { "field": "mpls_label", "mask": null, "value": 624485 } }, { "OXMTlv": { "field": "mpls_tc", "mask": null, "value": 5 } }, { "OXMTlv": { "field": "mpls_bos", "mask": null, "value": 1 } }, { "OXMTlv": { "field": "pbb_isid", "mask": null, "value": 11259375 } }, { "OXMTlv": { "field": "tunnel_id", "mask": null, "value": 651061555542690057 } }, { "OXMTlv": { "field": "ipv6_exthdr", "mask": null, "value": 500 } }, { "OXMTlv": { "field": "pbb_uca", "mask": null, "value": 1 } }, { "OXMTlv": { "field": "tun_ipv4_src", "mask": null, "value": "1.2.3.4" } }, { "OXMTlv": { "field": "tun_ipv4_dst", "mask": null, "value": "1.2.3.4" } } ], "type": 1 } }, "match_len": 347, "out_port": 4294967295, "table_id": 255 } } ], "exp_type": 1870, "experimenter": 1330529792, "flags": 0, "type": 65535 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-7-ofp_set_config.packet.json0000664000175000017500000000011300000000000027246 0ustar00zuulzuul00000000000000{ "OFPSetConfig": { "flags": 0, "miss_send_len": 128 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-8-ofp_get_config_request.packet.json0000664000175000017500000000004100000000000031003 0ustar00zuulzuul00000000000000{ "OFPGetConfigRequest": {} } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/4-9-ofp_get_config_reply.packet.json0000664000175000017500000000012000000000000030445 0ustar00zuulzuul00000000000000{ "OFPGetConfigReply": { "flags": 0, "miss_send_len": 128 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/lib-ofctl-ofp_group_stats_request.packet.json0000664000175000017500000000013500000000000032620 0ustar00zuulzuul00000000000000{ "OFPGroupStatsRequest": { "flags": 0, "group_id": 1, "type": 6 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/lib-ofctl-ofp_meter_config_request.packet.json0000664000175000017500000000014400000000000032707 0ustar00zuulzuul00000000000000{ "OFPMeterConfigStatsRequest": { "flags": 0, "meter_id": 1, "type": 10 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/lib-ofctl-ofp_meter_stats_request.packet.json0000664000175000017500000000013500000000000032600 0ustar00zuulzuul00000000000000{ "OFPMeterStatsRequest": { "flags": 0, "meter_id": 1, "type": 9 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/lib-ofctl-ofp_port_stats_request.packet.json0000664000175000017500000000013300000000000032446 0ustar00zuulzuul00000000000000{ "OFPPortStatsRequest": { "flags": 0, "port_no": 7, "type": 4 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/lib-ofctl-ofp_queue_get_config_request.packet.json0000664000175000017500000000010300000000000033551 0ustar00zuulzuul00000000000000{ "OFPQueueGetConfigRequest": { "port": 4294967295 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/lib-ofctl-ofp_queue_stats_request.packet1.json0000664000175000017500000000017200000000000032672 0ustar00zuulzuul00000000000000{ "OFPQueueStatsRequest": { "flags": 0, "port_no": 7, "queue_id": 4294967295, "type": 5 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/lib-ofctl-ofp_queue_stats_request.packet2.json0000664000175000017500000000016100000000000032671 0ustar00zuulzuul00000000000000{ "OFPQueueStatsRequest": { "flags": 0, "port_no": 7, "queue_id": 1, "type": 5 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/lib-ofctl-ofp_queue_stats_request.packet3.json0000664000175000017500000000017200000000000032674 0ustar00zuulzuul00000000000000{ "OFPQueueStatsRequest": { "flags": 0, "port_no": 4294967295, "queue_id": 1, "type": 5 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/lib-ofctl-ofp_table_features_request.packet.json0000664000175000017500000000014300000000000033232 0ustar00zuulzuul00000000000000{ "OFPTableFeaturesStatsRequest": { "body": [], "flags": 0, "type": 12 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/libofproto-OFP13-echo_reply.packet.json0000664000175000017500000000005700000000000031060 0ustar00zuulzuul00000000000000{ "OFPEchoReply": { "data": "" } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/libofproto-OFP13-echo_request.packet.json0000664000175000017500000000006100000000000031410 0ustar00zuulzuul00000000000000{ "OFPEchoRequest": { "data": "" } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/libofproto-OFP13-error_msg.packet.json0000664000175000017500000000013400000000000030722 0ustar00zuulzuul00000000000000{ "OFPErrorMsg": { "code": 6, "data": "BA4ACAAAAAA=", "type": 4 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/libofproto-OFP13-features_reply.packet.json0000664000175000017500000000023400000000000031755 0ustar00zuulzuul00000000000000{ "OFPSwitchFeatures": { "auxiliary_id": 0, "capabilities": 79, "datapath_id": 1, "n_buffers": 255, "n_tables": 255 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/libofproto-OFP13-flow_mod.packet.json0000664000175000017500000001370600000000000030542 0ustar00zuulzuul00000000000000{ "OFPFlowMod": { "buffer_id": 0, "command": 0, "cookie": 1311768467463790320, "cookie_mask": 18446744073709551615, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "instructions": [ { "OFPInstructionActions": { "actions": [ { "OFPActionPopVlan": { "len": 8, "type": 18 } }, { "OFPActionSetField": { "field": { "OXMTlv": { "field": "ipv4_dst", "mask": null, "value": "192.168.2.9" } }, "len": 16, "type": 25 } }, { "NXActionLearn": { "cookie": 0, "experimenter": 8992, "fin_hard_timeout": 0, "fin_idle_timeout": 0, "flags": 0, "hard_timeout": 300, "idle_timeout": 0, "len": 96, "priority": 1, "specs": [ { "NXFlowSpecMatch": { "dst": [ "vlan_vid", 0 ], "n_bits": 12, "src": [ "vlan_vid", 0 ] } }, { "NXFlowSpecMatch": { "dst": [ "eth_dst_nxm", 0 ], "n_bits": 48, "src": [ "eth_src_nxm", 0 ] } }, { "NXFlowSpecLoad": { "dst": [ "vlan_vid", 0 ], "n_bits": 12, "src": 0 } }, { "NXFlowSpecLoad": { "dst": [ "tunnel_id_nxm", 0 ], "n_bits": 64, "src": [ "tunnel_id_nxm", 0 ] } }, { "NXFlowSpecOutput": { "dst": "", "n_bits": 32, "src": [ "in_port", 0 ] } } ], "subtype": 16, "table_id": 99, "type": 65535 } } ], "len": 128, "type": 4 } }, { "OFPInstructionGotoTable": { "len": 8, "table_id": 100, "type": 1 } } ], "match": { "OFPMatch": { "length": 70, "oxm_fields": [ { "OXMTlv": { "field": "in_port", "mask": null, "value": 43981 } }, { "OXMTlv": { "field": "eth_dst", "mask": null, "value": "aa:bb:cc:99:88:77" } }, { "OXMTlv": { "field": "eth_type", "mask": null, "value": 2048 } }, { "OXMTlv": { "field": "vlan_vid", "mask": null, "value": 5095 } }, { "OXMTlv": { "field": "ipv4_dst", "mask": null, "value": "192.168.2.1" } }, { "OXMTlv": { "field": "tunnel_id", "mask": null, "value": 50000 } }, { "OXMTlv": { "field": "tun_ipv4_src", "mask": null, "value": "192.168.2.3" } }, { "OXMTlv": { "field": "tun_ipv4_dst", "mask": null, "value": "192.168.2.4" } } ], "type": 1 } }, "out_group": 0, "out_port": 0, "priority": 0, "table_id": 2 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/libofproto-OFP13-flow_mod.packet.truncated64.json0000664000175000017500000000143300000000000032676 0ustar00zuulzuul00000000000000{ "OFPTruncatedMessage": { "OFPFlowMod": { "buffer_id": 0, "command": 0, "cookie": 1311768467463790320, "cookie_mask": 18446744073709551615, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "instructions": [], "match": { "OFPMatch": { "length": 70, "oxm_fields": [ { "OXMTlv": { "field": "in_port", "mask": null, "value": 43981 } } ], "type": 1 } }, "out_group": 0, "out_port": 0, "priority": 0, "table_id": 2 } } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/libofproto-OFP13-flow_mod_conjunction.packet.json0000664000175000017500000000515400000000000033151 0ustar00zuulzuul00000000000000{ "OFPFlowMod": { "buffer_id": 0, "command": 0, "cookie": 1311768467463790320, "cookie_mask": 18446744073709551615, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "instructions": [ { "OFPInstructionActions": { "actions": [ { "NXActionConjunction": { "clause": 1, "experimenter": 8992, "id": 11259375, "len": 16, "n_clauses": 2, "subtype": 34, "type": 65535 } } ], "len": 24, "type": 4 } } ], "match": { "OFPMatch": { "length": 70, "oxm_fields": [ { "OXMTlv": { "field": "in_port", "mask": null, "value": 43981 } }, { "OXMTlv": { "field": "eth_dst", "mask": null, "value": "aa:bb:cc:99:88:77" } }, { "OXMTlv": { "field": "eth_type", "mask": null, "value": 2048 } }, { "OXMTlv": { "field": "vlan_vid", "mask": null, "value": 5095 } }, { "OXMTlv": { "field": "ipv4_dst", "mask": null, "value": "192.168.2.1" } }, { "OXMTlv": { "field": "tunnel_id", "mask": null, "value": 50000 } }, { "OXMTlv": { "field": "tun_ipv4_src", "mask": null, "value": "192.168.2.3" } }, { "OXMTlv": { "field": "tun_ipv4_dst", "mask": null, "value": "192.168.2.4" } } ], "type": 1 } }, "out_group": 0, "out_port": 0, "priority": 0, "table_id": 4 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/libofproto-OFP13-flow_mod_match_conj.packet.json0000664000175000017500000000316000000000000032720 0ustar00zuulzuul00000000000000{ "OFPFlowMod": { "buffer_id": 0, "command": 0, "cookie": 1311768467463790320, "cookie_mask": 18446744073709551615, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "instructions": [ { "OFPInstructionActions": { "actions": [ { "OFPActionPopVlan": { "len": 8, "type": 18 } }, { "OFPActionSetField": { "field": { "OXMTlv": { "field": "ipv4_dst", "mask": null, "value": "192.168.2.9" } }, "len": 16, "type": 25 } } ], "len": 32, "type": 4 } }, { "OFPInstructionGotoTable": { "len": 8, "table_id": 100, "type": 1 } } ], "match": { "OFPMatch": { "length": 12, "oxm_fields": [ { "OXMTlv": { "field": "conj_id", "mask": null, "value": 11259375 } } ], "type": 1 } }, "out_group": 0, "out_port": 0, "priority": 0, "table_id": 3 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/libofproto-OFP13-flow_removed.packet.json0000664000175000017500000000402500000000000031416 0ustar00zuulzuul00000000000000{ "OFPFlowRemoved": { "byte_count": 100, "cookie": 1311768467463790320, "duration_nsec": 500, "duration_sec": 600, "hard_timeout": 300, "idle_timeout": 400, "match": { "OFPMatch": { "length": 70, "oxm_fields": [ { "OXMTlv": { "field": "in_port", "mask": null, "value": 43981 } }, { "OXMTlv": { "field": "eth_dst", "mask": null, "value": "aa:bb:cc:99:88:77" } }, { "OXMTlv": { "field": "eth_type", "mask": null, "value": 2048 } }, { "OXMTlv": { "field": "vlan_vid", "mask": null, "value": 5095 } }, { "OXMTlv": { "field": "ipv4_dst", "mask": null, "value": "192.168.2.1" } }, { "OXMTlv": { "field": "tunnel_id", "mask": null, "value": 50000 } }, { "OXMTlv": { "field": "tun_ipv4_src", "mask": null, "value": "192.168.2.3" } }, { "OXMTlv": { "field": "tun_ipv4_dst", "mask": null, "value": "192.168.2.4" } } ], "type": 1 } }, "packet_count": 200, "priority": 100, "reason": 0, "table_id": 1 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/libofproto-OFP13-get_config_reply.packet.json0000664000175000017500000000012000000000000032235 0ustar00zuulzuul00000000000000{ "OFPGetConfigReply": { "flags": 0, "miss_send_len": 128 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/libofproto-OFP13-hello.packet.json0000664000175000017500000000037500000000000030035 0ustar00zuulzuul00000000000000{ "OFPHello": { "elements": [ { "OFPHelloElemVersionBitmap": { "length": 8, "type": 1, "versions": [ 4 ] } } ] } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/libofproto-OFP13-meter_mod.packet.json0000664000175000017500000000101100000000000030671 0ustar00zuulzuul00000000000000{ "OFPMeterMod": { "bands": [ { "OFPMeterBandDrop": { "burst_size": 10, "len": 16, "rate": 1000, "type": 1 } }, { "OFPMeterBandDscpRemark": { "burst_size": 10, "len": 16, "prec_level": 1, "rate": 1000, "type": 2 } } ], "command": 0, "flags": 14, "meter_id": 100 } } ././@PaxHeader0000000000000000000000000000021400000000000011452 xustar0000000000000000118 path=os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/libofproto-OFP13-ofp_packet_out_packet_library.packet.json 22 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/libofproto-OFP13-ofp_packet_out_packet_library.pac0000664000175000017500000000324300000000000033330 0ustar00zuulzuul00000000000000{ "OFPPacketOut": { "actions": [ { "OFPActionOutput": { "len": 16, "max_len": 65535, "port": 4294967292, "type": 0 } } ], "actions_len": 16, "buffer_id": 4294967295, "data": { "Packet": { "protocols": [ { "ethernet": { "dst": "f2:0b:a4:d0:3f:70", "ethertype": 2048, "src": "f2:0b:a4:7d:f8:ea" } }, { "ipv4": { "csum": 44939, "dst": "10.0.0.2", "flags": 0, "header_length": 5, "identification": 63514, "offset": 0, "option": null, "proto": 1, "src": "10.0.0.1", "tos": 0, "total_length": 84, "ttl": 255, "version": 4 } }, { "icmp": { "code": 0, "csum": 520, "data": { "echo": { "data": "MdYCAAAAAACrjS0xAAAAABAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vAAAAAAAAAAA=", "id": 63328, "seq": 0 } }, "type": 8 } } ] } }, "in_port": 4294967293 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/libofproto-OFP13-packet_in.packet.json0000664000175000017500000000215200000000000030662 0ustar00zuulzuul00000000000000{ "OFPPacketIn": { "buffer_id": 200, "cookie": 0, "data": "aG9nZQ==", "match": { "OFPMatch": { "length": 40, "oxm_fields": [ { "OXMTlv": { "field": "in_port", "mask": null, "value": 43981 } }, { "OXMTlv": { "field": "tunnel_id", "mask": null, "value": 50000 } }, { "OXMTlv": { "field": "tun_ipv4_src", "mask": null, "value": "192.168.2.3" } }, { "OXMTlv": { "field": "tun_ipv4_dst", "mask": null, "value": "192.168.2.4" } } ], "type": 1 } }, "reason": 0, "table_id": 100, "total_len": 1000 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/libofproto-OFP13-port_mod.packet.json0000664000175000017500000000022300000000000030545 0ustar00zuulzuul00000000000000{ "OFPPortMod": { "advertise": 10248, "config": 1, "hw_addr": "aa:bb:cc:99:88:77", "mask": 1, "port_no": 1 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/libofproto-OFP13-port_status.packet.json0000664000175000017500000000066600000000000031324 0ustar00zuulzuul00000000000000{ "OFPPortStatus": { "desc": { "OFPPort": { "advertised": 10248, "config": 0, "curr": 10248, "curr_speed": 50000, "hw_addr": "ff:ff:ff:ff:ff:ff", "max_speed": 100000, "name": "eth0", "peer": 10248, "port_no": 1, "state": 4, "supported": 10248 } }, "reason": 2 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/libofproto-OFP13-set_config.packet.json0000664000175000017500000000011300000000000031040 0ustar00zuulzuul00000000000000{ "OFPSetConfig": { "flags": 0, "miss_send_len": 128 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/libofproto-OFP13-table_mod.packet.json0000664000175000017500000000010600000000000030650 0ustar00zuulzuul00000000000000{ "OFPTableMod": { "config": 0, "table_id": 255 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/ovs-ofctl-of13-action_conjunction.packet.json0000664000175000017500000000521300000000000032331 0ustar00zuulzuul00000000000000{ "OFPFlowMod": { "buffer_id": 4294967295, "command": 1, "cookie": 1311768467463790320, "cookie_mask": 18446744073709551615, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "instructions": [ { "OFPInstructionActions": { "actions": [ { "NXActionConjunction": { "clause": 0, "experimenter": 8992, "id": 11259375, "len": 16, "n_clauses": 2, "subtype": 34, "type": 65535 } } ], "len": 24, "type": 4 } } ], "match": { "OFPMatch": { "length": 70, "oxm_fields": [ { "OXMTlv": { "field": "in_port", "mask": null, "value": 43981 } }, { "OXMTlv": { "field": "eth_dst", "mask": null, "value": "aa:bb:cc:99:88:77" } }, { "OXMTlv": { "field": "eth_type", "mask": null, "value": 2048 } }, { "OXMTlv": { "field": "vlan_vid", "mask": null, "value": 5095 } }, { "OXMTlv": { "field": "ipv4_dst", "mask": null, "value": "192.168.2.1" } }, { "OXMTlv": { "field": "tunnel_id", "mask": null, "value": 50000 } }, { "OXMTlv": { "field": "tun_ipv4_src", "mask": null, "value": "192.168.2.3" } }, { "OXMTlv": { "field": "tun_ipv4_dst", "mask": null, "value": "192.168.2.4" } } ], "type": 1 } }, "out_group": 4294967295, "out_port": 4294967295, "priority": 32768, "table_id": 2 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/ovs-ofctl-of13-action_controller.packet.json0000664000175000017500000000224600000000000032166 0ustar00zuulzuul00000000000000{ "OFPFlowMod": { "buffer_id": 4294967295, "command": 0, "cookie": 0, "cookie_mask": 0, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "instructions": [ { "OFPInstructionActions": { "actions": [ { "NXActionController": { "controller_id": 1, "experimenter": 8992, "len": 16, "max_len": 1024, "reason": 5, "subtype": 20, "type": 65535 } } ], "len": 24, "type": 4 } } ], "match": { "OFPMatch": { "length": 4, "oxm_fields": [], "type": 1 } }, "out_group": 4294967295, "out_port": 4294967295, "priority": 100, "table_id": 0 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/ovs-ofctl-of13-action_controller2.packet.json0000664000175000017500000000275100000000000032251 0ustar00zuulzuul00000000000000{ "OFPFlowMod": { "buffer_id": 4294967295, "command": 0, "cookie": 0, "cookie_mask": 0, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "instructions": [ { "OFPInstructionActions": { "actions": [ { "NXActionController2": { "controller_id": 10, "experimenter": 8992, "len": 64, "max_len": 1024, "pause": true, "reason": 5, "subtype": 37, "type": 65535, "userdata": [ 1, 2, 3, 4, 5 ] } } ], "len": 72, "type": 4 } } ], "match": { "OFPMatch": { "length": 4, "oxm_fields": [], "type": 1 } }, "out_group": 4294967295, "out_port": 4294967295, "priority": 100, "table_id": 0 } }././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/ovs-ofctl-of13-action_ct.packet.json0000664000175000017500000000300500000000000030403 0ustar00zuulzuul00000000000000{ "OFPFlowMod": { "buffer_id": 4294967295, "command": 0, "cookie": 0, "cookie_mask": 0, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "instructions": [ { "OFPInstructionActions": { "actions": [ { "NXActionCT": { "actions": [], "alg": 0, "experimenter": 8992, "flags": 0, "len": 24, "recirc_table": 4, "subtype": 35, "type": 65535, "zone_ofs_nbits": 283, "zone_src": "reg0" } } ], "len": 32, "type": 4 } } ], "match": { "OFPMatch": { "length": 22, "oxm_fields": [ { "OXMTlv": { "field": "eth_type", "mask": null, "value": 2048 } }, { "OXMTlv": { "field": "ct_state", "mask": 32, "value": 0 } } ], "type": 1 } }, "out_group": 4294967295, "out_port": 4294967295, "priority": 32768, "table_id": 3 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/ovs-ofctl-of13-action_ct_clear.packet.json0000664000175000017500000000243000000000000031552 0ustar00zuulzuul00000000000000{ "OFPFlowMod": { "buffer_id": 4294967295, "command": 0, "cookie": 0, "cookie_mask": 0, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "instructions": [ { "OFPInstructionActions": { "actions": [ { "NXActionCTClear": { "experimenter": 8992, "len": 16, "subtype": 43, "type": 65535 } } ], "len": 24, "type": 4 } } ], "match": { "OFPMatch": { "length": 22, "oxm_fields": [ { "OXMTlv": { "field": "eth_type", "mask": null, "value": 2048 } }, { "OXMTlv": { "field": "ct_state", "mask": 32, "value": 32 } } ], "type": 1 } }, "out_group": 4294967295, "out_port": 4294967295, "priority": 32768, "table_id": 3 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/ovs-ofctl-of13-action_ct_exec.packet.json0000664000175000017500000000412000000000000031406 0ustar00zuulzuul00000000000000{ "OFPFlowMod": { "buffer_id": 4294967295, "command": 0, "cookie": 0, "cookie_mask": 0, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "instructions": [ { "OFPInstructionActions": { "actions": [ { "NXActionCT": { "actions": [ { "OFPActionSetField": { "field": { "OXMTlv": { "field": "ct_mark", "mask": null, "value": 6636321 } }, "len": 16, "type": 25 } } ], "alg": 0, "experimenter": 8992, "flags": 1, "len": 40, "recirc_table": 255, "subtype": 35, "type": 65535, "zone_ofs_nbits": 0, "zone_src": "" } } ], "len": 48, "type": 4 } } ], "match": { "OFPMatch": { "length": 22, "oxm_fields": [ { "OXMTlv": { "field": "eth_type", "mask": null, "value": 2048 } }, { "OXMTlv": { "field": "ct_state", "mask": 34, "value": 34 } } ], "type": 1 } }, "out_group": 4294967295, "out_port": 4294967295, "priority": 32768, "table_id": 3 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/ovs-ofctl-of13-action_ct_nat.packet.json0000664000175000017500000000406300000000000031252 0ustar00zuulzuul00000000000000{ "OFPFlowMod": { "buffer_id": 4294967295, "command": 0, "cookie": 0, "cookie_mask": 0, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "instructions": [ { "OFPInstructionActions": { "actions": [ { "NXActionCT": { "actions": [ { "NXActionNAT": { "experimenter": 8992, "flags": 1, "len": 32, "range_ipv4_max": "10.1.13.255", "range_ipv4_min": "10.1.12.0", "range_ipv6_max": "", "range_ipv6_min": "", "range_proto_max": 1023, "range_proto_min": 1, "subtype": 36, "type": 65535 } } ], "alg": 0, "experimenter": 8992, "flags": 1, "len": 56, "recirc_table": 255, "subtype": 35, "type": 65535, "zone_ofs_nbits": 0, "zone_src": "" } } ], "len": 64, "type": 4 } } ], "match": { "OFPMatch": { "length": 10, "oxm_fields": [ { "OXMTlv": { "field": "eth_type", "mask": null, "value": 2048 } } ], "type": 1 } }, "out_group": 4294967295, "out_port": 4294967295, "priority": 32768, "table_id": 3 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/ovs-ofctl-of13-action_ct_nat_v6.packet.json0000664000175000017500000000407000000000000031663 0ustar00zuulzuul00000000000000{ "OFPFlowMod": { "buffer_id": 4294967295, "command": 0, "cookie": 0, "cookie_mask": 0, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "instructions": [ { "OFPInstructionActions": { "actions": [ { "NXActionCT": { "actions": [ { "NXActionNAT": { "experimenter": 8992, "flags": 2, "len": 48, "range_ipv4_max": "", "range_ipv4_min": "", "range_ipv6_max": "2001:1::ffff", "range_ipv6_min": "2001:1::1", "range_proto_max": null, "range_proto_min": null, "subtype": 36, "type": 65535 } } ], "alg": 0, "experimenter": 8992, "flags": 1, "len": 72, "recirc_table": 255, "subtype": 35, "type": 65535, "zone_ofs_nbits": 0, "zone_src": "" } } ], "len": 80, "type": 4 } } ], "match": { "OFPMatch": { "length": 10, "oxm_fields": [ { "OXMTlv": { "field": "eth_type", "mask": null, "value": 34525 } } ], "type": 1 } }, "out_group": 4294967295, "out_port": 4294967295, "priority": 32768, "table_id": 3 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/ovs-ofctl-of13-action_dec_ttl_cnt_ids.packet.json0000664000175000017500000000342500000000000033124 0ustar00zuulzuul00000000000000{ "OFPFlowMod": { "buffer_id": 4294967295, "command": 0, "cookie": 0, "cookie_mask": 0, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "instructions": [ { "OFPInstructionActions": { "actions": [ { "NXActionDecTtlCntIds": { "cnt_ids": [ 1, 2, 3, 4, 5 ], "experimenter": 8992, "len": 32, "subtype": 21, "type": 65535 } } ], "len": 40, "type": 4 } } ], "match": { "OFPMatch": { "length": 15, "oxm_fields": [ { "OXMTlv": { "field": "eth_type", "mask": null, "value": 2048 } }, { "OXMTlv": { "field": "ip_proto", "mask": null, "value": 6 } } ], "type": 1 } }, "out_group": 4294967295, "out_port": 4294967295, "priority": 100, "table_id": 0 } }././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/ovs-ofctl-of13-action_fintimeout.packet.json0000664000175000017500000000316200000000000032164 0ustar00zuulzuul00000000000000{ "OFPFlowMod": { "buffer_id": 4294967295, "command": 0, "cookie": 0, "cookie_mask": 0, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "instructions": [ { "OFPInstructionActions": { "actions": [ { "NXActionFinTimeout": { "experimenter": 8992, "fin_hard_timeout": 60, "fin_idle_timeout": 30, "len": 16, "subtype": 19, "type": 65535 } } ], "len": 24, "type": 4 } } ], "match": { "OFPMatch": { "length": 15, "oxm_fields": [ { "OXMTlv": { "field": "eth_type", "mask": null, "value": 2048 } }, { "OXMTlv": { "field": "ip_proto", "mask": null, "value": 6 } } ], "type": 1 } }, "out_group": 4294967295, "out_port": 4294967295, "priority": 100, "table_id": 0 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/ovs-ofctl-of13-action_learn.packet.json0000664000175000017500000001370000000000000031101 0ustar00zuulzuul00000000000000{ "OFPFlowMod": { "buffer_id": 4294967295, "command": 0, "cookie": 0, "cookie_mask": 0, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "instructions": [ { "OFPInstructionActions": { "actions": [ { "OFPActionPopVlan": { "len": 8, "type": 18 } }, { "OFPActionSetField": { "field": { "OXMTlv": { "field": "ipv4_dst", "mask": null, "value": "192.168.2.9" } }, "len": 16, "type": 25 } }, { "NXActionLearn": { "cookie": 0, "experimenter": 8992, "fin_hard_timeout": 0, "fin_idle_timeout": 0, "flags": 0, "hard_timeout": 300, "idle_timeout": 0, "len": 96, "priority": 1, "specs": [ { "NXFlowSpecMatch": { "dst": [ "vlan_vid", 0 ], "n_bits": 12, "src": [ "vlan_vid", 0 ] } }, { "NXFlowSpecMatch": { "dst": [ "eth_dst_nxm", 0 ], "n_bits": 48, "src": [ "eth_src_nxm", 0 ] } }, { "NXFlowSpecLoad": { "dst": [ "vlan_vid", 0 ], "n_bits": 12, "src": 0 } }, { "NXFlowSpecLoad": { "dst": [ "tunnel_id_nxm", 0 ], "n_bits": 64, "src": [ "tunnel_id_nxm", 0 ] } }, { "NXFlowSpecOutput": { "dst": "", "n_bits": 32, "src": [ "in_port", 0 ] } } ], "subtype": 16, "table_id": 99, "type": 65535 } } ], "len": 128, "type": 4 } }, { "OFPInstructionGotoTable": { "len": 8, "table_id": 100, "type": 1 } } ], "match": { "OFPMatch": { "length": 70, "oxm_fields": [ { "OXMTlv": { "field": "in_port", "mask": null, "value": 43981 } }, { "OXMTlv": { "field": "eth_dst", "mask": null, "value": "aa:bb:cc:99:88:77" } }, { "OXMTlv": { "field": "eth_type", "mask": null, "value": 2048 } }, { "OXMTlv": { "field": "vlan_vid", "mask": null, "value": 5095 } }, { "OXMTlv": { "field": "ipv4_dst", "mask": null, "value": "192.168.2.1" } }, { "OXMTlv": { "field": "tunnel_id", "mask": null, "value": 50000 } }, { "OXMTlv": { "field": "tun_ipv4_src", "mask": null, "value": "192.168.2.3" } }, { "OXMTlv": { "field": "tun_ipv4_dst", "mask": null, "value": "192.168.2.4" } } ], "type": 1 } }, "out_group": 4294967295, "out_port": 4294967295, "priority": 32768, "table_id": 2 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/ovs-ofctl-of13-action_note.packet.json0000664000175000017500000000250300000000000030744 0ustar00zuulzuul00000000000000{ "OFPFlowMod": { "buffer_id": 4294967295, "command": 0, "cookie": 0, "cookie_mask": 0, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "instructions": [ { "OFPInstructionActions": { "actions": [ { "NXActionNote": { "experimenter": 8992, "len": 16, "note": [ 4, 5, 6, 7, 0, 0 ], "subtype": 8, "type": 65535 } } ], "len": 24, "type": 4 } } ], "match": { "OFPMatch": { "length": 4, "oxm_fields": [], "type": 1 } }, "out_group": 4294967295, "out_port": 4294967295, "priority": 100, "table_id": 0 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/ovs-ofctl-of13-action_output_trunc.packet.json0000664000175000017500000000216300000000000032554 0ustar00zuulzuul00000000000000{ "OFPFlowMod": { "buffer_id": 4294967295, "command": 0, "cookie": 0, "cookie_mask": 0, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "instructions": [ { "OFPInstructionActions": { "actions": [ { "NXActionOutputTrunc": { "experimenter": 8992, "len": 16, "max_len": 1024, "port": 8080, "subtype": 39, "type": 65535 } } ], "len": 24, "type": 4 } } ], "match": { "OFPMatch": { "length": 4, "oxm_fields": [], "type": 1 } }, "out_group": 4294967295, "out_port": 4294967295, "priority": 100, "table_id": 0 } }././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/ovs-ofctl-of13-action_resubmit.packet.json0000664000175000017500000000510400000000000031631 0ustar00zuulzuul00000000000000{ "OFPFlowMod": { "buffer_id": 4294967295, "command": 0, "cookie": 0, "cookie_mask": 0, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "instructions": [ { "OFPInstructionActions": { "actions": [ { "NXActionResubmitTable": { "experimenter": 8992, "in_port": 1234, "len": 16, "subtype": 14, "table_id": 99, "type": 65535 } } ], "len": 24, "type": 4 } } ], "match": { "OFPMatch": { "length": 70, "oxm_fields": [ { "OXMTlv": { "field": "in_port", "mask": null, "value": 43981 } }, { "OXMTlv": { "field": "eth_dst", "mask": null, "value": "aa:bb:cc:99:88:77" } }, { "OXMTlv": { "field": "eth_type", "mask": null, "value": 2048 } }, { "OXMTlv": { "field": "vlan_vid", "mask": null, "value": 5095 } }, { "OXMTlv": { "field": "ipv4_dst", "mask": null, "value": "192.168.2.1" } }, { "OXMTlv": { "field": "tunnel_id", "mask": null, "value": 50000 } }, { "OXMTlv": { "field": "tun_ipv4_src", "mask": null, "value": "192.168.2.3" } }, { "OXMTlv": { "field": "tun_ipv4_dst", "mask": null, "value": "192.168.2.4" } } ], "type": 1 } }, "out_group": 4294967295, "out_port": 4294967295, "priority": 32768, "table_id": 3 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/ovs-ofctl-of13-action_sample.packet.json0000664000175000017500000000233700000000000031265 0ustar00zuulzuul00000000000000{ "OFPFlowMod": { "buffer_id": 4294967295, "command": 0, "cookie": 0, "cookie_mask": 0, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "instructions": [ { "OFPInstructionActions": { "actions": [ { "NXActionSample": { "collector_set_id": 1, "experimenter": 8992, "len": 24, "obs_domain_id": 2, "obs_point_id": 3, "probability": 3, "subtype": 29, "type": 65535 } } ], "len": 32, "type": 4 } } ], "match": { "OFPMatch": { "length": 4, "oxm_fields": [], "type": 1 } }, "out_group": 4294967295, "out_port": 4294967295, "priority": 100, "table_id": 0 } }././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/ovs-ofctl-of13-action_sample2.packet.json0000664000175000017500000000242700000000000031347 0ustar00zuulzuul00000000000000{ "OFPFlowMod": { "buffer_id": 4294967295, "command": 0, "cookie": 0, "cookie_mask": 0, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "instructions": [ { "OFPInstructionActions": { "actions": [ { "NXActionSample2": { "collector_set_id": 1, "experimenter": 8992, "len": 32, "obs_domain_id": 2, "obs_point_id": 3, "probability": 3, "sampling_port": 8080, "subtype": 38, "type": 65535 } } ], "len": 40, "type": 4 } } ], "match": { "OFPMatch": { "length": 4, "oxm_fields": [], "type": 1 } }, "out_group": 4294967295, "out_port": 4294967295, "priority": 100, "table_id": 0 } }././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/ovs-ofctl-of13-action_stack_pop.packet.json0000664000175000017500000000223000000000000031757 0ustar00zuulzuul00000000000000{ "OFPFlowMod": { "buffer_id": 4294967295, "command": 0, "cookie": 0, "cookie_mask": 0, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "instructions": [ { "OFPInstructionActions": { "actions": [ { "NXActionStackPop": { "end": 5, "experimenter": 8992, "field": "reg2", "len": 24, "start": 1, "subtype": 28, "type": 65535 } } ], "len": 32, "type": 4 } } ], "match": { "OFPMatch": { "length": 4, "oxm_fields": [], "type": 1 } }, "out_group": 4294967295, "out_port": 4294967295, "priority": 100, "table_id": 0 } }././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/ovs-ofctl-of13-action_stack_push.packet.json0000664000175000017500000000223100000000000032141 0ustar00zuulzuul00000000000000{ "OFPFlowMod": { "buffer_id": 4294967295, "command": 0, "cookie": 0, "cookie_mask": 0, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "instructions": [ { "OFPInstructionActions": { "actions": [ { "NXActionStackPush": { "end": 5, "experimenter": 8992, "field": "reg2", "len": 24, "start": 1, "subtype": 27, "type": 65535 } } ], "len": 32, "type": 4 } } ], "match": { "OFPMatch": { "length": 4, "oxm_fields": [], "type": 1 } }, "out_group": 4294967295, "out_port": 4294967295, "priority": 100, "table_id": 0 } }././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/ovs-ofctl-of13-match_conj.packet.json0000664000175000017500000000261400000000000030552 0ustar00zuulzuul00000000000000{ "OFPFlowMod": { "buffer_id": 4294967295, "command": 1, "cookie": 1311768467463790320, "cookie_mask": 18446744073709551615, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "instructions": [ { "OFPInstructionActions": { "actions": [ { "OFPActionPopVlan": { "len": 8, "type": 18 } } ], "len": 16, "type": 4 } }, { "OFPInstructionGotoTable": { "len": 8, "table_id": 100, "type": 1 } } ], "match": { "OFPMatch": { "length": 18, "oxm_fields": [ { "OXMTlv": { "field": "conj_id", "mask": null, "value": 11259375 } }, { "OXMTlv": { "field": "vlan_vid", "mask": null, "value": 5330 } } ], "type": 1 } }, "out_group": 4294967295, "out_port": 4294967295, "priority": 32768, "table_id": 3 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/ovs-ofctl-of13-match_load_nx_register.packet.json0000664000175000017500000000266700000000000033161 0ustar00zuulzuul00000000000000{ "OFPFlowMod": { "buffer_id": 4294967295, "command": 1, "cookie": 1311768467463790320, "cookie_mask": 18446744073709551615, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "instructions": [ { "OFPInstructionActions": { "actions": [ { "NXActionRegLoad": { "dst": "reg0", "experimenter": 8992, "len": 24, "ofs_nbits": 283, "subtype": 7, "type": 65535, "value": 233495534 } } ], "len": 32, "type": 4 } } ], "match": { "OFPMatch": { "length": 24, "oxm_fields": [ { "OXMTlv": { "field": "reg0", "mask": null, "value": 4660 } }, { "OXMTlv": { "field": "reg5", "mask": 65535, "value": 43981 } } ], "type": 1 } }, "out_group": 4294967295, "out_port": 4294967295, "priority": 32768, "table_id": 3 } }././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/ovs-ofctl-of13-match_move_nx_register.packet.json0000664000175000017500000000342500000000000033201 0ustar00zuulzuul00000000000000{ "OFPFlowMod": { "buffer_id": 4294967295, "command": 1, "cookie": 1311768467463790320, "cookie_mask": 18446744073709551615, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "instructions": [ { "OFPInstructionActions": { "actions": [ { "NXActionRegMove": { "dst_field": "reg1", "dst_ofs": 0, "experimenter": 8992, "len": 24, "n_bits": 6, "src_field": "reg0", "src_ofs": 10, "subtype": 6, "type": 65535 } } ], "len": 32, "type": 4 } } ], "match": { "OFPMatch": { "length": 24, "oxm_fields": [ { "OXMTlv": { "field": "reg0", "mask": null, "value": 4660 } }, { "OXMTlv": { "field": "reg5", "mask": 65535, "value": 43981 } } ], "type": 1 } }, "out_group": 4294967295, "out_port": 4294967295, "priority": 32768, "table_id": 3 } }././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/ovs-ofctl-of13-match_pkt_mark.packet.json0000664000175000017500000000261200000000000031427 0ustar00zuulzuul00000000000000{ "OFPFlowMod": { "buffer_id": 4294967295, "command": 1, "cookie": 1311768467463790320, "cookie_mask": 18446744073709551615, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "instructions": [ { "OFPInstructionActions": { "actions": [ { "OFPActionPopVlan": { "len": 8, "type": 18 } } ], "len": 16, "type": 4 } }, { "OFPInstructionGotoTable": { "len": 8, "table_id": 100, "type": 1 } } ], "match": { "OFPMatch": { "length": 18, "oxm_fields": [ { "OXMTlv": { "field": "vlan_vid", "mask": null, "value": 5330 } }, { "OXMTlv": { "field": "pkt_mark", "mask": null, "value": 54321 } } ], "type": 1 } }, "out_group": 4294967295, "out_port": 4294967295, "priority": 32768, "table_id": 3 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of13/ovs-ofctl-of13-match_pkt_mark_masked.packet.json0000664000175000017500000000261300000000000032754 0ustar00zuulzuul00000000000000{ "OFPFlowMod": { "buffer_id": 4294967295, "command": 1, "cookie": 1311768467463790320, "cookie_mask": 18446744073709551615, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "instructions": [ { "OFPInstructionActions": { "actions": [ { "OFPActionPopVlan": { "len": 8, "type": 18 } } ], "len": 16, "type": 4 } }, { "OFPInstructionGotoTable": { "len": 8, "table_id": 100, "type": 1 } } ], "match": { "OFPMatch": { "length": 22, "oxm_fields": [ { "OXMTlv": { "field": "vlan_vid", "mask": null, "value": 5330 } }, { "OXMTlv": { "field": "pkt_mark", "mask": 65535, "value": 54321 } } ], "type": 1 } }, "out_group": 4294967295, "out_port": 4294967295, "priority": 32768, "table_id": 3 } } ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.3461196 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/0000775000175000017500000000000000000000000021622 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-0-ofp_desc_reply.packet.json0000664000175000017500000000043500000000000027261 0ustar00zuulzuul00000000000000{ "OFPDescStatsReply": { "body": { "OFPDescStats": { "dp_desc": "dp", "hw_desc": "hw", "mfr_desc": "mfr", "serial_num": "serial", "sw_desc": "sw" } }, "flags": 0, "type": 0 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-1-ofp_packet_out.packet.json0000664000175000017500000000074000000000000027266 0ustar00zuulzuul00000000000000{ "OFPPacketOut": { "actions": [ { "OFPActionOutput": { "len": 16, "max_len": 65535, "port": 4294967292, "type": 0 } } ], "actions_len": 16, "buffer_id": 4294967295, "data": "8guk0D9w8gukffjqCABFAABU+BoAAP8Br4sKAAABCgAAAggAAgj3YAAAMdYCAAAAAACrjS0xAAAAABAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vAAAAAAAAAAA=", "in_port": 4294967293 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-10-ofp_hello.packet.json0000664000175000017500000000055000000000000026312 0ustar00zuulzuul00000000000000{ "OFPHello": { "elements": [ { "OFPHelloElemVersionBitmap": { "length": 8, "type": 1, "versions": [ 1, 2, 3, 9, 10, 30 ] } } ] } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-11-ofp_flow_stats_request.packet.json0000664000175000017500000000051500000000000031146 0ustar00zuulzuul00000000000000{ "OFPFlowStatsRequest": { "cookie": 0, "cookie_mask": 0, "flags": 0, "match": { "OFPMatch": { "length": 4, "oxm_fields": [], "type": 1 } }, "out_group": 4294967295, "out_port": 4294967295, "table_id": 0, "type": 1 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-12-ofp_flow_stats_reply.packet.json0000664000175000017500000002774400000000000030627 0ustar00zuulzuul00000000000000{ "OFPFlowStatsReply": { "body": [ { "OFPFlowStats": { "byte_count": 0, "cookie": 0, "duration_nsec": 115277000, "duration_sec": 358, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "importance": 0, "instructions": [], "length": 56, "match": { "OFPMatch": { "length": 4, "oxm_fields": [], "type": 1 } }, "packet_count": 0, "priority": 65535, "table_id": 0 } }, { "OFPFlowStats": { "byte_count": 0, "cookie": 0, "duration_nsec": 115055000, "duration_sec": 358, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "importance": 0, "instructions": [ { "OFPInstructionActions": { "actions": [ { "OFPActionOutput": { "len": 16, "max_len": 0, "port": 4294967290, "type": 0 } } ], "len": 24, "type": 4 } } ], "length": 88, "match": { "OFPMatch": { "length": 10, "oxm_fields": [ { "OXMTlv": { "field": "eth_type", "mask": null, "value": 2054 } } ], "type": 1 } }, "packet_count": 0, "priority": 65534, "table_id": 0 } }, { "OFPFlowStats": { "byte_count": 238, "cookie": 0, "duration_nsec": 511582000, "duration_sec": 316220, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "importance": 0, "instructions": [ { "OFPInstructionGotoTable": { "len": 8, "table_id": 1, "type": 1 } } ], "length": 80, "match": { "OFPMatch": { "length": 22, "oxm_fields": [ { "OXMTlv": { "field": "in_port", "mask": null, "value": 6 } }, { "OXMTlv": { "field": "eth_src", "mask": null, "value": "f2:0b:a4:7d:f8:ea" } } ], "type": 1 } }, "packet_count": 3, "priority": 123, "table_id": 0 } }, { "OFPFlowStats": { "byte_count": 98, "cookie": 0, "duration_nsec": 980901000, "duration_sec": 313499, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "importance": 0, "instructions": [ { "OFPInstructionActions": { "actions": [ { "OFPActionSetField": { "field": { "OXMTlv": { "field": "vlan_vid", "mask": null, "value": 258 } }, "len": 16, "type": 25 } }, { "OFPActionCopyTtlOut": { "len": 8, "type": 11 } }, { "OFPActionCopyTtlIn": { "len": 8, "type": 12 } }, { "OFPActionCopyTtlIn": { "len": 8, "type": 12 } }, { "OFPActionPopPbb": { "len": 8, "type": 27 } }, { "OFPActionPushPbb": { "ethertype": 4660, "len": 8, "type": 26 } }, { "OFPActionPopMpls": { "ethertype": 39030, "len": 8, "type": 20 } }, { "OFPActionPushMpls": { "ethertype": 34887, "len": 8, "type": 19 } }, { "OFPActionPopVlan": { "len": 8, "type": 18 } }, { "OFPActionPushVlan": { "ethertype": 33024, "len": 8, "type": 17 } }, { "OFPActionDecMplsTtl": { "len": 8, "type": 16 } }, { "OFPActionSetMplsTtl": { "len": 8, "mpls_ttl": 10, "type": 15 } }, { "OFPActionDecNwTtl": { "len": 8, "type": 24 } }, { "OFPActionSetNwTtl": { "len": 8, "nw_ttl": 10, "type": 23 } }, { "OFPActionSetQueue": { "len": 8, "queue_id": 3, "type": 21 } }, { "OFPActionGroup": { "group_id": 99, "len": 8, "type": 22 } }, { "OFPActionOutput": { "len": 16, "max_len": 65535, "port": 6, "type": 0 } }, { "OFPActionExperimenterUnknown": { "len": 16, "data": "ZXhwX2RhdGE=", "experimenter": 98765432, "type": 65535 } }, { "NXActionUnknown": { "len": 16, "data": "cF9kYXRh", "experimenter": 8992, "type": 65535, "subtype": 25976 } } ], "len": 192, "type": 3 } }, { "OFPInstructionActions": { "actions": [ { "OFPActionSetField": { "field": { "OXMTlv": { "field": "eth_src", "mask": null, "value": "01:02:03:04:05:06" } }, "len": 16, "type": 25 } }, { "OFPActionSetField": { "field": { "OXMTlv": { "field": "pbb_uca", "mask": null, "value": 1 } }, "len": 16, "type": 25 } } ], "len": 40, "type": 4 } }, { "OFPInstructionActions": { "actions": [ { "OFPActionOutput": { "len": 16, "max_len": 65535, "port": 4294967293, "type": 0 } } ], "len": 24, "type": 3 } } ], "length": 312, "match": { "OFPMatch": { "length": 4, "oxm_fields": [], "type": 1 } }, "packet_count": 1, "priority": 0, "table_id": 0 } } ], "flags": 0, "type": 1 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-13-ofp_echo_request.packet.json0000664000175000017500000000007100000000000027676 0ustar00zuulzuul00000000000000{ "OFPEchoRequest": { "data": "aG9nZQ==" } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-14-ofp_echo_reply.packet.json0000664000175000017500000000006700000000000027347 0ustar00zuulzuul00000000000000{ "OFPEchoReply": { "data": "aG9nZQ==" } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-15-ofp_error_msg.packet.json0000664000175000017500000000013500000000000027212 0ustar00zuulzuul00000000000000{ "OFPErrorMsg": { "code": 11, "data": "ZnVnYWZ1Z2E=", "type": 2 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-16-ofp_experimenter.packet.json0000664000175000017500000000016700000000000027730 0ustar00zuulzuul00000000000000{ "OFPExperimenter": { "data": "bmF6bw==", "exp_type": 123456789, "experimenter": 98765432 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-17-ofp_barrier_request.packet.json0000664000175000017500000000003700000000000030414 0ustar00zuulzuul00000000000000{ "OFPBarrierRequest": {} } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-18-ofp_barrier_reply.packet.json0000664000175000017500000000003500000000000030056 0ustar00zuulzuul00000000000000{ "OFPBarrierReply": {} } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-19-ofp_role_request.packet.json0000664000175000017500000000013500000000000027730 0ustar00zuulzuul00000000000000{ "OFPRoleRequest": { "generation_id": 17294086455919964160, "role": 2 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-2-ofp_flow_mod.packet.json0000664000175000017500000001344400000000000026744 0ustar00zuulzuul00000000000000{ "OFPFlowMod": { "buffer_id": 65535, "command": 0, "cookie": 0, "cookie_mask": 0, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "importance": 0, "instructions": [ { "OFPInstructionActions": { "actions": [ { "OFPActionSetField": { "field": { "OXMTlv": { "field": "vlan_vid", "mask": null, "value": 258 } }, "len": 16, "type": 25 } }, { "OFPActionCopyTtlOut": { "len": 8, "type": 11 } }, { "OFPActionCopyTtlIn": { "len": 8, "type": 12 } }, { "OFPActionCopyTtlIn": { "len": 8, "type": 12 } }, { "OFPActionPopPbb": { "len": 8, "type": 27 } }, { "OFPActionPushPbb": { "ethertype": 4660, "len": 8, "type": 26 } }, { "OFPActionPopMpls": { "ethertype": 39030, "len": 8, "type": 20 } }, { "OFPActionPushMpls": { "ethertype": 34887, "len": 8, "type": 19 } }, { "OFPActionPopVlan": { "len": 8, "type": 18 } }, { "OFPActionPushVlan": { "ethertype": 33024, "len": 8, "type": 17 } }, { "OFPActionDecMplsTtl": { "len": 8, "type": 16 } }, { "OFPActionSetMplsTtl": { "len": 8, "mpls_ttl": 10, "type": 15 } }, { "OFPActionDecNwTtl": { "len": 8, "type": 24 } }, { "OFPActionSetNwTtl": { "len": 8, "nw_ttl": 10, "type": 23 } }, { "OFPActionExperimenterUnknown": { "data": "AAECAwQFBgc=", "experimenter": 101, "len": 16, "type": 65535 } }, { "OFPActionSetQueue": { "len": 8, "queue_id": 3, "type": 21 } }, { "OFPActionGroup": { "group_id": 99, "len": 8, "type": 22 } }, { "OFPActionOutput": { "len": 16, "max_len": 65535, "port": 6, "type": 0 } } ], "len": 176, "type": 3 } }, { "OFPInstructionActions": { "actions": [ { "OFPActionSetField": { "field": { "OXMTlv": { "field": "eth_src", "mask": null, "value": "01:02:03:04:05:06" } }, "len": 16, "type": 25 } }, { "OFPActionSetField": { "field": { "OXMTlv": { "field": "pbb_uca", "mask": null, "value": 1 } }, "len": 16, "type": 25 } } ], "len": 40, "type": 4 } } ], "match": { "OFPMatch": { "length": 14, "oxm_fields": [ { "OXMTlv": { "field": "eth_dst", "mask": null, "value": "f2:0b:a4:7d:f8:ea" } } ], "type": 1 } }, "out_group": 4294967295, "out_port": 4294967295, "priority": 123, "table_id": 1 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-20-ofp_role_reply.packet.json0000664000175000017500000000013300000000000027361 0ustar00zuulzuul00000000000000{ "OFPRoleReply": { "generation_id": 17294086455919964160, "role": 3 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-21-ofp_group_mod.packet.json0000664000175000017500000000112000000000000027176 0ustar00zuulzuul00000000000000{ "OFPGroupMod": { "buckets": [ { "OFPBucket": { "actions": [ { "OFPActionOutput": { "len": 16, "max_len": 65535, "port": 2, "type": 0 } } ], "len": 32, "watch_group": 1, "watch_port": 1, "weight": 1 } } ], "command": 0, "group_id": 1, "type": 0 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-22-ofp_port_mod.packet.json0000664000175000017500000000256500000000000027045 0ustar00zuulzuul00000000000000{ "OFPPortMod": { "config": 0, "hw_addr": "00:11:00:00:11:11", "mask": 0, "port_no": 1, "properties": [ { "OFPPortModPropEthernet": { "advertise": 4096, "length": 8, "type": 0 } }, { "OFPPortModPropOptical": { "configure": 3, "fl_offset": 2000, "freq_lmda": 1500, "grid_span": 3000, "length": 24, "tx_pwr": 300, "type": 1 } }, { "OFPPortModPropExperimenter": { "data": [], "exp_type": 0, "experimenter": 101, "length": 12, "type": 65535 } }, { "OFPPortModPropExperimenter": { "data": [ 1 ], "exp_type": 1, "experimenter": 101, "length": 16, "type": 65535 } }, { "OFPPortModPropExperimenter": { "data": [ 1, 2 ], "exp_type": 2, "experimenter": 101, "length": 20, "type": 65535 } } ] } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-23-ofp_table_mod.packet.json0000664000175000017500000000237300000000000027146 0ustar00zuulzuul00000000000000{ "OFPTableMod": { "config": 0, "properties": [ { "OFPTableModPropEviction": { "flags": 0, "length": 8, "type": 2 } }, { "OFPTableModPropVacancy": { "length": 8, "type": 3, "vacancy": 0, "vacancy_down": 0, "vacancy_up": 0 } }, { "OFPTableModPropExperimenter": { "data": [], "exp_type": 0, "experimenter": 101, "length": 12, "type": 65535 } }, { "OFPTableModPropExperimenter": { "data": [ 1 ], "exp_type": 1, "experimenter": 101, "length": 16, "type": 65535 } }, { "OFPTableModPropExperimenter": { "data": [ 1, 2 ], "exp_type": 2, "experimenter": 101, "length": 20, "type": 65535 } } ], "table_id": 255 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-24-ofp_desc_request.packet.json0000664000175000017500000000010700000000000027700 0ustar00zuulzuul00000000000000{ "OFPDescStatsRequest": { "flags": 0, "type": 0 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-25-ofp_aggregate_stats_request.packet.json0000664000175000017500000000052400000000000032132 0ustar00zuulzuul00000000000000{ "OFPAggregateStatsRequest": { "cookie": 0, "cookie_mask": 0, "flags": 0, "match": { "OFPMatch": { "length": 4, "oxm_fields": [], "type": 1 } }, "out_group": 4294967295, "out_port": 4294967295, "table_id": 255, "type": 2 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-26-ofp_aggregate_stats_reply.packet.json0000664000175000017500000000035000000000000031573 0ustar00zuulzuul00000000000000{ "OFPAggregateStatsReply": { "body": { "OFPAggregateStats": { "byte_count": 574, "flow_count": 6, "packet_count": 7 } }, "flags": 0, "type": 2 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-27-ofp_table_stats_request.packet.json0000664000175000017500000000011000000000000031264 0ustar00zuulzuul00000000000000{ "OFPTableStatsRequest": { "flags": 0, "type": 3 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-28-ofp_table_stats_reply.packet.json0000664000175000017500000000075600000000000030750 0ustar00zuulzuul00000000000000{ "OFPTableStatsReply": { "body": [ { "OFPTableStats": { "active_count": 4, "lookup_count": 4, "matched_count": 4, "table_id": 0 } }, { "OFPTableStats": { "active_count": 4, "lookup_count": 4, "matched_count": 4, "table_id": 1 } } ], "flags": 0, "type": 3 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-29-ofp_port_stats_request.packet.json0000664000175000017500000000014400000000000031172 0ustar00zuulzuul00000000000000{ "OFPPortStatsRequest": { "flags": 0, "port_no": 4294967295, "type": 4 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-3-ofp_flow_mod.packet.json0000664000175000017500000000204000000000000026733 0ustar00zuulzuul00000000000000{ "OFPFlowMod": { "buffer_id": 65535, "command": 0, "cookie": 0, "cookie_mask": 0, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "importance": 0, "instructions": [ { "OFPInstructionGotoTable": { "len": 8, "table_id": 1, "type": 1 } } ], "match": { "OFPMatch": { "length": 22, "oxm_fields": [ { "OXMTlv": { "field": "in_port", "mask": null, "value": 6 } }, { "OXMTlv": { "field": "eth_src", "mask": null, "value": "f2:0b:a4:7d:f8:ea" } } ], "type": 1 } }, "out_group": 4294967295, "out_port": 4294967295, "priority": 123, "table_id": 0 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-30-ofp_port_stats_reply.packet.json0000664000175000017500000000671300000000000030635 0ustar00zuulzuul00000000000000{ "OFPPortStatsReply": { "body": [ { "OFPPortStats": { "duration_nsec": 0, "duration_sec": 0, "length": 224, "port_no": 7, "properties": [ { "OFPPortStatsPropEthernet": { "collisions": 0, "length": 40, "rx_crc_err": 0, "rx_frame_err": 0, "rx_over_err": 0, "type": 0 } }, { "OFPPortStatsPropOptical": { "bias_current": 300, "flags": 3, "length": 44, "rx_freq_lmda": 1500, "rx_grid_span": 500, "rx_offset": 700, "rx_pwr": 2000, "temperature": 273, "tx_freq_lmda": 1500, "tx_grid_span": 500, "tx_offset": 700, "tx_pwr": 2000, "type": 1 } }, { "OFPPortStatsPropExperimenter": { "data": [], "exp_type": 0, "experimenter": 101, "length": 12, "type": 65535 } }, { "OFPPortStatsPropExperimenter": { "data": [ 1 ], "exp_type": 1, "experimenter": 101, "length": 16, "type": 65535 } }, { "OFPPortStatsPropExperimenter": { "data": [ 1, 2 ], "exp_type": 2, "experimenter": 101, "length": 20, "type": 65535 } } ], "rx_bytes": 0, "rx_dropped": 0, "rx_errors": 0, "rx_packets": 0, "tx_bytes": 336, "tx_dropped": 0, "tx_errors": 0, "tx_packets": 4 } }, { "OFPPortStats": { "duration_nsec": 0, "duration_sec": 0, "length": 120, "port_no": 6, "properties": [ { "OFPPortStatsPropEthernet": { "collisions": 0, "length": 40, "rx_crc_err": 0, "rx_frame_err": 0, "rx_over_err": 0, "type": 0 } } ], "rx_bytes": 336, "rx_dropped": 0, "rx_errors": 0, "rx_packets": 4, "tx_bytes": 336, "tx_dropped": 0, "tx_errors": 0, "tx_packets": 4 } } ], "flags": 0, "type": 4 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-31-ofp_group_features_request.packet.json0000664000175000017500000000012000000000000032005 0ustar00zuulzuul00000000000000{ "OFPGroupFeaturesStatsRequest": { "flags": 0, "type": 8 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-32-ofp_group_features_reply.packet.json0000664000175000017500000000074600000000000031467 0ustar00zuulzuul00000000000000{ "OFPGroupFeaturesStatsReply": { "body": { "OFPGroupFeaturesStats": { "actions": [ 67082241, 67082241, 67082241, 67082241 ], "capabilities": 5, "max_groups": [ 16777216, 16777216, 16777216, 16777216 ], "types": 15 } }, "flags": 0, "type": 8 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-33-ofp_group_desc_request.packet.json0000664000175000017500000000011400000000000031112 0ustar00zuulzuul00000000000000{ "OFPGroupDescStatsRequest": { "flags": 0, "type": 7 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-34-ofp_group_desc_reply.packet.json0000664000175000017500000000165400000000000030570 0ustar00zuulzuul00000000000000{ "OFPGroupDescStatsReply": { "body": [ { "OFPGroupDescStats": { "buckets": [ { "OFPBucket": { "actions": [ { "OFPActionOutput": { "len": 16, "max_len": 65535, "port": 2, "type": 0 } } ], "len": 32, "watch_group": 1, "watch_port": 1, "weight": 1 } } ], "group_id": 1, "length": 40, "type": 0 } } ], "flags": 0, "type": 7 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-35-ofp_queue_stats_request.packet.json0000664000175000017500000000020300000000000031323 0ustar00zuulzuul00000000000000{ "OFPQueueStatsRequest": { "flags": 0, "port_no": 4294967295, "queue_id": 4294967295, "type": 5 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-36-ofp_queue_stats_reply.packet.json0000664000175000017500000000430600000000000030777 0ustar00zuulzuul00000000000000{ "OFPQueueStatsReply": { "body": [ { "OFPQueueStats": { "duration_nsec": 0, "duration_sec": 0, "length": 104, "port_no": 7, "properties": [ { "OFPQueueStatsPropExperimenter": { "data": [], "exp_type": 0, "experimenter": 101, "length": 12, "type": 65535 } }, { "OFPQueueStatsPropExperimenter": { "data": [ 1 ], "exp_type": 1, "experimenter": 101, "length": 16, "type": 65535 } }, { "OFPQueueStatsPropExperimenter": { "data": [ 1, 2 ], "exp_type": 2, "experimenter": 101, "length": 20, "type": 65535 } } ], "queue_id": 1, "tx_bytes": 0, "tx_errors": 0, "tx_packets": 0 } }, { "OFPQueueStats": { "duration_nsec": 0, "duration_sec": 0, "length": 48, "port_no": 6, "properties": [], "queue_id": 1, "tx_bytes": 0, "tx_errors": 0, "tx_packets": 0 } }, { "OFPQueueStats": { "duration_nsec": 0, "duration_sec": 0, "length": 48, "port_no": 7, "properties": [], "queue_id": 2, "tx_bytes": 0, "tx_errors": 0, "tx_packets": 0 } } ], "flags": 0, "type": 5 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-37-ofp_port_status.packet.json0000664000175000017500000000440200000000000027607 0ustar00zuulzuul00000000000000{ "OFPPortStatus": { "desc": { "OFPPort": { "config": 0, "hw_addr": "f2:0b:a4:d0:3f:70", "length": 168, "name": "\u79c1\u306e\u30dd\u30fc\u30c8", "port_no": 7, "properties": [ { "OFPPortDescPropEthernet": { "advertised": 10240, "curr": 10248, "curr_speed": 5000, "length": 32, "max_speed": 5000, "peer": 10248, "supported": 10248, "type": 0 } }, { "OFPPortDescPropOptical": { "length": 40, "rx_grid_freq_lmda": 1500, "rx_max_freq_lmda": 2000, "rx_min_freq_lmda": 1000, "supported": 1, "tx_grid_freq_lmda": 1500, "tx_max_freq_lmda": 2000, "tx_min_freq_lmda": 1000, "tx_pwr_max": 2000, "tx_pwr_min": 1000, "type": 1 } }, { "OFPPortDescPropExperimenter": { "data": [], "exp_type": 0, "experimenter": 101, "length": 12, "type": 65535 } }, { "OFPPortDescPropExperimenter": { "data": [ 1 ], "exp_type": 1, "experimenter": 101, "length": 16, "type": 65535 } }, { "OFPPortDescPropExperimenter": { "data": [ 1, 2 ], "exp_type": 2, "experimenter": 101, "length": 20, "type": 65535 } } ], "state": 4 } }, "reason": 0 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-38-ofp_flow_removed.packet.json0000664000175000017500000000117100000000000027711 0ustar00zuulzuul00000000000000{ "OFPFlowRemoved": { "byte_count": 86, "cookie": 0, "duration_nsec": 48825000, "duration_sec": 3, "hard_timeout": 0, "idle_timeout": 3, "match": { "OFPMatch": { "length": 14, "oxm_fields": [ { "OXMTlv": { "field": "eth_dst", "mask": null, "value": "f2:0b:a4:7d:f8:ea" } } ], "type": 1 } }, "packet_count": 1, "priority": 65535, "reason": 0, "table_id": 0 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-39-ofp_error_msg_experimenter.packet.json0000664000175000017500000000023600000000000032011 0ustar00zuulzuul00000000000000{ "OFPErrorMsg": { "code": null, "data": "amlra2VuIGRhdGE=", "exp_type": 60000, "experimenter": 999999, "type": 65535 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-4-ofp_packet_in.packet.json0000664000175000017500000000423000000000000027066 0ustar00zuulzuul00000000000000{ "OFPPacketIn": { "buffer_id": 2, "cookie": 283686884868096, "data": "////////8gukffjqCAYAAQgABgQAAfILpH346goAAAEAAAAAAAAKAAAD", "match": { "OFPMatch": { "length": 80, "oxm_fields": [ { "OXMTlv": { "field": "in_port", "mask": null, "value": 6 } }, { "OXMTlv": { "field": "eth_type", "mask": null, "value": 2054 } }, { "OXMTlv": { "field": "eth_dst", "mask": null, "value": "ff:ff:ff:ff:ff:ff" } }, { "OXMTlv": { "field": "eth_src", "mask": null, "value": "f2:0b:a4:7d:f8:ea" } }, { "OXMTlv": { "field": "arp_op", "mask": null, "value": 1 } }, { "OXMTlv": { "field": "arp_spa", "mask": null, "value": "10.0.0.1" } }, { "OXMTlv": { "field": "arp_tpa", "mask": null, "value": "10.0.0.3" } }, { "OXMTlv": { "field": "arp_sha", "mask": null, "value": "f2:0b:a4:7d:f8:ea" } }, { "OXMTlv": { "field": "arp_tha", "mask": null, "value": "00:00:00:00:00:00" } } ], "type": 1 } }, "reason": 3, "table_id": 1, "total_len": 42 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-40-ofp_get_async_request.packet.json0000664000175000017500000000004000000000000030730 0ustar00zuulzuul00000000000000{ "OFPGetAsyncRequest": {} } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-41-ofp_get_async_reply.packet.json0000664000175000017500000000533000000000000030403 0ustar00zuulzuul00000000000000{ "OFPGetAsyncReply": { "properties": [ { "OFPAsyncConfigPropReasons": { "length": 8, "mask": 3, "type": 0 } }, { "OFPAsyncConfigPropReasons": { "length": 8, "mask": 3, "type": 1 } }, { "OFPAsyncConfigPropReasons": { "length": 8, "mask": 3, "type": 2 } }, { "OFPAsyncConfigPropReasons": { "length": 8, "mask": 3, "type": 3 } }, { "OFPAsyncConfigPropReasons": { "length": 8, "mask": 3, "type": 4 } }, { "OFPAsyncConfigPropReasons": { "length": 8, "mask": 3, "type": 5 } }, { "OFPAsyncConfigPropReasons": { "length": 8, "mask": 3, "type": 6 } }, { "OFPAsyncConfigPropReasons": { "length": 8, "mask": 3, "type": 7 } }, { "OFPAsyncConfigPropReasons": { "length": 8, "mask": 24, "type": 8 } }, { "OFPAsyncConfigPropReasons": { "length": 8, "mask": 24, "type": 9 } }, { "OFPAsyncConfigPropReasons": { "length": 8, "mask": 3, "type": 10 } }, { "OFPAsyncConfigPropReasons": { "length": 8, "mask": 3, "type": 11 } }, { "OFPAsyncConfigPropExperimenter": { "data": [], "exp_type": 0, "experimenter": 101, "length": 12, "type": 65534 } }, { "OFPAsyncConfigPropExperimenter": { "data": [ 1 ], "exp_type": 1, "experimenter": 101, "length": 16, "type": 65535 } }, { "OFPAsyncConfigPropExperimenter": { "data": [ 1, 2 ], "exp_type": 2, "experimenter": 101, "length": 20, "type": 65535 } } ] } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-42-ofp_set_async.packet.json0000664000175000017500000000532300000000000027207 0ustar00zuulzuul00000000000000{ "OFPSetAsync": { "properties": [ { "OFPAsyncConfigPropReasons": { "length": 8, "mask": 3, "type": 0 } }, { "OFPAsyncConfigPropReasons": { "length": 8, "mask": 3, "type": 1 } }, { "OFPAsyncConfigPropReasons": { "length": 8, "mask": 3, "type": 2 } }, { "OFPAsyncConfigPropReasons": { "length": 8, "mask": 3, "type": 3 } }, { "OFPAsyncConfigPropReasons": { "length": 8, "mask": 3, "type": 4 } }, { "OFPAsyncConfigPropReasons": { "length": 8, "mask": 3, "type": 5 } }, { "OFPAsyncConfigPropReasons": { "length": 8, "mask": 3, "type": 6 } }, { "OFPAsyncConfigPropReasons": { "length": 8, "mask": 3, "type": 7 } }, { "OFPAsyncConfigPropReasons": { "length": 8, "mask": 24, "type": 8 } }, { "OFPAsyncConfigPropReasons": { "length": 8, "mask": 24, "type": 9 } }, { "OFPAsyncConfigPropReasons": { "length": 8, "mask": 3, "type": 10 } }, { "OFPAsyncConfigPropReasons": { "length": 8, "mask": 3, "type": 11 } }, { "OFPAsyncConfigPropExperimenter": { "data": [], "exp_type": 0, "experimenter": 101, "length": 12, "type": 65534 } }, { "OFPAsyncConfigPropExperimenter": { "data": [ 1 ], "exp_type": 1, "experimenter": 101, "length": 16, "type": 65535 } }, { "OFPAsyncConfigPropExperimenter": { "data": [ 1, 2 ], "exp_type": 2, "experimenter": 101, "length": 20, "type": 65535 } } ] } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-43-ofp_meter_mod.packet.json0000664000175000017500000000136100000000000027171 0ustar00zuulzuul00000000000000{ "OFPMeterMod": { "bands": [ { "OFPMeterBandDrop": { "burst_size": 10, "len": 16, "rate": 1000, "type": 1 } }, { "OFPMeterBandDscpRemark": { "burst_size": 10, "len": 16, "prec_level": 1, "rate": 1000, "type": 2 } }, { "OFPMeterBandExperimenter": { "burst_size": 10, "experimenter": 999, "len": 16, "rate": 1000, "type": 65535 } } ], "command": 0, "flags": 14, "meter_id": 100 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-44-ofp_flow_mod.packet.json0000664000175000017500000000240300000000000027023 0ustar00zuulzuul00000000000000{ "OFPFlowMod": { "buffer_id": 65535, "command": 0, "cookie": 0, "cookie_mask": 0, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "importance": 0, "instructions": [ { "OFPInstructionMeter": { "len": 8, "meter_id": 1, "type": 6 } }, { "OFPInstructionActions": { "actions": [ { "OFPActionOutput": { "len": 16, "max_len": 65535, "port": 6, "type": 0 } } ], "len": 24, "type": 3 } } ], "match": { "OFPMatch": { "length": 14, "oxm_fields": [ { "OXMTlv": { "field": "eth_dst", "mask": null, "value": "f2:0b:a4:7d:f8:ea" } } ], "type": 1 } }, "out_group": 4294967295, "out_port": 4294967295, "priority": 123, "table_id": 1 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-45-ofp_meter_config_request.packet.json0000664000175000017500000000015500000000000031431 0ustar00zuulzuul00000000000000{ "OFPMeterConfigStatsRequest": { "flags": 0, "meter_id": 4294967295, "type": 10 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-46-ofp_meter_config_reply.packet.json0000664000175000017500000000106200000000000031073 0ustar00zuulzuul00000000000000{ "OFPMeterConfigStatsReply": { "body": [ { "OFPMeterConfigStats": { "bands": [ { "OFPMeterBandDrop": { "burst_size": 10, "len": 16, "rate": 1000, "type": 1 } } ], "flags": 14, "length": 24, "meter_id": 100 } } ], "flags": 0, "type": 10 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-47-ofp_meter_stats_request.packet.json0000664000175000017500000000014600000000000031324 0ustar00zuulzuul00000000000000{ "OFPMeterStatsRequest": { "flags": 0, "meter_id": 4294967295, "type": 9 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-48-ofp_meter_stats_reply.packet.json0000664000175000017500000000120600000000000030766 0ustar00zuulzuul00000000000000{ "OFPMeterStatsReply": { "body": [ { "OFPMeterStats": { "band_stats": [ { "OFPMeterBandStats": { "byte_band_count": 0, "packet_band_count": 0 } } ], "byte_in_count": 0, "duration_nsec": 480000, "duration_sec": 0, "flow_count": 0, "len": 56, "meter_id": 100, "packet_in_count": 0 } } ], "flags": 0, "type": 9 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-49-ofp_meter_features_request.packet.json0000664000175000017500000000012100000000000031777 0ustar00zuulzuul00000000000000{ "OFPMeterFeaturesStatsRequest": { "flags": 0, "type": 11 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-5-ofp_features_request.packet.json0000664000175000017500000000004000000000000030513 0ustar00zuulzuul00000000000000{ "OFPFeaturesRequest": {} } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-50-ofp_meter_features_reply.packet.json0000664000175000017500000000054400000000000031443 0ustar00zuulzuul00000000000000{ "OFPMeterFeaturesStatsReply": { "body": [ { "OFPMeterFeaturesStats": { "band_types": 2147483654, "capabilities": 15, "max_bands": 255, "max_color": 0, "max_meter": 16777216 } } ], "flags": 0, "type": 11 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-51-ofp_port_desc_request.packet.json0000664000175000017500000000011400000000000030742 0ustar00zuulzuul00000000000000{ "OFPPortDescStatsRequest": { "flags": 0, "type": 13 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-52-ofp_port_desc_reply.packet.json0000664000175000017500000000631400000000000030416 0ustar00zuulzuul00000000000000{ "OFPPortDescStatsReply": { "body": [ { "OFPPort": { "config": 0, "hw_addr": "f2:0b:a4:d0:3f:70", "length": 168, "name": "Port7", "port_no": 7, "properties": [ { "OFPPortDescPropEthernet": { "advertised": 10240, "curr": 10248, "curr_speed": 5000, "length": 32, "max_speed": 5000, "peer": 10248, "supported": 10248, "type": 0 } }, { "OFPPortDescPropOptical": { "length": 40, "rx_grid_freq_lmda": 1500, "rx_max_freq_lmda": 2000, "rx_min_freq_lmda": 1000, "supported": 1, "tx_grid_freq_lmda": 1500, "tx_max_freq_lmda": 2000, "tx_min_freq_lmda": 1000, "tx_pwr_max": 2000, "tx_pwr_min": 1000, "type": 1 } }, { "OFPPortDescPropExperimenter": { "data": [], "exp_type": 0, "experimenter": 101, "length": 12, "type": 65535 } }, { "OFPPortDescPropExperimenter": { "data": [ 1 ], "exp_type": 1, "experimenter": 101, "length": 16, "type": 65535 } }, { "OFPPortDescPropExperimenter": { "data": [ 1, 2 ], "exp_type": 2, "experimenter": 101, "length": 20, "type": 65535 } } ], "state": 4 } }, { "OFPPort": { "config": 0, "hw_addr": "f2:0b:a4:7d:f8:ea", "length": 72, "name": "Port6", "port_no": 6, "properties": [ { "OFPPortDescPropEthernet": { "advertised": 10240, "curr": 10248, "curr_speed": 5000, "length": 32, "max_speed": 5000, "peer": 10248, "supported": 10248, "type": 0 } } ], "state": 4 } } ], "flags": 0, "type": 13 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-53-ofp_table_features_request.packet.json0000664000175000017500000223551700000000000031772 0ustar00zuulzuul00000000000000{ "OFPTableFeaturesStatsRequest": { "body": [ { "OFPTableFeaturesStats": { "config": 0, "length": 1168, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x00", "properties": [ { "OFPTableFeaturePropInstructions": { "instruction_ids": [ { "OFPInstructionId": { "len": 4, "type": 1 } }, { "OFPInstructionId": { "len": 4, "type": 2 } }, { "OFPInstructionId": { "len": 4, "type": 3 } }, { "OFPInstructionId": { "len": 4, "type": 4 } }, { "OFPInstructionId": { "len": 4, "type": 5 } }, { "OFPInstructionId": { "len": 4, "type": 6 } } ], "length": 28, "type": 0 } }, { "OFPTableFeaturePropNextTables": { "length": 258, "table_ids": [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254 ], "type": 2 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 4 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 6 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 8 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 10 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 12 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 14 } }, { "OFPTableFeaturePropExperimenter": { "data": [], "exp_type": 0, "experimenter": 101, "length": 12, "type": 65534 } }, { "OFPTableFeaturePropExperimenter": { "data": [ 1 ], "exp_type": 1, "experimenter": 101, "length": 16, "type": 65534 } }, { "OFPTableFeaturePropExperimenter": { "data": [ 1, 2 ], "exp_type": 2, "experimenter": 101, "length": 20, "type": 65534 } } ], "table_id": 0 } }, { "OFPTableFeaturesStats": { "config": 0, "length": 1112, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x01", "properties": [ { "OFPTableFeaturePropInstructions": { "instruction_ids": [ { "OFPInstructionId": { "len": 4, "type": 1 } }, { "OFPInstructionId": { "len": 4, "type": 2 } }, { "OFPInstructionId": { "len": 4, "type": 3 } }, { "OFPInstructionId": { "len": 4, "type": 4 } }, { "OFPInstructionId": { "len": 4, "type": 5 } }, { "OFPInstructionId": { "len": 4, "type": 6 } } ], "length": 28, "type": 0 } }, { "OFPTableFeaturePropNextTables": { "length": 257, "table_ids": [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254 ], "type": 2 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 4 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 6 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 8 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 10 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 12 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 14 } } ], "table_id": 1 } }, { "OFPTableFeaturesStats": { "config": 0, "length": 1104, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x02", "properties": [ { "OFPTableFeaturePropInstructions": { "instruction_ids": [ { "OFPInstructionId": { "len": 4, "type": 1 } }, { "OFPInstructionId": { "len": 4, "type": 2 } }, { "OFPInstructionId": { "len": 4, "type": 3 } }, { "OFPInstructionId": { "len": 4, "type": 4 } }, { "OFPInstructionId": { "len": 4, "type": 5 } }, { "OFPInstructionId": { "len": 4, "type": 6 } } ], "length": 28, "type": 0 } }, { "OFPTableFeaturePropNextTables": { "length": 256, "table_ids": [ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254 ], "type": 2 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 4 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 6 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 8 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 10 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 12 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 14 } } ], "table_id": 2 } }, { "OFPTableFeaturesStats": { "config": 0, "length": 1104, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x03", "properties": [ { "OFPTableFeaturePropInstructions": { "instruction_ids": [ { "OFPInstructionId": { "len": 4, "type": 1 } }, { "OFPInstructionId": { "len": 4, "type": 2 } }, { "OFPInstructionId": { "len": 4, "type": 3 } }, { "OFPInstructionId": { "len": 4, "type": 4 } }, { "OFPInstructionId": { "len": 4, "type": 5 } }, { "OFPInstructionId": { "len": 4, "type": 6 } } ], "length": 28, "type": 0 } }, { "OFPTableFeaturePropNextTables": { "length": 255, "table_ids": [ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254 ], "type": 2 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 4 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 6 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 8 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 10 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 12 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 14 } } ], "table_id": 3 } }, { "OFPTableFeaturesStats": { "config": 0, "length": 1104, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x04", "properties": [ { "OFPTableFeaturePropInstructions": { "instruction_ids": [ { "OFPInstructionId": { "len": 4, "type": 1 } }, { "OFPInstructionId": { "len": 4, "type": 2 } }, { "OFPInstructionId": { "len": 4, "type": 3 } }, { "OFPInstructionId": { "len": 4, "type": 4 } }, { "OFPInstructionId": { "len": 4, "type": 5 } }, { "OFPInstructionId": { "len": 4, "type": 6 } } ], "length": 28, "type": 0 } }, { "OFPTableFeaturePropNextTables": { "length": 254, "table_ids": [ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254 ], "type": 2 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 4 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 6 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 8 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 10 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 12 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 14 } } ], "table_id": 4 } }, { "OFPTableFeaturesStats": { "config": 0, "length": 1104, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x05", "properties": [ { "OFPTableFeaturePropInstructions": { "instruction_ids": [ { "OFPInstructionId": { "len": 4, "type": 1 } }, { "OFPInstructionId": { "len": 4, "type": 2 } }, { "OFPInstructionId": { "len": 4, "type": 3 } }, { "OFPInstructionId": { "len": 4, "type": 4 } }, { "OFPInstructionId": { "len": 4, "type": 5 } }, { "OFPInstructionId": { "len": 4, "type": 6 } } ], "length": 28, "type": 0 } }, { "OFPTableFeaturePropNextTables": { "length": 253, "table_ids": [ 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254 ], "type": 2 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 4 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 6 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 8 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 10 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 12 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 14 } } ], "table_id": 5 } }, { "OFPTableFeaturesStats": { "config": 0, "length": 1104, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x06", "properties": [ { "OFPTableFeaturePropInstructions": { "instruction_ids": [ { "OFPInstructionId": { "len": 4, "type": 1 } }, { "OFPInstructionId": { "len": 4, "type": 2 } }, { "OFPInstructionId": { "len": 4, "type": 3 } }, { "OFPInstructionId": { "len": 4, "type": 4 } }, { "OFPInstructionId": { "len": 4, "type": 5 } }, { "OFPInstructionId": { "len": 4, "type": 6 } } ], "length": 28, "type": 0 } }, { "OFPTableFeaturePropNextTables": { "length": 252, "table_ids": [ 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254 ], "type": 2 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 4 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 6 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 8 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 10 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 12 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 14 } } ], "table_id": 6 } }, { "OFPTableFeaturesStats": { "config": 0, "length": 1104, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x07", "properties": [ { "OFPTableFeaturePropInstructions": { "instruction_ids": [ { "OFPInstructionId": { "len": 4, "type": 1 } }, { "OFPInstructionId": { "len": 4, "type": 2 } }, { "OFPInstructionId": { "len": 4, "type": 3 } }, { "OFPInstructionId": { "len": 4, "type": 4 } }, { "OFPInstructionId": { "len": 4, "type": 5 } }, { "OFPInstructionId": { "len": 4, "type": 6 } } ], "length": 28, "type": 0 } }, { "OFPTableFeaturePropNextTables": { "length": 251, "table_ids": [ 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254 ], "type": 2 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 4 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 6 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 8 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 10 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 12 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 14 } } ], "table_id": 7 } }, { "OFPTableFeaturesStats": { "config": 0, "length": 1104, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x08", "properties": [ { "OFPTableFeaturePropInstructions": { "instruction_ids": [ { "OFPInstructionId": { "len": 4, "type": 1 } }, { "OFPInstructionId": { "len": 4, "type": 2 } }, { "OFPInstructionId": { "len": 4, "type": 3 } }, { "OFPInstructionId": { "len": 4, "type": 4 } }, { "OFPInstructionId": { "len": 4, "type": 5 } }, { "OFPInstructionId": { "len": 4, "type": 6 } } ], "length": 28, "type": 0 } }, { "OFPTableFeaturePropNextTables": { "length": 250, "table_ids": [ 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254 ], "type": 2 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 4 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 6 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 8 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 10 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 12 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 14 } } ], "table_id": 8 } }, { "OFPTableFeaturesStats": { "config": 0, "length": 1104, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x09", "properties": [ { "OFPTableFeaturePropInstructions": { "instruction_ids": [ { "OFPInstructionId": { "len": 4, "type": 1 } }, { "OFPInstructionId": { "len": 4, "type": 2 } }, { "OFPInstructionId": { "len": 4, "type": 3 } }, { "OFPInstructionId": { "len": 4, "type": 4 } }, { "OFPInstructionId": { "len": 4, "type": 5 } }, { "OFPInstructionId": { "len": 4, "type": 6 } } ], "length": 28, "type": 0 } }, { "OFPTableFeaturePropNextTables": { "length": 249, "table_ids": [ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254 ], "type": 2 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 4 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 6 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 8 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 10 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 12 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 14 } } ], "table_id": 9 } } ], "flags": 1, "type": 12 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-54-ofp_table_features_reply.packet.json0000664000175000017500000223554200000000000031434 0ustar00zuulzuul00000000000000{ "OFPTableFeaturesStatsReply": { "body": [ { "OFPTableFeaturesStats": { "config": 0, "length": 1168, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "\u79c1\u306e\u30c6\u30fc\u30d6\u30eb", "properties": [ { "OFPTableFeaturePropInstructions": { "instruction_ids": [ { "OFPInstructionId": { "len": 4, "type": 1 } }, { "OFPInstructionId": { "len": 4, "type": 2 } }, { "OFPInstructionId": { "len": 4, "type": 3 } }, { "OFPInstructionId": { "len": 4, "type": 4 } }, { "OFPInstructionId": { "len": 4, "type": 5 } }, { "OFPInstructionId": { "len": 4, "type": 6 } } ], "length": 28, "type": 0 } }, { "OFPTableFeaturePropNextTables": { "length": 258, "table_ids": [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254 ], "type": 2 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 4 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 6 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 8 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 10 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 12 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 14 } }, { "OFPTableFeaturePropExperimenter": { "data": [], "exp_type": 0, "experimenter": 101, "length": 12, "type": 65534 } }, { "OFPTableFeaturePropExperimenter": { "data": [ 1 ], "exp_type": 1, "experimenter": 101, "length": 16, "type": 65534 } }, { "OFPTableFeaturePropExperimenter": { "data": [ 1, 2 ], "exp_type": 2, "experimenter": 101, "length": 20, "type": 65534 } } ], "table_id": 0 } }, { "OFPTableFeaturesStats": { "config": 0, "length": 1112, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x01", "properties": [ { "OFPTableFeaturePropInstructions": { "instruction_ids": [ { "OFPInstructionId": { "len": 4, "type": 1 } }, { "OFPInstructionId": { "len": 4, "type": 2 } }, { "OFPInstructionId": { "len": 4, "type": 3 } }, { "OFPInstructionId": { "len": 4, "type": 4 } }, { "OFPInstructionId": { "len": 4, "type": 5 } }, { "OFPInstructionId": { "len": 4, "type": 6 } } ], "length": 28, "type": 0 } }, { "OFPTableFeaturePropNextTables": { "length": 257, "table_ids": [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254 ], "type": 2 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 4 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 6 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 8 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 10 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 12 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 14 } } ], "table_id": 1 } }, { "OFPTableFeaturesStats": { "config": 0, "length": 1104, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x02", "properties": [ { "OFPTableFeaturePropInstructions": { "instruction_ids": [ { "OFPInstructionId": { "len": 4, "type": 1 } }, { "OFPInstructionId": { "len": 4, "type": 2 } }, { "OFPInstructionId": { "len": 4, "type": 3 } }, { "OFPInstructionId": { "len": 4, "type": 4 } }, { "OFPInstructionId": { "len": 4, "type": 5 } }, { "OFPInstructionId": { "len": 4, "type": 6 } } ], "length": 28, "type": 0 } }, { "OFPTableFeaturePropNextTables": { "length": 256, "table_ids": [ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254 ], "type": 2 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 4 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 6 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 8 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 10 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 12 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 14 } } ], "table_id": 2 } }, { "OFPTableFeaturesStats": { "config": 0, "length": 1104, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x03", "properties": [ { "OFPTableFeaturePropInstructions": { "instruction_ids": [ { "OFPInstructionId": { "len": 4, "type": 1 } }, { "OFPInstructionId": { "len": 4, "type": 2 } }, { "OFPInstructionId": { "len": 4, "type": 3 } }, { "OFPInstructionId": { "len": 4, "type": 4 } }, { "OFPInstructionId": { "len": 4, "type": 5 } }, { "OFPInstructionId": { "len": 4, "type": 6 } } ], "length": 28, "type": 0 } }, { "OFPTableFeaturePropNextTables": { "length": 255, "table_ids": [ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254 ], "type": 2 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 4 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 6 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 8 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 10 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 12 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 14 } } ], "table_id": 3 } }, { "OFPTableFeaturesStats": { "config": 0, "length": 1104, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x04", "properties": [ { "OFPTableFeaturePropInstructions": { "instruction_ids": [ { "OFPInstructionId": { "len": 4, "type": 1 } }, { "OFPInstructionId": { "len": 4, "type": 2 } }, { "OFPInstructionId": { "len": 4, "type": 3 } }, { "OFPInstructionId": { "len": 4, "type": 4 } }, { "OFPInstructionId": { "len": 4, "type": 5 } }, { "OFPInstructionId": { "len": 4, "type": 6 } } ], "length": 28, "type": 0 } }, { "OFPTableFeaturePropNextTables": { "length": 254, "table_ids": [ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254 ], "type": 2 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 4 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 6 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 8 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 10 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 12 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 14 } } ], "table_id": 4 } }, { "OFPTableFeaturesStats": { "config": 0, "length": 1104, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x05", "properties": [ { "OFPTableFeaturePropInstructions": { "instruction_ids": [ { "OFPInstructionId": { "len": 4, "type": 1 } }, { "OFPInstructionId": { "len": 4, "type": 2 } }, { "OFPInstructionId": { "len": 4, "type": 3 } }, { "OFPInstructionId": { "len": 4, "type": 4 } }, { "OFPInstructionId": { "len": 4, "type": 5 } }, { "OFPInstructionId": { "len": 4, "type": 6 } } ], "length": 28, "type": 0 } }, { "OFPTableFeaturePropNextTables": { "length": 253, "table_ids": [ 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254 ], "type": 2 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 4 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 6 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 8 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 10 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 12 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 14 } } ], "table_id": 5 } }, { "OFPTableFeaturesStats": { "config": 0, "length": 1104, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x06", "properties": [ { "OFPTableFeaturePropInstructions": { "instruction_ids": [ { "OFPInstructionId": { "len": 4, "type": 1 } }, { "OFPInstructionId": { "len": 4, "type": 2 } }, { "OFPInstructionId": { "len": 4, "type": 3 } }, { "OFPInstructionId": { "len": 4, "type": 4 } }, { "OFPInstructionId": { "len": 4, "type": 5 } }, { "OFPInstructionId": { "len": 4, "type": 6 } } ], "length": 28, "type": 0 } }, { "OFPTableFeaturePropNextTables": { "length": 252, "table_ids": [ 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254 ], "type": 2 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 4 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 6 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 8 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 10 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 12 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 14 } } ], "table_id": 6 } }, { "OFPTableFeaturesStats": { "config": 0, "length": 1104, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x07", "properties": [ { "OFPTableFeaturePropInstructions": { "instruction_ids": [ { "OFPInstructionId": { "len": 4, "type": 1 } }, { "OFPInstructionId": { "len": 4, "type": 2 } }, { "OFPInstructionId": { "len": 4, "type": 3 } }, { "OFPInstructionId": { "len": 4, "type": 4 } }, { "OFPInstructionId": { "len": 4, "type": 5 } }, { "OFPInstructionId": { "len": 4, "type": 6 } } ], "length": 28, "type": 0 } }, { "OFPTableFeaturePropNextTables": { "length": 251, "table_ids": [ 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254 ], "type": 2 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 4 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 6 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 8 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 10 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 12 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 14 } } ], "table_id": 7 } }, { "OFPTableFeaturesStats": { "config": 0, "length": 1104, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x08", "properties": [ { "OFPTableFeaturePropInstructions": { "instruction_ids": [ { "OFPInstructionId": { "len": 4, "type": 1 } }, { "OFPInstructionId": { "len": 4, "type": 2 } }, { "OFPInstructionId": { "len": 4, "type": 3 } }, { "OFPInstructionId": { "len": 4, "type": 4 } }, { "OFPInstructionId": { "len": 4, "type": 5 } }, { "OFPInstructionId": { "len": 4, "type": 6 } } ], "length": 28, "type": 0 } }, { "OFPTableFeaturePropNextTables": { "length": 250, "table_ids": [ 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254 ], "type": 2 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 4 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 6 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 8 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 10 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 12 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 14 } } ], "table_id": 8 } }, { "OFPTableFeaturesStats": { "config": 0, "length": 1104, "max_entries": 16777216, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "Flow Table 0x09", "properties": [ { "OFPTableFeaturePropInstructions": { "instruction_ids": [ { "OFPInstructionId": { "len": 4, "type": 1 } }, { "OFPInstructionId": { "len": 4, "type": 2 } }, { "OFPInstructionId": { "len": 4, "type": 3 } }, { "OFPInstructionId": { "len": 4, "type": 4 } }, { "OFPInstructionId": { "len": 4, "type": 5 } }, { "OFPInstructionId": { "len": 4, "type": 6 } } ], "length": 28, "type": 0 } }, { "OFPTableFeaturePropNextTables": { "length": 249, "table_ids": [ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254 ], "type": 2 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 4 } }, { "OFPTableFeaturePropActions": { "action_ids": [ { "OFPActionId": { "len": 4, "type": 0 } }, { "OFPActionId": { "len": 4, "type": 22 } }, { "OFPActionId": { "len": 4, "type": 21 } }, { "OFPActionId": { "len": 4, "type": 15 } }, { "OFPActionId": { "len": 4, "type": 16 } }, { "OFPActionId": { "len": 4, "type": 23 } }, { "OFPActionId": { "len": 4, "type": 24 } }, { "OFPActionId": { "len": 4, "type": 11 } }, { "OFPActionId": { "len": 4, "type": 12 } }, { "OFPActionId": { "len": 4, "type": 17 } }, { "OFPActionId": { "len": 4, "type": 18 } }, { "OFPActionId": { "len": 4, "type": 19 } }, { "OFPActionId": { "len": 4, "type": 20 } }, { "OFPActionId": { "len": 4, "type": 26 } }, { "OFPActionId": { "len": 4, "type": 27 } }, { "OFPActionId": { "len": 4, "type": 25 } } ], "length": 68, "type": 6 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 8 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 10 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 12 } }, { "OFPTableFeaturePropOxm": { "length": 152, "oxm_ids": [ { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "in_port" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "metadata" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "eth_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_vid" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "vlan_pcp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_dscp" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_ecn" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ip_proto" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv4_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "tcp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "udp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "sctp_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv4_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_op" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_spa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tpa" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_sha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "arp_tha" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_src" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_dst" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_flabel" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_type" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "icmpv6_code" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_target" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_sll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "ipv6_nd_tll" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_label" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_tc" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "mpls_bos" } }, { "OFPOxmId": { "hasmask": 0, "length": 0, "type": "pbb_isid" } } ], "type": 14 } } ], "table_id": 9 } } ], "flags": 1, "type": 12 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-55-ofp_group_stats_request.packet.json0000664000175000017500000000014600000000000031343 0ustar00zuulzuul00000000000000{ "OFPGroupStatsRequest": { "flags": 0, "group_id": 4294967292, "type": 6 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-56-ofp_group_stats_reply.packet.json0000664000175000017500000000120500000000000031004 0ustar00zuulzuul00000000000000{ "OFPGroupStatsReply": { "body": [ { "OFPGroupStats": { "bucket_stats": [ { "OFPBucketCounter": { "byte_count": 2345, "packet_count": 234 } } ], "byte_count": 12345, "duration_nsec": 609036000, "duration_sec": 9, "group_id": 1, "length": 56, "packet_count": 123, "ref_count": 2 } } ], "flags": 0, "type": 6 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-57-ofp_packet_in.packet.json0000664000175000017500000002034700000000000027165 0ustar00zuulzuul00000000000000{ "OFPPacketIn": { "buffer_id": 4026531840, "cookie": 283686884868096, "data": "", "match": { "OFPMatch": { "length": 329, "oxm_fields": [ { "OXMTlv": { "field": "in_port", "mask": null, "value": 84281096 } }, { "OXMTlv": { "field": "in_phy_port", "mask": null, "value": 16909060 } }, { "OXMTlv": { "field": "metadata", "mask": null, "value": 283686952306183 } }, { "OXMTlv": { "field": "eth_type", "mask": null, "value": 2054 } }, { "OXMTlv": { "field": "eth_dst", "mask": null, "value": "ff:ff:ff:ff:ff:ff" } }, { "OXMTlv": { "field": "eth_src", "mask": null, "value": "f2:0b:a4:7d:f8:ea" } }, { "OXMTlv": { "field": "vlan_vid", "mask": null, "value": 999 } }, { "OXMTlv": { "field": "ip_dscp", "mask": null, "value": 9 } }, { "OXMTlv": { "field": "ip_ecn", "mask": null, "value": 3 } }, { "OXMTlv": { "field": "ip_proto", "mask": null, "value": 99 } }, { "OXMTlv": { "field": "ipv4_src", "mask": null, "value": "1.2.3.4" } }, { "OXMTlv": { "field": "ipv4_dst", "mask": null, "value": "1.2.3.4" } }, { "OXMTlv": { "field": "tcp_src", "mask": null, "value": 8080 } }, { "OXMTlv": { "field": "tcp_dst", "mask": null, "value": 18080 } }, { "OXMTlv": { "field": "udp_src", "mask": null, "value": 28080 } }, { "OXMTlv": { "field": "udp_dst", "mask": null, "value": 55936 } }, { "OXMTlv": { "field": "sctp_src", "mask": null, "value": 48080 } }, { "OXMTlv": { "field": "sctp_dst", "mask": null, "value": 59328 } }, { "OXMTlv": { "field": "icmpv4_type", "mask": null, "value": 100 } }, { "OXMTlv": { "field": "icmpv4_code", "mask": null, "value": 101 } }, { "OXMTlv": { "field": "arp_op", "mask": null, "value": 1 } }, { "OXMTlv": { "field": "arp_spa", "mask": null, "value": "10.0.0.1" } }, { "OXMTlv": { "field": "arp_tpa", "mask": null, "value": "10.0.0.3" } }, { "OXMTlv": { "field": "arp_sha", "mask": null, "value": "f2:0b:a4:7d:f8:ea" } }, { "OXMTlv": { "field": "arp_tha", "mask": null, "value": "00:00:00:00:00:00" } }, { "OXMTlv": { "field": "ipv6_src", "mask": null, "value": "fe80::f00b:a4ff:fe48:28a5" } }, { "OXMTlv": { "field": "ipv6_dst", "mask": null, "value": "fe80::f00b:a4ff:fe05:b7dc" } }, { "OXMTlv": { "field": "ipv6_flabel", "mask": null, "value": 541473 } }, { "OXMTlv": { "field": "icmpv6_type", "mask": null, "value": 200 } }, { "OXMTlv": { "field": "icmpv6_code", "mask": null, "value": 201 } }, { "OXMTlv": { "field": "ipv6_nd_target", "mask": null, "value": "fe80::a60:6eff:fe7f:74e7" } }, { "OXMTlv": { "field": "ipv6_nd_sll", "mask": null, "value": "00:00:00:00:02:9a" } }, { "OXMTlv": { "field": "ipv6_nd_tll", "mask": null, "value": "00:00:00:00:02:2b" } }, { "OXMTlv": { "field": "mpls_label", "mask": null, "value": 624485 } }, { "OXMTlv": { "field": "mpls_tc", "mask": null, "value": 5 } }, { "OXMTlv": { "field": "mpls_bos", "mask": null, "value": 1 } }, { "OXMTlv": { "field": "pbb_isid", "mask": null, "value": 11259375 } }, { "OXMTlv": { "field": "tunnel_id", "mask": null, "value": 651061555542690057 } }, { "OXMTlv": { "field": "ipv6_exthdr", "mask": null, "value": 500 } }, { "OXMTlv": { "field": "pbb_uca", "mask": null, "value": 1 } } ], "type": 1 } }, "reason": 0, "table_id": 200, "total_len": 0 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-58-ofp_flow_mod.packet.json0000664000175000017500000002061300000000000027033 0ustar00zuulzuul00000000000000{ "OFPFlowMod": { "buffer_id": 65535, "command": 0, "cookie": 0, "cookie_mask": 0, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "importance": 0, "instructions": [], "match": { "OFPMatch": { "length": 329, "oxm_fields": [ { "OXMTlv": { "field": "in_port", "mask": null, "value": 84281096 } }, { "OXMTlv": { "field": "in_phy_port", "mask": null, "value": 16909060 } }, { "OXMTlv": { "field": "metadata", "mask": null, "value": 283686952306183 } }, { "OXMTlv": { "field": "eth_type", "mask": null, "value": 2054 } }, { "OXMTlv": { "field": "eth_dst", "mask": null, "value": "ff:ff:ff:ff:ff:ff" } }, { "OXMTlv": { "field": "eth_src", "mask": null, "value": "f2:0b:a4:7d:f8:ea" } }, { "OXMTlv": { "field": "vlan_vid", "mask": null, "value": 999 } }, { "OXMTlv": { "field": "ip_dscp", "mask": null, "value": 9 } }, { "OXMTlv": { "field": "ip_ecn", "mask": null, "value": 3 } }, { "OXMTlv": { "field": "ip_proto", "mask": null, "value": 99 } }, { "OXMTlv": { "field": "ipv4_src", "mask": null, "value": "1.2.3.4" } }, { "OXMTlv": { "field": "ipv4_dst", "mask": null, "value": "1.2.3.4" } }, { "OXMTlv": { "field": "tcp_src", "mask": null, "value": 8080 } }, { "OXMTlv": { "field": "tcp_dst", "mask": null, "value": 18080 } }, { "OXMTlv": { "field": "udp_src", "mask": null, "value": 28080 } }, { "OXMTlv": { "field": "udp_dst", "mask": null, "value": 55936 } }, { "OXMTlv": { "field": "sctp_src", "mask": null, "value": 48080 } }, { "OXMTlv": { "field": "sctp_dst", "mask": null, "value": 59328 } }, { "OXMTlv": { "field": "icmpv4_type", "mask": null, "value": 100 } }, { "OXMTlv": { "field": "icmpv4_code", "mask": null, "value": 101 } }, { "OXMTlv": { "field": "arp_op", "mask": null, "value": 1 } }, { "OXMTlv": { "field": "arp_spa", "mask": null, "value": "10.0.0.1" } }, { "OXMTlv": { "field": "arp_tpa", "mask": null, "value": "10.0.0.3" } }, { "OXMTlv": { "field": "arp_sha", "mask": null, "value": "f2:0b:a4:7d:f8:ea" } }, { "OXMTlv": { "field": "arp_tha", "mask": null, "value": "00:00:00:00:00:00" } }, { "OXMTlv": { "field": "ipv6_src", "mask": null, "value": "fe80::f00b:a4ff:fe48:28a5" } }, { "OXMTlv": { "field": "ipv6_dst", "mask": null, "value": "fe80::f00b:a4ff:fe05:b7dc" } }, { "OXMTlv": { "field": "ipv6_flabel", "mask": null, "value": 541473 } }, { "OXMTlv": { "field": "icmpv6_type", "mask": null, "value": 200 } }, { "OXMTlv": { "field": "icmpv6_code", "mask": null, "value": 201 } }, { "OXMTlv": { "field": "ipv6_nd_target", "mask": null, "value": "fe80::a60:6eff:fe7f:74e7" } }, { "OXMTlv": { "field": "ipv6_nd_sll", "mask": null, "value": "00:00:00:00:02:9a" } }, { "OXMTlv": { "field": "ipv6_nd_tll", "mask": null, "value": "00:00:00:00:02:2b" } }, { "OXMTlv": { "field": "mpls_label", "mask": null, "value": 624485 } }, { "OXMTlv": { "field": "mpls_tc", "mask": null, "value": 5 } }, { "OXMTlv": { "field": "mpls_bos", "mask": null, "value": 1 } }, { "OXMTlv": { "field": "pbb_isid", "mask": null, "value": 11259375 } }, { "OXMTlv": { "field": "tunnel_id", "mask": null, "value": 651061555542690057 } }, { "OXMTlv": { "field": "ipv6_exthdr", "mask": null, "value": 500 } }, { "OXMTlv": { "field": "pbb_uca", "mask": null, "value": 1 } } ], "type": 1 } }, "out_group": 4294967295, "out_port": 4294967295, "priority": 123, "table_id": 1 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-59-ofp_experimenter_request.packet.json0000664000175000017500000000026100000000000031502 0ustar00zuulzuul00000000000000{ "OFPExperimenterStatsRequest": { "data": "aG9nZWhvZ2U=", "exp_type": 3405678728, "experimenter": 3735928495, "flags": 0, "type": 65535 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-6-ofp_features_reply.packet.json0000664000175000017500000000024700000000000030170 0ustar00zuulzuul00000000000000{ "OFPSwitchFeatures": { "auxiliary_id": 99, "capabilities": 79, "datapath_id": 9210263729383, "n_buffers": 0, "n_tables": 255 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-60-ofp_experimenter_reply.packet.json0000664000175000017500000000042700000000000031141 0ustar00zuulzuul00000000000000{ "OFPExperimenterStatsReply": { "body": { "OFPExperimenterMultipart": { "data": "dGVzdGRhdGE5OTk5OTk5OQ==", "exp_type": 3405674359, "experimenter": 3735928495 } }, "flags": 0, "type": 65535 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-61-ofp_table_desc_request.packet.json0000664000175000017500000000011500000000000031047 0ustar00zuulzuul00000000000000{ "OFPTableDescStatsRequest": { "flags": 0, "type": 14 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-62-ofp_table_desc_reply.packet.json0000664000175000017500000000456600000000000030531 0ustar00zuulzuul00000000000000{ "OFPTableDescStatsReply": { "body": [ { "OFPTableDesc": { "config": 0, "length": 24, "properties": [ { "OFPTableModPropExperimenter": { "data": [], "exp_type": 0, "experimenter": 101, "length": 12, "type": 65535 } } ], "table_id": 7 } }, { "OFPTableDesc": { "config": 0, "length": 80, "properties": [ { "OFPTableModPropEviction": { "flags": 0, "length": 8, "type": 2 } }, { "OFPTableModPropVacancy": { "length": 8, "type": 3, "vacancy": 0, "vacancy_down": 0, "vacancy_up": 0 } }, { "OFPTableModPropExperimenter": { "data": [], "exp_type": 0, "experimenter": 101, "length": 12, "type": 65535 } }, { "OFPTableModPropExperimenter": { "data": [ 1 ], "exp_type": 1, "experimenter": 101, "length": 16, "type": 65535 } }, { "OFPTableModPropExperimenter": { "data": [ 1, 2 ], "exp_type": 2, "experimenter": 101, "length": 20, "type": 65535 } } ], "table_id": 8 } } ], "flags": 0, "type": 14 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-63-ofp_queue_desc_request.packet.json0000664000175000017500000000017700000000000031116 0ustar00zuulzuul00000000000000{ "OFPQueueDescStatsRequest": { "flags": 0, "port_no": 7, "queue_id": 4294967295, "type": 15 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-64-ofp_queue_desc_reply.packet.json0000664000175000017500000000444300000000000030562 0ustar00zuulzuul00000000000000{ "OFPQueueDescStatsReply": { "body": [ { "OFPQueueDesc": { "len": 32, "port_no": 7, "properties": [ { "OFPQueueDescPropExperimenter": { "data": [], "exp_type": 0, "experimenter": 101, "length": 12, "type": 65535 } } ], "queue_id": 0 } }, { "OFPQueueDesc": { "len": 88, "port_no": 8, "properties": [ { "OFPQueueDescPropMinRate": { "length": 8, "rate": 300, "type": 1 } }, { "OFPQueueDescPropMaxRate": { "length": 8, "rate": 900, "type": 2 } }, { "OFPQueueDescPropExperimenter": { "data": [], "exp_type": 0, "experimenter": 101, "length": 12, "type": 65535 } }, { "OFPQueueDescPropExperimenter": { "data": [ 1 ], "exp_type": 1, "experimenter": 101, "length": 16, "type": 65535 } }, { "OFPQueueDescPropExperimenter": { "data": [ 1, 2 ], "exp_type": 2, "experimenter": 101, "length": 20, "type": 65535 } } ], "queue_id": 1 } } ], "flags": 0, "type": 15 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-65-ofp_role_status.packet.json0000664000175000017500000000160600000000000027570 0ustar00zuulzuul00000000000000{ "OFPRoleStatus": { "generation_id": 7, "properties": [ { "OFPRolePropExperimenter": { "data": [], "exp_type": 0, "experimenter": 101, "length": 12, "type": 65535 } }, { "OFPRolePropExperimenter": { "data": [ 1 ], "exp_type": 1, "experimenter": 101, "length": 16, "type": 65535 } }, { "OFPRolePropExperimenter": { "data": [ 1, 2 ], "exp_type": 2, "experimenter": 101, "length": 20, "type": 65535 } } ], "reason": 0, "role": 2 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-66-ofp_flow_monitor_request.packet.json0000664000175000017500000000111400000000000031505 0ustar00zuulzuul00000000000000{ "OFPFlowMonitorRequest": { "command": 0, "flags": 0, "match": { "OFPMatch": { "length": 14, "oxm_fields": [ { "OXMTlv": { "field": "eth_dst", "mask": null, "value": "f2:0b:a4:7d:f8:ea" } } ], "type": 1 } }, "monitor_flags": 15, "monitor_id": 100000000, "out_group": 4294967295, "out_port": 22, "table_id": 33, "type": 16 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-67-ofp_flow_monitor_reply.packet.json0000664000175000017500000000341000000000000031152 0ustar00zuulzuul00000000000000{ "OFPFlowMonitorReply": { "body": [ { "OFPFlowUpdateFull": { "cookie": 0, "event": 0, "hard_timeout": 700, "idle_timeout": 600, "instructions": [ { "OFPInstructionActions": { "actions": [ { "OFPActionOutput": { "len": 16, "max_len": 0, "port": 4294967290, "type": 0 } } ], "len": 24, "type": 4 } } ], "length": 64, "match": { "OFPMatch": { "length": 10, "oxm_fields": [ { "OXMTlv": { "field": "eth_type", "mask": null, "value": 2054 } } ], "type": 1 } }, "priority": 3, "reason": 0, "table_id": 0 } }, { "OFPFlowUpdateAbbrev": { "event": 4, "length": 8, "xid": 1234 } }, { "OFPFlowUpdatePaused": { "event": 5, "length": 8 } } ], "flags": 0, "type": 16 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-68-ofp_table_status.packet.json0000664000175000017500000000324000000000000027715 0ustar00zuulzuul00000000000000{ "OFPTableStatus": { "reason": 3, "table": { "OFPTableDesc": { "config": 0, "length": 80, "properties": [ { "OFPTableModPropEviction": { "flags": 0, "length": 8, "type": 2 } }, { "OFPTableModPropVacancy": { "length": 8, "type": 3, "vacancy": 0, "vacancy_down": 0, "vacancy_up": 0 } }, { "OFPTableModPropExperimenter": { "data": [], "exp_type": 0, "experimenter": 101, "length": 12, "type": 65535 } }, { "OFPTableModPropExperimenter": { "data": [ 1 ], "exp_type": 1, "experimenter": 101, "length": 16, "type": 65535 } }, { "OFPTableModPropExperimenter": { "data": [ 1, 2 ], "exp_type": 2, "experimenter": 101, "length": 20, "type": 65535 } } ], "table_id": 8 } } } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-69-ofp_bundle_ctrl_msg.packet.json0000664000175000017500000000161500000000000030373 0ustar00zuulzuul00000000000000{ "OFPBundleCtrlMsg": { "bundle_id": 1234, "flags": 1, "properties": [ { "OFPBundlePropExperimenter": { "data": [], "exp_type": 0, "experimenter": 101, "length": 12, "type": 65535 } }, { "OFPBundlePropExperimenter": { "data": [ 1 ], "exp_type": 1, "experimenter": 101, "length": 16, "type": 65535 } }, { "OFPBundlePropExperimenter": { "data": [ 1, 2 ], "exp_type": 2, "experimenter": 101, "length": 20, "type": 65535 } } ], "type": 0 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-7-ofp_set_config.packet.json0000664000175000017500000000011300000000000027250 0ustar00zuulzuul00000000000000{ "OFPSetConfig": { "flags": 0, "miss_send_len": 128 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-70-ofp_bundle_add_msg.packet.json0000664000175000017500000000173000000000000030145 0ustar00zuulzuul00000000000000{ "OFPBundleAddMsg": { "bundle_id": 1234, "flags": 1, "message": { "OFPEchoRequest": { "data": null } }, "properties": [ { "OFPBundlePropExperimenter": { "data": [], "exp_type": 0, "experimenter": 101, "length": 12, "type": 65535 } }, { "OFPBundlePropExperimenter": { "data": [ 1 ], "exp_type": 1, "experimenter": 101, "length": 16, "type": 65535 } }, { "OFPBundlePropExperimenter": { "data": [ 1, 2 ], "exp_type": 2, "experimenter": 101, "length": 20, "type": 65535 } } ] } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-71-ofp_requestforward.packet.json0000664000175000017500000000144000000000000030272 0ustar00zuulzuul00000000000000{ "OFPRequestForward": { "request": { "OFPGroupMod": { "buckets": [ { "OFPBucket": { "actions": [ { "OFPActionOutput": { "len": 16, "max_len": 65535, "port": 2, "type": 0 } } ], "len": 32, "watch_group": 1, "watch_port": 1, "weight": 1 } } ], "command": 0, "group_id": 1, "type": 0 } } } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-8-ofp_get_config_request.packet.json0000664000175000017500000000004100000000000031005 0ustar00zuulzuul00000000000000{ "OFPGetConfigRequest": {} } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/5-9-ofp_get_config_reply.packet.json0000664000175000017500000000012000000000000030447 0ustar00zuulzuul00000000000000{ "OFPGetConfigReply": { "flags": 0, "miss_send_len": 128 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/lib-ofctl-ofp_table_features_request.packet.json0000664000175000017500000000014300000000000033233 0ustar00zuulzuul00000000000000{ "OFPTableFeaturesStatsRequest": { "body": [], "flags": 0, "type": 12 } } ././@PaxHeader0000000000000000000000000000021400000000000011452 xustar0000000000000000118 path=os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/libofproto-OFP14-ofp_packet_out_packet_library.packet.json 22 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of14/libofproto-OFP14-ofp_packet_out_packet_library.pac0000664000175000017500000000324300000000000033332 0ustar00zuulzuul00000000000000{ "OFPPacketOut": { "actions": [ { "OFPActionOutput": { "len": 16, "max_len": 65535, "port": 4294967292, "type": 0 } } ], "actions_len": 16, "buffer_id": 4294967295, "data": { "Packet": { "protocols": [ { "ethernet": { "dst": "f2:0b:a4:d0:3f:70", "ethertype": 2048, "src": "f2:0b:a4:7d:f8:ea" } }, { "ipv4": { "csum": 44939, "dst": "10.0.0.2", "flags": 0, "header_length": 5, "identification": 63514, "offset": 0, "option": null, "proto": 1, "src": "10.0.0.1", "tos": 0, "total_length": 84, "ttl": 255, "version": 4 } }, { "icmp": { "code": 0, "csum": 520, "data": { "echo": { "data": "MdYCAAAAAACrjS0xAAAAABAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vAAAAAAAAAAA=", "id": 63328, "seq": 0 } }, "type": 8 } } ] } }, "in_port": 4294967293 } } ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.3581202 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/0000775000175000017500000000000000000000000021623 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/lib-ofctl-OFP15-flow_desc_reply.packet.json0000664000175000017500000001037700000000000031615 0ustar00zuulzuul00000000000000{ "OFPFlowDescStatsReply": { "body": [ { "OFPFlowDesc": { "cookie": 1234605616436508552, "flags": 1, "hard_timeout": 255, "idle_timeout": 255, "importance": 43690, "instructions": [ { "OFPInstructionGotoTable": { "len": 8, "table_id": 2, "type": 1 } }, { "OFPInstructionActions": { "actions": [ { "OFPActionMeter": { "len": 8, "meter_id": 2, "type": 29 } } ], "len": 8, "type": 3 } }, { "OFPInstructionActions": { "actions": [ { "OFPActionCopyField": { "type": 28, "len": 20, "n_bits": 32, "src_offset": 1, "dst_offset": 2, "oxm_ids": [ { "OFPOxmId": { "hasmask": false, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": false, "length": 0, "type": "eth_dst" } } ] } } ], "len": 28, "type": 4 } } ], "length": 84, "match": { "OFPMatch": { "length": 12, "oxm_fields": [ { "OXMTlv": { "field": "in_port", "mask": null, "value": 1 } } ], "type": 1 } }, "priority": 5, "stats": { "OFPStats": { "length": 12, "oxs_fields": [ { "OXSTlv": { "field": "flow_count", "value": 1 } } ] } }, "table_id": 1 } } ], "flags": 0, "type": 1 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/lib-ofctl-OFP15-flow_desc_request.packet.json0000664000175000017500000000123100000000000032137 0ustar00zuulzuul00000000000000{ "OFPFlowDescStatsRequest": { "cookie": 1234605616436508552, "cookie_mask": 18446744073709551615, "flags": 0, "match": { "OFPMatch": { "length": 12, "oxm_fields": [ { "OXMTlv": { "field": "in_port", "mask": null, "value": 1 } } ], "type": 1 } }, "out_group": 4294967295, "out_port": 4294967295, "table_id": 1, "type": 1 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/lib-ofctl-OFP15-flow_mod.packet.json0000664000175000017500000001571400000000000030243 0ustar00zuulzuul00000000000000{ "OFPFlowMod": { "buffer_id": 65535, "command": 0, "cookie": 0, "cookie_mask": 0, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "importance": 0, "instructions": [ { "OFPInstructionActions": { "actions": [ { "OFPActionSetField": { "field": { "OXMTlv": { "field": "vlan_vid", "mask": null, "value": 258 } }, "len": 16, "type": 25 } }, { "OFPActionCopyTtlOut": { "len": 8, "type": 11 } }, { "OFPActionCopyTtlIn": { "len": 8, "type": 12 } }, { "OFPActionCopyTtlIn": { "len": 8, "type": 12 } }, { "OFPActionPopPbb": { "len": 8, "type": 27 } }, { "OFPActionPushPbb": { "ethertype": 4660, "len": 8, "type": 26 } }, { "OFPActionPopMpls": { "ethertype": 39030, "len": 8, "type": 20 } }, { "OFPActionPushMpls": { "ethertype": 34887, "len": 8, "type": 19 } }, { "OFPActionPopVlan": { "len": 8, "type": 18 } }, { "OFPActionPushVlan": { "ethertype": 33024, "len": 8, "type": 17 } }, { "OFPActionDecMplsTtl": { "len": 8, "type": 16 } }, { "OFPActionSetMplsTtl": { "len": 8, "mpls_ttl": 10, "type": 15 } }, { "OFPActionDecNwTtl": { "len": 8, "type": 24 } }, { "OFPActionSetNwTtl": { "len": 8, "nw_ttl": 10, "type": 23 } }, { "OFPActionExperimenterUnknown": { "data": "AAECAwQFBgc=", "experimenter": 101, "len": 16, "type": 65535 } }, { "OFPActionSetQueue": { "len": 8, "queue_id": 3, "type": 21 } }, { "OFPActionMeter": { "len": 8, "meter_id": 2, "type": 29 } }, { "OFPActionGroup": { "group_id": 99, "len": 8, "type": 22 } }, { "OFPActionOutput": { "len": 16, "max_len": 65535, "port": 6, "type": 0 } } ], "len": 176, "type": 3 } }, { "OFPInstructionActions": { "actions": [ { "OFPActionSetField": { "field": { "OXMTlv": { "field": "eth_src", "mask": null, "value": "01:02:03:04:05:06" } }, "len": 16, "type": 25 } }, { "OFPActionSetField": { "field": { "OXMTlv": { "field": "pbb_uca", "mask": null, "value": 1 } }, "len": 16, "type": 25 } }, { "OFPActionCopyField": { "type": 28, "len": 20, "n_bits": 32, "src_offset": 1, "dst_offset": 2, "oxm_ids": [ { "OFPOxmId": { "hasmask": false, "length": 0, "type": "eth_src" } }, { "OFPOxmId": { "hasmask": false, "length": 0, "type": "eth_dst" } } ] } } ], "len": 60, "type": 4 } } ], "match": { "OFPMatch": { "length": 14, "oxm_fields": [ { "OXMTlv": { "field": "eth_dst", "mask": null, "value": "f2:0b:a4:7d:f8:ea" } } ], "type": 1 } }, "out_group": 4294967295, "out_port": 4294967295, "priority": 123, "table_id": 1 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/lib-ofctl-ofp_queue_stats_request.packet.json0000664000175000017500000000020300000000000032606 0ustar00zuulzuul00000000000000{ "OFPQueueStatsRequest": { "flags": 0, "port_no": 4294967295, "queue_id": 4294967295, "type": 5 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/lib-ofctl-ofp_table_features_request.packet.json0000664000175000017500000000014300000000000033234 0ustar00zuulzuul00000000000000{ "OFPTableFeaturesStatsRequest": { "body": [], "flags": 0, "type": 12 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-aggregate_stats_reply.packet.json0000664000175000017500000000117500000000000033314 0ustar00zuulzuul00000000000000{ "OFPAggregateStatsReply": { "body": { "OFPAggregateStats": { "length": 16, "stats": { "OFPStats": { "length": 12, "oxs_fields": [ { "OXSTlv": { "field": "flow_count", "value": 1 } } ] } } } }, "flags": 0, "type": 2 } } ././@PaxHeader0000000000000000000000000000020600000000000011453 xustar0000000000000000112 path=os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-aggregate_stats_request.packet.json 22 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-aggregate_stats_request.packet.js0000664000175000017500000000052400000000000033311 0ustar00zuulzuul00000000000000{ "OFPAggregateStatsRequest": { "cookie": 0, "cookie_mask": 0, "flags": 0, "match": { "OFPMatch": { "length": 4, "oxm_fields": [], "type": 1 } }, "out_group": 4294967295, "out_port": 4294967295, "table_id": 255, "type": 2 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-barrier_reply.packet.json0000664000175000017500000000003500000000000031570 0ustar00zuulzuul00000000000000{ "OFPBarrierReply": {} } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-barrier_request.packet.json0000664000175000017500000000003700000000000032127 0ustar00zuulzuul00000000000000{ "OFPBarrierRequest": {} } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-bundle_add.packet.json0000664000175000017500000001633200000000000031017 0ustar00zuulzuul00000000000000{ "OFPBundleAddMsg": { "bundle_id": 99999999, "flags": 1, "message": { "OFPFlowMod": { "buffer_id": 0, "command": 0, "cookie": 1311768467463790320, "cookie_mask": 18446744073709551615, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "importance": 39032, "instructions": [ { "OFPInstructionActions": { "actions": [ { "OFPActionPopVlan": { "len": 8, "type": 18 } }, { "OFPActionSetField": { "field": { "OXMTlv": { "field": "ipv4_dst", "mask": null, "value": "192.168.2.9" } }, "len": 16, "type": 25 } }, { "NXActionLearn": { "cookie": 0, "experimenter": 8992, "fin_hard_timeout": 0, "fin_idle_timeout": 0, "flags": 0, "hard_timeout": 300, "idle_timeout": 0, "len": 96, "priority": 1, "specs": [ { "NXFlowSpecMatch": { "dst": [ "vlan_vid", 0 ], "n_bits": 12, "src": [ "vlan_vid", 0 ] } }, { "NXFlowSpecMatch": { "dst": [ "eth_dst_nxm", 0 ], "n_bits": 48, "src": [ "eth_src_nxm", 0 ] } }, { "NXFlowSpecLoad": { "dst": [ "vlan_vid", 0 ], "n_bits": 12, "src": 0 } }, { "NXFlowSpecLoad": { "dst": [ "tunnel_id_nxm", 0 ], "n_bits": 64, "src": [ "tunnel_id_nxm", 0 ] } }, { "NXFlowSpecOutput": { "dst": "", "n_bits": 32, "src": [ "in_port", 0 ] } } ], "subtype": 16, "table_id": 99, "type": 65535 } } ], "len": 128, "type": 4 } }, { "OFPInstructionGotoTable": { "len": 8, "table_id": 100, "type": 1 } } ], "match": { "OFPMatch": { "length": 70, "oxm_fields": [ { "OXMTlv": { "field": "in_port", "mask": null, "value": 43981 } }, { "OXMTlv": { "field": "eth_dst", "mask": null, "value": "aa:bb:cc:99:88:77" } }, { "OXMTlv": { "field": "eth_type", "mask": null, "value": 2048 } }, { "OXMTlv": { "field": "vlan_vid", "mask": null, "value": 5095 } }, { "OXMTlv": { "field": "ipv4_dst", "mask": null, "value": "192.168.2.1" } }, { "OXMTlv": { "field": "tunnel_id", "mask": null, "value": 50000 } }, { "OXMTlv": { "field": "tun_ipv4_src", "mask": null, "value": "192.168.2.3" } }, { "OXMTlv": { "field": "tun_ipv4_dst", "mask": null, "value": "192.168.2.4" } } ], "type": 1 } }, "out_group": 0, "out_port": 0, "priority": 0, "table_id": 2 } }, "properties": [] } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-bundle_ctrl.packet.json0000664000175000017500000000017100000000000031225 0ustar00zuulzuul00000000000000{ "OFPBundleCtrlMsg": { "bundle_id": 99999999, "flags": 1, "properties": [], "type": 1 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-bundle_features_reply.packet.json0000664000175000017500000000311200000000000033310 0ustar00zuulzuul00000000000000{ "OFPBundleFeaturesStatsReply": { "body": { "OFPBundleFeaturesStats": { "capabilities": 7, "properties": [ { "OFPBundleFeaturesPropTime": { "length": 72, "sched_accuracy": { "OFPTime": { "nanoseconds": 1717986918, "seconds": 6148914691236517205 } }, "sched_max_future": { "OFPTime": { "nanoseconds": 2290649224, "seconds": 8608480567731124087 } }, "sched_max_past": { "OFPTime": { "nanoseconds": 2863311530, "seconds": 11068046444225730969 } }, "timestamp": { "OFPTime": { "nanoseconds": 3435973836, "seconds": 13527612320720337851 } }, "type": 1 } } ] } }, "flags": 0, "type": 19 } } ././@PaxHeader0000000000000000000000000000020600000000000011453 xustar0000000000000000112 path=os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-bundle_features_request.packet.json 22 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-bundle_features_request.packet.js0000664000175000017500000000237300000000000033320 0ustar00zuulzuul00000000000000{ "OFPBundleFeaturesStatsRequest": { "feature_request_flags": 3, "flags": 0, "properties": [ { "OFPBundleFeaturesPropTime": { "length": 72, "sched_accuracy": { "OFPTime": { "nanoseconds": 1717986918, "seconds": 6148914691236517205 } }, "sched_max_future": { "OFPTime": { "nanoseconds": 2290649224, "seconds": 8608480567731124087 } }, "sched_max_past": { "OFPTime": { "nanoseconds": 2863311530, "seconds": 11068046444225730969 } }, "timestamp": { "OFPTime": { "nanoseconds": 3435973836, "seconds": 13527612320720337851 } }, "type": 1 } } ], "type": 19 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-controller_status.packet.json0000664000175000017500000000113000000000000032512 0ustar00zuulzuul00000000000000{ "OFPControllerStatus": { "status": { "OFPControllerStatusStats": { "channel_status": 1, "length": 48, "properties": [ { "OFPControllerStatusPropUri": { "length": 26, "type": 0, "uri": "tls:192.168.34.23:6653" } } ], "reason": 1, "role": 1, "short_id": 65535 } } } } ././@PaxHeader0000000000000000000000000000020600000000000011453 xustar0000000000000000112 path=os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-controller_status_reply.packet.json 22 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-controller_status_reply.packet.js0000664000175000017500000000134400000000000033377 0ustar00zuulzuul00000000000000{ "OFPControllerStatusStatsReply": { "body": [ { "OFPControllerStatusStats": { "channel_status": 1, "length": 48, "properties": [ { "OFPControllerStatusPropUri": { "length": 26, "type": 0, "uri": "tls:192.168.34.23:6653" } } ], "reason": 1, "role": 1, "short_id": 65535 } } ], "flags": 0, "type": 18 } } ././@PaxHeader0000000000000000000000000000021000000000000011446 xustar0000000000000000114 path=os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-controller_status_request.packet.json 22 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-controller_status_request.packet.0000664000175000017500000000013200000000000033371 0ustar00zuulzuul00000000000000{ "OFPControllerStatusStatsRequest": { "flags": 0, "type": 18 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-desc_reply.packet.json0000664000175000017500000000043500000000000031064 0ustar00zuulzuul00000000000000{ "OFPDescStatsReply": { "body": { "OFPDescStats": { "dp_desc": "dp", "hw_desc": "hw", "mfr_desc": "mfr", "serial_num": "serial", "sw_desc": "sw" } }, "flags": 0, "type": 0 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-desc_request.packet.json0000664000175000017500000000010700000000000031415 0ustar00zuulzuul00000000000000{ "OFPDescStatsRequest": { "flags": 0, "type": 0 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-echo_reply.packet.json0000664000175000017500000000005700000000000031064 0ustar00zuulzuul00000000000000{ "OFPEchoReply": { "data": "" } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-echo_request.packet.json0000664000175000017500000000006100000000000031414 0ustar00zuulzuul00000000000000{ "OFPEchoRequest": { "data": "" } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-error_msg.packet.json0000664000175000017500000000013400000000000030726 0ustar00zuulzuul00000000000000{ "OFPErrorMsg": { "code": 6, "data": "Bg4ACAAAAAA=", "type": 4 } } ././@PaxHeader0000000000000000000000000000020500000000000011452 xustar0000000000000000111 path=os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-error_msg_experimenter.packet.json 22 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-error_msg_experimenter.packet.jso0000664000175000017500000000023600000000000033342 0ustar00zuulzuul00000000000000{ "OFPErrorMsg": { "code": null, "data": "amlra2VuIGRhdGE=", "exp_type": 60000, "experimenter": 999999, "type": 65535 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-experimenter.packet.json0000664000175000017500000000016700000000000031444 0ustar00zuulzuul00000000000000{ "OFPExperimenter": { "data": "bmF6bw==", "exp_type": 123456789, "experimenter": 98765432 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-experimenter_reply.packet.json0000664000175000017500000000042700000000000032656 0ustar00zuulzuul00000000000000{ "OFPExperimenterStatsReply": { "body": { "OFPExperimenterMultipart": { "data": "dGVzdGRhdGE5OTk5OTk5OQ==", "exp_type": 3405674359, "experimenter": 3735928495 } }, "flags": 0, "type": 65535 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-experimenter_request.packet.json0000664000175000017500000000026100000000000033207 0ustar00zuulzuul00000000000000{ "OFPExperimenterStatsRequest": { "data": "aG9nZWhvZ2U=", "exp_type": 3405678728, "experimenter": 3735928495, "flags": 0, "type": 65535 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-features_reply.packet.json0000664000175000017500000000023400000000000031761 0ustar00zuulzuul00000000000000{ "OFPSwitchFeatures": { "auxiliary_id": 0, "capabilities": 79, "datapath_id": 1, "n_buffers": 255, "n_tables": 255 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-features_request.packet.json0000664000175000017500000000004000000000000032311 0ustar00zuulzuul00000000000000{ "OFPFeaturesRequest": {} } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-flow_desc_reply.packet.json0000664000175000017500000000360100000000000032111 0ustar00zuulzuul00000000000000{ "OFPFlowDescStatsReply": { "body": [ { "OFPFlowDesc": { "cookie": 1234605616436508552, "flags": 1, "hard_timeout": 255, "idle_timeout": 255, "importance": 43690, "instructions": [ { "OFPInstructionGotoTable": { "len": 8, "table_id": 2, "type": 1 } } ], "length": 64, "match": { "OFPMatch": { "length": 12, "oxm_fields": [ { "OXMTlv": { "field": "in_port", "mask": null, "value": 1 } } ], "type": 1 } }, "priority": 5, "stats": { "OFPStats": { "length": 12, "oxs_fields": [ { "OXSTlv": { "field": "flow_count", "value": 1 } } ] } }, "table_id": 1 } } ], "flags": 0, "type": 1 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-flow_desc_request.packet.json0000664000175000017500000000123100000000000032443 0ustar00zuulzuul00000000000000{ "OFPFlowDescStatsRequest": { "cookie": 1234605616436508552, "cookie_mask": 18446744073709551615, "flags": 0, "match": { "OFPMatch": { "length": 12, "oxm_fields": [ { "OXMTlv": { "field": "in_port", "mask": null, "value": 1 } } ], "type": 1 } }, "out_group": 4294967295, "out_port": 4294967295, "table_id": 1, "type": 1 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-flow_mod.packet.json0000664000175000017500000001374100000000000030545 0ustar00zuulzuul00000000000000{ "OFPFlowMod": { "buffer_id": 0, "command": 0, "cookie": 1311768467463790320, "cookie_mask": 18446744073709551615, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "importance": 39032, "instructions": [ { "OFPInstructionActions": { "actions": [ { "OFPActionPopVlan": { "len": 8, "type": 18 } }, { "OFPActionSetField": { "field": { "OXMTlv": { "field": "ipv4_dst", "mask": null, "value": "192.168.2.9" } }, "len": 16, "type": 25 } }, { "NXActionLearn": { "cookie": 0, "experimenter": 8992, "fin_hard_timeout": 0, "fin_idle_timeout": 0, "flags": 0, "hard_timeout": 300, "idle_timeout": 0, "len": 96, "priority": 1, "specs": [ { "NXFlowSpecMatch": { "dst": [ "vlan_vid", 0 ], "n_bits": 12, "src": [ "vlan_vid", 0 ] } }, { "NXFlowSpecMatch": { "dst": [ "eth_dst_nxm", 0 ], "n_bits": 48, "src": [ "eth_src_nxm", 0 ] } }, { "NXFlowSpecLoad": { "dst": [ "vlan_vid", 0 ], "n_bits": 12, "src": 0 } }, { "NXFlowSpecLoad": { "dst": [ "tunnel_id_nxm", 0 ], "n_bits": 64, "src": [ "tunnel_id_nxm", 0 ] } }, { "NXFlowSpecOutput": { "dst": "", "n_bits": 32, "src": [ "in_port", 0 ] } } ], "subtype": 16, "table_id": 99, "type": 65535 } } ], "len": 128, "type": 4 } }, { "OFPInstructionGotoTable": { "len": 8, "table_id": 100, "type": 1 } } ], "match": { "OFPMatch": { "length": 70, "oxm_fields": [ { "OXMTlv": { "field": "in_port", "mask": null, "value": 43981 } }, { "OXMTlv": { "field": "eth_dst", "mask": null, "value": "aa:bb:cc:99:88:77" } }, { "OXMTlv": { "field": "eth_type", "mask": null, "value": 2048 } }, { "OXMTlv": { "field": "vlan_vid", "mask": null, "value": 5095 } }, { "OXMTlv": { "field": "ipv4_dst", "mask": null, "value": "192.168.2.1" } }, { "OXMTlv": { "field": "tunnel_id", "mask": null, "value": 50000 } }, { "OXMTlv": { "field": "tun_ipv4_src", "mask": null, "value": "192.168.2.3" } }, { "OXMTlv": { "field": "tun_ipv4_dst", "mask": null, "value": "192.168.2.4" } } ], "type": 1 } }, "out_group": 0, "out_port": 0, "priority": 0, "table_id": 2 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-flow_mod_conjunction.packet.json0000664000175000017500000000520700000000000033154 0ustar00zuulzuul00000000000000{ "OFPFlowMod": { "buffer_id": 0, "command": 0, "cookie": 1311768467463790320, "cookie_mask": 18446744073709551615, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "importance": 39032, "instructions": [ { "OFPInstructionActions": { "actions": [ { "NXActionConjunction": { "clause": 1, "experimenter": 8992, "id": 11259375, "len": 16, "n_clauses": 2, "subtype": 34, "type": 65535 } } ], "len": 24, "type": 4 } } ], "match": { "OFPMatch": { "length": 70, "oxm_fields": [ { "OXMTlv": { "field": "in_port", "mask": null, "value": 43981 } }, { "OXMTlv": { "field": "eth_dst", "mask": null, "value": "aa:bb:cc:99:88:77" } }, { "OXMTlv": { "field": "eth_type", "mask": null, "value": 2048 } }, { "OXMTlv": { "field": "vlan_vid", "mask": null, "value": 5095 } }, { "OXMTlv": { "field": "ipv4_dst", "mask": null, "value": "192.168.2.1" } }, { "OXMTlv": { "field": "tunnel_id", "mask": null, "value": 50000 } }, { "OXMTlv": { "field": "tun_ipv4_src", "mask": null, "value": "192.168.2.3" } }, { "OXMTlv": { "field": "tun_ipv4_dst", "mask": null, "value": "192.168.2.4" } } ], "type": 1 } }, "out_group": 0, "out_port": 0, "priority": 0, "table_id": 4 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-flow_mod_match_conj.packet.json0000664000175000017500000000321300000000000032723 0ustar00zuulzuul00000000000000{ "OFPFlowMod": { "buffer_id": 0, "command": 0, "cookie": 1311768467463790320, "cookie_mask": 18446744073709551615, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "importance": 39032, "instructions": [ { "OFPInstructionActions": { "actions": [ { "OFPActionPopVlan": { "len": 8, "type": 18 } }, { "OFPActionSetField": { "field": { "OXMTlv": { "field": "ipv4_dst", "mask": null, "value": "192.168.2.9" } }, "len": 16, "type": 25 } } ], "len": 32, "type": 4 } }, { "OFPInstructionGotoTable": { "len": 8, "table_id": 100, "type": 1 } } ], "match": { "OFPMatch": { "length": 12, "oxm_fields": [ { "OXMTlv": { "field": "conj_id", "mask": null, "value": 11259375 } } ], "type": 1 } }, "out_group": 0, "out_port": 0, "priority": 0, "table_id": 3 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-flow_mod_no_nx.packet.json0000664000175000017500000001344400000000000031746 0ustar00zuulzuul00000000000000{ "OFPFlowMod": { "buffer_id": 65535, "command": 0, "cookie": 0, "cookie_mask": 0, "flags": 0, "hard_timeout": 0, "idle_timeout": 0, "importance": 0, "instructions": [ { "OFPInstructionActions": { "actions": [ { "OFPActionSetField": { "field": { "OXMTlv": { "field": "vlan_vid", "mask": null, "value": 258 } }, "len": 16, "type": 25 } }, { "OFPActionCopyTtlOut": { "len": 8, "type": 11 } }, { "OFPActionCopyTtlIn": { "len": 8, "type": 12 } }, { "OFPActionCopyTtlIn": { "len": 8, "type": 12 } }, { "OFPActionPopPbb": { "len": 8, "type": 27 } }, { "OFPActionPushPbb": { "ethertype": 4660, "len": 8, "type": 26 } }, { "OFPActionPopMpls": { "ethertype": 39030, "len": 8, "type": 20 } }, { "OFPActionPushMpls": { "ethertype": 34887, "len": 8, "type": 19 } }, { "OFPActionPopVlan": { "len": 8, "type": 18 } }, { "OFPActionPushVlan": { "ethertype": 33024, "len": 8, "type": 17 } }, { "OFPActionDecMplsTtl": { "len": 8, "type": 16 } }, { "OFPActionSetMplsTtl": { "len": 8, "mpls_ttl": 10, "type": 15 } }, { "OFPActionDecNwTtl": { "len": 8, "type": 24 } }, { "OFPActionSetNwTtl": { "len": 8, "nw_ttl": 10, "type": 23 } }, { "OFPActionExperimenterUnknown": { "data": "AAECAwQFBgc=", "experimenter": 101, "len": 16, "type": 65535 } }, { "OFPActionSetQueue": { "len": 8, "queue_id": 3, "type": 21 } }, { "OFPActionGroup": { "group_id": 99, "len": 8, "type": 22 } }, { "OFPActionOutput": { "len": 16, "max_len": 65535, "port": 6, "type": 0 } } ], "len": 176, "type": 3 } }, { "OFPInstructionActions": { "actions": [ { "OFPActionSetField": { "field": { "OXMTlv": { "field": "eth_src", "mask": null, "value": "01:02:03:04:05:06" } }, "len": 16, "type": 25 } }, { "OFPActionSetField": { "field": { "OXMTlv": { "field": "pbb_uca", "mask": null, "value": 1 } }, "len": 16, "type": 25 } } ], "len": 40, "type": 4 } } ], "match": { "OFPMatch": { "length": 14, "oxm_fields": [ { "OXMTlv": { "field": "eth_dst", "mask": null, "value": "f2:0b:a4:7d:f8:ea" } } ], "type": 1 } }, "out_group": 4294967295, "out_port": 4294967295, "priority": 123, "table_id": 1 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-flow_monitor_reply.packet.json0000664000175000017500000000341000000000000032660 0ustar00zuulzuul00000000000000{ "OFPFlowMonitorReply": { "body": [ { "OFPFlowUpdateFull": { "cookie": 0, "event": 0, "hard_timeout": 700, "idle_timeout": 600, "instructions": [ { "OFPInstructionActions": { "actions": [ { "OFPActionOutput": { "len": 16, "max_len": 0, "port": 4294967290, "type": 0 } } ], "len": 24, "type": 4 } } ], "length": 64, "match": { "OFPMatch": { "length": 10, "oxm_fields": [ { "OXMTlv": { "field": "eth_type", "mask": null, "value": 2054 } } ], "type": 1 } }, "priority": 3, "reason": 0, "table_id": 0 } }, { "OFPFlowUpdateAbbrev": { "event": 4, "length": 8, "xid": 1234 } }, { "OFPFlowUpdatePaused": { "event": 5, "length": 8 } } ], "flags": 0, "type": 16 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-flow_monitor_request.packet.json0000664000175000017500000000111400000000000033214 0ustar00zuulzuul00000000000000{ "OFPFlowMonitorRequest": { "command": 0, "flags": 0, "match": { "OFPMatch": { "length": 14, "oxm_fields": [ { "OXMTlv": { "field": "eth_dst", "mask": null, "value": "f2:0b:a4:7d:f8:ea" } } ], "type": 1 } }, "monitor_flags": 15, "monitor_id": 100000000, "out_group": 4294967295, "out_port": 22, "table_id": 33, "type": 16 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-flow_removed.packet.json0000664000175000017500000000167300000000000031430 0ustar00zuulzuul00000000000000{ "OFPFlowRemoved": { "cookie": 1234605616436508552, "hard_timeout": 255, "idle_timeout": 255, "match": { "OFPMatch": { "length": 12, "oxm_fields": [ { "OXMTlv": { "field": "in_port", "mask": null, "value": 1 } } ], "type": 1 } }, "priority": 1, "reason": 0, "stats": { "OFPStats": { "length": 12, "oxs_fields": [ { "OXSTlv": { "field": "flow_count", "value": 1 } } ] } }, "table_id": 1 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-flow_stats_reply.packet.json0000664000175000017500000000260700000000000032336 0ustar00zuulzuul00000000000000{ "OFPFlowStatsReply": { "body": [ { "OFPFlowStats": { "length": 40, "match": { "OFPMatch": { "length": 12, "oxm_fields": [ { "OXMTlv": { "field": "in_port", "mask": null, "value": 1 } } ], "type": 1 } }, "priority": 1, "reason": 0, "stats": { "OFPStats": { "length": 12, "oxs_fields": [ { "OXSTlv": { "field": "flow_count", "value": 1 } } ] } }, "table_id": 1 } } ], "flags": 0, "type": 17 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-flow_stats_request.packet.json0000664000175000017500000000051600000000000032670 0ustar00zuulzuul00000000000000{ "OFPFlowStatsRequest": { "cookie": 0, "cookie_mask": 0, "flags": 0, "match": { "OFPMatch": { "length": 4, "oxm_fields": [], "type": 1 } }, "out_group": 4294967295, "out_port": 4294967295, "table_id": 0, "type": 17 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-get_async_reply.packet.json0000664000175000017500000000533000000000000032121 0ustar00zuulzuul00000000000000{ "OFPGetAsyncReply": { "properties": [ { "OFPAsyncConfigPropReasons": { "length": 8, "mask": 3, "type": 0 } }, { "OFPAsyncConfigPropReasons": { "length": 8, "mask": 3, "type": 1 } }, { "OFPAsyncConfigPropReasons": { "length": 8, "mask": 3, "type": 2 } }, { "OFPAsyncConfigPropReasons": { "length": 8, "mask": 3, "type": 3 } }, { "OFPAsyncConfigPropReasons": { "length": 8, "mask": 3, "type": 4 } }, { "OFPAsyncConfigPropReasons": { "length": 8, "mask": 3, "type": 5 } }, { "OFPAsyncConfigPropReasons": { "length": 8, "mask": 3, "type": 6 } }, { "OFPAsyncConfigPropReasons": { "length": 8, "mask": 3, "type": 7 } }, { "OFPAsyncConfigPropReasons": { "length": 8, "mask": 24, "type": 8 } }, { "OFPAsyncConfigPropReasons": { "length": 8, "mask": 24, "type": 9 } }, { "OFPAsyncConfigPropReasons": { "length": 8, "mask": 3, "type": 10 } }, { "OFPAsyncConfigPropReasons": { "length": 8, "mask": 3, "type": 11 } }, { "OFPAsyncConfigPropExperimenter": { "data": [], "exp_type": 0, "experimenter": 101, "length": 12, "type": 65534 } }, { "OFPAsyncConfigPropExperimenter": { "data": [ 1 ], "exp_type": 1, "experimenter": 101, "length": 16, "type": 65535 } }, { "OFPAsyncConfigPropExperimenter": { "data": [ 1, 2 ], "exp_type": 2, "experimenter": 101, "length": 20, "type": 65535 } } ] } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-get_async_request.packet.json0000664000175000017500000000004000000000000032447 0ustar00zuulzuul00000000000000{ "OFPGetAsyncRequest": {} } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-get_config_reply.packet.json0000664000175000017500000000012000000000000032241 0ustar00zuulzuul00000000000000{ "OFPGetConfigReply": { "flags": 0, "miss_send_len": 128 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-get_config_request.packet.json0000664000175000017500000000004100000000000032600 0ustar00zuulzuul00000000000000{ "OFPGetConfigRequest": {} } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-group_desc_reply.packet.json0000664000175000017500000000314200000000000032276 0ustar00zuulzuul00000000000000{ "OFPGroupDescStatsReply": { "body": [ { "OFPGroupDescStats": { "bucket_array_len": 32, "buckets": [ { "OFPBucket": { "action_array_len": 16, "actions": [ { "OFPActionOutput": { "len": 16, "max_len": 65509, "port": 1, "type": 0 } } ], "bucket_id": 65535, "len": 32, "properties": [ { "OFPGroupBucketPropWeight": { "length": 8, "type": 0, "weight": 65535 } } ] } } ], "group_id": 1, "length": 48, "properties": [], "type": 1 } } ], "flags": 0, "type": 7 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-group_desc_request.packet.json0000664000175000017500000000015500000000000032634 0ustar00zuulzuul00000000000000{ "OFPGroupDescStatsRequest": { "flags": 0, "group_id": 52651, "type": 7 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-group_features_reply.packet.json0000664000175000017500000000074600000000000033205 0ustar00zuulzuul00000000000000{ "OFPGroupFeaturesStatsReply": { "body": { "OFPGroupFeaturesStats": { "actions": [ 67082241, 67082241, 67082241, 67082241 ], "capabilities": 5, "max_groups": [ 16777216, 16777216, 16777216, 16777216 ], "types": 15 } }, "flags": 0, "type": 8 } } ././@PaxHeader0000000000000000000000000000020500000000000011452 xustar0000000000000000111 path=os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-group_features_request.packet.json 22 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-group_features_request.packet.jso0000664000175000017500000000012000000000000033346 0ustar00zuulzuul00000000000000{ "OFPGroupFeaturesStatsRequest": { "flags": 0, "type": 8 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-group_mod.packet.json0000664000175000017500000000415200000000000030726 0ustar00zuulzuul00000000000000{ "OFPGroupMod": { "bucket_array_len": 56, "buckets": [ { "OFPBucket": { "action_array_len": 24, "actions": [ { "OFPActionPopVlan": { "len": 8, "type": 18 } }, { "OFPActionSetField": { "field": { "OXMTlv": { "field": "ipv4_dst", "mask": null, "value": "192.168.2.9" } }, "len": 16, "type": 25 } } ], "bucket_id": 305419896, "len": 56, "properties": [ { "OFPGroupBucketPropWeight": { "length": 8, "type": 0, "weight": 52428 } }, { "OFPGroupBucketPropWatch": { "length": 8, "type": 1, "watch": 56797 } }, { "OFPGroupBucketPropWatch": { "length": 8, "type": 2, "watch": 4008636142 } } ] } } ], "command": 3, "command_bucket_id": 3149642683, "group_id": 2863311530, "properties": [], "type": 1 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-group_stats_reply.packet.json0000664000175000017500000000120500000000000032514 0ustar00zuulzuul00000000000000{ "OFPGroupStatsReply": { "body": [ { "OFPGroupStats": { "bucket_stats": [ { "OFPBucketCounter": { "byte_count": 2345, "packet_count": 234 } } ], "byte_count": 12345, "duration_nsec": 609036000, "duration_sec": 9, "group_id": 1, "length": 56, "packet_count": 123, "ref_count": 2 } } ], "flags": 0, "type": 6 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-group_stats_request.packet.json0000664000175000017500000000014600000000000033054 0ustar00zuulzuul00000000000000{ "OFPGroupStatsRequest": { "flags": 0, "group_id": 4294967292, "type": 6 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-hello.packet.json0000664000175000017500000000037500000000000030041 0ustar00zuulzuul00000000000000{ "OFPHello": { "elements": [ { "OFPHelloElemVersionBitmap": { "length": 8, "type": 1, "versions": [ 6 ] } } ] } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-meter_desc_reply.packet.json0000664000175000017500000000105600000000000032260 0ustar00zuulzuul00000000000000{ "OFPMeterDescStatsReply": { "body": [ { "OFPMeterDescStats": { "bands": [ { "OFPMeterBandDrop": { "burst_size": 10, "len": 16, "rate": 1000, "type": 1 } } ], "flags": 14, "length": 24, "meter_id": 100 } } ], "flags": 0, "type": 10 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-meter_desc_request.packet.json0000664000175000017500000000015300000000000032612 0ustar00zuulzuul00000000000000{ "OFPMeterDescStatsRequest": { "flags": 0, "meter_id": 4294967295, "type": 10 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-meter_features_reply.packet.json0000664000175000017500000000060200000000000033154 0ustar00zuulzuul00000000000000{ "OFPMeterFeaturesStatsReply": { "body": [ { "OFPMeterFeaturesStats": { "band_types": 2147483654, "capabilities": 15, "features": 3, "max_bands": 255, "max_color": 0, "max_meter": 16777216 } } ], "flags": 0, "type": 11 } } ././@PaxHeader0000000000000000000000000000020500000000000011452 xustar0000000000000000111 path=os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-meter_features_request.packet.json 22 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-meter_features_request.packet.jso0000664000175000017500000000012100000000000033327 0ustar00zuulzuul00000000000000{ "OFPMeterFeaturesStatsRequest": { "flags": 0, "type": 11 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-meter_mod.packet.json0000664000175000017500000000101100000000000030675 0ustar00zuulzuul00000000000000{ "OFPMeterMod": { "bands": [ { "OFPMeterBandDrop": { "burst_size": 10, "len": 16, "rate": 1000, "type": 1 } }, { "OFPMeterBandDscpRemark": { "burst_size": 10, "len": 16, "prec_level": 1, "rate": 1000, "type": 2 } } ], "command": 0, "flags": 14, "meter_id": 100 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-meter_stats_reply.packet.json0000664000175000017500000000120500000000000032474 0ustar00zuulzuul00000000000000{ "OFPMeterStatsReply": { "body": [ { "OFPMeterStats": { "band_stats": [ { "OFPMeterBandStats": { "byte_band_count": 0, "packet_band_count": 0 } } ], "byte_in_count": 0, "duration_nsec": 480000, "duration_sec": 0, "ref_count": 0, "len": 56, "meter_id": 100, "packet_in_count": 0 } } ], "flags": 0, "type": 9 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-meter_stats_request.packet.json0000664000175000017500000000014600000000000033034 0ustar00zuulzuul00000000000000{ "OFPMeterStatsRequest": { "flags": 0, "meter_id": 4294967295, "type": 9 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-packet_in.packet.json0000664000175000017500000000215200000000000030666 0ustar00zuulzuul00000000000000{ "OFPPacketIn": { "buffer_id": 200, "cookie": 0, "data": "aG9nZQ==", "match": { "OFPMatch": { "length": 40, "oxm_fields": [ { "OXMTlv": { "field": "in_port", "mask": null, "value": 43981 } }, { "OXMTlv": { "field": "tunnel_id", "mask": null, "value": 50000 } }, { "OXMTlv": { "field": "tun_ipv4_src", "mask": null, "value": "192.168.2.3" } }, { "OXMTlv": { "field": "tun_ipv4_dst", "mask": null, "value": "192.168.2.4" } } ], "type": 1 } }, "reason": 0, "table_id": 100, "total_len": 1000 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-packet_out.packet.json0000664000175000017500000000143200000000000031067 0ustar00zuulzuul00000000000000{ "OFPPacketOut": { "actions": [ { "OFPActionOutput": { "len": 16, "max_len": 65535, "port": 4294967291, "type": 0 } } ], "actions_len": 16, "buffer_id": 4294967295, "data": "dGVzdA==", "match": { "OFPMatch": { "length": 12, "oxm_fields": [ { "OXMTlv": { "field": "in_port", "mask": null, "value": 4294967040 } } ], "type": 1 } } } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-port_desc_reply.packet.json0000664000175000017500000000631400000000000032132 0ustar00zuulzuul00000000000000{ "OFPPortDescStatsReply": { "body": [ { "OFPPort": { "config": 0, "hw_addr": "f2:0b:a4:d0:3f:70", "length": 168, "name": "Port7", "port_no": 7, "properties": [ { "OFPPortDescPropEthernet": { "advertised": 10240, "curr": 10248, "curr_speed": 5000, "length": 32, "max_speed": 5000, "peer": 10248, "supported": 10248, "type": 0 } }, { "OFPPortDescPropOptical": { "length": 40, "rx_grid_freq_lmda": 1500, "rx_max_freq_lmda": 2000, "rx_min_freq_lmda": 1000, "supported": 1, "tx_grid_freq_lmda": 1500, "tx_max_freq_lmda": 2000, "tx_min_freq_lmda": 1000, "tx_pwr_max": 2000, "tx_pwr_min": 1000, "type": 1 } }, { "OFPPortDescPropExperimenter": { "data": [], "exp_type": 0, "experimenter": 101, "length": 12, "type": 65535 } }, { "OFPPortDescPropExperimenter": { "data": [ 1 ], "exp_type": 1, "experimenter": 101, "length": 16, "type": 65535 } }, { "OFPPortDescPropExperimenter": { "data": [ 1, 2 ], "exp_type": 2, "experimenter": 101, "length": 20, "type": 65535 } } ], "state": 4 } }, { "OFPPort": { "config": 0, "hw_addr": "f2:0b:a4:7d:f8:ea", "length": 72, "name": "Port6", "port_no": 6, "properties": [ { "OFPPortDescPropEthernet": { "advertised": 10240, "curr": 10248, "curr_speed": 5000, "length": 32, "max_speed": 5000, "peer": 10248, "supported": 10248, "type": 0 } } ], "state": 4 } } ], "flags": 0, "type": 13 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-port_desc_request.packet.json0000664000175000017500000000015400000000000032463 0ustar00zuulzuul00000000000000{ "OFPPortDescStatsRequest": { "flags": 0, "port_no": 48346, "type": 13 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-port_mod.packet.json0000664000175000017500000000256500000000000030564 0ustar00zuulzuul00000000000000{ "OFPPortMod": { "config": 0, "hw_addr": "00:11:00:00:11:11", "mask": 0, "port_no": 1, "properties": [ { "OFPPortModPropEthernet": { "advertise": 4096, "length": 8, "type": 0 } }, { "OFPPortModPropOptical": { "configure": 3, "fl_offset": 2000, "freq_lmda": 1500, "grid_span": 3000, "length": 24, "tx_pwr": 300, "type": 1 } }, { "OFPPortModPropExperimenter": { "data": [], "exp_type": 0, "experimenter": 101, "length": 12, "type": 65535 } }, { "OFPPortModPropExperimenter": { "data": [ 1 ], "exp_type": 1, "experimenter": 101, "length": 16, "type": 65535 } }, { "OFPPortModPropExperimenter": { "data": [ 1, 2 ], "exp_type": 2, "experimenter": 101, "length": 20, "type": 65535 } } ] } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-port_stats_reply.packet.json0000664000175000017500000000671300000000000032355 0ustar00zuulzuul00000000000000{ "OFPPortStatsReply": { "body": [ { "OFPPortStats": { "duration_nsec": 0, "duration_sec": 0, "length": 224, "port_no": 7, "properties": [ { "OFPPortStatsPropEthernet": { "collisions": 0, "length": 40, "rx_crc_err": 0, "rx_frame_err": 0, "rx_over_err": 0, "type": 0 } }, { "OFPPortStatsPropOptical": { "bias_current": 300, "flags": 3, "length": 44, "rx_freq_lmda": 1500, "rx_grid_span": 500, "rx_offset": 700, "rx_pwr": 2000, "temperature": 273, "tx_freq_lmda": 1500, "tx_grid_span": 500, "tx_offset": 700, "tx_pwr": 2000, "type": 1 } }, { "OFPPortStatsPropExperimenter": { "data": [], "exp_type": 0, "experimenter": 101, "length": 12, "type": 65535 } }, { "OFPPortStatsPropExperimenter": { "data": [ 1 ], "exp_type": 1, "experimenter": 101, "length": 16, "type": 65535 } }, { "OFPPortStatsPropExperimenter": { "data": [ 1, 2 ], "exp_type": 2, "experimenter": 101, "length": 20, "type": 65535 } } ], "rx_bytes": 0, "rx_dropped": 0, "rx_errors": 0, "rx_packets": 0, "tx_bytes": 336, "tx_dropped": 0, "tx_errors": 0, "tx_packets": 4 } }, { "OFPPortStats": { "duration_nsec": 0, "duration_sec": 0, "length": 120, "port_no": 6, "properties": [ { "OFPPortStatsPropEthernet": { "collisions": 0, "length": 40, "rx_crc_err": 0, "rx_frame_err": 0, "rx_over_err": 0, "type": 0 } } ], "rx_bytes": 336, "rx_dropped": 0, "rx_errors": 0, "rx_packets": 4, "tx_bytes": 336, "tx_dropped": 0, "tx_errors": 0, "tx_packets": 4 } } ], "flags": 0, "type": 4 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-port_stats_request.packet.json0000664000175000017500000000014400000000000032702 0ustar00zuulzuul00000000000000{ "OFPPortStatsRequest": { "flags": 0, "port_no": 4294967295, "type": 4 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-port_status.packet.json0000664000175000017500000000440200000000000031320 0ustar00zuulzuul00000000000000{ "OFPPortStatus": { "desc": { "OFPPort": { "config": 0, "hw_addr": "f2:0b:a4:d0:3f:70", "length": 168, "name": "\u79c1\u306e\u30dd\u30fc\u30c8", "port_no": 7, "properties": [ { "OFPPortDescPropEthernet": { "advertised": 10240, "curr": 10248, "curr_speed": 5000, "length": 32, "max_speed": 5000, "peer": 10248, "supported": 10248, "type": 0 } }, { "OFPPortDescPropOptical": { "length": 40, "rx_grid_freq_lmda": 1500, "rx_max_freq_lmda": 2000, "rx_min_freq_lmda": 1000, "supported": 1, "tx_grid_freq_lmda": 1500, "tx_max_freq_lmda": 2000, "tx_min_freq_lmda": 1000, "tx_pwr_max": 2000, "tx_pwr_min": 1000, "type": 1 } }, { "OFPPortDescPropExperimenter": { "data": [], "exp_type": 0, "experimenter": 101, "length": 12, "type": 65535 } }, { "OFPPortDescPropExperimenter": { "data": [ 1 ], "exp_type": 1, "experimenter": 101, "length": 16, "type": 65535 } }, { "OFPPortDescPropExperimenter": { "data": [ 1, 2 ], "exp_type": 2, "experimenter": 101, "length": 20, "type": 65535 } } ], "state": 4 } }, "reason": 0 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-queue_desc_reply.packet.json0000664000175000017500000000444300000000000032273 0ustar00zuulzuul00000000000000{ "OFPQueueDescStatsReply": { "body": [ { "OFPQueueDesc": { "len": 32, "port_no": 7, "properties": [ { "OFPQueueDescPropExperimenter": { "data": [], "exp_type": 0, "experimenter": 101, "length": 12, "type": 65535 } } ], "queue_id": 0 } }, { "OFPQueueDesc": { "len": 88, "port_no": 8, "properties": [ { "OFPQueueDescPropMinRate": { "length": 8, "rate": 300, "type": 1 } }, { "OFPQueueDescPropMaxRate": { "length": 8, "rate": 900, "type": 2 } }, { "OFPQueueDescPropExperimenter": { "data": [], "exp_type": 0, "experimenter": 101, "length": 12, "type": 65535 } }, { "OFPQueueDescPropExperimenter": { "data": [ 1 ], "exp_type": 1, "experimenter": 101, "length": 16, "type": 65535 } }, { "OFPQueueDescPropExperimenter": { "data": [ 1, 2 ], "exp_type": 2, "experimenter": 101, "length": 20, "type": 65535 } } ], "queue_id": 1 } } ], "flags": 0, "type": 15 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-queue_desc_request.packet.json0000664000175000017500000000021000000000000032614 0ustar00zuulzuul00000000000000{ "OFPQueueDescStatsRequest": { "flags": 0, "port_no": 52651, "queue_id": 57020, "type": 15 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-queue_stats_reply.packet.json0000664000175000017500000000430600000000000032511 0ustar00zuulzuul00000000000000{ "OFPQueueStatsReply": { "body": [ { "OFPQueueStats": { "duration_nsec": 0, "duration_sec": 0, "length": 104, "port_no": 7, "properties": [ { "OFPQueueStatsPropExperimenter": { "data": [], "exp_type": 0, "experimenter": 101, "length": 12, "type": 65535 } }, { "OFPQueueStatsPropExperimenter": { "data": [ 1 ], "exp_type": 1, "experimenter": 101, "length": 16, "type": 65535 } }, { "OFPQueueStatsPropExperimenter": { "data": [ 1, 2 ], "exp_type": 2, "experimenter": 101, "length": 20, "type": 65535 } } ], "queue_id": 1, "tx_bytes": 0, "tx_errors": 0, "tx_packets": 0 } }, { "OFPQueueStats": { "duration_nsec": 0, "duration_sec": 0, "length": 48, "port_no": 6, "properties": [], "queue_id": 1, "tx_bytes": 0, "tx_errors": 0, "tx_packets": 0 } }, { "OFPQueueStats": { "duration_nsec": 0, "duration_sec": 0, "length": 48, "port_no": 7, "properties": [], "queue_id": 2, "tx_bytes": 0, "tx_errors": 0, "tx_packets": 0 } } ], "flags": 0, "type": 5 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-queue_stats_request.packet.json0000664000175000017500000000017600000000000033047 0ustar00zuulzuul00000000000000{ "OFPQueueStatsRequest": { "flags": 0, "port_no": 43981, "queue_id": 4294967295, "type": 5 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-requestforward.packet.json0000664000175000017500000000424500000000000032013 0ustar00zuulzuul00000000000000{ "OFPRequestForward": { "request": { "OFPGroupMod": { "bucket_array_len": 56, "buckets": [ { "OFPBucket": { "action_array_len": 24, "actions": [ { "OFPActionPopVlan": { "len": 8, "type": 18 } }, { "OFPActionSetField": { "field": { "OXMTlv": { "field": "ipv4_dst", "mask": null, "value": "192.168.2.9" } }, "len": 16, "type": 25 } } ], "bucket_id": 305419896, "len": 56, "properties": [ { "OFPGroupBucketPropWeight": { "length": 8, "type": 0, "weight": 52428 } }, { "OFPGroupBucketPropWatch": { "length": 8, "type": 1, "watch": 56797 } }, { "OFPGroupBucketPropWatch": { "length": 8, "type": 2, "watch": 4008636142 } } ] } } ], "command": 3, "command_bucket_id": 3149642683, "group_id": 2863311530, "properties": [], "type": 1 } } } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-role_reply.packet.json0000664000175000017500000000016300000000000031105 0ustar00zuulzuul00000000000000{ "OFPRoleReply": { "generation_id": 1234605616436508552, "role": 1, "short_id": 43690 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-role_request.packet.json0000664000175000017500000000016500000000000031444 0ustar00zuulzuul00000000000000{ "OFPRoleRequest": { "generation_id": 1234605616436508552, "role": 1, "short_id": 43690 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-role_status.packet.json0000664000175000017500000000020700000000000031274 0ustar00zuulzuul00000000000000{ "OFPRoleStatus": { "generation_id": 17356517385562371090, "properties": [], "reason": 0, "role": 3 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-set_async.packet.json0000664000175000017500000000532300000000000030724 0ustar00zuulzuul00000000000000{ "OFPSetAsync": { "properties": [ { "OFPAsyncConfigPropReasons": { "length": 8, "mask": 3, "type": 0 } }, { "OFPAsyncConfigPropReasons": { "length": 8, "mask": 3, "type": 1 } }, { "OFPAsyncConfigPropReasons": { "length": 8, "mask": 3, "type": 2 } }, { "OFPAsyncConfigPropReasons": { "length": 8, "mask": 3, "type": 3 } }, { "OFPAsyncConfigPropReasons": { "length": 8, "mask": 3, "type": 4 } }, { "OFPAsyncConfigPropReasons": { "length": 8, "mask": 3, "type": 5 } }, { "OFPAsyncConfigPropReasons": { "length": 8, "mask": 3, "type": 6 } }, { "OFPAsyncConfigPropReasons": { "length": 8, "mask": 3, "type": 7 } }, { "OFPAsyncConfigPropReasons": { "length": 8, "mask": 24, "type": 8 } }, { "OFPAsyncConfigPropReasons": { "length": 8, "mask": 24, "type": 9 } }, { "OFPAsyncConfigPropReasons": { "length": 8, "mask": 3, "type": 10 } }, { "OFPAsyncConfigPropReasons": { "length": 8, "mask": 3, "type": 11 } }, { "OFPAsyncConfigPropExperimenter": { "data": [], "exp_type": 0, "experimenter": 101, "length": 12, "type": 65534 } }, { "OFPAsyncConfigPropExperimenter": { "data": [ 1 ], "exp_type": 1, "experimenter": 101, "length": 16, "type": 65535 } }, { "OFPAsyncConfigPropExperimenter": { "data": [ 1, 2 ], "exp_type": 2, "experimenter": 101, "length": 20, "type": 65535 } } ] } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-set_config.packet.json0000664000175000017500000000011300000000000031044 0ustar00zuulzuul00000000000000{ "OFPSetConfig": { "flags": 0, "miss_send_len": 128 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-table_desc_reply.packet.json0000664000175000017500000000456600000000000032244 0ustar00zuulzuul00000000000000{ "OFPTableDescStatsReply": { "body": [ { "OFPTableDesc": { "config": 0, "length": 24, "properties": [ { "OFPTableModPropExperimenter": { "data": [], "exp_type": 0, "experimenter": 101, "length": 12, "type": 65535 } } ], "table_id": 7 } }, { "OFPTableDesc": { "config": 0, "length": 80, "properties": [ { "OFPTableModPropEviction": { "flags": 0, "length": 8, "type": 2 } }, { "OFPTableModPropVacancy": { "length": 8, "type": 3, "vacancy": 0, "vacancy_down": 0, "vacancy_up": 0 } }, { "OFPTableModPropExperimenter": { "data": [], "exp_type": 0, "experimenter": 101, "length": 12, "type": 65535 } }, { "OFPTableModPropExperimenter": { "data": [ 1 ], "exp_type": 1, "experimenter": 101, "length": 16, "type": 65535 } }, { "OFPTableModPropExperimenter": { "data": [ 1, 2 ], "exp_type": 2, "experimenter": 101, "length": 20, "type": 65535 } } ], "table_id": 8 } } ], "flags": 0, "type": 14 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-table_desc_request.packet.json0000664000175000017500000000011500000000000032563 0ustar00zuulzuul00000000000000{ "OFPTableDescStatsRequest": { "flags": 0, "type": 14 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-table_features_reply.packet.json0000664000175000017500000000212500000000000033131 0ustar00zuulzuul00000000000000{ "OFPTableFeaturesStatsReply": { "body": [ { "OFPTableFeaturesStats": { "capabilities": 4, "command": 1, "features": 1, "length": 80, "max_entries": 255, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "table1", "properties": [ { "OFPTableFeaturePropOxmValues": { "length": 14, "oxm_values": [ { "OXMTlv": { "field": "eth_src", "mask": null, "value": "aa:bb:cc:dd:ee:ff" } } ], "type": 22 } } ], "table_id": 1 } } ], "flags": 0, "type": 12 } } ././@PaxHeader0000000000000000000000000000020500000000000011452 xustar0000000000000000111 path=os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-table_features_request.packet.json 22 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-table_features_request.packet.jso0000664000175000017500000000244700000000000033317 0ustar00zuulzuul00000000000000{ "OFPTableFeaturesStatsRequest": { "body": [ { "OFPTableFeaturesStats": { "capabilities": 4, "command": 1, "features": 1, "length": 80, "max_entries": 255, "metadata_match": 18446744073709551615, "metadata_write": 18446744073709551615, "name": "table1", "properties": [ { "OFPTableFeaturePropOxmValues": { "length": 14, "oxm_values": [ { "OXMTlv": { "field": "eth_src", "mask": null, "value": "aa:bb:cc:dd:ee:ff" } } ], "type": 22 } } ], "table_id": 1 } } ], "flags": 0, "type": 12 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-table_mod.packet.json0000664000175000017500000000040200000000000030653 0ustar00zuulzuul00000000000000{ "OFPTableMod": { "config": 4, "properties": [ { "OFPTableModPropEviction": { "flags": 2, "length": 8, "type": 2 } } ], "table_id": 255 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-table_stats_reply.packet.json0000664000175000017500000000075600000000000032461 0ustar00zuulzuul00000000000000{ "OFPTableStatsReply": { "body": [ { "OFPTableStats": { "active_count": 4, "lookup_count": 4, "matched_count": 4, "table_id": 0 } }, { "OFPTableStats": { "active_count": 4, "lookup_count": 4, "matched_count": 4, "table_id": 1 } } ], "flags": 0, "type": 3 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-table_stats_request.packet.json0000664000175000017500000000011000000000000032776 0ustar00zuulzuul00000000000000{ "OFPTableStatsRequest": { "flags": 0, "type": 3 } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-table_status.packet.json0000664000175000017500000000324000000000000031422 0ustar00zuulzuul00000000000000{ "OFPTableStatus": { "reason": 3, "table": { "OFPTableDesc": { "config": 0, "length": 80, "properties": [ { "OFPTableModPropEviction": { "flags": 0, "length": 8, "type": 2 } }, { "OFPTableModPropVacancy": { "length": 8, "type": 3, "vacancy": 0, "vacancy_down": 0, "vacancy_up": 0 } }, { "OFPTableModPropExperimenter": { "data": [], "exp_type": 0, "experimenter": 101, "length": 12, "type": 65535 } }, { "OFPTableModPropExperimenter": { "data": [ 1 ], "exp_type": 1, "experimenter": 101, "length": 16, "type": 65535 } }, { "OFPTableModPropExperimenter": { "data": [ 1, 2 ], "exp_type": 2, "experimenter": 101, "length": 20, "type": 65535 } } ], "table_id": 8 } } } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/test_ether.py0000664000175000017500000000220300000000000022615 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone 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. # vim: tabstop=4 shiftwidth=4 softtabstop=4 import unittest import logging from os_ken.ofproto.ether import * LOG = logging.getLogger('test_ether') class TestInet(unittest.TestCase): """ Test case for ether """ def test_ether_type(self): self.assertEqual(ETH_TYPE_IP, 0x0800) self.assertEqual(ETH_TYPE_ARP, 0x0806) self.assertEqual(ETH_TYPE_8021Q, 0x8100) self.assertEqual(ETH_TYPE_IPV6, 0x86dd) self.assertEqual(ETH_TYPE_MPLS, 0x8847) self.assertEqual(ETH_TYPE_SLOW, 0x8809) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/test_inet.py0000664000175000017500000000255200000000000022454 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone 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. # vim: tabstop=4 shiftwidth=4 softtabstop=4 import unittest import logging from os_ken.ofproto.inet import * LOG = logging.getLogger('test_inet') class TestInet(unittest.TestCase): """ Test case for inet """ def test_ip_proto(self): self.assertEqual(IPPROTO_IP, 0) self.assertEqual(IPPROTO_HOPOPTS, 0) self.assertEqual(IPPROTO_ICMP, 1) self.assertEqual(IPPROTO_TCP, 6) self.assertEqual(IPPROTO_UDP, 17) self.assertEqual(IPPROTO_ROUTING, 43) self.assertEqual(IPPROTO_FRAGMENT, 44) self.assertEqual(IPPROTO_AH, 51) self.assertEqual(IPPROTO_ICMPV6, 58) self.assertEqual(IPPROTO_NONE, 59) self.assertEqual(IPPROTO_DSTOPTS, 60) self.assertEqual(IPPROTO_SCTP, 132) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/test_nx_flow_spec.py0000664000175000017500000000677500000000000024216 0ustar00zuulzuul00000000000000# Copyright (C) 2015 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2015 YAMAMOTO Takashi # # 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. import unittest import os_ken.ofproto.ofproto_v1_3_parser as ofpp class Test_FlowSpec(unittest.TestCase): def test_flowspec_src_0_dst_0(self): user = ofpp.NXFlowSpecMatch(src=('in_port', 0), dst=('in_port', 0), n_bits=16) on_wire = ( b'\x00\x10' b'\x80\x00\x00\x04\x00\x00' b'\x80\x00\x00\x04\x00\x00' ) self.assertEqual(on_wire, user.serialize()) (o, rest) = ofpp._NXFlowSpec.parse(on_wire) self.assertEqual(user.to_jsondict(), o.to_jsondict()) self.assertEqual(str(user), str(o)) self.assertEqual(b'', rest) def test_flowspec_src_1_dst_0(self): user = ofpp.NXFlowSpecMatch(src=99, dst=('in_port', 0), n_bits=16) on_wire = ( b'\x20\x10' b'\x00\x63' b'\x80\x00\x00\x04\x00\x00' ) self.assertEqual(on_wire, user.serialize()) (o, rest) = ofpp._NXFlowSpec.parse(on_wire) self.assertEqual(user.to_jsondict(), o.to_jsondict()) self.assertEqual(str(user), str(o)) self.assertEqual(b'', rest) def test_flowspec_src_0_dst_1(self): user = ofpp.NXFlowSpecLoad(src=('in_port', 0), dst=('in_port', 0), n_bits=16) on_wire = ( b'\x08\x10' b'\x80\x00\x00\x04\x00\x00' b'\x80\x00\x00\x04\x00\x00' ) self.assertEqual(on_wire, user.serialize()) (o, rest) = ofpp._NXFlowSpec.parse(on_wire) self.assertEqual(user.to_jsondict(), o.to_jsondict()) self.assertEqual(str(user), str(o)) self.assertEqual(b'', rest) def test_flowspec_src_1_dst_1(self): user = ofpp.NXFlowSpecLoad(src=99, dst=('in_port', 0), n_bits=16) on_wire = ( b'\x28\x10' b'\x00\x63' b'\x80\x00\x00\x04\x00\x00' ) self.assertEqual(on_wire, user.serialize()) (o, rest) = ofpp._NXFlowSpec.parse(on_wire) self.assertEqual(user.to_jsondict(), o.to_jsondict()) self.assertEqual(str(user), str(o)) self.assertEqual(b'', rest) def test_flowspec_src_0_dst_2(self): user = ofpp.NXFlowSpecOutput(src=('in_port', 0), dst='', n_bits=16) on_wire = ( b'\x10\x10' b'\x80\x00\x00\x04\x00\x00' ) self.assertEqual(on_wire, user.serialize()) (o, rest) = ofpp._NXFlowSpec.parse(on_wire) self.assertEqual(user.to_jsondict(), o.to_jsondict()) self.assertEqual(str(user), str(o)) self.assertEqual(b'', rest) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/test_ofproto.py0000664000175000017500000000620600000000000023205 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013 Isaku Yamahata # # 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. # vim: tabstop=4 shiftwidth=4 softtabstop=4 from importlib import reload import unittest import logging LOG = logging.getLogger('test_ofproto') class TestOfprotCommon(unittest.TestCase): """ Test case for ofproto """ def test_ofp_event(self): import os_ken.ofproto reload(os_ken.ofproto) import os_ken.controller.ofp_event reload(os_ken.controller.ofp_event) def test_ofproto(self): # When new version of OFP support is added, # this test must be updated. import os_ken.ofproto reload(os_ken.ofproto) ofp_modules = os_ken.ofproto.get_ofp_modules() import os_ken.ofproto.ofproto_v1_0 import os_ken.ofproto.ofproto_v1_2 import os_ken.ofproto.ofproto_v1_3 import os_ken.ofproto.ofproto_v1_4 import os_ken.ofproto.ofproto_v1_5 self.assertEqual(set(ofp_modules.keys()), set([os_ken.ofproto.ofproto_v1_0.OFP_VERSION, os_ken.ofproto.ofproto_v1_2.OFP_VERSION, os_ken.ofproto.ofproto_v1_3.OFP_VERSION, os_ken.ofproto.ofproto_v1_4.OFP_VERSION, os_ken.ofproto.ofproto_v1_5.OFP_VERSION, ])) consts_mods = set([ofp_mod[0] for ofp_mod in ofp_modules.values()]) self.assertEqual(consts_mods, set([os_ken.ofproto.ofproto_v1_0, os_ken.ofproto.ofproto_v1_2, os_ken.ofproto.ofproto_v1_3, os_ken.ofproto.ofproto_v1_4, os_ken.ofproto.ofproto_v1_5, ]) ) parser_mods = set([ofp_mod[1] for ofp_mod in ofp_modules.values()]) import os_ken.ofproto.ofproto_v1_0_parser import os_ken.ofproto.ofproto_v1_2_parser import os_ken.ofproto.ofproto_v1_3_parser import os_ken.ofproto.ofproto_v1_4_parser import os_ken.ofproto.ofproto_v1_5_parser self.assertEqual(parser_mods, set([os_ken.ofproto.ofproto_v1_0_parser, os_ken.ofproto.ofproto_v1_2_parser, os_ken.ofproto.ofproto_v1_3_parser, os_ken.ofproto.ofproto_v1_4_parser, os_ken.ofproto.ofproto_v1_5_parser, ]) ) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/test_ofproto_common.py0000664000175000017500000000216300000000000024553 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone 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. # vim: tabstop=4 shiftwidth=4 softtabstop=4 import unittest import logging from os_ken.ofproto.ofproto_common import * LOG = logging.getLogger('test_ofproto_common') class TestOfprotCommon(unittest.TestCase): """ Test case for ofproto_common """ def test_struct_ofp_header(self): self.assertEqual(OFP_HEADER_PACK_STR, '!BBHI') self.assertEqual(OFP_HEADER_SIZE, 8) def test_define_constants(self): self.assertEqual(OFP_TCP_PORT, 6653) self.assertEqual(OFP_SSL_PORT, 6653) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/test_ofproto_parser.py0000664000175000017500000001611700000000000024563 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone 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. import binascii import unittest import struct from os_ken import exception from os_ken.ofproto import ofproto_common, ofproto_parser from os_ken.ofproto import ofproto_v1_0, ofproto_v1_0_parser import logging LOG = logging.getLogger(__name__) class TestOfproto_Parser(unittest.TestCase): def setUp(self): LOG.debug('setUp') self.bufHello = binascii.unhexlify('0100000800000001') fr = '010600b0000000020000000000000abc' \ + '00000100010000000000008700000fff' \ + '0002aefa39d2b9177472656d61302d30' \ + '00000000000000000000000000000000' \ + '000000c0000000000000000000000000' \ + 'fffe723f9a764cc87673775f30786162' \ + '63000000000000000000000100000001' \ + '00000082000000000000000000000000' \ + '00012200d6c5a1947472656d61312d30' \ + '00000000000000000000000000000000' \ + '000000c0000000000000000000000000' self.bufFeaturesReply = binascii.unhexlify(fr) pi = '010a005200000000000001010040' \ + '00020000000000000002000000000001' \ + '080045000032000000004011f967c0a8' \ + '0001c0a8000200010001001e00000000' \ + '00000000000000000000000000000000' \ + '00000000' self.bufPacketIn = binascii.unhexlify(pi) def tearDown(self): LOG.debug('tearDown') pass def testHello(self): (version, msg_type, msg_len, xid) = ofproto_parser.header(self.bufHello) self.assertEqual(version, 1) self.assertEqual(msg_type, 0) self.assertEqual(msg_len, 8) self.assertEqual(xid, 1) def testFeaturesReply(self): (version, msg_type, msg_len, xid) = ofproto_parser.header(self.bufFeaturesReply) msg = ofproto_parser.msg(self, version, msg_type, msg_len, xid, self.bufFeaturesReply) LOG.debug(msg) self.assertTrue(isinstance(msg, ofproto_v1_0_parser.OFPSwitchFeatures)) LOG.debug(msg.ports[65534]) self.assertTrue(isinstance(msg.ports[1], ofproto_v1_0_parser.OFPPhyPort)) self.assertTrue(isinstance(msg.ports[2], ofproto_v1_0_parser.OFPPhyPort)) self.assertTrue(isinstance(msg.ports[65534], ofproto_v1_0_parser.OFPPhyPort)) def testPacketIn(self): (version, msg_type, msg_len, xid) = ofproto_parser.header(self.bufPacketIn) msg = ofproto_parser.msg(self, version, msg_type, msg_len, xid, self.bufPacketIn) LOG.debug(msg) self.assertTrue(isinstance(msg, ofproto_v1_0_parser.OFPPacketIn)) def test_check_msg_len(self): (version, msg_type, msg_len, xid) = ofproto_parser.header(self.bufPacketIn) msg_len = len(self.bufPacketIn) + 1 self.assertRaises(AssertionError, ofproto_parser.msg, self, version, msg_type, msg_len, xid, self.bufPacketIn) def test_check_msg_parser(self): (version, msg_type, msg_len, xid) = ofproto_parser.header(self.bufPacketIn) version = 0xff self.assertRaises(exception.OFPUnknownVersion, ofproto_parser.msg, self, version, msg_type, msg_len, xid, self.bufPacketIn) class TestMsgBase(unittest.TestCase): """ Test case for ofproto_parser.MsgBase """ def setUp(self): pass def tearDown(self): pass def test_init(self): pass def test_set_xid(self): xid = 3841413783 c = ofproto_parser.MsgBase(object) c.set_xid(xid) self.assertEqual(xid, c.xid) def test_set_xid_check_xid(self): xid = 2160492514 c = ofproto_parser.MsgBase(object) c.xid = xid self.assertRaises(AssertionError, c.set_xid, xid) def _test_parser(self, msg_type=ofproto_v1_0.OFPT_HELLO): version = ofproto_v1_0.OFP_VERSION msg_len = ofproto_v1_0.OFP_HEADER_SIZE xid = 2183948390 data = b'\x00\x01\x02\x03' fmt = ofproto_v1_0.OFP_HEADER_PACK_STR buf = struct.pack(fmt, version, msg_type, msg_len, xid) \ + data res = ofproto_v1_0_parser.OFPHello.parser( object, version, msg_type, msg_len, xid, bytearray(buf)) self.assertEqual(version, res.version) self.assertEqual(msg_type, res.msg_type) self.assertEqual(msg_len, res.msg_len) self.assertEqual(xid, res.xid) self.assertEqual(bytes(buf), res.buf) # test __str__() list_ = ('version', 'msg_type', 'msg_len', 'xid') check = {} for s in str(res).rsplit(','): if '=' in s: (k, v,) = s.rsplit('=') if k in list_: check[k] = v self.assertEqual(hex(ofproto_v1_0.OFP_VERSION), check['version']) self.assertEqual(hex(ofproto_v1_0.OFPT_HELLO), check['msg_type']) self.assertEqual(hex(msg_len), check['msg_len']) self.assertEqual(hex(xid), check['xid']) return True def test_parser(self): self.assertTrue(self._test_parser()) def test_parser_check_msg_type(self): self.assertRaises(AssertionError, self._test_parser, ofproto_v1_0.OFPT_ERROR) def _test_serialize(self): class Datapath(object): ofproto = ofproto_v1_0 ofproto_parser = ofproto_v1_0_parser c = ofproto_v1_0_parser.OFPHello(Datapath) c.serialize() self.assertEqual(ofproto_v1_0.OFP_VERSION, c.version) self.assertEqual(ofproto_v1_0.OFPT_HELLO, c.msg_type) self.assertEqual(0, c.xid) return True def test_serialize(self): self.assertTrue(self._test_serialize()) class TestMsgStrAttr(unittest.TestCase): """ Test case for ofproto_parser.msg_str_attr """ def test_msg_str_attr(self): class Check(object): check = 'msg_str_attr_test' c = Check() buf = '' res = ofproto_parser.msg_str_attr(c, buf, ('check',)) str_ = str(res) str_ = str_.rsplit() self.assertEqual('check', str_[0]) self.assertEqual('msg_str_attr_test', str_[1]) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/test_ofproto_v12.py0000664000175000017500000007561200000000000023704 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone 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. # vim: tabstop=4 shiftwidth=4 softtabstop=4 import unittest import logging from os_ken.ofproto.ofproto_v1_2 import * LOG = logging.getLogger('test_ofproto_v12') class TestOfprot12(unittest.TestCase): """ Test case for ofproto_v1_2 """ def test_struct_ofp_header(self): self.assertEqual(OFP_HEADER_PACK_STR, '!BBHI') self.assertEqual(OFP_HEADER_SIZE, 8) def test_enum_ofp_type(self): self.assertEqual(OFPT_HELLO, 0) self.assertEqual(OFPT_ERROR, 1) self.assertEqual(OFPT_ECHO_REQUEST, 2) self.assertEqual(OFPT_ECHO_REPLY, 3) self.assertEqual(OFPT_EXPERIMENTER, 4) self.assertEqual(OFPT_FEATURES_REQUEST, 5) self.assertEqual(OFPT_FEATURES_REPLY, 6) self.assertEqual(OFPT_GET_CONFIG_REQUEST, 7) self.assertEqual(OFPT_GET_CONFIG_REPLY, 8) self.assertEqual(OFPT_SET_CONFIG, 9) self.assertEqual(OFPT_PACKET_IN, 10) self.assertEqual(OFPT_FLOW_REMOVED, 11) self.assertEqual(OFPT_PORT_STATUS, 12) self.assertEqual(OFPT_PACKET_OUT, 13) self.assertEqual(OFPT_FLOW_MOD, 14) self.assertEqual(OFPT_GROUP_MOD, 15) self.assertEqual(OFPT_PORT_MOD, 16) self.assertEqual(OFPT_TABLE_MOD, 17) self.assertEqual(OFPT_STATS_REQUEST, 18) self.assertEqual(OFPT_STATS_REPLY, 19) self.assertEqual(OFPT_BARRIER_REQUEST, 20) self.assertEqual(OFPT_BARRIER_REPLY, 21) self.assertEqual(OFPT_QUEUE_GET_CONFIG_REQUEST, 22) self.assertEqual(OFPT_QUEUE_GET_CONFIG_REPLY, 23) self.assertEqual(OFPT_ROLE_REQUEST, 24) self.assertEqual(OFPT_ROLE_REPLY, 25) def test_struct_ofp_port(self): self.assertEqual(OFP_PORT_PACK_STR, '!I4x6s2x16sIIIIIIII') self.assertEqual(OFP_PORT_SIZE, 64) def test_enum_ofp_port_config(self): self.assertEqual(OFPPC_PORT_DOWN, 1 << 0) self.assertEqual(OFPPC_NO_RECV, 1 << 2) self.assertEqual(OFPPC_NO_FWD, 1 << 5) self.assertEqual(OFPPC_NO_PACKET_IN, 1 << 6) def test_enum_ofp_port_state(self): self.assertEqual(OFPPS_LINK_DOWN, 1 << 0) self.assertEqual(OFPPS_BLOCKED, 1 << 1) self.assertEqual(OFPPS_LIVE, 1 << 2) def test_enum_ofp_port_no(self): self.assertEqual(OFPP_MAX, 0xffffff00) self.assertEqual(OFPP_IN_PORT, 0xfffffff8) self.assertEqual(OFPP_TABLE, 0xfffffff9) self.assertEqual(OFPP_NORMAL, 0xfffffffa) self.assertEqual(OFPP_FLOOD, 0xfffffffb) self.assertEqual(OFPP_ALL, 0xfffffffc) self.assertEqual(OFPP_CONTROLLER, 0xfffffffd) self.assertEqual(OFPP_LOCAL, 0xfffffffe) self.assertEqual(OFPP_ANY, 0xffffffff) self.assertEqual(OFPQ_ALL, 0xffffffff) def test_enum_ofp_port_features(self): self.assertEqual(OFPPF_10MB_HD, 1 << 0) self.assertEqual(OFPPF_10MB_FD, 1 << 1) self.assertEqual(OFPPF_100MB_HD, 1 << 2) self.assertEqual(OFPPF_100MB_FD, 1 << 3) self.assertEqual(OFPPF_1GB_HD, 1 << 4) self.assertEqual(OFPPF_1GB_FD, 1 << 5) self.assertEqual(OFPPF_10GB_FD, 1 << 6) self.assertEqual(OFPPF_40GB_FD, 1 << 7) self.assertEqual(OFPPF_100GB_FD, 1 << 8) self.assertEqual(OFPPF_1TB_FD, 1 << 9) self.assertEqual(OFPPF_OTHER, 1 << 10) self.assertEqual(OFPPF_COPPER, 1 << 11) self.assertEqual(OFPPF_FIBER, 1 << 12) self.assertEqual(OFPPF_AUTONEG, 1 << 13) self.assertEqual(OFPPF_PAUSE, 1 << 14) self.assertEqual(OFPPF_PAUSE_ASYM, 1 << 15) def test_struct_ofp_packet_queue(self): self.assertEqual(OFP_PACKET_QUEUE_PACK_STR, '!IIH6x') self.assertEqual(OFP_PACKET_QUEUE_SIZE, 16) def test_enum_ofp_queue_properties(self): self.assertEqual(OFPQT_MIN_RATE, 1) self.assertEqual(OFPQT_MAX_RATE, 2) self.assertEqual(OFPQT_EXPERIMENTER, 0xffff) def test_struct_ofp_queue_prop_header(self): self.assertEqual(OFP_QUEUE_PROP_HEADER_PACK_STR, '!HH4x') self.assertEqual(OFP_QUEUE_PROP_HEADER_SIZE, 8) def test_struct_ofp_queue_prop_min_rate(self): self.assertEqual(OFP_QUEUE_PROP_MIN_RATE_PACK_STR, '!H6x') self.assertEqual(OFP_QUEUE_PROP_MIN_RATE_SIZE, 16) def test_struct_ofp_queue_prop_max_rate(self): self.assertEqual(OFP_QUEUE_PROP_MAX_RATE_PACK_STR, '!H6x') self.assertEqual(OFP_QUEUE_PROP_MAX_RATE_SIZE, 16) def test_struct_ofp_queue_prop_experimenter(self): self.assertEqual(OFP_QUEUE_PROP_EXPERIMENTER_PACK_STR, '!I4x') self.assertEqual(OFP_QUEUE_PROP_EXPERIMENTER_SIZE, 16) def test_struct_ofp_match(self): self.assertEqual(OFP_MATCH_PACK_STR, '!HHBBBB') self.assertEqual(OFP_MATCH_SIZE, 8) def test_enum_ofp_match_type(self): self.assertEqual(OFPMT_STANDARD, 0) self.assertEqual(OFPMT_OXM, 1) def test_enum_ofp_oxm_class(self): self.assertEqual(OFPXMC_NXM_0, 0x0000) self.assertEqual(OFPXMC_NXM_1, 0x0001) self.assertEqual(OFPXMC_OPENFLOW_BASIC, 0x8000) self.assertEqual(OFPXMC_EXPERIMENTER, 0xFFFF) def test_enmu_oxm_ofb_match_fields(self): self.assertEqual(OFPXMT_OFB_IN_PORT, 0) self.assertEqual(OFPXMT_OFB_IN_PHY_PORT, 1) self.assertEqual(OFPXMT_OFB_METADATA, 2) self.assertEqual(OFPXMT_OFB_ETH_DST, 3) self.assertEqual(OFPXMT_OFB_ETH_SRC, 4) self.assertEqual(OFPXMT_OFB_ETH_TYPE, 5) self.assertEqual(OFPXMT_OFB_VLAN_VID, 6) self.assertEqual(OFPXMT_OFB_VLAN_PCP, 7) self.assertEqual(OFPXMT_OFB_IP_DSCP, 8) self.assertEqual(OFPXMT_OFB_IP_ECN, 9) self.assertEqual(OFPXMT_OFB_IP_PROTO, 10) self.assertEqual(OFPXMT_OFB_IPV4_SRC, 11) self.assertEqual(OFPXMT_OFB_IPV4_DST, 12) self.assertEqual(OFPXMT_OFB_TCP_SRC, 13) self.assertEqual(OFPXMT_OFB_TCP_DST, 14) self.assertEqual(OFPXMT_OFB_UDP_SRC, 15) self.assertEqual(OFPXMT_OFB_UDP_DST, 16) self.assertEqual(OFPXMT_OFB_SCTP_SRC, 17) self.assertEqual(OFPXMT_OFB_SCTP_DST, 18) self.assertEqual(OFPXMT_OFB_ICMPV4_TYPE, 19) self.assertEqual(OFPXMT_OFB_ICMPV4_CODE, 20) self.assertEqual(OFPXMT_OFB_ARP_OP, 21) self.assertEqual(OFPXMT_OFB_ARP_SPA, 22) self.assertEqual(OFPXMT_OFB_ARP_TPA, 23) self.assertEqual(OFPXMT_OFB_ARP_SHA, 24) self.assertEqual(OFPXMT_OFB_ARP_THA, 25) self.assertEqual(OFPXMT_OFB_IPV6_SRC, 26) self.assertEqual(OFPXMT_OFB_IPV6_DST, 27) self.assertEqual(OFPXMT_OFB_IPV6_FLABEL, 28) self.assertEqual(OFPXMT_OFB_ICMPV6_TYPE, 29) self.assertEqual(OFPXMT_OFB_ICMPV6_CODE, 30) self.assertEqual(OFPXMT_OFB_IPV6_ND_TARGET, 31) self.assertEqual(OFPXMT_OFB_IPV6_ND_SLL, 32) self.assertEqual(OFPXMT_OFB_IPV6_ND_TLL, 33) self.assertEqual(OFPXMT_OFB_MPLS_LABEL, 34) self.assertEqual(OFPXMT_OFB_MPLS_TC, 35) def test_enum_ofp_vlan_id(self): self.assertEqual(OFPVID_PRESENT, 0x1000) self.assertEqual(OFPVID_NONE, 0x0000) def test_struct_ofp_oxm_experimenter_header(self): self.assertEqual(OFP_OXM_EXPERIMENTER_HEADER_PACK_STR, '!II') self.assertEqual(OFP_OXM_EXPERIMENTER_HEADER_SIZE, 8) def test_enum_ofp_instruction_type(self): self.assertEqual(OFPIT_GOTO_TABLE, 1) self.assertEqual(OFPIT_WRITE_METADATA, 2) self.assertEqual(OFPIT_WRITE_ACTIONS, 3) self.assertEqual(OFPIT_APPLY_ACTIONS, 4) self.assertEqual(OFPIT_CLEAR_ACTIONS, 5) self.assertEqual(OFPIT_EXPERIMENTER, 0xFFFF) def test_struct_ofp_instruction_goto_table(self): self.assertEqual(OFP_INSTRUCTION_GOTO_TABLE_PACK_STR, '!HHB3x') self.assertEqual(OFP_INSTRUCTION_GOTO_TABLE_SIZE, 8) def test_struct_ofp_instruction_write_metadata(self): self.assertEqual(OFP_INSTRUCTION_WRITE_METADATA_PACK_STR, '!HH4xQQ') self.assertEqual(OFP_INSTRUCTION_WRITE_METADATA_SIZE, 24) def test_struct_ofp_instaruction_actions(self): self.assertEqual(OFP_INSTRUCTION_ACTIONS_PACK_STR, '!HH4x') self.assertEqual(OFP_INSTRUCTION_ACTIONS_SIZE, 8) def test_enum_ofp_action_type(self): self.assertEqual(OFPAT_OUTPUT, 0) self.assertEqual(OFPAT_COPY_TTL_OUT, 11) self.assertEqual(OFPAT_COPY_TTL_IN, 12) self.assertEqual(OFPAT_SET_MPLS_TTL, 15) self.assertEqual(OFPAT_DEC_MPLS_TTL, 16) self.assertEqual(OFPAT_PUSH_VLAN, 17) self.assertEqual(OFPAT_POP_VLAN, 18) self.assertEqual(OFPAT_PUSH_MPLS, 19) self.assertEqual(OFPAT_POP_MPLS, 20) self.assertEqual(OFPAT_SET_QUEUE, 21) self.assertEqual(OFPAT_GROUP, 22) self.assertEqual(OFPAT_SET_NW_TTL, 23) self.assertEqual(OFPAT_DEC_NW_TTL, 24) self.assertEqual(OFPAT_SET_FIELD, 25) self.assertEqual(OFPAT_EXPERIMENTER, 0xffff) def test_struct_ofp_action_header(self): self.assertEqual(OFP_ACTION_HEADER_PACK_STR, '!HH4x') self.assertEqual(OFP_ACTION_HEADER_SIZE, 8) def test_struct_ofp_action_output(self): self.assertEqual(OFP_ACTION_OUTPUT_PACK_STR, '!HHIH6x') self.assertEqual(OFP_ACTION_OUTPUT_SIZE, 16) def test_enum_ofp_controller_max_len(self): self.assertEqual(OFPCML_MAX, 0xffe5) self.assertEqual(OFPCML_NO_BUFFER, 0xffff) def test_struct_ofp_action_group(self): self.assertEqual(OFP_ACTION_GROUP_PACK_STR, '!HHI') self.assertEqual(OFP_ACTION_GROUP_SIZE, 8) def test_struct_ofp_action_set_queue(self): self.assertEqual(OFP_ACTION_SET_QUEUE_PACK_STR, '!HHI') self.assertEqual(OFP_ACTION_SET_QUEUE_SIZE, 8) def test_struct_ofp_aciton_mpls_ttl(self): self.assertEqual(OFP_ACTION_MPLS_TTL_PACK_STR, '!HHB3x') self.assertEqual(OFP_ACTION_MPLS_TTL_SIZE, 8) def test_struct_ofp_action_nw_ttl(self): self.assertEqual(OFP_ACTION_NW_TTL_PACK_STR, '!HHB3x') self.assertEqual(OFP_ACTION_NW_TTL_SIZE, 8) def test_struct_ofp_action_push(self): self.assertEqual(OFP_ACTION_PUSH_PACK_STR, '!HHH2x') self.assertEqual(OFP_ACTION_PUSH_SIZE, 8) def test_struct_ofp_action_pop_mpls(self): self.assertEqual(OFP_ACTION_POP_MPLS_PACK_STR, '!HHH2x') self.assertEqual(OFP_ACTION_POP_MPLS_SIZE, 8) def test_struct_ofp_action_set_field(self): self.assertEqual(OFP_ACTION_SET_FIELD_PACK_STR, '!HH4B') self.assertEqual(OFP_ACTION_SET_FIELD_SIZE, 8) def test_struct_ofp_action_experimenter_header(self): self.assertEqual(OFP_ACTION_EXPERIMENTER_HEADER_PACK_STR, '!HHI') self.assertEqual(OFP_ACTION_EXPERIMENTER_HEADER_SIZE, 8) def test_struct_ofp_switch_feature(self): self.assertEqual(OFP_SWITCH_FEATURES_PACK_STR, '!QIB3xII') self.assertEqual(OFP_SWITCH_FEATURES_SIZE, 32) def test_enum_ofp_capabilities(self): self.assertEqual(OFPC_FLOW_STATS, 1 << 0) self.assertEqual(OFPC_TABLE_STATS, 1 << 1) self.assertEqual(OFPC_PORT_STATS, 1 << 2) self.assertEqual(OFPC_GROUP_STATS, 1 << 3) self.assertEqual(OFPC_IP_REASM, 1 << 5) self.assertEqual(OFPC_QUEUE_STATS, 1 << 6) self.assertEqual(OFPC_PORT_BLOCKED, 1 << 8) def test_struct_ofp_switch_config(self): self.assertEqual(OFP_SWITCH_CONFIG_PACK_STR, '!HH') self.assertEqual(OFP_SWITCH_CONFIG_SIZE, 12) def test_enum_ofp_config_flags(self): self.assertEqual(OFPC_FRAG_NORMAL, 0) self.assertEqual(OFPC_FRAG_DROP, 1 << 0) self.assertEqual(OFPC_FRAG_REASM, 1 << 1) self.assertEqual(OFPC_FRAG_MASK, 3) self.assertEqual(OFPC_INVALID_TTL_TO_CONTROLLER, 1 << 2) def test_enum_ofp_table(self): self.assertEqual(OFPTT_MAX, 0xfe) self.assertEqual(OFPTT_ALL, 0xff) def test_struct_ofp_table_mod(self): self.assertEqual(OFP_TABLE_MOD_PACK_STR, '!B3xI') self.assertEqual(OFP_TABLE_MOD_SIZE, 16) def test_enum_ofp_table_config(self): self.assertEqual(OFPTC_TABLE_MISS_CONTROLLER, 0) self.assertEqual(OFPTC_TABLE_MISS_CONTINUE, 1 << 0) self.assertEqual(OFPTC_TABLE_MISS_DROP, 1 << 1) self.assertEqual(OFPTC_TABLE_MISS_MASK, 3) def test_struct_ofp_flow_mod(self): self.assertEqual(OFP_FLOW_MOD_PACK_STR, '!QQBBHHHIIIH2xHHBBBB') self.assertEqual(OFP_FLOW_MOD_SIZE, 56) def test_enum_ofp_flow_mod_command(self): self.assertEqual(OFPFC_ADD, 0) self.assertEqual(OFPFC_MODIFY, 1) self.assertEqual(OFPFC_MODIFY_STRICT, 2) self.assertEqual(OFPFC_DELETE, 3) self.assertEqual(OFPFC_DELETE_STRICT, 4) def test_enum_ofp_flow_mod_flags(self): self.assertEqual(OFPFF_SEND_FLOW_REM, 1 << 0) self.assertEqual(OFPFF_CHECK_OVERLAP, 1 << 1) self.assertEqual(OFPFF_RESET_COUNTS, 1 << 2) def test_struct_ofp_group_mod(self): self.assertEqual(OFP_GROUP_MOD_PACK_STR, '!HBxI') self.assertEqual(OFP_GROUP_MOD_SIZE, 16) # same to OFPP_* def test_enum_ofp_group(self): self.assertEqual(OFPG_MAX, 0xffffff00) self.assertEqual(OFPG_ALL, 0xfffffffc) self.assertEqual(OFPG_ANY, 0xffffffff) def test_enum_ofp_group_mod_command(self): self.assertEqual(OFPGC_ADD, 0) self.assertEqual(OFPGC_MODIFY, 1) self.assertEqual(OFPGC_DELETE, 2) def test_enum_ofp_group_type(self): self.assertEqual(OFPGT_ALL, 0) self.assertEqual(OFPGT_SELECT, 1) self.assertEqual(OFPGT_INDIRECT, 2) self.assertEqual(OFPGT_FF, 3) def test_struct_ofp_bucket(self): self.assertEqual(OFP_BUCKET_PACK_STR, '!HHII4x') self.assertEqual(OFP_BUCKET_SIZE, 16) def test_struct_ofp_port_mod(self): self.assertEqual(OFP_PORT_MOD_PACK_STR, '!I4x6s2xIII4x') self.assertEqual(OFP_PORT_MOD_SIZE, 40) def test_sturct_ofp_stats_request(self): self.assertEqual(OFP_STATS_REQUEST_PACK_STR, '!HH4x') self.assertEqual(OFP_STATS_REQUEST_SIZE, 16) # OFPSF_Rself.assertEqual* flags (none yet defined). # The only value defined for flags in a reply is whether more # replies will follow this one - this has the value 0x0001. def test_enum_ofp_stats_reply_flags(self): self.assertEqual(OFPSF_REPLY_MORE, 0x0001) def test_struct_ofp_stats_reply(self): self.assertEqual(OFP_STATS_REPLY_PACK_STR, '!HH4x') self.assertEqual(OFP_STATS_REPLY_SIZE, 16) def test_enum_ofp_stats_types(self): self.assertEqual(OFPST_DESC, 0) self.assertEqual(OFPST_FLOW, 1) self.assertEqual(OFPST_AGGREGATE, 2) self.assertEqual(OFPST_TABLE, 3) self.assertEqual(OFPST_PORT, 4) self.assertEqual(OFPST_QUEUE, 5) self.assertEqual(OFPST_GROUP, 6) self.assertEqual(OFPST_GROUP_DESC, 7) self.assertEqual(OFPST_GROUP_FEATURES, 8) self.assertEqual(OFPST_EXPERIMENTER, 0xffff) def test_struct_ofp_desc_stats(self): self.assertEqual(OFP_DESC_STATS_PACK_STR, '!256s256s256s32s256s') self.assertEqual(OFP_DESC_STATS_SIZE, 1056) def test_struct_ofp_flow_stats_request(self): self.assertEqual(OFP_FLOW_STATS_REQUEST_PACK_STR, '!B3xII4xQQ') self.assertEqual(OFP_FLOW_STATS_REQUEST_SIZE, 40) def test_struct_ofp_flow_stats(self): self.assertEqual(OFP_FLOW_STATS_PACK_STR, '!HBxIIHHH6xQQQ') self.assertEqual(OFP_FLOW_STATS_SIZE, 56) def test_struct_ofp_aggregate_stats_request(self): self.assertEqual(OFP_AGGREGATE_STATS_REQUEST_PACK_STR, '!B3xII4xQQ') self.assertEqual(OFP_AGGREGATE_STATS_REQUEST_SIZE, 40) def test_struct_ofp_aggregate_stats_reply(self): self.assertEqual(OFP_AGGREGATE_STATS_REPLY_PACK_STR, '!QQI4x') self.assertEqual(OFP_AGGREGATE_STATS_REPLY_SIZE, 24) def test_sturct_ofp_table_stats(self): self.assertEqual(OFP_TABLE_STATS_PACK_STR, '!B7x32sQQIIQQQQIIIIQQ') self.assertEqual(OFP_TABLE_STATS_SIZE, 128) def test_struct_ofp_port_stats_request(self): self.assertEqual(OFP_PORT_STATS_REQUEST_PACK_STR, '!I4x') self.assertEqual(OFP_PORT_STATS_REQUEST_SIZE, 8) def test_struct_ofp_port_stats(self): self.assertEqual(OFP_PORT_STATS_PACK_STR, '!I4xQQQQQQQQQQQQ') self.assertEqual(OFP_PORT_STATS_SIZE, 104) def test_struct_ofp_queue_stats_request(self): self.assertEqual(OFP_QUEUE_STATS_REQUEST_PACK_STR, '!II') self.assertEqual(OFP_QUEUE_STATS_REQUEST_SIZE, 8) def test_struct_ofp_queue_stats(self): self.assertEqual(OFP_QUEUE_STATS_PACK_STR, '!IIQQQ') self.assertEqual(OFP_QUEUE_STATS_SIZE, 32) def test_struct_ofp_group_stats_request(self): self.assertEqual(OFP_GROUP_STATS_REQUEST_PACK_STR, '!I4x') self.assertEqual(OFP_GROUP_STATS_REQUEST_SIZE, 8) def test_struct_ofp_group_stats(self): self.assertEqual(OFP_GROUP_STATS_PACK_STR, '!H2xII4xQQ') self.assertEqual(OFP_GROUP_STATS_SIZE, 32) def test_struct_ofp_bucket_counter(self): self.assertEqual(OFP_BUCKET_COUNTER_PACK_STR, '!QQ') self.assertEqual(OFP_BUCKET_COUNTER_SIZE, 16) def test_struct_ofp_group_desc_stats(self): self.assertEqual(OFP_GROUP_DESC_STATS_PACK_STR, '!HBxI') self.assertEqual(OFP_GROUP_DESC_STATS_SIZE, 8) def test_struct_ofp_group_features_stats(self): self.assertEqual(OFP_GROUP_FEATURES_STATS_PACK_STR, '!II4I4I') self.assertEqual(OFP_GROUP_FEATURES_STATS_SIZE, 40) def test_enmu_ofp_group_capabilities(self): self.assertEqual(OFPGFC_SELECT_WEIGHT, 1 << 0) self.assertEqual(OFPGFC_SELECT_LIVENESS, 1 << 1) self.assertEqual(OFPGFC_CHAINING, 1 << 2) self.assertEqual(OFPGFC_CHAINING_CHECKS, 1 << 3) def test_struct_ofp_experimenter_stats_header(self): self.assertEqual(OFP_EXPERIMENTER_STATS_HEADER_PACK_STR, '!II') self.assertEqual(OFP_EXPERIMENTER_STATS_HEADER_SIZE, 8) def test_struct_opf_queue_get_config_request(self): self.assertEqual(OFP_QUEUE_GET_CONFIG_REQUEST_PACK_STR, '!I4x') self.assertEqual(OFP_QUEUE_GET_CONFIG_REQUEST_SIZE, 16) def test_struct_ofp_queue_get_config_reply(self): self.assertEqual(OFP_QUEUE_GET_CONFIG_REPLY_PACK_STR, '!I4x') self.assertEqual(OFP_QUEUE_GET_CONFIG_REPLY_SIZE, 16) def test_struct_ofp_packet_out(self): self.assertEqual(OFP_PACKET_OUT_PACK_STR, '!IIH6x') self.assertEqual(OFP_PACKET_OUT_SIZE, 24) def test_struct_ofp_role_request(self): self.assertEqual(OFP_ROLE_REQUEST_PACK_STR, '!I4xQ') self.assertEqual(OFP_ROLE_REQUEST_SIZE, 24) def test_enum_ofp_controller_role(self): self.assertEqual(OFPCR_ROLE_NOCHANGE, 0) self.assertEqual(OFPCR_ROLE_EQUAL, 1) self.assertEqual(OFPCR_ROLE_MASTER, 2) self.assertEqual(OFPCR_ROLE_SLAVE, 3) def test_struct_ofp_packet_in(self): self.assertEqual(OFP_PACKET_IN_PACK_STR, '!IHBB') self.assertEqual(OFP_PACKET_IN_SIZE, 24) def test_enum_ofp_packet_in_reason(self): self.assertEqual(OFPR_NO_MATCH, 0) self.assertEqual(OFPR_ACTION, 1) self.assertEqual(OFPR_INVALID_TTL, 2) def test_struct_ofp_flow_removed(self): self.assertEqual(OFP_FLOW_REMOVED_PACK_STR, '!QHBBIIHHQQHHBBBB') self.assertEqual(OFP_FLOW_REMOVED_PACK_STR0, '!QHBBIIHHQQ') self.assertEqual(OFP_FLOW_REMOVED_SIZE, 56) def test_enum_ofp_flow_removed_reason(self): self.assertEqual(OFPRR_IDLE_TIMEOUT, 0) self.assertEqual(OFPRR_HARD_TIMEOUT, 1) self.assertEqual(OFPRR_DELETE, 2) self.assertEqual(OFPRR_GROUP_DELETE, 3) def test_struct_ofp_port_status(self): self.assertEqual(OFP_PORT_STATUS_PACK_STR, '!B7xI4x6s2x16sIIIIIIII') self.assertEqual(OFP_PORT_STATUS_DESC_OFFSET, 16) self.assertEqual(OFP_PORT_STATUS_SIZE, 80) def test_enum_ofp_port_reason(self): self.assertEqual(OFPPR_ADD, 0) self.assertEqual(OFPPR_DELETE, 1) self.assertEqual(OFPPR_MODIFY, 2) def test_struct_ofp_error_msg(self): self.assertEqual(OFP_ERROR_MSG_PACK_STR, '!HH') self.assertEqual(OFP_ERROR_MSG_SIZE, 12) def test_enum_ofp_error_type(self): self.assertEqual(OFPET_HELLO_FAILED, 0) self.assertEqual(OFPET_BAD_REQUEST, 1) self.assertEqual(OFPET_BAD_ACTION, 2) self.assertEqual(OFPET_BAD_INSTRUCTION, 3) self.assertEqual(OFPET_BAD_MATCH, 4) self.assertEqual(OFPET_FLOW_MOD_FAILED, 5) self.assertEqual(OFPET_GROUP_MOD_FAILED, 6) self.assertEqual(OFPET_PORT_MOD_FAILED, 7) self.assertEqual(OFPET_TABLE_MOD_FAILED, 8) self.assertEqual(OFPET_QUEUE_OP_FAILED, 9) self.assertEqual(OFPET_SWITCH_CONFIG_FAILED, 10) self.assertEqual(OFPET_ROLE_REQUEST_FAILED, 11) self.assertEqual(OFPET_EXPERIMENTER, 0xffff) def test_enum_ofp_hello_failed_code(self): self.assertEqual(OFPHFC_INCOMPATIBLE, 0) self.assertEqual(OFPHFC_EPERM, 1) def test_enum_ofp_bad_request_code(self): self.assertEqual(OFPBRC_BAD_VERSION, 0) self.assertEqual(OFPBRC_BAD_TYPE, 1) self.assertEqual(OFPBRC_BAD_STAT, 2) self.assertEqual(OFPBRC_BAD_EXPERIMENTER, 3) self.assertEqual(OFPBRC_BAD_EXP_TYPE, 4) self.assertEqual(OFPBRC_EPERM, 5) self.assertEqual(OFPBRC_BAD_LEN, 6) self.assertEqual(OFPBRC_BUFFER_EMPTY, 7) self.assertEqual(OFPBRC_BUFFER_UNKNOWN, 8) self.assertEqual(OFPBRC_BAD_TABLE_ID, 9) self.assertEqual(OFPBRC_IS_SLAVE, 10) self.assertEqual(OFPBRC_BAD_PORT, 11) self.assertEqual(OFPBRC_BAD_PACKET, 12) def test_enum_ofp_bad_action_code(self): self.assertEqual(OFPBAC_BAD_TYPE, 0) self.assertEqual(OFPBAC_BAD_LEN, 1) self.assertEqual(OFPBAC_BAD_EXPERIMENTER, 2) self.assertEqual(OFPBAC_BAD_EXP_TYPE, 3) self.assertEqual(OFPBAC_BAD_OUT_PORT, 4) self.assertEqual(OFPBAC_BAD_ARGUMENT, 5) self.assertEqual(OFPBAC_EPERM, 6) self.assertEqual(OFPBAC_TOO_MANY, 7) self.assertEqual(OFPBAC_BAD_QUEUE, 8) self.assertEqual(OFPBAC_BAD_OUT_GROUP, 9) self.assertEqual(OFPBAC_MATCH_INCONSISTENT, 10) self.assertEqual(OFPBAC_UNSUPPORTED_ORDER, 11) self.assertEqual(OFPBAC_BAD_TAG, 12) self.assertEqual(OFPBAC_BAD_SET_TYPE, 13) self.assertEqual(OFPBAC_BAD_SET_LEN, 14) self.assertEqual(OFPBAC_BAD_SET_ARGUMENT, 15) def test_enum_ofp_bad_instruction_code(self): self.assertEqual(OFPBIC_UNKNOWN_INST, 0) self.assertEqual(OFPBIC_UNSUP_INST, 1) self.assertEqual(OFPBIC_BAD_TABLE_ID, 2) self.assertEqual(OFPBIC_UNSUP_METADATA, 3) self.assertEqual(OFPBIC_UNSUP_METADATA_MASK, 4) self.assertEqual(OFPBIC_BAD_EXPERIMENTER, 5) self.assertEqual(OFPBIC_BAD_EXP_TYPE, 6) self.assertEqual(OFPBIC_BAD_LEN, 7) self.assertEqual(OFPBIC_EPERM, 8) def test_enum_ofp_bad_match_code(self): self.assertEqual(OFPBMC_BAD_TYPE, 0) self.assertEqual(OFPBMC_BAD_LEN, 1) self.assertEqual(OFPBMC_BAD_TAG, 2) self.assertEqual(OFPBMC_BAD_DL_ADDR_MASK, 3) self.assertEqual(OFPBMC_BAD_NW_ADDR_MASK, 4) self.assertEqual(OFPBMC_BAD_WILDCARDS, 5) self.assertEqual(OFPBMC_BAD_FIELD, 6) self.assertEqual(OFPBMC_BAD_VALUE, 7) self.assertEqual(OFPBMC_BAD_MASK, 8) self.assertEqual(OFPBMC_BAD_PREREQ, 9) self.assertEqual(OFPBMC_DUP_FIELD, 10) self.assertEqual(OFPBMC_EPERM, 11) def test_enum_ofp_flow_mod_failed_code(self): self.assertEqual(OFPFMFC_UNKNOWN, 0) self.assertEqual(OFPFMFC_TABLE_FULL, 1) self.assertEqual(OFPFMFC_BAD_TABLE_ID, 2) self.assertEqual(OFPFMFC_OVERLAP, 3) self.assertEqual(OFPFMFC_EPERM, 4) self.assertEqual(OFPFMFC_BAD_TIMEOUT, 5) self.assertEqual(OFPFMFC_BAD_COMMAND, 6) self.assertEqual(OFPFMFC_BAD_FLAGS, 7) def test_enum_ofp_group_mod_failed_code(self): self.assertEqual(OFPGMFC_GROUP_EXISTS, 0) self.assertEqual(OFPGMFC_INVALID_GROUP, 1) self.assertEqual(OFPGMFC_WEIGHT_UNSUPPORTED, 2) self.assertEqual(OFPGMFC_OUT_OF_GROUPS, 3) self.assertEqual(OFPGMFC_OUT_OF_BUCKETS, 4) self.assertEqual(OFPGMFC_CHAINING_UNSUPPORTED, 5) self.assertEqual(OFPGMFC_WATCH_UNSUPPORTED, 6) self.assertEqual(OFPGMFC_LOOP, 7) self.assertEqual(OFPGMFC_UNKNOWN_GROUP, 8) self.assertEqual(OFPGMFC_CHAINED_GROUP, 9) self.assertEqual(OFPGMFC_BAD_TYPE, 10) self.assertEqual(OFPGMFC_BAD_COMMAND, 11) self.assertEqual(OFPGMFC_BAD_BUCKET, 12) self.assertEqual(OFPGMFC_BAD_WATCH, 13) self.assertEqual(OFPGMFC_EPERM, 14) def test_enum_ofp_port_mod_failed_code(self): self.assertEqual(OFPPMFC_BAD_PORT, 0) self.assertEqual(OFPPMFC_BAD_HW_ADDR, 1) self.assertEqual(OFPPMFC_BAD_CONFIG, 2) self.assertEqual(OFPPMFC_BAD_ADVERTISE, 3) self.assertEqual(OFPPMFC_EPERM, 4) def test_enum_ofp_table_mod_failed_code(self): self.assertEqual(OFPTMFC_BAD_TABLE, 0) self.assertEqual(OFPTMFC_BAD_CONFIG, 1) self.assertEqual(OFPTMFC_EPERM, 2) def test_enum_ofp_queue_op_failed_code(self): self.assertEqual(OFPQOFC_BAD_PORT, 0) self.assertEqual(OFPQOFC_BAD_QUEUE, 1) self.assertEqual(OFPQOFC_EPERM, 2) def test_enum_ofp_switch_config_failed_code(self): self.assertEqual(OFPSCFC_BAD_FLAGS, 0) self.assertEqual(OFPSCFC_BAD_LEN, 1) self.assertEqual(OFPSCFC_EPERM, 2) def test_enum_ofp_role_request_failed_code(self): self.assertEqual(OFPRRFC_STALE, 0) self.assertEqual(OFPRRFC_UNSUP, 1) self.assertEqual(OFPRRFC_BAD_ROLE, 2) def test_struct_ofp_error_experimenter_msg(self): self.assertEqual(OFP_ERROR_EXPERIMENTER_MSG_PACK_STR, '!HHI') self.assertEqual(OFP_ERROR_EXPERIMENTER_MSG_SIZE, 16) def test_struct_ofp_experimenter_header(self): self.assertEqual(OFP_EXPERIMENTER_HEADER_PACK_STR, '!II') self.assertEqual(OFP_EXPERIMENTER_HEADER_SIZE, 16) # OXM is interpreted as a 32-bit word in network byte order. # - oxm_class 17-bit to 32-bit (OFPXMC_*). # - oxm_field 10-bit to 16-bit (OFPXMT_OFB_*). # - oxm_hasmask 9-bit (Set if OXM include a bitmask). # - oxm_length 1-bit to 8-bit (Lenght of OXM payload). def _test_OXM(self, value, class_, field, hasmask, length): virfy = (class_ << 16) | (field << 9) | (hasmask << 8) | length self.assertEqual(value >> 32, 0) self.assertEqual(value, virfy) def _test_OXM_basic(self, value, field, hasmask, length): self._test_OXM(value, OFPXMC_OPENFLOW_BASIC, field, hasmask, length) def test_OXM_basic(self): self._test_OXM_basic(OXM_OF_IN_PORT, OFPXMT_OFB_IN_PORT, 0, 4) self._test_OXM_basic(OXM_OF_IN_PHY_PORT, OFPXMT_OFB_IN_PHY_PORT, 0, 4) self._test_OXM_basic(OXM_OF_METADATA, OFPXMT_OFB_METADATA, 0, 8) self._test_OXM_basic(OXM_OF_METADATA_W, OFPXMT_OFB_METADATA, 1, 16) self._test_OXM_basic(OXM_OF_ETH_DST, OFPXMT_OFB_ETH_DST, 0, 6) self._test_OXM_basic(OXM_OF_ETH_DST_W, OFPXMT_OFB_ETH_DST, 1, 12) self._test_OXM_basic(OXM_OF_ETH_SRC, OFPXMT_OFB_ETH_SRC, 0, 6) self._test_OXM_basic(OXM_OF_ETH_SRC_W, OFPXMT_OFB_ETH_SRC, 1, 12) self._test_OXM_basic(OXM_OF_ETH_TYPE, OFPXMT_OFB_ETH_TYPE, 0, 2) self._test_OXM_basic(OXM_OF_VLAN_VID, OFPXMT_OFB_VLAN_VID, 0, 2) self._test_OXM_basic(OXM_OF_VLAN_VID_W, OFPXMT_OFB_VLAN_VID, 1, 4) self._test_OXM_basic(OXM_OF_VLAN_PCP, OFPXMT_OFB_VLAN_PCP, 0, 1) self._test_OXM_basic(OXM_OF_IP_DSCP, OFPXMT_OFB_IP_DSCP, 0, 1) self._test_OXM_basic(OXM_OF_IP_ECN, OFPXMT_OFB_IP_ECN, 0, 1) self._test_OXM_basic(OXM_OF_IP_PROTO, OFPXMT_OFB_IP_PROTO, 0, 1) self._test_OXM_basic(OXM_OF_IPV4_SRC, OFPXMT_OFB_IPV4_SRC, 0, 4) self._test_OXM_basic(OXM_OF_IPV4_SRC_W, OFPXMT_OFB_IPV4_SRC, 1, 8) self._test_OXM_basic(OXM_OF_IPV4_DST, OFPXMT_OFB_IPV4_DST, 0, 4) self._test_OXM_basic(OXM_OF_IPV4_DST_W, OFPXMT_OFB_IPV4_DST, 1, 8) self._test_OXM_basic(OXM_OF_TCP_SRC, OFPXMT_OFB_TCP_SRC, 0, 2) self._test_OXM_basic(OXM_OF_TCP_DST, OFPXMT_OFB_TCP_DST, 0, 2) self._test_OXM_basic(OXM_OF_UDP_SRC, OFPXMT_OFB_UDP_SRC, 0, 2) self._test_OXM_basic(OXM_OF_UDP_DST, OFPXMT_OFB_UDP_DST, 0, 2) self._test_OXM_basic(OXM_OF_SCTP_SRC, OFPXMT_OFB_SCTP_SRC, 0, 2) self._test_OXM_basic(OXM_OF_SCTP_DST, OFPXMT_OFB_SCTP_DST, 0, 2) self._test_OXM_basic(OXM_OF_ICMPV4_TYPE, OFPXMT_OFB_ICMPV4_TYPE, 0, 1) self._test_OXM_basic(OXM_OF_ICMPV4_CODE, OFPXMT_OFB_ICMPV4_CODE, 0, 1) self._test_OXM_basic(OXM_OF_ARP_OP, OFPXMT_OFB_ARP_OP, 0, 2) self._test_OXM_basic(OXM_OF_ARP_SPA, OFPXMT_OFB_ARP_SPA, 0, 4) self._test_OXM_basic(OXM_OF_ARP_SPA_W, OFPXMT_OFB_ARP_SPA, 1, 8) self._test_OXM_basic(OXM_OF_ARP_TPA, OFPXMT_OFB_ARP_TPA, 0, 4) self._test_OXM_basic(OXM_OF_ARP_TPA_W, OFPXMT_OFB_ARP_TPA, 1, 8) self._test_OXM_basic(OXM_OF_ARP_SHA, OFPXMT_OFB_ARP_SHA, 0, 6) self._test_OXM_basic(OXM_OF_ARP_SHA_W, OFPXMT_OFB_ARP_SHA, 1, 12) self._test_OXM_basic(OXM_OF_ARP_THA, OFPXMT_OFB_ARP_THA, 0, 6) self._test_OXM_basic(OXM_OF_ARP_THA_W, OFPXMT_OFB_ARP_THA, 1, 12) self._test_OXM_basic(OXM_OF_IPV6_SRC, OFPXMT_OFB_IPV6_SRC, 0, 16) self._test_OXM_basic(OXM_OF_IPV6_SRC_W, OFPXMT_OFB_IPV6_SRC, 1, 32) self._test_OXM_basic(OXM_OF_IPV6_DST, OFPXMT_OFB_IPV6_DST, 0, 16) self._test_OXM_basic(OXM_OF_IPV6_DST_W, OFPXMT_OFB_IPV6_DST, 1, 32) self._test_OXM_basic(OXM_OF_IPV6_FLABEL, OFPXMT_OFB_IPV6_FLABEL, 0, 4) self._test_OXM_basic(OXM_OF_IPV6_FLABEL_W, OFPXMT_OFB_IPV6_FLABEL, 1, 8) self._test_OXM_basic(OXM_OF_ICMPV6_TYPE, OFPXMT_OFB_ICMPV6_TYPE, 0, 1) self._test_OXM_basic(OXM_OF_ICMPV6_CODE, OFPXMT_OFB_ICMPV6_CODE, 0, 1) self._test_OXM_basic(OXM_OF_IPV6_ND_TARGET, OFPXMT_OFB_IPV6_ND_TARGET, 0, 16) self._test_OXM_basic(OXM_OF_IPV6_ND_SLL, OFPXMT_OFB_IPV6_ND_SLL, 0, 6) self._test_OXM_basic(OXM_OF_IPV6_ND_TLL, OFPXMT_OFB_IPV6_ND_TLL, 0, 6) self._test_OXM_basic(OXM_OF_MPLS_LABEL, OFPXMT_OFB_MPLS_LABEL, 0, 4) self._test_OXM_basic(OXM_OF_MPLS_TC, OFPXMT_OFB_MPLS_TC, 0, 1) def test_define_constants(self): self.assertEqual(OFP_VERSION, 0x03) self.assertEqual(OFP_TCP_PORT, 6633) self.assertEqual(MAX_XID, 0xffffffff) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/test_oxm.py0000664000175000017500000001275400000000000022325 0ustar00zuulzuul00000000000000# Copyright (C) 2015 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2015 YAMAMOTO Takashi # # 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. import unittest import os_ken.ofproto.ofproto_v1_3 as ofp class Test_OXM(unittest.TestCase): def _test_encode(self, user, on_wire): (f, uv) = user (n, v, m) = ofp.oxm_from_user(f, uv) buf = bytearray() ofp.oxm_serialize(n, v, m, buf, 0) self.assertEqual(on_wire, buf) def _test_decode(self, user, on_wire): (n, v, m, l) = ofp.oxm_parse(on_wire, 0) self.assertEqual(len(on_wire), l) (f, uv) = ofp.oxm_to_user(n, v, m) self.assertEqual(user, (f, uv)) def _test_encode_header(self, user, on_wire): f = user n = ofp.oxm_from_user_header(f) buf = bytearray() ofp.oxm_serialize_header(n, buf, 0) self.assertEqual(on_wire, buf) def _test_decode_header(self, user, on_wire): (n, l) = ofp.oxm_parse_header(on_wire, 0) self.assertEqual(len(on_wire), l) f = ofp.oxm_to_user_header(n) self.assertEqual(user, f) def _test(self, user, on_wire, header_bytes): self._test_encode(user, on_wire) self._test_decode(user, on_wire) if isinstance(user[1], tuple): # has mask? return user_header = user[0] on_wire_header = on_wire[:header_bytes] self._test_decode_header(user_header, on_wire_header) if user_header.startswith('field_'): return # not supported self._test_encode_header(user_header, on_wire_header) def test_basic_nomask(self): user = ('ipv4_src', '192.0.2.1') on_wire = ( b'\x80\x00\x16\x04' b'\xc0\x00\x02\x01' ) self._test(user, on_wire, 4) def test_basic_mask(self): user = ('ipv4_src', ('192.0.2.1', '255.255.0.0')) on_wire = ( b'\x80\x00\x17\x08' b'\xc0\x00\x02\x01' b'\xff\xff\x00\x00' ) self._test(user, on_wire, 4) def test_exp_nomask(self): user = ('_dp_hash', 0x12345678) on_wire = ( b'\xff\xff\x00\x08' b'\x00\x00\x23\x20' # Nicira b'\x12\x34\x56\x78' ) self._test(user, on_wire, 8) def test_exp_mask(self): user = ('_dp_hash', (0x12345678, 0x7fffffff)) on_wire = ( b'\xff\xff\x01\x0c' b'\x00\x00\x23\x20' # Nicira b'\x12\x34\x56\x78' b'\x7f\xff\xff\xff' ) self._test(user, on_wire, 8) def test_exp_nomask_2(self): user = ('tcp_flags', 0x876) on_wire = ( b'\xff\xff\x54\x06' b'\x4f\x4e\x46\x00' # ONF b'\x08\x76' ) self._test(user, on_wire, 8) def test_exp_mask_2(self): user = ('tcp_flags', (0x876, 0x7ff)) on_wire = ( b'\xff\xff\x55\x08' b'\x4f\x4e\x46\x00' # ONF b'\x08\x76' b'\x07\xff' ) self._test(user, on_wire, 8) def test_exp_nomask_3(self): user = ('actset_output', 0x98765432) on_wire = ( b'\xff\xff\x56\x08' b'\x4f\x4e\x46\x00' # ONF b'\x98\x76\x54\x32' ) self._test(user, on_wire, 8) def test_exp_mask_3(self): user = ('actset_output', (0x98765432, 0xfffffffe)) on_wire = ( b'\xff\xff\x57\x0c' b'\x4f\x4e\x46\x00' # ONF b'\x98\x76\x54\x32' b'\xff\xff\xff\xfe' ) self._test(user, on_wire, 8) def test_nxm_1_nomask(self): user = ('tun_ipv4_src', '192.0.2.1') on_wire = ( b'\x00\x01\x3e\x04' b'\xc0\x00\x02\x01' ) self._test(user, on_wire, 4) def test_nxm_1_mask(self): user = ('tun_ipv4_src', ('192.0.2.1', '255.255.0.0')) on_wire = ( b'\x00\x01\x3f\x08' b'\xc0\x00\x02\x01' b'\xff\xff\x00\x00' ) self._test(user, on_wire, 4) def test_ext_256_nomask(self): user = ('pbb_uca', 50) on_wire = ( b'\xff\xff\x00\x07' b'\x4f\x4e\x46\x00' # ONF b'\x0a\x00' b'\x32' ) self._test(user, on_wire, 10) def test_ext_256_mask(self): user = ('pbb_uca', (50, 51)) on_wire = ( b'\xff\xff\x01\x08' b'\x4f\x4e\x46\x00' # ONF b'\x0a\x00' b'\x32' b'\x33' ) self._test(user, on_wire, 10) def test_basic_unknown_nomask(self): user = ('field_100', 'aG9nZWhvZ2U=') on_wire = ( b'\x00\x00\xc8\x08' b'hogehoge' ) self._test(user, on_wire, 4) def test_basic_unknown_mask(self): user = ('field_100', ('aG9nZWhvZ2U=', 'ZnVnYWZ1Z2E=')) on_wire = ( b'\x00\x00\xc9\x10' b'hogehoge' b'fugafuga' ) self._test(user, on_wire, 4) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/test_oxs.py0000664000175000017500000000655400000000000022334 0ustar00zuulzuul00000000000000# Copyright (C) 2015 Nippon Telegraph and Telephone 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. import logging import unittest import os_ken.ofproto.ofproto_v1_5 as ofp LOG = logging.getLogger(__name__) class Test_OXS(unittest.TestCase): def _test_encode(self, user, on_wire): """ test encording user value into on-wire bytes. n: name of OXS field uv: user vale t: oxs_type v: on-wire bytes value """ (n, uv) = user (t, v, _) = ofp.oxs_from_user(n, uv) buf = bytearray() ofp.oxs_serialize(t, v, None, buf, 0) self.assertEqual(on_wire, buf) def _test_decode(self, user, on_wire): """ test decording user value from on-wire bytes. t: oxs_type v: on-wire bytes value l: length of field n: name of OXS field uv: user vale """ (t, v, _, l) = ofp.oxs_parse(on_wire, 0) self.assertEqual(len(on_wire), l) (n, uv) = ofp.oxs_to_user(t, v, None) self.assertEqual(user, (n, uv)) def _test_encode_header(self, user, on_wire): """ test encording header. t: oxs_type """ t = ofp.oxs_from_user_header(user) buf = bytearray() ofp.oxs_serialize_header(t, buf, 0) self.assertEqual(on_wire, buf) def _test_decode_header(self, user, on_wire): """ test decording header. t: oxs_type l: length of header n: name of OXS field """ (t, l) = ofp.oxs_parse_header(on_wire, 0) self.assertEqual(len(on_wire), l) n = ofp.oxs_to_user_header(t) self.assertEqual(user, n) def _test(self, user, on_wire, header_bytes): """ execute tests. user: user specified value. eg. user = ('duration', (100, 100)) on_wire: on-wire bytes header_bytes: header length """ self._test_encode(user, on_wire) self._test_decode(user, on_wire) user_header = user[0] on_wire_header = on_wire[:header_bytes] self._test_decode_header(user_header, on_wire_header) if user_header.startswith('field_'): return # not supported self._test_encode_header(user_header, on_wire_header) def test_basic_single(self): user = ('flow_count', 100) on_wire = ( b'\x80\x02\x06\x04' b'\x00\x00\x00\x64' ) self._test(user, on_wire, 4) def test_basic_double(self): user = ('duration', (100, 200)) on_wire = ( b'\x80\x02\x00\x08' b'\x00\x00\x00\x64' b'\x00\x00\x00\xc8' ) self._test(user, on_wire, 4) def test_basic_unknown(self): user = ('field_100', 'aG9nZWhvZ2U=') on_wire = ( b'\x00\x00\xc8\x08' b'hogehoge' ) self._test(user, on_wire, 4) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/test_parser.py0000664000175000017500000002746100000000000023017 0ustar00zuulzuul00000000000000# Copyright (C) 2013,2014,2015 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013,2014,2015 YAMAMOTO Takashi # # 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. import operator import os.path import sys import unittest import testscenarios from os_ken.ofproto import ofproto_parser from os_ken.ofproto import ofproto_protocol from os_ken.ofproto import ofproto_v1_0 from os_ken.ofproto import ofproto_v1_2 from os_ken.ofproto import ofproto_v1_3 from os_ken.ofproto import ofproto_v1_4 from os_ken.ofproto import ofproto_v1_5 from os_ken import exception import json # (has_parser, has_serializer) implemented = { 1: { ofproto_v1_0.OFPT_PACKET_OUT: (False, True), ofproto_v1_0.OFPT_FEATURES_REQUEST: (False, True), ofproto_v1_0.OFPT_FEATURES_REPLY: (True, False), ofproto_v1_0.OFPT_PACKET_IN: (True, False), ofproto_v1_0.OFPT_FLOW_MOD: (True, True), }, 3: { ofproto_v1_2.OFPT_FEATURES_REQUEST: (False, True), ofproto_v1_2.OFPT_FEATURES_REPLY: (True, False), ofproto_v1_2.OFPT_GET_CONFIG_REQUEST: (False, True), ofproto_v1_2.OFPT_GET_CONFIG_REPLY: (True, False), ofproto_v1_2.OFPT_SET_CONFIG: (False, True), ofproto_v1_2.OFPT_PACKET_IN: (True, False), ofproto_v1_2.OFPT_FLOW_REMOVED: (True, False), ofproto_v1_2.OFPT_PORT_STATUS: (True, False), ofproto_v1_2.OFPT_PACKET_OUT: (False, True), ofproto_v1_2.OFPT_FLOW_MOD: (True, True), ofproto_v1_2.OFPT_GROUP_MOD: (False, True), ofproto_v1_2.OFPT_PORT_MOD: (False, True), ofproto_v1_2.OFPT_TABLE_MOD: (False, True), ofproto_v1_2.OFPT_STATS_REQUEST: (False, True), ofproto_v1_2.OFPT_STATS_REPLY: (True, False), ofproto_v1_2.OFPT_BARRIER_REQUEST: (False, True), ofproto_v1_2.OFPT_QUEUE_GET_CONFIG_REQUEST: (False, True), ofproto_v1_2.OFPT_QUEUE_GET_CONFIG_REPLY: (True, False), ofproto_v1_2.OFPT_ROLE_REQUEST: (False, True), ofproto_v1_2.OFPT_ROLE_REPLY: (True, False), }, 4: { ofproto_v1_3.OFPT_HELLO: (True, False), ofproto_v1_3.OFPT_FEATURES_REQUEST: (False, True), ofproto_v1_3.OFPT_FEATURES_REPLY: (True, False), ofproto_v1_3.OFPT_GET_CONFIG_REQUEST: (False, True), ofproto_v1_3.OFPT_GET_CONFIG_REPLY: (True, False), ofproto_v1_3.OFPT_SET_CONFIG: (False, True), ofproto_v1_3.OFPT_PACKET_IN: (True, False), ofproto_v1_3.OFPT_FLOW_REMOVED: (True, False), ofproto_v1_3.OFPT_PORT_STATUS: (True, False), ofproto_v1_3.OFPT_PACKET_OUT: (False, True), ofproto_v1_3.OFPT_FLOW_MOD: (True, True), ofproto_v1_3.OFPT_GROUP_MOD: (False, True), ofproto_v1_3.OFPT_PORT_MOD: (False, True), ofproto_v1_3.OFPT_METER_MOD: (False, True), ofproto_v1_3.OFPT_TABLE_MOD: (False, True), ofproto_v1_3.OFPT_MULTIPART_REQUEST: (False, True), ofproto_v1_3.OFPT_MULTIPART_REPLY: (True, False), ofproto_v1_3.OFPT_BARRIER_REQUEST: (False, True), ofproto_v1_3.OFPT_QUEUE_GET_CONFIG_REQUEST: (False, True), ofproto_v1_3.OFPT_QUEUE_GET_CONFIG_REPLY: (True, False), ofproto_v1_3.OFPT_ROLE_REQUEST: (False, True), ofproto_v1_3.OFPT_ROLE_REPLY: (True, False), ofproto_v1_3.OFPT_GET_ASYNC_REQUEST: (False, True), ofproto_v1_3.OFPT_GET_ASYNC_REPLY: (True, False), ofproto_v1_3.OFPT_SET_ASYNC: (False, True), }, 5: { ofproto_v1_4.OFPT_HELLO: (True, False), ofproto_v1_4.OFPT_FEATURES_REQUEST: (False, True), ofproto_v1_4.OFPT_FEATURES_REPLY: (True, False), ofproto_v1_4.OFPT_GET_CONFIG_REQUEST: (False, True), ofproto_v1_4.OFPT_GET_CONFIG_REPLY: (True, False), ofproto_v1_4.OFPT_SET_CONFIG: (False, True), ofproto_v1_4.OFPT_PACKET_IN: (True, False), ofproto_v1_4.OFPT_FLOW_REMOVED: (True, False), ofproto_v1_4.OFPT_PORT_STATUS: (True, False), ofproto_v1_4.OFPT_PACKET_OUT: (False, True), ofproto_v1_4.OFPT_FLOW_MOD: (True, True), ofproto_v1_4.OFPT_GROUP_MOD: (True, True), ofproto_v1_4.OFPT_PORT_MOD: (False, True), ofproto_v1_4.OFPT_METER_MOD: (True, True), ofproto_v1_4.OFPT_TABLE_MOD: (False, True), ofproto_v1_4.OFPT_MULTIPART_REQUEST: (False, True), ofproto_v1_4.OFPT_MULTIPART_REPLY: (True, False), ofproto_v1_4.OFPT_BARRIER_REQUEST: (False, True), ofproto_v1_4.OFPT_ROLE_REQUEST: (False, True), ofproto_v1_4.OFPT_ROLE_REPLY: (True, False), ofproto_v1_4.OFPT_GET_ASYNC_REQUEST: (False, True), ofproto_v1_4.OFPT_GET_ASYNC_REPLY: (True, False), ofproto_v1_4.OFPT_SET_ASYNC: (False, True), ofproto_v1_4.OFPT_ROLE_STATUS: (True, False), ofproto_v1_4.OFPT_TABLE_STATUS: (True, False), ofproto_v1_4.OFPT_REQUESTFORWARD: (True, True), ofproto_v1_4.OFPT_BUNDLE_CONTROL: (True, True), ofproto_v1_4.OFPT_BUNDLE_ADD_MESSAGE: (False, True), }, 6: { ofproto_v1_5.OFPT_HELLO: (True, False), ofproto_v1_5.OFPT_FEATURES_REQUEST: (False, True), ofproto_v1_5.OFPT_FEATURES_REPLY: (True, False), ofproto_v1_5.OFPT_GET_CONFIG_REQUEST: (False, True), ofproto_v1_5.OFPT_GET_CONFIG_REPLY: (True, False), ofproto_v1_5.OFPT_SET_CONFIG: (False, True), ofproto_v1_5.OFPT_PACKET_IN: (True, False), ofproto_v1_5.OFPT_FLOW_REMOVED: (True, False), ofproto_v1_5.OFPT_PORT_STATUS: (True, False), ofproto_v1_5.OFPT_PACKET_OUT: (False, True), ofproto_v1_5.OFPT_FLOW_MOD: (True, True), ofproto_v1_5.OFPT_GROUP_MOD: (True, True), ofproto_v1_5.OFPT_PORT_MOD: (False, True), ofproto_v1_5.OFPT_METER_MOD: (True, True), ofproto_v1_5.OFPT_TABLE_MOD: (False, True), ofproto_v1_5.OFPT_MULTIPART_REQUEST: (False, True), ofproto_v1_5.OFPT_MULTIPART_REPLY: (True, False), ofproto_v1_5.OFPT_BARRIER_REQUEST: (False, True), ofproto_v1_5.OFPT_ROLE_REQUEST: (False, True), ofproto_v1_5.OFPT_ROLE_REPLY: (True, False), ofproto_v1_5.OFPT_GET_ASYNC_REQUEST: (False, True), ofproto_v1_5.OFPT_GET_ASYNC_REPLY: (True, False), ofproto_v1_5.OFPT_SET_ASYNC: (False, True), ofproto_v1_5.OFPT_ROLE_STATUS: (True, False), ofproto_v1_5.OFPT_TABLE_STATUS: (True, False), ofproto_v1_5.OFPT_REQUESTFORWARD: (True, True), ofproto_v1_5.OFPT_BUNDLE_CONTROL: (True, True), ofproto_v1_5.OFPT_BUNDLE_ADD_MESSAGE: (False, True), ofproto_v1_5.OFPT_CONTROLLER_STATUS: (True, False), }, } def _list_test_cases(): this_dir = os.path.dirname(sys.modules[__name__].__file__) packet_data_dir = os.path.join(this_dir, '../../packet_data') json_dir = os.path.join(this_dir, 'json') ofvers = [ 'of10', 'of12', 'of13', 'of14', 'of15', ] cases = [] for ver in ofvers: pdir = packet_data_dir + '/' + ver jdir = json_dir + '/' + ver for file in os.listdir(pdir): if file.endswith('.packet'): truncated = None elif '.truncated' in file: # contents of .truncated files aren't relevant s1, s2 = file.split('.truncated') try: truncated = int(s2) except ValueError: continue file = s1 + '.packet' else: continue wire_msg = open(pdir + '/' + file, 'rb').read() if not truncated: json_str = open(jdir + '/' + file + '.json', 'r').read() else: json_str = open(jdir + '/' + file + '.truncated%d.json' % truncated, 'r').read() wire_msg = wire_msg[:truncated] method_name = ('test_' + file).replace('-', '_').replace('.', '_') if truncated: method_name += '_truncated%d' % truncated cases.append({'name': method_name, 'wire_msg': wire_msg, 'json_str': json_str}) return cases class Test_Parser(testscenarios.WithScenarios, unittest.TestCase): """Test case for os_ken.ofproto, especially json representation""" scenarios = [(case['name'], case) for case in _list_test_cases()] def setUp(self): pass def tearDown(self): pass @staticmethod def _msg_to_jsondict(msg): return msg.to_jsondict() @staticmethod def _jsondict_to_msg(dp, jsondict): return ofproto_parser.ofp_msg_from_jsondict(dp, jsondict) def test_parser(self): self._test_msg(name=self.name, wire_msg=self.wire_msg, json_str=self.json_str) def _test_msg(self, name, wire_msg, json_str): def bytes_eq(buf1, buf2): if buf1 != buf2: msg = 'EOF in either data' for i in range(0, min(len(buf1), len(buf2))): c1 = operator.getitem(bytes(buf1), i) c2 = operator.getitem(bytes(buf2), i) if c1 != c2: msg = 'differs at chr %d, %d != %d' % (i, c1, c2) break assert buf1 == buf2, "%r != %r, %s" % (buf1, buf2, msg) json_dict = json.loads(json_str) # on-wire -> OFPxxx -> json (version, msg_type, msg_len, xid) = ofproto_parser.header(wire_msg) try: has_parser, has_serializer = implemented[version][msg_type] except KeyError: has_parser = True has_serializer = True dp = ofproto_protocol.ProtocolDesc(version=version) if has_parser: try: msg = ofproto_parser.msg(dp, version, msg_type, msg_len, xid, wire_msg) json_dict2 = self._msg_to_jsondict(msg) except exception.OFPTruncatedMessage as e: json_dict2 = {'OFPTruncatedMessage': self._msg_to_jsondict(e.ofpmsg)} # XXXdebug code with open(('/tmp/%s.json' % name), 'w') as _file: _file.write(json.dumps(json_dict2)) self.assertEqual(json_dict, json_dict2) if 'OFPTruncatedMessage' in json_dict2: return # json -> OFPxxx -> json xid = json_dict[list(json_dict.keys())[0]].pop('xid', None) msg2 = self._jsondict_to_msg(dp, json_dict) msg2.set_xid(xid) if has_serializer: msg2.serialize() self.assertEqual(self._msg_to_jsondict(msg2), json_dict) bytes_eq(wire_msg, msg2.buf) # check if "len" "length" fields can be omitted def _remove(d, names): f = lambda x: _remove(x, names) if isinstance(d, list): return list(map(f, d)) if isinstance(d, dict): d2 = {} for k, v in d.items(): if k in names: continue d2[k] = f(v) return d2 return d json_dict3 = _remove(json_dict, ['len', 'length']) msg3 = self._jsondict_to_msg(dp, json_dict3) msg3.set_xid(xid) msg3.serialize() bytes_eq(wire_msg, msg3.buf) msg2.serialize() bytes_eq(wire_msg, msg2.buf) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/test_parser_compat.py0000664000175000017500000001131600000000000024352 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013 YAMAMOTO Takashi # # 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. import unittest import testscenarios from os_ken.ofproto import ofproto_v1_2 from os_ken.ofproto import ofproto_v1_3 from os_ken.ofproto import ofproto_v1_2_parser from os_ken.ofproto import ofproto_v1_3_parser from os_ken.lib import addrconv from struct import unpack def _list_test_cases(): ofpps = [ofproto_v1_2_parser, ofproto_v1_3_parser] cases = [] for ofpp in ofpps: mod = ofpp.__name__.split('.')[-1] method_name = 'test_' + mod + '_ofpmatch_compat' cases.append({'name': method_name, 'ofpp': ofpp}) return cases class Test_Parser_Compat(testscenarios.WithScenarios, unittest.TestCase): scenarios = [(case['name'], case) for case in _list_test_cases()] def setUp(self): pass def tearDown(self): pass def test_parser(self): self._test(name=self.name, ofpp=self.ofpp) def _test(self, name, ofpp): ofp = { ofproto_v1_2_parser: ofproto_v1_2, ofproto_v1_3_parser: ofproto_v1_3, }[ofpp] in_port = 987654321 eth_src = 'aa:bb:cc:dd:ee:ff' ipv4_src = '192.0.2.9' ipv6_src = 'fe80::f00b:a4ff:feef:5d8f' old_in_port = in_port old_eth_src = addrconv.mac.text_to_bin(eth_src) old_ipv4_src = unpack('!I', addrconv.ipv4.text_to_bin(ipv4_src))[0] old_ipv6_src = list(unpack('!8H', addrconv.ipv6.text_to_bin(ipv6_src))) def check(o): check_old(o) check_new(o) def check_old(o): # old api def get_field(m, t): for f in m.fields: if isinstance(f, t): return f get_value = lambda m, t: get_field(m, t).value self.assertEqual(get_value(o, ofpp.MTInPort), old_in_port) self.assertEqual(get_value(o, ofpp.MTEthSrc), old_eth_src) self.assertEqual(get_value(o, ofpp.MTIPV4Src), old_ipv4_src) self.assertEqual(get_value(o, ofpp.MTIPv6Src), old_ipv6_src) def check_new(o): # new api self.assertEqual(o['in_port'], in_port) self.assertEqual(o['eth_src'], eth_src) self.assertEqual(o['ipv4_src'], ipv4_src) self.assertEqual(o['ipv6_src'], ipv6_src) # ensure that old and new api produces the same thing # old api old = ofpp.OFPMatch() old.set_in_port(old_in_port) old.set_dl_src(old_eth_src) old.set_ipv4_src(old_ipv4_src) old.set_ipv6_src(old_ipv6_src) old_buf = bytearray() old.serialize(old_buf, 0) # note: you can't inspect an object composed with the old set_XXX api # before serialize(). check_old(old) # another variant of old api; originally it was intended to be # internal but actually used in the field. eg. LINC l2_switch_v1_3.py old2 = ofpp.OFPMatch() old2.append_field(ofp.OXM_OF_IN_PORT, old_in_port) old2.append_field(ofp.OXM_OF_ETH_SRC, old_eth_src) old2.append_field(ofp.OXM_OF_IPV4_SRC, old_ipv4_src) old2.append_field(ofp.OXM_OF_IPV6_SRC, old_ipv6_src) check_old(old2) old2_buf = bytearray() old2.serialize(old2_buf, 0) # new api new = ofpp.OFPMatch(in_port=in_port, eth_src=eth_src, ipv4_src=ipv4_src, ipv6_src=ipv6_src) check_new(new) new_buf = bytearray() new.serialize(new_buf, 0) self.assertEqual(new_buf, old_buf) self.assertEqual(new_buf, old2_buf) old_jsondict = old.to_jsondict() old2_jsondict = old2.to_jsondict() new_jsondict = new.to_jsondict() self.assertEqual(new_jsondict, old_jsondict) self.assertEqual(new_jsondict, old2_jsondict) self.assertEqual(str(new), str(old)) self.assertEqual(str(new), str(old2)) # a parsed object can be inspected by old and new api check(ofpp.OFPMatch.parser(bytes(new_buf), 0)) check(ofpp.OFPMatch.from_jsondict(list(new_jsondict.values())[0])) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/test_parser_ofpmatch.py0000664000175000017500000002050100000000000024664 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013 YAMAMOTO Takashi # # 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. import functools import itertools import unittest import testscenarios from os_ken.ofproto import ofproto_v1_2 from os_ken.ofproto import ofproto_v1_3 from os_ken.ofproto import ofproto_v1_4 from os_ken.ofproto import ofproto_v1_5 from os_ken.ofproto import ofproto_v1_2_parser from os_ken.ofproto import ofproto_v1_3_parser from os_ken.ofproto import ofproto_v1_4_parser from os_ken.ofproto import ofproto_v1_5_parser def _list_test_cases(): class Field(object): @classmethod def generate_mask(cls): return list(cls.generate())[1] class Int1(Field): @staticmethod def generate(): yield 0 yield 0xff class Int2(Field): @staticmethod def generate(): yield 0 yield 0x1234 yield 0xffff class Int3(Field): @staticmethod def generate(): yield 0 yield 0x123456 yield 0xffffff class Int4(Field): @staticmethod def generate(): yield 0 yield 0x12345678 yield 0xffffffff class Int8(Field): @staticmethod def generate(): yield 0 yield 0x123456789abcdef0 yield 0xffffffffffffffff class Mac(Field): @staticmethod def generate(): yield '00:00:00:00:00:00' yield 'f2:0b:a4:7d:f8:ea' yield 'ff:ff:ff:ff:ff:ff' class IPv4(Field): @staticmethod def generate(): yield '0.0.0.0' yield '192.0.2.1' yield '255.255.255.255' class IPv6(Field): @staticmethod def generate(): yield '::' yield 'fe80::f00b:a4ff:fed0:3f70' yield 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff' class B64(Field): @staticmethod def generate(): yield 'aG9nZWhvZ2U=' yield 'ZnVnYWZ1Z2E=' ofpps = [ofproto_v1_2_parser, ofproto_v1_3_parser, ofproto_v1_4_parser, ofproto_v1_5_parser] common = [ # OpenFlow Basic ('in_port', Int4), ('in_phy_port', Int4), ('metadata', Int8), ('eth_dst', Mac), ('eth_src', Mac), ('eth_type', Int2), ('vlan_vid', Int2), ('vlan_pcp', Int1), ('ip_dscp', Int1), ('ip_ecn', Int1), ('ip_proto', Int1), ('ipv4_src', IPv4), ('ipv4_dst', IPv4), ('tcp_src', Int2), ('tcp_dst', Int2), ('udp_src', Int2), ('udp_dst', Int2), ('sctp_src', Int2), ('sctp_dst', Int2), ('icmpv4_type', Int1), ('icmpv4_code', Int1), ('arp_op', Int2), ('arp_spa', IPv4), ('arp_tpa', IPv4), ('arp_sha', Mac), ('arp_tha', Mac), ('ipv6_src', IPv6), ('ipv6_dst', IPv6), ('ipv6_flabel', Int4), ('icmpv6_type', Int1), ('icmpv6_code', Int1), ('ipv6_nd_target', IPv6), ('ipv6_nd_sll', Mac), ('ipv6_nd_tll', Mac), ('mpls_label', Int4), ('mpls_tc', Int1), # Old ONF Experimenter --> OpenFlow Basic (OF1.4+) ('pbb_uca', Int1), # ONF Experimenter --> OpenFlow Basic (OF1.5+) ('tcp_flags', Int2), ('actset_output', Int4), # Nicira Experimenter ('eth_dst_nxm', Mac), ('eth_src_nxm', Mac), ('tunnel_id_nxm', Int8), ('tun_ipv4_src', IPv4), ('tun_ipv4_dst', IPv4), ('pkt_mark', Int4), ('conj_id', Int4), ('tun_ipv6_src', IPv6), ('tun_ipv6_dst', IPv6), ('_dp_hash', Int4), ('reg0', Int4), ('reg1', Int4), ('reg2', Int4), ('reg3', Int4), ('reg4', Int4), ('reg5', Int4), ('reg6', Int4), ('reg7', Int4), # Common Experimenter ('field_100', B64), ] L = {} L[ofproto_v1_2_parser] = common + [ # OF1.2 doesn't have OXM_OF_PBB_ISID. # OFPXMC_OPENFLOW_BASIC = 0x8000 # OXM_OF_PBB_ISID = 37 # (OFPXMC_OPENFLOW_BASIC << 7) + OXM_OF_PBB_ISID == 4194341 ('field_4194341', B64), ] L[ofproto_v1_3_parser] = common + [ # OpenFlow Basic (OF1.3+) ('mpls_bos', Int1), ('pbb_isid', Int3), ('tunnel_id', Int8), ('ipv6_exthdr', Int2), ] L[ofproto_v1_4_parser] = L[ofproto_v1_3_parser] L[ofproto_v1_5_parser] = L[ofproto_v1_4_parser] + [ # OpenFlow Basic (OF1.5+) ('packet_type', Int4), ] def flatten_one(l, i): if isinstance(i, tuple): return l + flatten(i) else: return l + [i] flatten = lambda l: functools.reduce(flatten_one, l, []) cases = [] for ofpp in ofpps: for n in range(1, 3): for C in itertools.combinations(L[ofpp], n): l = [1] keys = [] clss = [] for (k, cls) in C: l = itertools.product(l, cls.generate()) keys.append(k) clss.append(cls) l = [flatten(x)[1:] for x in l] for domask in [True, False]: for values in l: if domask: values = [(value, cls.generate_mask()) for (cls, value) in zip(clss, values)] d = dict(zip(keys, values)) mod = ofpp.__name__.split('.')[-1] method_name = 'test_' + mod if domask: method_name += '_mask' for k in sorted(dict(d).keys()): method_name += '_' + str(k) method_name += '_' + str(d[k]) method_name = method_name.replace(':', '_') method_name = method_name.replace('.', '_') method_name = method_name.replace('(', '_') method_name = method_name.replace(')', '_') method_name = method_name.replace(',', '_') method_name = method_name.replace("'", '_') method_name = method_name.replace(' ', '_') cases.append({'name': method_name, 'ofpp': ofpp, 'd': d, 'domask': domask}) return cases class Test_Parser_OFPMatch(testscenarios.WithScenarios, unittest.TestCase): scenarios = [(case['name'], case) for case in _list_test_cases()] _ofp = {ofproto_v1_2_parser: ofproto_v1_2, ofproto_v1_3_parser: ofproto_v1_3, ofproto_v1_4_parser: ofproto_v1_4, ofproto_v1_5_parser: ofproto_v1_5} def setUp(self): pass def tearDown(self): pass def test_parser(self): self._test(name=self.name, ofpp=self.ofpp, d=self.d, domask=self.domask) def _test(self, name, ofpp, d, domask): if domask: d = dict(self._ofp[ofpp].oxm_normalize_user(k, uv) for (k, uv) in d.items()) match = ofpp.OFPMatch(**d) b = bytearray() match.serialize(b, 0) match2 = match.parser(bytes(b), 0) for k, v in d.items(): self.assertTrue(k in match) self.assertTrue(k in match2) self.assertEqual(match[k], v) self.assertEqual(match2[k], v) for k, v in match.iteritems(): self.assertTrue(k in d) self.assertEqual(d[k], v) for k, v in match2.iteritems(): self.assertTrue(k in d) self.assertEqual(d[k], v) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/test_parser_ofpstats.py0000664000175000017500000001316400000000000024735 0ustar00zuulzuul00000000000000# Copyright (C) 2015 Nippon Telegraph and Telephone 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. from functools import reduce import unittest import testscenarios from os_ken.ofproto import ofproto_v1_5 from os_ken.ofproto import ofproto_v1_5_parser def _list_test_cases(): import functools import itertools class Field(object): pass class Int1(Field): @staticmethod def generate(): yield 0 yield 0xff class Int2(Field): @staticmethod def generate(): yield 0 yield 0x1234 yield 0xffff class Int3(Field): @staticmethod def generate(): yield 0 yield 0x123456 yield 0xffffff class Int4(Field): @staticmethod def generate(): yield 0 yield 0x12345678 yield 0xffffffff class Int4double(Field): @staticmethod def generate(): # Note: If yield value as a tuple, flatten_one() will reduce it # into a single value. So the followings avoid this problem by # using a list value. yield [0, 1] yield [0x12345678, 0x23456789] yield [0xffffffff, 0xfffffffe] class Int8(Field): @staticmethod def generate(): yield 0 yield 0x123456789abcdef0 yield 0xffffffffffffffff class Mac(Field): @staticmethod def generate(): yield '00:00:00:00:00:00' yield 'f2:0b:a4:7d:f8:ea' yield 'ff:ff:ff:ff:ff:ff' class IPv4(Field): @staticmethod def generate(): yield '0.0.0.0' yield '192.0.2.1' yield '255.255.255.255' class IPv6(Field): @staticmethod def generate(): yield '::' yield 'fe80::f00b:a4ff:fed0:3f70' yield 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff' class B64(Field): @staticmethod def generate(): yield 'aG9nZWhvZ2U=' yield 'ZnVnYWZ1Z2E=' ofpps = [ofproto_v1_5_parser] common = [ ('duration', Int4double), ('idle_time', Int4double), ('flow_count', Int4), ('packet_count', Int8), ('byte_count', Int8), ('field_100', B64), ] L = {} L[ofproto_v1_5_parser] = common def flatten_one(l, i): if isinstance(i, tuple): return l + flatten(i) else: return l + [i] flatten = lambda l: reduce(flatten_one, l, []) cases = [] for ofpp in ofpps: for n in range(1, 3): for C in itertools.combinations(L[ofpp], n): l = [1] keys = [] clss = [] for (k, cls) in C: l = itertools.product(l, cls.generate()) keys.append(k) clss.append(cls) l = [flatten(x)[1:] for x in l] for values in l: d = dict(zip(keys, values)) for n, uv in d.items(): if isinstance(uv, list): # XXX # OFPStats returns value as tuple when field is # 'duration' or 'idle_time'. Then convert list # value into tuple here. d[n] = tuple(uv) mod = ofpp.__name__.split('.')[-1] method_name = 'test_' + mod for k in sorted(dict(d).keys()): method_name += '_' + str(k) method_name += '_' + str(d[k]) method_name = method_name.replace(':', '_') method_name = method_name.replace('.', '_') method_name = method_name.replace('(', '_') method_name = method_name.replace(')', '_') method_name = method_name.replace(',', '_') method_name = method_name.replace("'", '_') method_name = method_name.replace(' ', '_') cases.append({'name': method_name, 'ofpp': ofpp, 'd': d}) return cases class Test_Parser_OFPStats(testscenarios.WithScenarios, unittest.TestCase): scenarios = [(case['name'], case) for case in _list_test_cases()] _ofp = {ofproto_v1_5_parser: ofproto_v1_5} def setUp(self): pass def tearDown(self): pass def test_parser(self): self._test(name=self.name, ofpp=self.ofpp, d=self.d) def _test(self, name, ofpp, d): stats = ofpp.OFPStats(**d) b = bytearray() stats.serialize(b, 0) stats2 = stats.parser(bytes(b), 0) for k, v in d.items(): self.assertTrue(k in stats) self.assertTrue(k in stats2) self.assertEqual(stats[k], v) self.assertEqual(stats2[k], v) for k, v in stats.iteritems(): self.assertTrue(k in d) self.assertEqual(d[k], v) for k, v in stats2.iteritems(): self.assertTrue(k in d) self.assertEqual(d[k], v) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/test_parser_v10.py0000664000175000017500000054536000000000000023510 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone 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. import unittest import logging from os_ken.ofproto.ofproto_v1_0_parser import * from os_ken.ofproto.nx_actions import * from os_ken.ofproto import ofproto_v1_0_parser from os_ken.lib import addrconv LOG = logging.getLogger('test_ofproto_v10') class TestOFPPhyPort(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPPhyPort """ # OFP_PHY_PORT_PACK_STR # '!H6s16sIIIIII'... port_no, hw_addr, name, config, state # curr, advertised, supported, peer port_no = {'buf': b'\xe7\x6b', 'val': 59243} hw_addr = '52:54:54:10:20:99' name = b'name'.ljust(16) config = {'buf': b'\x84\xb6\x8c\x53', 'val': 2226555987} state = {'buf': b'\x64\x07\xfb\xc9', 'val': 1678244809} curr = {'buf': b'\xa9\xe8\x0a\x2b', 'val': 2850556459} advertised = {'buf': b'\x78\xb9\x7b\x72', 'val': 2025421682} supported = {'buf': b'\x7e\x65\x68\xad', 'val': 2120575149} peer = {'buf': b'\xa4\x5b\x8b\xed', 'val': 2757463021} buf = port_no['buf'] \ + addrconv.mac.text_to_bin(hw_addr) \ + name \ + config['buf'] \ + state['buf'] \ + curr['buf'] \ + advertised['buf'] \ + supported['buf'] \ + peer['buf'] c = OFPPhyPort(port_no['val'], hw_addr, name, config['val'], state['val'], curr['val'], advertised['val'], supported['val'], peer['val']) def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(self.port_no['val'], self.c.port_no) self.assertEqual(self.hw_addr, self.c.hw_addr) self.assertEqual(self.name, self.c.name) self.assertEqual(self.config['val'], self.c.config) self.assertEqual(self.state['val'], self.c.state) self.assertEqual(self.curr['val'], self.c.curr) self.assertEqual(self.advertised['val'], self.c.advertised) self.assertEqual(self.supported['val'], self.c.supported) self.assertEqual(self.peer['val'], self.c.peer) def test_parser(self): res = self.c.parser(self.buf, 0) self.assertEqual(self.port_no['val'], res.port_no) self.assertEqual(self.hw_addr, res.hw_addr) self.assertEqual(self.name, res.name) self.assertEqual(self.config['val'], res.config) self.assertEqual(self.state['val'], res.state) self.assertEqual(self.curr['val'], res.curr) self.assertEqual(self.advertised['val'], res.advertised) self.assertEqual(self.supported['val'], res.supported) self.assertEqual(self.peer['val'], res.peer) class TestOFPMatch(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPMatch """ # OFP_MATCH_PACK_STR # '!IH6s6sHBxHBB2xIIHH'...wildcards, in_port, dl_src, dl_dst, dl_vlan, # dl_vlan_pcp, dl_type, nw_tos, nw_proto, # nw_src, nw_dst, tp_src, tp_dst wildcards = {'buf': b'\x00\x02\x10\x00', 'val': 135168} in_port = {'buf': b'\x37\x8b', 'val': 14219} dl_src = {'buf': b'\x52\x54\x54\x10\x20\x99', 'human': '52:54:54:10:20:99'} dl_dst = {'buf': b'\x61\x31\x50\x6d\xc9\xe5', 'human': '61:31:50:6d:c9:e5'} dl_vlan = {'buf': b'\xc1\xf9', 'val': 49657} dl_vlan_pcp = {'buf': b'\x79', 'val': 121} zfill0 = b'\x00' dl_type = {'buf': b'\xa6\x9e', 'val': 42654} nw_tos = {'buf': b'\xde', 'val': 222} nw_proto = {'buf': b'\xe5', 'val': 229} zfil11 = b'\x00' * 2 nw_src = {'buf': b'\x1b\x6d\x8d\x4b', 'val': 460164427, 'human': '27.109.141.75'} nw_dst = {'buf': b'\xab\x25\xe1\x20', 'val': 2871386400, 'human': '171.37.225.32'} tp_src = {'buf': b'\xd5\xc3', 'val': 54723} tp_dst = {'buf': b'\x78\xb9', 'val': 30905} buf = wildcards['buf'] \ + in_port['buf'] \ + dl_src['buf'] \ + dl_dst['buf'] \ + dl_vlan['buf'] \ + dl_vlan_pcp['buf'] \ + zfill0 \ + dl_type['buf'] \ + nw_tos['buf'] \ + nw_proto['buf'] \ + zfil11 \ + nw_src['buf'] \ + nw_dst['buf'] \ + tp_src['buf'] \ + tp_dst['buf'] def _get_obj(self, dl_src, dl_dst): c = OFPMatch(self.wildcards['val'], self.in_port['val'], dl_src, dl_dst, self.dl_vlan['val'], self.dl_vlan_pcp['val'], self.dl_type['val'], self.nw_tos['val'], self.nw_proto['val'], self.nw_src['val'], self.nw_dst['val'], self.tp_src['val'], self.tp_dst['val']) return c def setUp(self): pass def tearDown(self): pass def test_init(self): c = self._get_obj(self.dl_src['buf'], self.dl_dst['buf']) self.assertEqual(self.wildcards['val'], c.wildcards) self.assertEqual(self.in_port['val'], c.in_port) self.assertEqual(self.dl_src['buf'], c.dl_src) self.assertEqual(self.dl_dst['buf'], c.dl_dst) self.assertEqual(self.dl_vlan['val'], c.dl_vlan) self.assertEqual(self.dl_vlan_pcp['val'], c.dl_vlan_pcp) self.assertEqual(self.dl_type['val'], c.dl_type) self.assertEqual(self.nw_tos['val'], c.nw_tos) self.assertEqual(self.nw_proto['val'], c.nw_proto) self.assertEqual(self.nw_src['val'], c.nw_src) self.assertEqual(self.nw_dst['val'], c.nw_dst) self.assertEqual(self.tp_src['val'], c.tp_src) self.assertEqual(self.tp_dst['val'], c.tp_dst) def test_init_zero(self): c = self._get_obj(0, 0) self.assertEqual(mac.DONTCARE, c.dl_src) self.assertEqual(mac.DONTCARE, c.dl_dst) def test_parse(self): c = self._get_obj(self.dl_src['buf'], self.dl_dst['buf']) res = c.parse(self.buf, 0) self.assertEqual(self.wildcards['val'], res.wildcards) self.assertEqual(self.in_port['val'], res.in_port) self.assertEqual(self.dl_src['buf'], res.dl_src) self.assertEqual(self.dl_dst['buf'], res.dl_dst) self.assertEqual(self.dl_vlan['val'], res.dl_vlan) self.assertEqual(self.dl_vlan_pcp['val'], res.dl_vlan_pcp) self.assertEqual(self.dl_type['val'], res.dl_type) self.assertEqual(self.nw_tos['val'], res.nw_tos) self.assertEqual(self.nw_proto['val'], res.nw_proto) self.assertEqual(self.nw_src['val'], res.nw_src) self.assertEqual(self.nw_dst['val'], res.nw_dst) self.assertEqual(self.tp_src['val'], res.tp_src) self.assertEqual(self.tp_dst['val'], res.tp_dst) def test_serialize(self): buf = bytearray() c = self._get_obj(self.dl_src['buf'], self.dl_dst['buf']) c.serialize(buf, 0) fmt = ofproto.OFP_MATCH_PACK_STR res = struct.unpack_from(fmt, bytes(buf)) self.assertEqual(self.wildcards['val'], res[0]) self.assertEqual(self.in_port['val'], res[1]) self.assertEqual(self.dl_src['buf'], res[2]) self.assertEqual(self.dl_dst['buf'], res[3]) self.assertEqual(self.dl_vlan['val'], res[4]) self.assertEqual(self.dl_vlan_pcp['val'], res[5]) self.assertEqual(self.dl_type['val'], res[6]) self.assertEqual(self.nw_tos['val'], res[7]) self.assertEqual(self.nw_proto['val'], res[8]) self.assertEqual(self.nw_src['val'], res[9]) self.assertEqual(self.nw_dst['val'], res[10]) self.assertEqual(self.tp_src['val'], res[11]) self.assertEqual(self.tp_dst['val'], res[12]) def test_getitem(self): c = self._get_obj(self.dl_src['buf'], self.dl_dst['buf']) self.assertEqual(self.wildcards['val'], c["wildcards"]) self.assertEqual(self.in_port['val'], c["in_port"]) self.assertEqual(self.dl_src['human'], c["dl_src"]) self.assertEqual(self.dl_dst['human'], c["dl_dst"]) self.assertEqual(self.dl_vlan['val'], c["dl_vlan"]) self.assertEqual(self.dl_vlan_pcp['val'], c["dl_vlan_pcp"]) self.assertEqual(self.dl_type['val'], c["dl_type"]) self.assertEqual(self.nw_tos['val'], c["nw_tos"]) self.assertEqual(self.nw_proto['val'], c["nw_proto"]) self.assertEqual(self.nw_src['human'], c["nw_src"]) self.assertEqual(self.nw_dst['human'], c["nw_dst"]) self.assertEqual(self.tp_src['val'], c["tp_src"]) self.assertEqual(self.tp_dst['val'], c["tp_dst"]) class TestOFPActionHeader(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPActionHeader """ # OFP_ACTION_HEADER_PACK_STR # '!HH4x'...type, len, zfill type = {'buf': b'\x00\x02', 'val': ofproto.OFPAT_SET_VLAN_PCP} len = {'buf': b'\x00\x08', 'val': ofproto.OFP_ACTION_HEADER_SIZE} zfill = b'\x00' * 4 buf = type['buf'] \ + len['buf'] \ + zfill c = OFPActionHeader(type['val'], len['val']) def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(self.type['val'], self.c.type) self.assertEqual(self.len['val'], self.c.len) def test_serialize(self): buf = bytearray() self.c.serialize(buf, 0) fmt = ofproto.OFP_ACTION_HEADER_PACK_STR res = struct.unpack(fmt, bytes(buf)) self.assertEqual(self.type['val'], res[0]) self.assertEqual(self.len['val'], res[1]) class TestOFPActionOutput(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPActionOutput """ # OFP_ACTION_OUTPUT_PACK_STR # '!HHHH'...type, len, port, max_len type_ = {'buf': b'\x00\x00', 'val': ofproto.OFPAT_OUTPUT} len_ = {'buf': b'\x00\x08', 'val': ofproto.OFP_ACTION_OUTPUT_SIZE} port = {'buf': b'\x19\xce', 'val': 6606} max_len = {'buf': b'\x00\x08', 'val': ofproto.OFP_ACTION_OUTPUT_SIZE} buf = type_['buf'] \ + len_['buf'] \ + port['buf'] \ + max_len['buf'] c = OFPActionOutput(port['val'], max_len['val']) def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(self.port['val'], self.c.port) self.assertEqual(self.max_len['val'], self.c.max_len) def test_parser(self): res = self.c.parser(self.buf, 0) self.assertEqual(self.port['val'], res.port) self.assertEqual(self.max_len['val'], res.max_len) def test_parser_check_type(self): type_ = {'buf': b'\x00\x01', 'val': 1} buf = type_['buf'] \ + self.len_['buf'] \ + self.port['buf'] \ + self.max_len['buf'] self.assertRaises(AssertionError, self.c.parser, buf, 0) def test_parser_check_len(self): len_ = {'buf': b'\x00\x07', 'val': 7} buf = self.type_['buf'] \ + len_['buf'] \ + self.port['buf'] \ + self.max_len['buf'] self.assertRaises(AssertionError, self.c.parser, buf, 0) def test_serialize(self): buf = bytearray() self.c.serialize(buf, 0) fmt = ofproto.OFP_ACTION_OUTPUT_PACK_STR res = struct.unpack(fmt, bytes(buf)) self.assertEqual(self.type_['val'], res[0]) self.assertEqual(self.len_['val'], res[1]) self.assertEqual(self.port['val'], res[2]) self.assertEqual(self.max_len['val'], res[3]) class TestOFPActionVlanVid(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPActionVlanVid """ # OFP_ACTION_VLAN_VID_PACK_STR # '!HHH2x'...type, len, vlan_vid, zfill type_ = {'buf': b'\x00\x01', 'val': ofproto.OFPAT_SET_VLAN_VID} len_ = {'buf': b'\x00\x08', 'val': ofproto.OFP_ACTION_VLAN_VID_SIZE} vlan_vid = {'buf': b'\x3c\x0e', 'val': 15374} zfill = b'\x00' * 2 buf = type_['buf'] \ + len_['buf'] \ + vlan_vid['buf'] \ + zfill c = OFPActionVlanVid(vlan_vid['val']) def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(self.vlan_vid['val'], self.c.vlan_vid) def test_parser(self): res = self.c.parser(self.buf, 0) self.assertEqual(self.vlan_vid['val'], res.vlan_vid) def test_parser_check_type(self): type_ = {'buf': b'\x00\x02', 'val': 2} buf = type_['buf'] \ + self.len_['buf'] \ + self.vlan_vid['buf'] \ + self.zfill self.assertRaises(AssertionError, self.c.parser, buf, 0) def test_parser_check_len(self): len_ = {'buf': b'\x00\x07', 'val': 7} buf = self.type_['buf'] \ + len_['buf'] \ + self.vlan_vid['buf'] \ + self.zfill self.assertRaises(AssertionError, self.c.parser, buf, 0) def test_serialize(self): buf = bytearray() self.c.serialize(buf, 0) fmt = ofproto.OFP_ACTION_VLAN_VID_PACK_STR res = struct.unpack(fmt, bytes(buf)) self.assertEqual(self.type_['val'], res[0]) self.assertEqual(self.len_['val'], res[1]) self.assertEqual(self.vlan_vid['val'], res[2]) class TestOFPActionVlanPcp(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPActionVlanPcp """ # OFP_ACTION_VLAN_PCP_PACK_STR # '!HHB3x'...type, len, vlan_pcp, zfill type_ = {'buf': b'\x00\x02', 'val': ofproto.OFPAT_SET_VLAN_PCP} len_ = {'buf': b'\x00\x08', 'val': ofproto.OFP_ACTION_VLAN_PCP_SIZE} vlan_pcp = {'buf': b'\x1c', 'val': 28} zfill = b'\x00' * 3 buf = type_['buf'] \ + len_['buf'] \ + vlan_pcp['buf'] \ + zfill c = OFPActionVlanPcp(vlan_pcp['val']) def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(self.vlan_pcp['val'], self.c.vlan_pcp) def test_parser(self): res = self.c.parser(self.buf, 0) self.assertEqual(self.vlan_pcp['val'], res.vlan_pcp) def test_parser_check_type(self): type_ = {'buf': b'\x00\x01', 'val': 1} buf = type_['buf'] \ + self.len_['buf'] \ + self.vlan_pcp['buf'] \ + self.zfill self.assertRaises(AssertionError, self.c.parser, buf, 0) def test_parser_check_len(self): len_ = {'buf': b'\x00\x07', 'val': 7} buf = self.type_['buf'] \ + len_['buf'] \ + self.vlan_pcp['buf'] \ + self.zfill self.assertRaises(AssertionError, self.c.parser, buf, 0) def test_serialize(self): buf = bytearray() self.c.serialize(buf, 0) fmt = ofproto.OFP_ACTION_VLAN_PCP_PACK_STR res = struct.unpack(fmt, bytes(buf)) self.assertEqual(self.type_['val'], res[0]) self.assertEqual(self.len_['val'], res[1]) self.assertEqual(self.vlan_pcp['val'], res[2]) class TestOFPActionStripVlan(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPActionStripVlan """ # OFP_ACTION_HEADER_PACK_STR # '!HH4x'...type, len, zfill type_ = {'buf': b'\x00\x03', 'val': ofproto.OFPAT_STRIP_VLAN} len_ = {'buf': b'\x00\x08', 'val': ofproto.OFP_ACTION_HEADER_SIZE} zfill = b'\x00' * 4 buf = type_['buf'] \ + len_['buf'] \ + zfill c = OFPActionStripVlan() def setUp(self): pass def tearDown(self): pass def test_init(self): pass def test_parser(self): self.assertTrue(self.c.parser(self.buf, 0)) def test_parser_check_type(self): type_ = {'buf': b'\x00\x01', 'val': 1} buf = type_['buf'] \ + self.len_['buf'] \ + self.zfill self.assertRaises(AssertionError, self.c.parser, buf, 0) def test_parser_check_len(self): len_ = {'buf': b'\x00\x07', 'val': 7} buf = self.type_['buf'] \ + len_['buf'] \ + self.zfill self.assertRaises(AssertionError, self.c.parser, buf, 0) class TestOFPActionSetDlSrc(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPActionSetDlSrc """ # OFP_ACTION_DL_ADDR_PACK_STR # '!HH6s6x'...type, len, dl_addr, zfill type_ = {'buf': b'\x00\x04', 'val': ofproto.OFPAT_SET_DL_SRC} len_ = {'buf': b'\x00\x10', 'val': ofproto.OFP_ACTION_DL_ADDR_SIZE} dl_addr = b'\x0e\xde\x27\xce\xc6\xcf' zfill = b'\x00' * 6 buf = type_['buf'] \ + len_['buf'] \ + dl_addr \ + zfill c = OFPActionSetDlSrc(dl_addr) def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(self.dl_addr, self.c.dl_addr) def test_parser_type_src(self): res = self.c.parser(self.buf, 0) self.assertEqual(self.dl_addr, res.dl_addr) def test_parser_type_dst(self): type_ = {'buf': b'\x00\x05', 'val': ofproto.OFPAT_SET_DL_DST} buf = type_['buf'] \ + self.len_['buf'] \ + self.dl_addr \ + self.zfill res = self.c.parser(buf, 0) self.assertEqual(self.dl_addr, res.dl_addr) def test_parser_check_type(self): type_ = {'buf': b'\x00\x06', 'val': 6} buf = type_['buf'] \ + self.len_['buf'] \ + self.dl_addr \ + self.zfill self.assertRaises(AssertionError, self.c.parser, buf, 0) def test_parser_check_len(self): len_ = {'buf': b'\x00\x07', 'val': 7} buf = self.type_['buf'] \ + len_['buf'] \ + self.dl_addr \ + self.zfill self.assertRaises(AssertionError, self.c.parser, buf, 0) def test_serialize(self): buf = bytearray() self.c.serialize(buf, 0) fmt = ofproto.OFP_ACTION_DL_ADDR_PACK_STR res = struct.unpack(fmt, bytes(buf)) self.assertEqual(self.type_['val'], res[0]) self.assertEqual(self.len_['val'], res[1]) self.assertEqual(self.dl_addr, res[2]) class TestOFPActionSetDlDst(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPActionSetDlDst """ # OFP_ACTION_DL_ADDR_PACK_STR # '!HH6s6x'...type, len, dl_addr, zfill type_ = {'buf': b'\x00\x05', 'val': ofproto.OFPAT_SET_DL_DST} len_ = {'buf': b'\x00\x10', 'val': ofproto.OFP_ACTION_DL_ADDR_SIZE} dl_addr = b'\x37\x48\x38\x9a\xf4\x28' zfill = b'\x00' * 6 buf = type_['buf'] \ + len_['buf'] \ + dl_addr \ + zfill c = OFPActionSetDlDst(dl_addr) def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(self.dl_addr, self.c.dl_addr) def test_parser_type_dst(self): res = self.c.parser(self.buf, 0) self.assertEqual(self.dl_addr, res.dl_addr) def test_parser_type_src(self): type_ = {'buf': b'\x00\x04', 'val': ofproto.OFPAT_SET_DL_SRC} buf = type_['buf'] \ + self.len_['buf'] \ + self.dl_addr \ + self.zfill res = self.c.parser(buf, 0) self.assertEqual(self.dl_addr, res.dl_addr) def test_parser_check_type(self): type_ = {'buf': b'\x00\x06', 'val': 6} buf = type_['buf'] \ + self.len_['buf'] \ + self.dl_addr \ + self.zfill self.assertRaises(AssertionError, self.c.parser, buf, 0) def test_parser_check_len(self): len_ = {'buf': b'\x00\x07', 'val': 7} buf = self.type_['buf'] \ + len_['buf'] \ + self.dl_addr \ + self.zfill self.assertRaises(AssertionError, self.c.parser, buf, 0) def test_serialize(self): buf = bytearray() self.c.serialize(buf, 0) fmt = ofproto.OFP_ACTION_DL_ADDR_PACK_STR res = struct.unpack(fmt, bytes(buf)) self.assertEqual(self.type_['val'], res[0]) self.assertEqual(self.len_['val'], res[1]) self.assertEqual(self.dl_addr, res[2]) class TestOFPActionSetNwSrc(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPActionSetNwSrc """ # OFP_ACTION_NW_ADDR_PACK_STR # '!HHI'...type, len, nw_addr type_ = {'buf': b'\x00\x06', 'val': ofproto.OFPAT_SET_NW_SRC} len_ = {'buf': b'\x00\x08', 'val': ofproto.OFP_ACTION_NW_ADDR_SIZE} nw_addr = {'buf': b'\xc0\xa8\x7a\x0a', 'val': 3232266762} buf = type_['buf'] \ + len_['buf'] \ + nw_addr['buf'] c = OFPActionSetNwSrc(nw_addr['val']) def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(self.nw_addr['val'], self.c.nw_addr) def test_parser_src(self): res = self.c.parser(self.buf, 0) self.assertEqual(self.nw_addr['val'], res.nw_addr) def test_parser_dst(self): type_ = {'buf': b'\x00\x07', 'val': ofproto.OFPAT_SET_NW_DST} buf = type_['buf'] \ + self.len_['buf'] \ + self.nw_addr['buf'] res = self.c.parser(buf, 0) self.assertEqual(self.nw_addr['val'], res.nw_addr) def test_parser_check_type(self): type_ = {'buf': b'\x00\x05', 'val': 5} buf = type_['buf'] \ + self.len_['buf'] \ + self.nw_addr['buf'] self.assertRaises(AssertionError, self.c.parser, buf, 0) def test_parser_check_len(self): len_ = {'buf': b'\x00\x10', 'val': 16} buf = self.type_['buf'] \ + len_['buf'] \ + self.nw_addr['buf'] self.assertRaises(AssertionError, self.c.parser, buf, 0) def test_serialize(self): buf = bytearray() self.c.serialize(buf, 0) fmt = ofproto.OFP_ACTION_NW_ADDR_PACK_STR res = struct.unpack(fmt, bytes(buf)) self.assertEqual(self.type_['val'], res[0]) self.assertEqual(self.len_['val'], res[1]) self.assertEqual(self.nw_addr['val'], res[2]) class TestOFPActionSetNwDst(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPActionSetNwDst """ # OFP_ACTION_NW_ADDR_PACK_STR # '!HHI'...type, len, nw_addr type_ = {'buf': b'\x00\x07', 'val': ofproto.OFPAT_SET_NW_DST} len_ = {'buf': b'\x00\x08', 'val': ofproto.OFP_ACTION_NW_ADDR_SIZE} nw_addr = {'buf': b'\xc0\xa8\x7a\x0a', 'val': 3232266762} buf = type_['buf'] \ + len_['buf'] \ + nw_addr['buf'] c = OFPActionSetNwDst(nw_addr['val']) def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(self.nw_addr['val'], self.c.nw_addr) def test_parser_dst(self): res = self.c.parser(self.buf, 0) self.assertEqual(self.nw_addr['val'], res.nw_addr) def test_parser_src(self): type_ = {'buf': b'\x00\x06', 'val': ofproto.OFPAT_SET_NW_SRC} buf = type_['buf'] \ + self.len_['buf'] \ + self.nw_addr['buf'] res = self.c.parser(buf, 0) self.assertEqual(self.nw_addr['val'], res.nw_addr) def test_parser_check_type(self): type_ = {'buf': b'\x00\x05', 'val': 5} buf = type_['buf'] \ + self.len_['buf'] \ + self.nw_addr['buf'] self.assertRaises(AssertionError, self.c.parser, buf, 0) def test_parser_check_len(self): len_ = {'buf': b'\x00\x10', 'val': 16} buf = self.type_['buf'] \ + len_['buf'] \ + self.nw_addr['buf'] self.assertRaises(AssertionError, self.c.parser, buf, 0) def test_serialize(self): buf = bytearray() self.c.serialize(buf, 0) fmt = ofproto.OFP_ACTION_NW_ADDR_PACK_STR res = struct.unpack(fmt, bytes(buf)) self.assertEqual(self.type_['val'], res[0]) self.assertEqual(self.len_['val'], res[1]) self.assertEqual(self.nw_addr['val'], res[2]) class TestOFPActionSetNwTos(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPActionSetNwTos """ # OFP_ACTION_NW_TOS_PACK_STR # '!HHB3x'...type, len, tos, zfill type_ = {'buf': b'\x00\x08', 'val': ofproto.OFPAT_SET_NW_TOS} len_ = {'buf': b'\x00\x08', 'val': ofproto.OFP_ACTION_NW_TOS_SIZE} tos = {'buf': b'\xb6', 'val': 182} zfill = b'\x00' * 3 buf = type_['buf'] \ + len_['buf'] \ + tos['buf'] \ + zfill c = OFPActionSetNwTos(tos['val']) def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(self.tos['val'], self.c.tos) def test_parser(self): res = self.c.parser(self.buf, 0) self.assertEqual(self.tos['val'], res.tos) def test_parser_check_type(self): type_ = {'buf': b'\x00\x05', 'val': 5} buf = type_['buf'] \ + self.len_['buf'] \ + self.tos['buf'] \ + self.zfill self.assertRaises(AssertionError, self.c.parser, buf, 0) def test_parser_check_len(self): len_ = {'buf': b'\x00\x07', 'val': 7} buf = self.type_['buf'] \ + len_['buf'] \ + self.tos['buf'] \ + self.zfill self.assertRaises(AssertionError, self.c.parser, buf, 0) def test_serialize(self): buf = bytearray() self.c.serialize(buf, 0) fmt = ofproto.OFP_ACTION_NW_TOS_PACK_STR res = struct.unpack(fmt, bytes(buf)) self.assertEqual(self.type_['val'], res[0]) self.assertEqual(self.len_['val'], res[1]) self.assertEqual(self.tos['val'], res[2]) class TestOFPActionSetTpSrc(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPActionSetTpSrc """ # OFP_ACTION_TP_PORT_PACK_STR # '!HHH2x'...type, len, tp, zfill type_ = {'buf': b'\x00\x09', 'val': ofproto.OFPAT_SET_TP_SRC} len_ = {'buf': b'\x00\x08', 'val': ofproto.OFP_ACTION_TP_PORT_SIZE} tp = {'buf': b'\x07\xf1', 'val': 2033} zfill = b'\x00' * 2 buf = type_['buf'] \ + len_['buf'] \ + tp['buf'] \ + zfill c = OFPActionSetTpSrc(tp['val']) def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(self.tp['val'], self.c.tp) def test_parser_src(self): res = self.c.parser(self.buf, 0) self.assertEqual(self.tp['val'], res.tp) def test_parser_dst(self): type_ = {'buf': b'\x00\x0a', 'val': ofproto.OFPAT_SET_TP_DST} buf = type_['buf'] \ + self.len_['buf'] \ + self.tp['buf'] \ + self.zfill res = self.c.parser(self.buf, 0) self.assertEqual(self.tp['val'], res.tp) def test_parser_check_type(self): type_ = {'buf': b'\x00\x07', 'val': 7} buf = type_['buf'] \ + self.len_['buf'] \ + self.tp['buf'] \ + self.zfill self.assertRaises(AssertionError, self.c.parser, buf, 0) def test_parser_check_len(self): len_ = {'buf': b'\x00\x07', 'val': 7} buf = self.type_['buf'] \ + len_['buf'] \ + self.tp['buf'] \ + self.zfill self.assertRaises(AssertionError, self.c.parser, buf, 0) def test_serialize(self): buf = bytearray() self.c.serialize(buf, 0) fmt = ofproto.OFP_ACTION_TP_PORT_PACK_STR res = struct.unpack(fmt, bytes(buf)) self.assertEqual(self.type_['val'], res[0]) self.assertEqual(self.len_['val'], res[1]) self.assertEqual(self.tp['val'], res[2]) class TestOFPActionSetTpDst(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPActionSetTpDst """ # OFP_ACTION_TP_PORT_PACK_STR # '!HHH2x'...type, len, tp, zfill type_ = {'buf': b'\x00\x0a', 'val': ofproto.OFPAT_SET_TP_DST} len_ = {'buf': b'\x00\x08', 'val': ofproto.OFP_ACTION_TP_PORT_SIZE} tp = {'buf': b'\x06\x6d', 'val': 1645} zfill = b'\x00' * 2 buf = type_['buf'] \ + len_['buf'] \ + tp['buf'] \ + zfill c = OFPActionSetTpDst(tp['val']) def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(self.tp['val'], self.c.tp) def test_parser_dst(self): res = self.c.parser(self.buf, 0) self.assertEqual(self.tp['val'], res.tp) def test_parser_src(self): type_ = {'buf': b'\x00\x09', 'val': ofproto.OFPAT_SET_TP_SRC} buf = type_['buf'] \ + self.len_['buf'] \ + self.tp['buf'] \ + self.zfill res = self.c.parser(buf, 0) self.assertEqual(self.tp['val'], res.tp) def test_parser_check_type(self): type_ = {'buf': b'\x00\x10', 'val': 16} buf = type_['buf'] \ + self.len_['buf'] \ + self.tp['buf'] \ + self.zfill self.assertRaises(AssertionError, self.c.parser, buf, 0) def test_parser_check_len(self): len_ = {'buf': b'\x00\x07', 'val': 7} buf = self.type_['buf'] \ + len_['buf'] \ + self.tp['buf'] \ + self.zfill self.assertRaises(AssertionError, self.c.parser, buf, 0) def test_serialize(self): buf = bytearray() self.c.serialize(buf, 0) fmt = ofproto.OFP_ACTION_TP_PORT_PACK_STR res = struct.unpack(fmt, bytes(buf)) self.assertEqual(self.type_['val'], res[0]) self.assertEqual(self.len_['val'], res[1]) self.assertEqual(self.tp['val'], res[2]) class TestOFPActionEnqueue(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPActionEnqueue """ # OFP_ACTION_ENQUEUE_PACK_STR # '!HHH6xI'...type_, len_, port, zfill, queue_id type_ = {'buf': b'\x00\x0b', 'val': ofproto.OFPAT_ENQUEUE} len_ = {'buf': b'\x00\x10', 'val': ofproto.OFP_ACTION_ENQUEUE_SIZE} port = {'buf': b'\x04\x55', 'val': 1109} zfill = b'\x00' * 6 queue_id = {'buf': b'\x0a\x5b\x03\x5e', 'val': 173736798} buf = type_['buf'] \ + len_['buf'] \ + port['buf'] \ + zfill \ + queue_id['buf'] c = OFPActionEnqueue(port['val'], queue_id['val']) def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(self.port['val'], self.c.port) self.assertEqual(self.queue_id['val'], self.c.queue_id) def test_parser(self): res = self.c.parser(self.buf, 0) self.assertEqual(self.port['val'], res.port) self.assertEqual(self.queue_id['val'], res.queue_id) def test_parser_check_type(self): type_ = {'buf': b'\x00\x0a', 'val': 10} buf = type_['buf'] \ + self.len_['buf'] \ + self.port['buf'] \ + self.zfill \ + self.queue_id['buf'] self.assertRaises(AssertionError, self.c.parser, buf, 0) def test_parser_check_len(self): len_ = {'buf': b'\x00\x05', 'val': 5} buf = self.type_['buf'] \ + len_['buf'] \ + self.port['buf'] \ + self.zfill \ + self.queue_id['buf'] self.assertRaises(AssertionError, self.c.parser, buf, 0) def test_serialize(self): buf = bytearray() self.c.serialize(buf, 0) fmt = ofproto.OFP_ACTION_ENQUEUE_PACK_STR res = struct.unpack(fmt, bytes(buf)) self.assertEqual(self.type_['val'], res[0]) self.assertEqual(self.len_['val'], res[1]) self.assertEqual(self.port['val'], res[2]) self.assertEqual(self.queue_id['val'], res[3]) class TestNXActionResubmit(unittest.TestCase): """ Test case for ofproto_v1_0_parser.NXActionResubmit """ # NX_ACTION_RESUBMIT_PACK_STR # '!HHIHHB3x'...type, len, vendor, subtype, in_port, table, zfill type_ = {'buf': b'\xff\xff', 'val': ofproto.OFPAT_VENDOR} len_ = {'buf': b'\x00\x10', 'val': ofproto.NX_ACTION_RESUBMIT_SIZE} vendor = {'buf': b'\x00\x00\x23\x20', 'val': 8992} subtype = {'buf': b'\x00\x01', 'val': 1} in_port = {'buf': b'\x0a\x4c', 'val': 2636} table = {'buf': b'\x52', 'val': 82} zfill = b'\x00' * 3 buf = type_['buf'] \ + len_['buf'] \ + vendor['buf'] \ + subtype['buf'] \ + in_port['buf'] \ + table['buf'] \ + zfill c = NXActionResubmit(in_port['val']) def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(self.subtype['val'], self.c.subtype) self.assertEqual(self.in_port['val'], self.c.in_port) def test_parser(self): res = OFPActionVendor.parser(self.buf, 0) self.assertEqual(self.type_['val'], res.type) self.assertEqual(self.len_['val'], res.len) self.assertEqual(self.in_port['val'], res.in_port) def test_serialize(self): buf = bytearray() self.c.serialize(buf, 0) fmt = ofproto.NX_ACTION_RESUBMIT_PACK_STR res = struct.unpack(fmt, bytes(buf)) self.assertEqual(self.type_['val'], res[0]) self.assertEqual(self.len_['val'], res[1]) self.assertEqual(self.vendor['val'], res[2]) self.assertEqual(self.subtype['val'], res[3]) self.assertEqual(self.in_port['val'], res[4]) class TestNXActionResubmitTable(unittest.TestCase): """ Test case for ofproto_v1_0_parser.NXActionResubmitTable """ # NX_ACTION_RESUBMIT_PACK_STR # '!HHIHHB3x'...type, len, vendor, subtype, in_port, table, zfill type_ = {'buf': b'\xff\xff', 'val': ofproto.OFPAT_VENDOR} len_ = {'buf': b'\x00\x10', 'val': ofproto.NX_ACTION_RESUBMIT_SIZE} vendor = {'buf': b'\x00\x00\x23\x20', 'val': 8992} subtype = {'buf': b'\x00\x0e', 'val': 14} in_port = {'buf': b'\x0a\x4c', 'val': 2636} table_id = {'buf': b'\x52', 'val': 82} zfill = b'\x00' * 3 buf = type_['buf'] \ + len_['buf'] \ + vendor['buf'] \ + subtype['buf'] \ + in_port['buf'] \ + table_id['buf'] \ + zfill c = NXActionResubmitTable(in_port['val'], table_id['val']) def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(self.subtype['val'], self.c.subtype) self.assertEqual(self.in_port['val'], self.c.in_port) self.assertEqual(self.table_id['val'], self.c.table_id) def test_parser(self): res = OFPActionVendor.parser(self.buf, 0) self.assertEqual(self.type_['val'], res.type) self.assertEqual(self.len_['val'], res.len) self.assertEqual(self.in_port['val'], res.in_port) self.assertEqual(self.table_id['val'], res.table_id) def test_serialize(self): buf = bytearray() self.c.serialize(buf, 0) fmt = ofproto.NX_ACTION_RESUBMIT_PACK_STR res = struct.unpack(fmt, bytes(buf)) self.assertEqual(self.type_['val'], res[0]) self.assertEqual(self.len_['val'], res[1]) self.assertEqual(self.vendor['val'], res[2]) self.assertEqual(self.subtype['val'], res[3]) self.assertEqual(self.in_port['val'], res[4]) self.assertEqual(self.table_id['val'], res[5]) class TestNXActionSetTunnel(unittest.TestCase): """ Test case for ofproto_v1_0_parser.NXActionSetTunnel """ # NX_ACTION_SET_TUNNEL_PACK_STR # '!HHIH2xI'...type, len, vendor, subtype, zfill, tun_id type_ = {'buf': b'\xff\xff', 'val': ofproto.OFPAT_VENDOR} len_ = {'buf': b'\x00\x10', 'val': ofproto.NX_ACTION_SET_TUNNEL_SIZE} vendor = {'buf': b'\x00\x00\x23\x20', 'val': 8992} subtype = {'buf': b'\x00\x02', 'val': 2} zfill = b'\x00' * 2 tun_id = {'buf': b'\x01\x6f\x01\xd0', 'val': 24052176} buf = type_['buf'] \ + len_['buf'] \ + vendor['buf'] \ + subtype['buf'] \ + zfill \ + tun_id['buf'] c = NXActionSetTunnel(tun_id['val']) def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(self.subtype['val'], self.c.subtype) self.assertEqual(self.tun_id['val'], self.c.tun_id) def test_parse(self): res = OFPActionVendor.parser(self.buf, 0) self.assertEqual(self.type_['val'], res.type) self.assertEqual(self.len_['val'], res.len) self.assertEqual(self.tun_id['val'], res.tun_id) def test_serialize(self): buf = bytearray() self.c.serialize(buf, 0) fmt = ofproto.NX_ACTION_SET_TUNNEL_PACK_STR res = struct.unpack(fmt, bytes(buf)) self.assertEqual(self.type_['val'], res[0]) self.assertEqual(self.len_['val'], res[1]) self.assertEqual(self.vendor['val'], res[2]) self.assertEqual(self.subtype['val'], res[3]) self.assertEqual(self.tun_id['val'], res[4]) class TestNXActionSetQueue(unittest.TestCase): """ Test case for ofproto_v1_0_parser.NXActionSetQueue """ # NX_ACTION_SET_QUEUE_PACK_STR # '!HHIH2xI'...type, len, vendor, subtype, zfill, queue_id type_ = {'buf': b'\xff\xff', 'val': ofproto.OFPAT_VENDOR} len_ = {'buf': b'\x00\x10', 'val': ofproto.NX_ACTION_SET_TUNNEL_SIZE} vendor = {'buf': b'\x00\x00\x23\x20', 'val': ofproto_common.NX_EXPERIMENTER_ID} subtype = {'buf': b'\x00\x04', 'val': ofproto.NXAST_SET_QUEUE} zfill = b'\x00' * 2 queue_id = {'buf': b'\xde\xbe\xc5\x18', 'val': 3737044248} buf = type_['buf'] \ + len_['buf'] \ + vendor['buf'] \ + subtype['buf'] \ + zfill \ + queue_id['buf'] c = NXActionSetQueue(queue_id['val']) def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(self.subtype['val'], self.c.subtype) self.assertEqual(self.queue_id['val'], self.c.queue_id) def test_parser(self): res = OFPActionVendor.parser(self.buf, 0) self.assertEqual(self.type_['val'], res.type) self.assertEqual(self.len_['val'], res.len) self.assertEqual(self.queue_id['val'], res.queue_id) def test_serialize(self): buf = bytearray() self.c.serialize(buf, 0) fmt = ofproto.NX_ACTION_SET_QUEUE_PACK_STR res = struct.unpack(fmt, bytes(buf)) self.assertEqual(self.type_['val'], res[0]) self.assertEqual(self.len_['val'], res[1]) self.assertEqual(self.vendor['val'], res[2]) self.assertEqual(self.subtype['val'], res[3]) self.assertEqual(self.queue_id['val'], res[4]) class TestNXActionPopQueue(unittest.TestCase): """ Test case for ofproto_v1_0_parser.NXActionPopQueue """ # NX_ACTION_POP_QUEUE_PACK_STR # '!HHIH6x'...type, len, vendor, subtype, zfill type_ = {'buf': b'\xff\xff', 'val': ofproto.OFPAT_VENDOR} len_ = {'buf': b'\x00\x10', 'val': ofproto.NX_ACTION_SET_TUNNEL_SIZE} vendor = {'buf': b'\x00\x00\x23\x20', 'val': ofproto_common.NX_EXPERIMENTER_ID} subtype = {'buf': b'\x00\x05', 'val': ofproto.NXAST_POP_QUEUE} zfill = b'\x00' * 6 buf = type_['buf'] \ + len_['buf'] \ + vendor['buf'] \ + subtype['buf'] \ + zfill c = NXActionPopQueue() def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(self.subtype['val'], self.c.subtype) def test_parser(self): res = OFPActionVendor.parser(self.buf, 0) self.assertEqual(self.type_['val'], res.type) self.assertEqual(self.len_['val'], res.len) self.assertEqual(self.subtype['val'], res.subtype) def test_serialize(self): buf = bytearray() self.c.serialize(buf, 0) fmt = ofproto.NX_ACTION_POP_QUEUE_PACK_STR res = struct.unpack(fmt, bytes(buf)) self.assertEqual(self.type_['val'], res[0]) self.assertEqual(self.len_['val'], res[1]) self.assertEqual(self.vendor['val'], res[2]) self.assertEqual(self.subtype['val'], res[3]) class TestNXActionRegMove(unittest.TestCase): """ Test case for ofproto_v1_0_parser.NXActionRegMove """ # NX_ACTION_REG_MOVE_PACK_STR # '!HHIHHHHII'...type_, len_, vendor, subtype, n_bits, # src_ofs, dst_ofs, src, dst type_ = {'buf': b'\xff\xff', 'val': ofproto.OFPAT_VENDOR} len_ = {'buf': b'\x00\x18', 'val': ofproto.NX_ACTION_REG_MOVE_SIZE} vendor = {'buf': b'\x00\x00\x23\x20', 'val': ofproto_common.NX_EXPERIMENTER_ID} subtype = {'buf': b'\x00\x06', 'val': ofproto.NXAST_REG_MOVE} n_bits = {'buf': b'\x3d\x98', 'val': 15768} src_ofs = {'buf': b'\xf3\xa3', 'val': 62371} dst_ofs = {'buf': b'\xdc\x67', 'val': 56423} src_field = {'buf': b'\x00\x01\x00\x04', 'val': "reg0", "val2": 65540} dst_field = {'buf': b'\x00\x01\x02\x04', 'val': "reg1", "val2": 66052} buf = type_['buf'] \ + len_['buf'] \ + vendor['buf'] \ + subtype['buf'] \ + n_bits['buf'] \ + src_ofs['buf'] \ + dst_ofs['buf'] \ + src_field['buf'] \ + dst_field['buf'] c = NXActionRegMove(src_field['val'], dst_field['val'], n_bits['val'], src_ofs['val'], dst_ofs['val']) def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(self.subtype['val'], self.c.subtype) self.assertEqual(self.src_field['val'], self.c.src_field) self.assertEqual(self.dst_field['val'], self.c.dst_field) self.assertEqual(self.n_bits['val'], self.c.n_bits) self.assertEqual(self.src_field['val'], self.c.src_field) self.assertEqual(self.dst_field['val'], self.c.dst_field) def test_parser(self): res = OFPActionVendor.parser(self.buf, 0) self.assertEqual(self.type_['val'], res.type) self.assertEqual(self.len_['val'], res.len) self.assertEqual(self.subtype['val'], res.subtype) self.assertEqual(self.src_ofs['val'], res.src_ofs) self.assertEqual(self.dst_ofs['val'], res.dst_ofs) self.assertEqual(self.n_bits['val'], res.n_bits) self.assertEqual(self.src_field['val'], res.src_field) self.assertEqual(self.dst_field['val'], res.dst_field) def test_serialize(self): buf = bytearray() self.c.serialize(buf, 0) fmt = ofproto.NX_ACTION_REG_MOVE_PACK_STR res = struct.unpack(fmt, bytes(buf)) self.assertEqual(self.type_['val'], res[0]) self.assertEqual(self.len_['val'], res[1]) self.assertEqual(self.vendor['val'], res[2]) self.assertEqual(self.subtype['val'], res[3]) self.assertEqual(self.n_bits['val'], res[4]) self.assertEqual(self.src_ofs['val'], res[5]) self.assertEqual(self.dst_ofs['val'], res[6]) self.assertEqual(self.src_field['val2'], res[7]) self.assertEqual(self.dst_field['val2'], res[8]) class TestNXActionRegLoad(unittest.TestCase): """ Test case for ofproto_v1_0_parser.NXActionRegLoad """ # NX_ACTION_REG_LOAD_PACK_STR # '!HHIHHIQ'...type_, len_, vendor, subtype, # ofs_nbits, dst, value type_ = {'buf': b'\xff\xff', 'val': ofproto.OFPAT_VENDOR} len_ = {'buf': b'\x00\x18', 'val': ofproto.NX_ACTION_REG_MOVE_SIZE} vendor = {'buf': b'\x00\x00\x23\x20', 'val': ofproto_common.NX_EXPERIMENTER_ID} subtype = {'buf': b'\x00\x07', 'val': ofproto.NXAST_REG_LOAD} ofs_nbits = {'buf': b'\x3d\x98', 'val': 15768} dst = {'buf': b'\x00\x01\x00\x04', 'val': "reg0", "val2": 65540} value = {'buf': b'\x33\x51\xcd\x43\x25\x28\x18\x99', 'val': 3697962457317775513} start = 246 end = 270 buf = type_['buf'] \ + len_['buf'] \ + vendor['buf'] \ + subtype['buf'] \ + ofs_nbits['buf'] \ + dst['buf'] \ + value['buf'] c = NXActionRegLoad(ofs_nbits['val'], dst['val'], value['val']) def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(self.subtype['val'], self.c.subtype) self.assertEqual(self.ofs_nbits['val'], self.c.ofs_nbits) self.assertEqual(self.dst['val'], self.c.dst) self.assertEqual(self.value['val'], self.c.value) def test_parser(self): res = OFPActionVendor.parser(self.buf, 0) self.assertEqual(self.type_['val'], res.type) self.assertEqual(self.len_['val'], res.len) self.assertEqual(self.ofs_nbits['val'], self.c.ofs_nbits) self.assertEqual(self.dst['val'], res.dst) self.assertEqual(self.value['val'], res.value) def test_serialize(self): buf = bytearray() self.c.serialize(buf, 0) fmt = ofproto.NX_ACTION_REG_LOAD_PACK_STR res = struct.unpack(fmt, bytes(buf)) self.assertEqual(self.type_['val'], res[0]) self.assertEqual(self.len_['val'], res[1]) self.assertEqual(self.vendor['val'], res[2]) self.assertEqual(self.subtype['val'], res[3]) self.assertEqual(self.ofs_nbits['val'], res[4]) self.assertEqual(self.dst['val2'], res[5]) self.assertEqual(self.value['val'], res[6]) class TestNXActionSetTunnel64(unittest.TestCase): """ Test case for ofproto_v1_0_parser.NXActionSetTunnel64 """ # NX_ACTION_SET_TUNNEL64_PACK_STR # '!HHIH6xQ'...type, len, vendor, subtype, zfill, tun_id type_ = {'buf': b'\xff\xff', 'val': ofproto.OFPAT_VENDOR} len_ = {'buf': b'\x00\x18', 'val': ofproto.NX_ACTION_SET_TUNNEL64_SIZE} vendor = {'buf': b'\x00\x00\x23\x20', 'val': ofproto_common.NX_EXPERIMENTER_ID} subtype = {'buf': b'\x00\x09', 'val': ofproto.NXAST_SET_TUNNEL64} zfill = b'\x00' * 6 tun_id = {'buf': b'\x6e\x01\xa6\xea\x7e\x36\x1d\xd9', 'val': 7926800345218817497} buf = type_['buf'] \ + len_['buf'] \ + vendor['buf'] \ + subtype['buf'] \ + zfill \ + tun_id['buf'] c = NXActionSetTunnel64(tun_id['val']) def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(self.subtype['val'], self.c.subtype) self.assertEqual(self.tun_id['val'], self.c.tun_id) def test_parser(self): res = OFPActionVendor.parser(self.buf, 0) self.assertEqual(self.type_['val'], res.type) self.assertEqual(self.len_['val'], res.len) self.assertEqual(self.subtype['val'], res.subtype) self.assertEqual(self.tun_id['val'], res.tun_id) def test_serialize(self): buf = bytearray() self.c.serialize(buf, 0) fmt = ofproto.NX_ACTION_SET_TUNNEL64_PACK_STR res = struct.unpack(fmt, bytes(buf)) self.assertEqual(self.type_['val'], res[0]) self.assertEqual(self.len_['val'], res[1]) self.assertEqual(self.vendor['val'], res[2]) self.assertEqual(self.subtype['val'], res[3]) self.assertEqual(self.tun_id['val'], res[4]) class TestNXActionMultipath(unittest.TestCase): """ Test case for ofproto_v1_0_parser.NXActionMultipath """ # NX_ACTION_MULTIPATH_PACK_STR # '!HHIHHH2xHHI2xHI'...type, len, vendor, subtype, fields, basis, zfill # algorithm, max_link, arg, zfill, ofs_nbits, dst type_ = {'buf': b'\xff\xff', 'val': ofproto.OFPAT_VENDOR} len_ = {'buf': b'\x00\x20', 'val': ofproto.NX_ACTION_MULTIPATH_SIZE} vendor = {'buf': b'\x00\x00\x23\x20', 'val': ofproto_common.NX_EXPERIMENTER_ID} subtype = {'buf': b'\x00\x0a', 'val': ofproto.NXAST_MULTIPATH} fields = {'buf': b'\x6d\xf5', 'val': 28149} basis = {'buf': b'\x7c\x0a', 'val': 31754} zfill0 = b'\x00' * 2 algorithm = {'buf': b'\x82\x1d', 'val': 33309} max_link = {'buf': b'\x06\x2b', 'val': 1579} arg = {'buf': b'\x18\x79\x41\xc8', 'val': 410599880} zfill1 = b'\x00' * 2 ofs_nbits = {'buf': b'\xa9\x9a', 'val': 43418} dst = {'buf': b'\x00\x01\x00\x04', 'val': "reg0", 'val2': 65540} start = 678 end = 704 buf = type_['buf'] \ + len_['buf'] \ + vendor['buf'] \ + subtype['buf'] \ + fields['buf'] \ + basis['buf'] \ + zfill0 \ + algorithm['buf'] \ + max_link['buf'] \ + arg['buf'] \ + zfill1 \ + ofs_nbits['buf'] \ + dst['buf'] c = NXActionMultipath(fields['val'], basis['val'], algorithm['val'], max_link['val'], arg['val'], ofs_nbits['val'], dst['val']) def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(self.subtype['val'], self.c.subtype) self.assertEqual(self.fields['val'], self.c.fields) self.assertEqual(self.basis['val'], self.c.basis) self.assertEqual(self.algorithm['val'], self.c.algorithm) self.assertEqual(self.max_link['val'], self.c.max_link) self.assertEqual(self.arg['val'], self.c.arg) self.assertEqual(self.ofs_nbits['val'], self.c.ofs_nbits) self.assertEqual(self.dst['val'], self.c.dst) def test_parser(self): res = OFPActionVendor.parser(self.buf, 0) self.assertEqual(self.type_['val'], res.type) self.assertEqual(self.len_['val'], res.len) self.assertEqual(self.subtype['val'], res.subtype) self.assertEqual(self.fields['val'], res.fields) self.assertEqual(self.basis['val'], res.basis) self.assertEqual(self.algorithm['val'], res.algorithm) self.assertEqual(self.max_link['val'], res.max_link) self.assertEqual(self.arg['val'], res.arg) self.assertEqual(self.ofs_nbits['val'], res.ofs_nbits) self.assertEqual(self.dst['val'], res.dst) def test_serialize(self): buf = bytearray() self.c.serialize(buf, 0) fmt = ofproto.NX_ACTION_MULTIPATH_PACK_STR res = struct.unpack(fmt, bytes(buf)) self.assertEqual(self.type_['val'], res[0]) self.assertEqual(self.len_['val'], res[1]) self.assertEqual(self.vendor['val'], res[2]) self.assertEqual(self.subtype['val'], res[3]) self.assertEqual(self.fields['val'], res[4]) self.assertEqual(self.basis['val'], res[5]) self.assertEqual(self.algorithm['val'], res[6]) self.assertEqual(self.max_link['val'], res[7]) self.assertEqual(self.arg['val'], res[8]) self.assertEqual(self.ofs_nbits['val'], res[9]) self.assertEqual(self.dst['val2'], res[10]) class TestNXActionBundle(unittest.TestCase): """ Test case for ofproto_v1_0_parser.NXActionBundle """ # NX_ACTION_BUNDLE_PACK_STR # '!HHIHHHHIHHI4x'...type, len, vendor, subtype, algorithm, # fields, basis, slave_type, n_slaves, # ofs_nbits, dst, zfill type_ = {'buf': b'\xff\xff', 'val': ofproto.OFPAT_VENDOR} len_ = {'buf': b'\x00\x28', 'val': (ofproto.NX_ACTION_BUNDLE_SIZE + 8)} vendor = {'buf': b'\x00\x00\x23\x20', 'val': ofproto_common.NX_EXPERIMENTER_ID} subtype = {'buf': b'\x00\x0c', 'val': ofproto.NXAST_BUNDLE} algorithm = {'buf': b'\x51\xa7', 'val': 20903} fields = {'buf': b'\xf8\xef', 'val': 63727} basis = {'buf': b'\xfd\x6f', 'val': 64879} slave_type = {'buf': b'\x7c\x51\x0f\xe0', 'val': 2085687264} n_slaves = {'buf': b'\x00\x02', 'val': 2} ofs_nbits = {'buf': b'\x00\x00', 'val': 0} dst = {'buf': b'\x00\x00\x00\x00', 'val': 0} zfill = b'\x00' * 4 slaves_buf = (b'\x00\x01', b'\x00\x02') slaves_val = (1, 2) _len = len_['val'] + len(slaves_val) * 2 _len += (_len % 8) buf = type_['buf'] \ + len_['buf'] \ + vendor['buf'] \ + subtype['buf'] \ + algorithm['buf'] \ + fields['buf'] \ + basis['buf'] \ + slave_type['buf'] \ + n_slaves['buf'] \ + ofs_nbits['buf'] \ + dst['buf'] \ + zfill \ + slaves_buf[0] \ + slaves_buf[1] c = NXActionBundle(algorithm['val'], fields['val'], basis['val'], slave_type['val'], n_slaves['val'], ofs_nbits['val'], dst['val'], slaves_val) def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(self.subtype['val'], self.c.subtype) self.assertEqual(self.algorithm['val'], self.c.algorithm) self.assertEqual(self.fields['val'], self.c.fields) self.assertEqual(self.basis['val'], self.c.basis) self.assertEqual(self.slave_type['val'], self.c.slave_type) self.assertEqual(self.n_slaves['val'], self.c.n_slaves) self.assertEqual(self.ofs_nbits['val'], self.c.ofs_nbits) self.assertEqual(self.dst['val'], self.c.dst) # slaves slaves = self.c.slaves self.assertEqual(self.slaves_val[0], slaves[0]) self.assertEqual(self.slaves_val[1], slaves[1]) def test_parser(self): res = OFPActionVendor.parser(self.buf, 0) self.assertEqual(self.type_['val'], res.type) self.assertEqual(self.len_['val'], res.len) self.assertEqual(self.subtype['val'], res.subtype) self.assertEqual(self.algorithm['val'], res.algorithm) self.assertEqual(self.fields['val'], res.fields) self.assertEqual(self.basis['val'], res.basis) self.assertEqual(self.slave_type['val'], res.slave_type) self.assertEqual(self.n_slaves['val'], res.n_slaves) self.assertEqual(self.ofs_nbits['val'], res.ofs_nbits) self.assertEqual(self.dst['val'], res.dst) # slaves slaves = res.slaves self.assertEqual(self.slaves_val[0], slaves[0]) self.assertEqual(self.slaves_val[1], slaves[1]) def test_serialize(self): buf = bytearray() self.c.serialize(buf, 0) fmt = '!' \ + ofproto.NX_ACTION_BUNDLE_PACK_STR.replace('!', '') \ + 'HH4x' res = struct.unpack(fmt, bytes(buf)) self.assertEqual(self.type_['val'], res[0]) self.assertEqual(self.len_['val'], res[1]) self.assertEqual(self.vendor['val'], res[2]) self.assertEqual(self.subtype['val'], res[3]) self.assertEqual(self.algorithm['val'], res[4]) self.assertEqual(self.fields['val'], res[5]) self.assertEqual(self.basis['val'], res[6]) self.assertEqual(self.slave_type['val'], res[7]) self.assertEqual(self.n_slaves['val'], res[8]) self.assertEqual(self.ofs_nbits['val'], res[9]) self.assertEqual(self.dst['val'], res[10]) class TestNXActionBundleLoad(unittest.TestCase): """ Test case for ofproto_v1_0_parser.NXActionBundleLoad """ # NX_ACTION_BUNDLE_PACK_STR # '!HHIHHHHIHHI4x'...type, len, vendor, subtype, algorithm, # fields, basis, slave_type, n_slaves, # ofs_nbits, dst, zfill type_ = {'buf': b'\xff\xff', 'val': ofproto.OFPAT_VENDOR} len_ = {'buf': b'\x00\x28', 'val': (ofproto.NX_ACTION_BUNDLE_SIZE + 8)} vendor = {'buf': b'\x00\x00\x23\x20', 'val': ofproto_common.NX_EXPERIMENTER_ID} subtype = {'buf': b'\x00\x0d', 'val': ofproto.NXAST_BUNDLE_LOAD} algorithm = {'buf': b'\x83\x15', 'val': 33557} fields = {'buf': b'\xc2\x7a', 'val': 49786} basis = {'buf': b'\x86\x18', 'val': 34328} slave_type = {'buf': b'\x18\x42\x0b\x55', 'val': 406981461} n_slaves = {'buf': b'\x00\x02', 'val': 2} ofs_nbits = {'buf': b'\xd2\x9d', 'val': 53917} dst = {'buf': b'\x00\x01\x00\x04', 'val': "reg0", 'val2': 65540} zfill = b'\x00' * 4 slaves_buf = (b'\x00\x01', b'\x00\x02') slaves_val = (1, 2) _len = len_['val'] + len(slaves_val) * 2 _len += (_len % 8) buf = type_['buf'] \ + len_['buf'] \ + vendor['buf'] \ + subtype['buf'] \ + algorithm['buf'] \ + fields['buf'] \ + basis['buf'] \ + slave_type['buf'] \ + n_slaves['buf'] \ + ofs_nbits['buf'] \ + dst['buf'] \ + zfill \ + slaves_buf[0] \ + slaves_buf[1] c = NXActionBundleLoad(algorithm['val'], fields['val'], basis['val'], slave_type['val'], n_slaves['val'], ofs_nbits['val'], dst['val'], slaves_val) def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(self.subtype['val'], self.c.subtype) self.assertEqual(self.algorithm['val'], self.c.algorithm) self.assertEqual(self.fields['val'], self.c.fields) self.assertEqual(self.basis['val'], self.c.basis) self.assertEqual(self.slave_type['val'], self.c.slave_type) self.assertEqual(self.n_slaves['val'], self.c.n_slaves) self.assertEqual(self.ofs_nbits['val'], self.c.ofs_nbits) self.assertEqual(self.dst['val'], self.c.dst) # slaves slaves = self.c.slaves self.assertEqual(self.slaves_val[0], slaves[0]) self.assertEqual(self.slaves_val[1], slaves[1]) def test_parser(self): res = OFPActionVendor.parser(self.buf, 0) self.assertEqual(self.type_['val'], res.type) self.assertEqual(self.len_['val'], res.len) self.assertEqual(self.subtype['val'], res.subtype) self.assertEqual(self.algorithm['val'], res.algorithm) self.assertEqual(self.fields['val'], res.fields) self.assertEqual(self.basis['val'], res.basis) self.assertEqual(self.slave_type['val'], res.slave_type) self.assertEqual(self.n_slaves['val'], res.n_slaves) self.assertEqual(self.ofs_nbits['val'], res.ofs_nbits) self.assertEqual(self.dst['val'], res.dst) # slaves slaves = res.slaves self.assertEqual(self.slaves_val[0], slaves[0]) self.assertEqual(self.slaves_val[1], slaves[1]) def test_serialize(self): buf = bytearray() self.c.serialize(buf, 0) fmt = '!' \ + ofproto.NX_ACTION_BUNDLE_PACK_STR.replace('!', '') \ + 'HH4x' res = struct.unpack(fmt, bytes(buf)) self.assertEqual(self.type_['val'], res[0]) self.assertEqual(self.len_['val'], res[1]) self.assertEqual(self.vendor['val'], res[2]) self.assertEqual(self.subtype['val'], res[3]) self.assertEqual(self.algorithm['val'], res[4]) self.assertEqual(self.fields['val'], res[5]) self.assertEqual(self.basis['val'], res[6]) self.assertEqual(self.slave_type['val'], res[7]) self.assertEqual(self.n_slaves['val'], res[8]) self.assertEqual(self.ofs_nbits['val'], res[9]) self.assertEqual(self.dst['val2'], res[10]) class TestNXActionOutputReg(unittest.TestCase): """ Test case for ofproto_v1_0_parser.NXActionOutputReg """ # NX_ACTION_OUTPUT_REG_PACK_STR # '!HHIHHIH6x'...type, len, vendor, subtype, ofs_nbits, # src, max_len, zfill type_ = {'buf': b'\xff\xff', 'val': ofproto.OFPAT_VENDOR} len_ = {'buf': b'\x00\x18', 'val': ofproto.NX_ACTION_OUTPUT_REG_SIZE} vendor = {'buf': b'\x00\x00\x23\x20', 'val': ofproto_common.NX_EXPERIMENTER_ID} subtype = {'buf': b'\x00\x0f', 'val': ofproto.NXAST_OUTPUT_REG} ofs_nbits = {'buf': b'\xfe\x78', 'val': 65144} src = {'buf': b'\x00\x01\x00\x04', 'val': "reg0", 'val2': 65540} max_len = {'buf': b'\x00\x08', 'val': ofproto.OFP_ACTION_OUTPUT_SIZE} zfill = b'\x00' * 6 buf = type_['buf'] \ + len_['buf'] \ + vendor['buf'] \ + subtype['buf'] \ + ofs_nbits['buf'] \ + src['buf'] \ + max_len['buf'] \ + zfill c = NXActionOutputReg(ofs_nbits['val'], src['val'], max_len['val']) def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(self.subtype['val'], self.c.subtype) self.assertEqual(self.ofs_nbits['val'], self.c.ofs_nbits) self.assertEqual(self.src['val'], self.c.src) self.assertEqual(self.max_len['val'], self.c.max_len) def test_parser(self): res = OFPActionVendor.parser(self.buf, 0) self.assertEqual(self.type_['val'], res.type) self.assertEqual(self.len_['val'], res.len) self.assertEqual(self.subtype['val'], res.subtype) self.assertEqual(self.ofs_nbits['val'], self.c.ofs_nbits) self.assertEqual(self.src['val'], res.src) self.assertEqual(self.max_len['val'], res.max_len) def test_serialize(self): buf = bytearray() self.c.serialize(buf, 0) fmt = ofproto.NX_ACTION_OUTPUT_REG_PACK_STR res = struct.unpack(fmt, bytes(buf)) self.assertEqual(self.type_['val'], res[0]) self.assertEqual(self.len_['val'], res[1]) self.assertEqual(self.vendor['val'], res[2]) self.assertEqual(self.subtype['val'], res[3]) self.assertEqual(self.ofs_nbits['val'], res[4]) self.assertEqual(self.src['val2'], res[5]) self.assertEqual(self.max_len['val'], res[6]) class TestNXActionExit(unittest.TestCase): """ Test case for ofproto_v1_0_parser.NXActionExit """ # NX_ACTION_HEADER_PACK_STR # '!HHIH'...type, len, vendor, subtype type_ = {'buf': b'\xff\xff', 'val': ofproto.OFPAT_VENDOR} len_ = {'buf': b'\x00\x10', 'val': ofproto.NX_ACTION_HEADER_SIZE} vendor = {'buf': b'\x00\x00\x23\x20', 'val': ofproto_common.NX_EXPERIMENTER_ID} subtype = {'buf': b'\x00\x11', 'val': ofproto.NXAST_EXIT} zfill = b'\x00' * 6 buf = type_['buf'] \ + len_['buf'] \ + vendor['buf'] \ + subtype['buf'] \ + zfill c = NXActionExit() def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(self.subtype['val'], self.c.subtype) def test_parser(self): res = OFPActionVendor.parser(self.buf, 0) self.assertEqual(self.type_['val'], res.type) self.assertEqual(self.len_['val'], res.len) self.assertEqual(self.subtype['val'], res.subtype) def test_serialize(self): buf = bytearray() self.c.serialize(buf, 0) fmt = ofproto.NX_ACTION_HEADER_PACK_STR res = struct.unpack(fmt, bytes(buf)) self.assertEqual(self.type_['val'], res[0]) self.assertEqual(self.len_['val'], res[1]) self.assertEqual(self.vendor['val'], res[2]) self.assertEqual(self.subtype['val'], res[3]) class TestOFPDescStats(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPDescStats """ # OFP_DESC_STATS_PACK_STR # '!256s256s256s32s256s'...mfr_desc, hw_desc, sw_desc, serial_num, dp_desc mfr_desc = b'mfr_desc'.ljust(256) hw_desc = b'hw_desc'.ljust(256) sw_desc = b'sw_desc'.ljust(256) serial_num = b'serial_num'.ljust(32) dp_desc = b'dp_desc'.ljust(256) buf = mfr_desc \ + hw_desc \ + sw_desc \ + serial_num \ + dp_desc c = OFPDescStats(mfr_desc, hw_desc, sw_desc, serial_num, dp_desc) def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(self.mfr_desc, self.c.mfr_desc) self.assertEqual(self.hw_desc, self.c.hw_desc) self.assertEqual(self.sw_desc, self.c.sw_desc) self.assertEqual(self.serial_num, self.c.serial_num) self.assertEqual(self.dp_desc, self.c.dp_desc) def test_parser(self): res = self.c.parser(self.buf, 0) self.assertEqual(self.mfr_desc, self.mfr_desc) self.assertEqual(self.hw_desc, self.hw_desc) self.assertEqual(self.sw_desc, self.sw_desc) self.assertEqual(self.serial_num, self.serial_num) self.assertEqual(self.dp_desc, self.dp_desc) class TestOFPFlowStats(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPFlowStats """ # OFP_FLOW_STATS_0_PACK_STR # '!HBx'...length, table_id, zfill length = {'buf': b'\x00\x58', 'val': 88} length_append_action = {'buf': b'\x00\x60', 'val': 96} table_id = {'buf': b'\x51', 'val': 81} zfill_0 = b'\x00' # OFP_MATCH_PACK_STR # '!IH6s6sHBxHBB2xIIHH'... match = b'\x97\x7c\xa6\x1e' \ + b'\x5e\xa0' \ + b'\x7a\x3e\xed\x30\x4a\x90' \ + b'\x96\x8e\x67\xbe\x2f\xe2' \ + b'\xb1\x81' \ + b'\xbe' \ + b'\x00' \ + b'\x01\xab' \ + b'\x42' \ + b'\xfe' \ + b'\x00\x00' \ + b'\xa4\x5d\x5c\x42' \ + b'\xa2\x5c\x2e\x05' \ + b'\x5a\x94' \ + b'\x64\xd4' # OFP_FLOW_STATS_1_PACK_STR # '!IIHHH6xQQQ'...duration_sec, duration_nsec, priority, # idle_timeout, hard_timeout, zfill, # cookie, packet_count, byte_count duration_sec = {'buf': b'\x94\x19\xb3\xd2', 'val': 2484712402} duration_nsec = {'buf': b'\xee\x66\xcf\x7c', 'val': 3999715196} priority = {'buf': b'\xe1\xc0', 'val': 57792} idle_timeout = {'buf': b'\x8e\x10', 'val': 36368} hard_timeout = {'buf': b'\xd4\x99', 'val': 54425} zfill_1 = b'\x00\x00\x00\x00\x00\x00' cookie = {'buf': b'\x0b\x01\xe8\xe5\xf0\x84\x8a\xe0', 'val': 793171083674290912} packet_count = {'buf': b'\x47\x5c\xc6\x05\x28\xff\x7c\xdb', 'val': 5142202600015232219} byte_count = {'buf': b'\x24\xe9\x4b\xee\xcb\x57\xd9\xc3', 'val': 2659740543924820419} # _PACK_STR...type_, len_ [others...] type = {'buf': b'\x00\x00', 'val': ofproto.OFPAT_OUTPUT} len = {'buf': b'\x00\x08', 'val': ofproto.OFP_ACTION_OUTPUT_SIZE} port = {'buf': b'\x59\x2a', 'val': 22826} max_len = {'buf': b'\x00\x08', 'val': ofproto.OFP_ACTION_OUTPUT_SIZE} action = (type, len, port, max_len) ACTION_TYPE = 0 ACTION_LEN = 1 ACTION_PORT = 2 ACTION_MAX_LEN = 3 c = OFPFlowStats() def setUp(self): pass def tearDown(self): pass def test_init(self): pass def _parser(self, action=None): buf = self.table_id['buf'] \ + self.zfill_0 \ + self.match \ + self.duration_sec['buf'] \ + self.duration_nsec['buf'] \ + self.priority['buf'] \ + self.idle_timeout['buf'] \ + self.hard_timeout['buf'] \ + self.zfill_1 \ + self.cookie['buf'] \ + self.packet_count['buf'] \ + self.byte_count['buf'] if not action: buf = self.length['buf'] + buf else: buf = self.length_append_action['buf'] + buf for a in self.action: buf = buf + a['buf'] return self.c.parser(buf, 0) def test_parser(self): res = self._parser() self.assertEqual(self.length['val'], res.length) self.assertEqual(self.table_id['val'], res.table_id) self.assertEqual(self.duration_sec['val'], res.duration_sec) self.assertEqual(self.duration_nsec['val'], res.duration_nsec) self.assertEqual(self.priority['val'], res.priority) self.assertEqual(self.idle_timeout['val'], res.idle_timeout) self.assertEqual(self.hard_timeout['val'], res.hard_timeout) self.assertEqual(self.cookie['val'], res.cookie) self.assertEqual(self.packet_count['val'], res.packet_count) self.assertEqual(self.byte_count['val'], res.byte_count) def test_parser_append_actions(self): res = self._parser(True).actions[0] self.assertEqual(self.action[self.ACTION_TYPE]['val'], res.type) self.assertEqual(self.action[self.ACTION_LEN]['val'], res.len) self.assertEqual(self.action[self.ACTION_PORT]['val'], res.port) self.assertEqual(self.action[self.ACTION_MAX_LEN]['val'], res.max_len) class TestOFPAggregateStats(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPAggregateStats """ # OFP_AGGREGATE_STATS_REPLY_PACK_STR # '!QQI4x'...packet_count, byte_count, flow_count, zfill packet_count = {'buf': b'\x43\x95\x1b\xfb\x0f\xf6\xa7\xdd', 'val': 4869829337189623773} byte_count = {'buf': b'\x36\xda\x2d\x80\x2a\x95\x35\xdd', 'val': 3952521651464517085} flow_count = {'buf': b'\xc3\x0d\xc3\xed', 'val': 3272459245} zfill = b'\x00' * 4 buf = packet_count['buf'] \ + byte_count['buf'] \ + flow_count['buf'] \ + zfill c = OFPAggregateStats(packet_count['val'], byte_count['val'], flow_count['val']) def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(self.packet_count['val'], self.c.packet_count) self.assertEqual(self.byte_count['val'], self.c.byte_count) self.assertEqual(self.flow_count['val'], self.c.flow_count) def test_parser(self): res = self.c.parser(self.buf, 0) self.assertEqual(self.packet_count['val'], res.packet_count) self.assertEqual(self.byte_count['val'], res.byte_count) self.assertEqual(self.flow_count['val'], res.flow_count) class TestOFPTableStats(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPTableStats """ # OFP_TABLE_STATS_PACK_STR # '!B3x32sIIIQQ'...table_id, zfill, name, wildcards, max_entries, # active_count, lookup_count, matched_count table_id = {'buf': b'\x5b', 'val': 91} zfill = b'\x00' * 3 name = b'name'.ljust(32) wildcards = {'buf': b'\xc5\xaf\x6e\x12', 'val': 3316608530} max_entries = {'buf': b'\x95\x6c\x78\x4d', 'val': 2506913869} active_count = {'buf': b'\x78\xac\xa8\x1e', 'val': 2024581150} lookup_count = {'buf': b'\x40\x1d\x9c\x39\x19\xec\xd4\x1c', 'val': 4620020561814017052} matched_count = {'buf': b'\x27\x35\x02\xb6\xc5\x5e\x17\x65', 'val': 2825167325263435621} buf = table_id['buf'] \ + zfill \ + name \ + wildcards['buf'] \ + max_entries['buf'] \ + active_count['buf'] \ + lookup_count['buf'] \ + matched_count['buf'] c = OFPTableStats(table_id['val'], name, wildcards['val'], max_entries['val'], active_count['val'], lookup_count['val'], matched_count['val']) def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(self.table_id['val'], self.c.table_id) self.assertEqual(self.name, self.c.name) self.assertEqual(self.wildcards['val'], self.c.wildcards) self.assertEqual(self.max_entries['val'], self.c.max_entries) self.assertEqual(self.active_count['val'], self.c.active_count) self.assertEqual(self.lookup_count['val'], self.c.lookup_count) self.assertEqual(self.matched_count['val'], self.c.matched_count) def test_parser(self): res = self.c.parser(self.buf, 0) self.assertEqual(self.table_id['val'], res.table_id) self.assertEqual(self.name, res.name) self.assertEqual(self.wildcards['val'], res.wildcards) self.assertEqual(self.max_entries['val'], res.max_entries) self.assertEqual(self.active_count['val'], res.active_count) self.assertEqual(self.lookup_count['val'], res.lookup_count) self.assertEqual(self.matched_count['val'], res.matched_count) class TestOFPPortStats(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPPortStats """ # OFP_PORT_STATS_PACK_STR # '!H6xQQQQQQQQQQQQ'... port_no, zfill, rx_packets, tx_packets, # rx_bytes, tx_bytes, rx_dropped, tx_dropped, # rx_errors, tx_errors, rx_frame_err, # rx_over_err, rx_crc_err, collisions port_no = {'buf': b'\xe7\x6b', 'val': 59243} zfill = b'\x00' * 6 rx_packets = {'buf': b'\x53\x44\x36\x61\xc4\x86\xc0\x37', 'val': 5999980397101236279} tx_packets = {'buf': b'\x27\xa4\x41\xd7\xd4\x53\x9e\x42', 'val': 2856480458895760962} rx_bytes = {'buf': b'\x55\xa1\x38\x60\x43\x97\x0d\x89', 'val': 6170274950576278921} tx_bytes = {'buf': b'\x77\xe1\xd5\x63\x18\xae\x63\xaa', 'val': 8638420181865882538} rx_dropped = {'buf': b'\x60\xe6\x20\x01\x24\xda\x4e\x5a', 'val': 6982303461569875546} tx_dropped = {'buf': b'\x09\x2d\x5d\x71\x71\xb6\x8e\xc7', 'val': 661287462113808071} rx_errors = {'buf': b'\x2f\x7e\x35\xb3\x66\x3c\x19\x0d', 'val': 3422231811478788365} tx_errors = {'buf': b'\x57\x32\x08\x2f\x88\x32\x40\x6b', 'val': 6283093430376743019} rx_frame_err = {'buf': b'\x0c\x28\x6f\xad\xce\x66\x6e\x8b', 'val': 876072919806406283} rx_over_err = {'buf': b'\x5a\x90\x8f\x9b\xfc\x82\x2e\xa0', 'val': 6525873760178941600} rx_crc_err = {'buf': b'\x73\x3a\x71\x17\xd6\x74\x69\x47', 'val': 8303073210207070535} collisions = {'buf': b'\x2f\x52\x0c\x79\x96\x03\x6e\x79', 'val': 3409801584220270201} buf = port_no['buf'] \ + zfill \ + rx_packets['buf'] \ + tx_packets['buf'] \ + rx_bytes['buf'] \ + tx_bytes['buf'] \ + rx_dropped['buf'] \ + tx_dropped['buf'] \ + rx_errors['buf'] \ + tx_errors['buf'] \ + rx_frame_err['buf'] \ + rx_over_err['buf'] \ + rx_crc_err['buf'] \ + collisions['buf'] c = OFPPortStats(port_no['val'], rx_packets['val'], tx_packets['val'], rx_bytes['val'], tx_bytes['val'], rx_dropped['val'], tx_dropped['val'], rx_errors['val'], tx_errors['val'], rx_frame_err['val'], rx_over_err['val'], rx_crc_err['val'], collisions['val']) def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(self.port_no['val'], self.c.port_no) self.assertEqual(self.rx_packets['val'], self.c.rx_packets) self.assertEqual(self.tx_packets['val'], self.c.tx_packets) self.assertEqual(self.rx_bytes['val'], self.c.rx_bytes) self.assertEqual(self.tx_bytes['val'], self.c.tx_bytes) self.assertEqual(self.rx_dropped['val'], self.c.rx_dropped) self.assertEqual(self.tx_dropped['val'], self.c.tx_dropped) self.assertEqual(self.rx_errors['val'], self.c.rx_errors) self.assertEqual(self.tx_errors['val'], self.c.tx_errors) self.assertEqual(self.rx_frame_err['val'], self.c.rx_frame_err) self.assertEqual(self.rx_over_err['val'], self.c.rx_over_err) self.assertEqual(self.rx_crc_err['val'], self.c.rx_crc_err) self.assertEqual(self.collisions['val'], self.c.collisions) def test_parser(self): res = self.c.parser(self.buf, 0) self.assertEqual(self.port_no['val'], res.port_no) self.assertEqual(self.rx_packets['val'], res.rx_packets) self.assertEqual(self.tx_packets['val'], res.tx_packets) self.assertEqual(self.rx_bytes['val'], res.rx_bytes) self.assertEqual(self.tx_bytes['val'], res.tx_bytes) self.assertEqual(self.rx_dropped['val'], res.rx_dropped) self.assertEqual(self.tx_dropped['val'], res.tx_dropped) self.assertEqual(self.rx_errors['val'], res.rx_errors) self.assertEqual(self.tx_errors['val'], res.tx_errors) self.assertEqual(self.rx_frame_err['val'], res.rx_frame_err) self.assertEqual(self.rx_over_err['val'], res.rx_over_err) self.assertEqual(self.rx_crc_err['val'], res.rx_crc_err) self.assertEqual(self.collisions['val'], res.collisions) class TestOFPQueueStats(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPQueueStats """ # OFP_QUEUE_STATS_PACK_STR # '!H2xIQQQ...port_no, queue_id, tx_bytes, tx_packets, tx_errors port_no = {'buf': b'\xe7\x6b', 'val': 59243} zfill = b'\x00' * 2 queue_id = {'buf': b'\x2a\xa8\x7f\x32', 'val': 715685682} tx_bytes = {'buf': b'\x77\xe1\xd5\x63\x18\xae\x63\xaa', 'val': 8638420181865882538} tx_packets = {'buf': b'\x27\xa4\x41\xd7\xd4\x53\x9e\x42', 'val': 2856480458895760962} tx_errors = {'buf': b'\x57\x32\x08\x2f\x88\x32\x40\x6b', 'val': 6283093430376743019} c = OFPQueueStats(port_no['val'], queue_id['val'], tx_bytes['val'], tx_packets['val'], tx_errors['val']) buf = port_no['buf'] \ + zfill \ + queue_id['buf'] \ + tx_bytes['buf'] \ + tx_packets['buf'] \ + tx_errors['buf'] def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(self.port_no['val'], self.c.port_no) self.assertEqual(self.queue_id['val'], self.c.queue_id) self.assertEqual(self.tx_bytes['val'], self.c.tx_bytes) self.assertEqual(self.tx_packets['val'], self.c.tx_packets) self.assertEqual(self.tx_errors['val'], self.c.tx_errors) def test_parser(self): res = self.c.parser(self.buf, 0) self.assertEqual(self.port_no['val'], res.port_no) self.assertEqual(self.queue_id['val'], res.queue_id) self.assertEqual(self.tx_bytes['val'], res.tx_bytes) self.assertEqual(self.tx_packets['val'], res.tx_packets) self.assertEqual(self.tx_errors['val'], res.tx_errors) class TestOFPVendorStats(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPVendorStats """ specific_data = 'specific_data' specific_data_after = 'data' offset = specific_data.find(specific_data_after) c = OFPVendorStats(specific_data) def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(self.specific_data, self.c.specific_data) def test_parser(self): res = self.c.parser(self.specific_data, self.offset) self.assertEqual(self.specific_data_after, res.specific_data) class TestOFPQueuePropNone(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPQueuePropNone """ # OFP_QUEUE_PROP_HEADER_PACK_STR # '!HH4x'...property_, len_ property = {'buf': b'\x00\x00', 'val': ofproto.OFPQT_NONE} len = {'buf': b'\x00\x08', 'val': ofproto.OFP_QUEUE_PROP_HEADER_SIZE} zfill = b'\x00' * 4 c = OFPQueuePropNone() def setUp(self): pass def tearDown(self): pass def test_init(self): cls = OFPQueuePropHeader._QUEUE_PROPERTIES[self.c.cls_prop_type] self.assertEqual(self.property['val'], self.c.cls_prop_type) self.assertEqual(self.property['val'], self.c.property) self.assertEqual(self.property['val'], cls.cls_prop_type) self.assertEqual(self.len['val'], self.c.cls_prop_len) self.assertEqual(self.len['val'], self.c.len) self.assertEqual(self.len['val'], cls.cls_prop_len) def test_parser(self): buf = self.property['buf'] \ + self.len['buf'] \ + self.zfill self.assertTrue(self.c.parser(buf, 0)) class TestOFPQueuePropMinRate(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPQueuePropMinRate """ # OFP_QUEUE_PROP_MIN_RATE_PACK_STR # '!H6x'...rate rate = {'buf': b'\x00\x01', 'val': ofproto.OFPQT_MIN_RATE} len = {'buf': b'\x00\x10', 'val': ofproto.OFP_QUEUE_PROP_MIN_RATE_SIZE} zfill = b'\x00' * 6 buf = rate['buf'] \ + zfill c = OFPQueuePropMinRate(rate['val']) def setUp(self): pass def tearDown(self): pass def test_init(self): cls = OFPQueuePropHeader._QUEUE_PROPERTIES[self.c.cls_prop_type] self.assertEqual(self.rate['val'], self.c.cls_prop_type) self.assertEqual(self.rate['val'], self.c.rate) self.assertEqual(self.rate['val'], cls.cls_prop_type) self.assertEqual(self.len['val'], self.c.cls_prop_len) self.assertEqual(self.len['val'], cls.cls_prop_len) def test_parser(self): res = self.c.parser(self.buf, 0) self.assertEqual(self.rate['val'], res.rate) class TestOFPPacketQueue(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPPacketQueue """ # OFP_PACKET_QUEUE_PQCK_STR # '!IH2x'...queue_id, len_, zfill queue_id = {'buf': b'\x4d\x4b\x3a\xd1', 'val': 1296775889} len_ = {'buf': b'\x00\x08', 'val': ofproto.OFP_QUEUE_PROP_HEADER_SIZE} zfill = b'\x00' * 2 buf = queue_id['buf'] \ + len_['buf'] \ + zfill c = OFPPacketQueue(queue_id['val'], len_['val']) def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(self.queue_id['val'], self.c.queue_id) self.assertEqual(self.len_['val'], self.c.len) def test_parser(self): res = self.c.parser(self.buf, 0) self.assertEqual(self.queue_id['val'], res.queue_id) self.assertEqual(self.len_['val'], res.len) def test_parser_append_prop(self): # OFP_QUEUE_PROP_HEADER_PACK_STR + OFP_QUEUE_PROP_MIN_RATE_PACK_STR # '!HH4xH6x'...type, len, zfill, rate, zfill len_ = {'buf': b'\x00\x10', 'val': ofproto.OFP_QUEUE_PROP_MIN_RATE_SIZE} a_type = {'buf': b'\x00\x01', 'val': ofproto.OFPQT_MIN_RATE} a_len = {'buf': b'\x00\x10', 'val': ofproto.OFP_QUEUE_PROP_MIN_RATE_SIZE} a_zfill0 = b'\x00' * 4 a_rate = {'buf': b'\x00\x01', 'val': ofproto.OFPQT_MIN_RATE} a_zfill1 = b'\x00' * 6 buf = self.queue_id['buf'] \ + len_['buf'] \ + self.zfill \ + a_type['buf'] \ + a_len['buf'] \ + a_zfill0 \ + a_rate['buf'] \ + a_zfill1 res = self.c.parser(buf, 0) self.assertEqual(self.queue_id['val'], res.queue_id) self.assertEqual(len_['val'], res.len) append_cls = res.properties[0] self.assertEqual(a_type['val'], append_cls.property) self.assertEqual(a_len['val'], append_cls.len) self.assertEqual(a_rate['val'], append_cls.rate) class TestOFPHello(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPHello """ def setUp(self): pass def tearDown(self): pass def test_init(self): pass def test_parser(self): version = ofproto.OFP_VERSION msg_type = ofproto.OFPT_HELLO msg_len = ofproto.OFP_HEADER_SIZE xid = 2183948390 data = b'\x00\x01\x02\x03' fmt = ofproto.OFP_HEADER_PACK_STR buf = struct.pack(fmt, version, msg_type, msg_len, xid) \ + data res = OFPHello.parser(object, version, msg_type, msg_len, xid, bytearray(buf)) self.assertEqual(version, res.version) self.assertEqual(msg_type, res.msg_type) self.assertEqual(msg_len, res.msg_len) self.assertEqual(xid, res.xid) self.assertEqual(bytes(buf), bytes(res.buf)) def test_serialize(self): class Datapath(object): ofproto = ofproto # copy to class attribute ofproto_parser = ofproto_v1_0_parser c = OFPHello(Datapath) c.serialize() self.assertEqual(ofproto.OFP_VERSION, c.version) self.assertEqual(ofproto.OFPT_HELLO, c.msg_type) self.assertEqual(0, c.xid) class TestOFPErrorMsg(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPErrorMsg """ def setUp(self): pass def tearDown(self): pass def test_init(self): pass def test_parser(self): version = {'buf': b'\x01', 'val': ofproto.OFP_VERSION} msg_type = {'buf': b'\x01', 'val': ofproto.OFPT_ERROR} msg_len = {'buf': b'\x00\x0c', 'val': ofproto.OFP_ERROR_MSG_SIZE} xid = {'buf': b'\x87\x8b\x26\x7c', 'val': 2274043516} type = {'buf': b'\xab\x3e', 'val': 43838} code = {'buf': b'\x5d\x3c', 'val': 23868} data = b'Error Message.' buf = version['buf'] \ + msg_type['buf'] \ + msg_len['buf'] \ + xid['buf'] \ + type['buf'] \ + code['buf'] \ + data res = OFPErrorMsg.parser(object, version['val'], msg_type['val'], msg_len['val'], xid['val'], buf) self.assertEqual(version['val'], res.version) self.assertEqual(msg_type['val'], res.msg_type) self.assertEqual(msg_len['val'], res.msg_len) self.assertEqual(xid['val'], res.xid) self.assertEqual(type['val'], res.type) self.assertEqual(code['val'], res.code) self.assertEqual(data, res.data) def test_serialize(self): class Datapath(object): ofproto = ofproto # copy to class attribute ofproto_parser = ofproto_v1_0_parser type = 1306 code = 13774 data = b'Error Message.' c = OFPErrorMsg(Datapath) c.type = type c.code = code c.data = data c.serialize() self.assertEqual(ofproto.OFP_VERSION, c.version) self.assertEqual(ofproto.OFPT_ERROR, c.msg_type) self.assertEqual(0, c.xid) fmt = '!' \ + ofproto.OFP_HEADER_PACK_STR.replace('!', '') \ + ofproto.OFP_ERROR_MSG_PACK_STR.replace('!', '') \ + str(len(data)) + 's' res = struct.unpack(fmt, bytes(c.buf)) self.assertEqual(ofproto.OFP_VERSION, res[0]) self.assertEqual(ofproto.OFPT_ERROR, res[1]) self.assertEqual(len(c.buf), res[2]) self.assertEqual(0, res[3]) self.assertEqual(type, res[4]) self.assertEqual(code, res[5]) self.assertEqual(data, res[6]) class TestOFPEchoRequest(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPEchoRequest """ def setUp(self): pass def tearDown(self): pass def test_init(self): pass def test_parser(self): version = {'buf': b'\x01', 'val': ofproto.OFP_VERSION} msg_type = {'buf': b'\x02', 'val': ofproto.OFPT_ECHO_REQUEST} msg_len = {'buf': b'\x00\x08', 'val': ofproto.OFP_HEADER_SIZE} xid = {'buf': b'\x84\x47\xef\x3f', 'val': 2219306815} data = b'Request Message.' buf = version['buf'] \ + msg_type['buf'] \ + msg_len['buf'] \ + xid['buf'] \ + data res = OFPEchoRequest.parser(object, version['val'], msg_type['val'], msg_len['val'], xid['val'], buf) self.assertEqual(version['val'], res.version) self.assertEqual(msg_type['val'], res.msg_type) self.assertEqual(msg_len['val'], res.msg_len) self.assertEqual(xid['val'], res.xid) self.assertEqual(data, res.data) def test_serialize(self): class Datapath(object): ofproto = ofproto # copy to class attribute ofproto_parser = ofproto_v1_0_parser data = b'Request Message.' c = OFPEchoRequest(Datapath) c.data = data c.serialize() self.assertEqual(ofproto.OFP_VERSION, c.version) self.assertEqual(ofproto.OFPT_ECHO_REQUEST, c.msg_type) self.assertEqual(0, c.xid) fmt = '!' \ + ofproto.OFP_HEADER_PACK_STR.replace('!', '') \ + str(len(data)) + 's' res = struct.unpack(fmt, bytes(c.buf)) self.assertEqual(ofproto.OFP_VERSION, res[0]) self.assertEqual(ofproto.OFPT_ECHO_REQUEST, res[1]) self.assertEqual(len(c.buf), res[2]) self.assertEqual(0, res[3]) self.assertEqual(data, res[4]) class TestOFPEchoReply(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPEchoReply """ def setUp(self): pass def tearDown(self): pass def test_init(self): pass def test_parser(self): version = {'buf': b'\x01', 'val': ofproto.OFP_VERSION} msg_type = {'buf': b'\x03', 'val': ofproto.OFPT_ECHO_REPLY} msg_len = {'buf': b'\x00\x08', 'val': ofproto.OFP_HEADER_SIZE} xid = {'buf': b'\x6e\x21\x3e\x62', 'val': 1847672418} data = b'Reply Message.' buf = version['buf'] \ + msg_type['buf'] \ + msg_len['buf'] \ + xid['buf'] \ + data res = OFPEchoReply.parser(object, version['val'], msg_type['val'], msg_len['val'], xid['val'], buf) self.assertEqual(version['val'], res.version) self.assertEqual(msg_type['val'], res.msg_type) self.assertEqual(msg_len['val'], res.msg_len) self.assertEqual(xid['val'], res.xid) self.assertEqual(data, res.data) def test_serialize(self): class Datapath(object): ofproto = ofproto # copy to class attribute ofproto_parser = ofproto_v1_0_parser data = b'Reply Message.' c = OFPEchoReply(Datapath) c.data = data c.serialize() self.assertEqual(ofproto.OFP_VERSION, c.version) self.assertEqual(ofproto.OFPT_ECHO_REPLY, c.msg_type) self.assertEqual(0, c.xid) fmt = '!' \ + ofproto.OFP_HEADER_PACK_STR.replace('!', '') \ + str(len(data)) + 's' res = struct.unpack(fmt, bytes(c.buf)) self.assertEqual(ofproto.OFP_VERSION, res[0]) self.assertEqual(ofproto.OFPT_ECHO_REPLY, res[1]) self.assertEqual(len(c.buf), res[2]) self.assertEqual(0, res[3]) self.assertEqual(data, res[4]) class TestOFPVendor(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPVendor """ def setUp(self): pass def tearDown(self): pass def test_init(self): pass def test_parser(self): version = {'buf': b'\x01', 'val': ofproto.OFP_VERSION} msg_type = {'buf': b'\x04', 'val': ofproto.OFPT_VENDOR} msg_len = {'buf': b'\x00\x0c', 'val': ofproto.OFP_VENDOR_HEADER_SIZE} xid = {'buf': b'\x05\x45\xdf\x18', 'val': 88465176} vendor = {'buf': b'\x53\xea\x25\x3e', 'val': 1407853886} data = b'Vendor Message.' buf = version['buf'] \ + msg_type['buf'] \ + msg_len['buf'] \ + xid['buf'] \ + vendor['buf'] \ + data res = OFPVendor.parser(object, version['val'], msg_type['val'], msg_len['val'], xid['val'], buf) self.assertEqual(version['val'], res.version) self.assertEqual(msg_type['val'], res.msg_type) self.assertEqual(msg_len['val'], res.msg_len) self.assertEqual(xid['val'], res.xid) self.assertEqual(vendor['val'], res.vendor) self.assertEqual(data, res.data) def test_serialize(self): class Datapath(object): ofproto = ofproto # copy to class attribute ofproto_parser = ofproto_v1_0_parser vendor = {'buf': b'\x38\x4b\xf9\x6c', 'val': 944503148} data = b'Reply Message.' c = OFPVendor(Datapath) c.vendor = vendor['val'] c.data = data c.serialize() self.assertEqual(ofproto.OFP_VERSION, c.version) self.assertEqual(ofproto.OFPT_VENDOR, c.msg_type) self.assertEqual(0, c.xid) self.assertEqual(vendor['val'], c.vendor) fmt = '!' \ + ofproto.OFP_HEADER_PACK_STR.replace('!', '') \ + ofproto.OFP_VENDOR_HEADER_PACK_STR.replace('!', '') \ + str(len(data)) + 's' res = struct.unpack(fmt, bytes(c.buf)) self.assertEqual(ofproto.OFP_VERSION, res[0]) self.assertEqual(ofproto.OFPT_VENDOR, res[1]) self.assertEqual(len(c.buf), res[2]) self.assertEqual(0, res[3]) self.assertEqual(vendor['val'], res[4]) self.assertEqual(data, res[5]) # class TestNXTRequest(unittest.TestCase): class TestNiciraHeader(unittest.TestCase): """ Test case for ofproto_v1_0_parser.NiciraHeader """ def setUp(self): pass def tearDown(self): pass def test_init(self): subtype = ofproto.NXT_FLOW_MOD_TABLE_ID c = NiciraHeader(object, subtype) self.assertEqual(subtype, c.subtype) def test_parser(self): # Not used. pass def test_serialize(self): class Datapath(object): ofproto = ofproto # copy to class attribute ofproto_parser = ofproto_v1_0_parser data = b'Reply Message.' subtype = ofproto.NXT_FLOW_MOD_TABLE_ID c = NiciraHeader(Datapath, subtype) c.data = data c.serialize() self.assertEqual(ofproto.OFP_VERSION, c.version) self.assertEqual(ofproto.OFPT_VENDOR, c.msg_type) self.assertEqual(0, c.xid) self.assertEqual(ofproto_common.NX_EXPERIMENTER_ID, c.vendor) fmt = '!' \ + ofproto.OFP_HEADER_PACK_STR.replace('!', '') \ + ofproto.NICIRA_HEADER_PACK_STR.replace('!', '') \ + str(len(data)) + 's' res = struct.unpack(fmt, bytes(c.buf)) self.assertEqual(ofproto.OFP_VERSION, res[0]) self.assertEqual(ofproto.OFPT_VENDOR, res[1]) self.assertEqual(len(c.buf), res[2]) self.assertEqual(0, res[3]) self.assertEqual(ofproto_common.NX_EXPERIMENTER_ID, res[4]) self.assertEqual(subtype, res[5]) self.assertEqual(data, res[6]) class TestNXTSetFlowFormat(unittest.TestCase): """ Test case for ofproto_v1_0_parser.NXTSetFlowFormat """ def setUp(self): pass def tearDown(self): pass def test_init(self): flow_format = {'buf': b'\xdc\x6b\xf5\x24', 'val': 3698062628} c = NXTSetFlowFormat(object, flow_format['val']) self.assertEqual(flow_format['val'], c.format) def test_parser(self): # Not used. pass def test_serialize(self): class Datapath(object): ofproto = ofproto # copy to class attribute ofproto_parser = ofproto_v1_0_parser flow_format = {'buf': b'\x5a\x4e\x59\xad', 'val': 1515084205} c = NXTSetFlowFormat(Datapath, flow_format['val']) c.serialize() self.assertEqual(ofproto.OFP_VERSION, c.version) self.assertEqual(ofproto.OFPT_VENDOR, c.msg_type) self.assertEqual(0, c.xid) self.assertEqual(ofproto_common.NX_EXPERIMENTER_ID, c.vendor) fmt = '!' \ + ofproto.OFP_HEADER_PACK_STR.replace('!', '') \ + ofproto.NICIRA_HEADER_PACK_STR.replace('!', '') \ + ofproto.NX_SET_FLOW_FORMAT_PACK_STR.replace('!', '') res = struct.unpack(fmt, bytes(c.buf)) self.assertEqual(ofproto.OFP_VERSION, res[0]) self.assertEqual(ofproto.OFPT_VENDOR, res[1]) self.assertEqual(len(c.buf), res[2]) self.assertEqual(0, res[3]) self.assertEqual(ofproto_common.NX_EXPERIMENTER_ID, res[4]) self.assertEqual(ofproto.NXT_SET_FLOW_FORMAT, res[5]) self.assertEqual(flow_format['val'], res[6]) class TestNXTFlowMod(unittest.TestCase): """ Test case for ofproto_v1_0_parser.NXTFlowMod """ # NX_FLOW_MOD_PACK_STR # '!Q4HI3H6x'...cokkie, command, idle_timeout, head_timeout, # priority, buffer_id, out_port, flags, rule, zfill cookie = {'buf': b'\x04\x56\x27\xad\xbd\x43\xd6\x83', 'val': 312480851306993283} command = {'buf': b'\x61\xaa', 'val': 25002} idle_timeout = {'buf': b'\x4e\xff', 'val': 20223} hard_timeout = {'buf': b'\x80\x16', 'val': 32790} priority = {'buf': b'\x70\x5f', 'val': 28767} buffer_id = {'buf': b'\x7b\x97\x3a\x09', 'val': 2073508361} out_port = {'buf': b'\x11\x7d', 'val': 4477} flags = {'buf': b'\x5c\xb9', 'val': 23737} rule = nx_match.ClsRule() zfill = b'\x00' * 6 port = {'buf': b'\x2a\xe0', 'val': 10976} actions = [OFPActionOutput(port['val'])] def _get_obj(self, append_action=False): class Datapath(object): ofproto = ofproto # copy to class attribute ofproto_parser = ofproto_v1_0_parser actions = None if append_action: actions = self.actions c = NXTFlowMod(Datapath, self.cookie['val'], self.command['val'], self.idle_timeout['val'], self.hard_timeout['val'], self.priority['val'], self.buffer_id['val'], self.out_port['val'], self.flags['val'], self.rule, actions) return c def setUp(self): pass def tearDown(self): pass def test_init(self): c = self._get_obj() self.assertEqual(self.cookie['val'], c.cookie) self.assertEqual(self.command['val'], c.command) self.assertEqual(self.idle_timeout['val'], c.idle_timeout) self.assertEqual(self.hard_timeout['val'], c.hard_timeout) self.assertEqual(self.priority['val'], c.priority) self.assertEqual(self.buffer_id['val'], c.buffer_id) self.assertEqual(self.out_port['val'], c.out_port) self.assertEqual(self.flags['val'], c.flags) self.assertEqual(self.rule.__hash__(), c.rule.__hash__()) def test_init_append_actions(self): c = self._get_obj(True) action = c.actions[0] self.assertEqual(ofproto.OFPAT_OUTPUT, action.type) self.assertEqual(ofproto.OFP_ACTION_OUTPUT_SIZE, action.len) self.assertEqual(self.port['val'], action.port) def test_parser(self): # Not used. pass def test_serialize(self): c = self._get_obj() c.serialize() self.assertEqual(ofproto.OFP_VERSION, c.version) self.assertEqual(ofproto.OFPT_VENDOR, c.msg_type) self.assertEqual(0, c.xid) self.assertEqual(ofproto_common.NX_EXPERIMENTER_ID, c.vendor) fmt = '!' \ + ofproto.OFP_HEADER_PACK_STR.replace('!', '') \ + ofproto.NICIRA_HEADER_PACK_STR.replace('!', '') \ + ofproto.NX_FLOW_MOD_PACK_STR.replace('!', '') res = struct.unpack(fmt, bytes(c.buf)) self.assertEqual(ofproto.OFP_VERSION, res[0]) self.assertEqual(ofproto.OFPT_VENDOR, res[1]) self.assertEqual(len(c.buf), res[2]) self.assertEqual(0, res[3]) self.assertEqual(ofproto_common.NX_EXPERIMENTER_ID, res[4]) self.assertEqual(ofproto.NXT_FLOW_MOD, res[5]) self.assertEqual(self.cookie['val'], res[6]) self.assertEqual(self.command['val'], res[7]) self.assertEqual(self.idle_timeout['val'], res[8]) self.assertEqual(self.hard_timeout['val'], res[9]) self.assertEqual(self.priority['val'], res[10]) self.assertEqual(self.buffer_id['val'], res[11]) self.assertEqual(self.out_port['val'], res[12]) self.assertEqual(self.flags['val'], res[13]) def test_serialize_append_actions(self): c = self._get_obj(True) c.serialize() self.assertEqual(ofproto.OFP_VERSION, c.version) self.assertEqual(ofproto.OFPT_VENDOR, c.msg_type) self.assertEqual(0, c.xid) self.assertEqual(ofproto_common.NX_EXPERIMENTER_ID, c.vendor) fmt = '!' \ + ofproto.OFP_HEADER_PACK_STR.replace('!', '') \ + ofproto.NICIRA_HEADER_PACK_STR.replace('!', '') \ + ofproto.NX_FLOW_MOD_PACK_STR.replace('!', '') \ + ofproto.OFP_ACTION_OUTPUT_PACK_STR.replace('!', '') res = struct.unpack(fmt, bytes(c.buf)) self.assertEqual(ofproto.OFP_VERSION, res[0]) self.assertEqual(ofproto.OFPT_VENDOR, res[1]) self.assertEqual(len(c.buf), res[2]) self.assertEqual(0, res[3]) self.assertEqual(ofproto_common.NX_EXPERIMENTER_ID, res[4]) self.assertEqual(ofproto.NXT_FLOW_MOD, res[5]) self.assertEqual(self.cookie['val'], res[6]) self.assertEqual(self.command['val'], res[7]) self.assertEqual(self.idle_timeout['val'], res[8]) self.assertEqual(self.hard_timeout['val'], res[9]) self.assertEqual(self.priority['val'], res[10]) self.assertEqual(self.buffer_id['val'], res[11]) self.assertEqual(self.out_port['val'], res[12]) self.assertEqual(self.flags['val'], res[13]) # action self.assertEqual(0, res[14]) self.assertEqual(ofproto.OFPAT_OUTPUT, res[15]) self.assertEqual(ofproto.OFP_ACTION_OUTPUT_SIZE, res[16]) self.assertEqual(self.port['val'], res[17]) self.assertEqual(0xffe5, res[18]) class TestNXTRoleRequest(unittest.TestCase): """ Test case for ofproto_v1_0_parser.NXTRoleRequest """ # NX_ROLE_PACK_STR # '!I'...role role = {'buf': b'\x62\x81\x27\x61', 'val': 1652631393} class Datapath(object): ofproto = ofproto # copy to class attribute ofproto_parser = ofproto_v1_0_parser c = NXTRoleRequest(Datapath, role['val']) def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(self.role['val'], self.c.role) def test_parser(self): # Not used. pass def test_serialize(self): self.c.serialize() self.assertEqual(ofproto.OFP_VERSION, self.c.version) self.assertEqual(ofproto.OFPT_VENDOR, self.c.msg_type) self.assertEqual(0, self.c.xid) self.assertEqual(ofproto_common.NX_EXPERIMENTER_ID, self.c.vendor) fmt = '!' \ + ofproto.OFP_HEADER_PACK_STR.replace('!', '') \ + ofproto.NICIRA_HEADER_PACK_STR.replace('!', '') \ + ofproto.NX_ROLE_PACK_STR.replace('!', '') res = struct.unpack(fmt, bytes(self.c.buf)) self.assertEqual(ofproto.OFP_VERSION, res[0]) self.assertEqual(ofproto.OFPT_VENDOR, res[1]) self.assertEqual(len(self.c.buf), res[2]) self.assertEqual(0, res[3]) self.assertEqual(ofproto_common.NX_EXPERIMENTER_ID, res[4]) self.assertEqual(ofproto.NXT_ROLE_REQUEST, res[5]) self.assertEqual(self.role['val'], res[6]) class TestNXTFlowModTableId(unittest.TestCase): """ Test case for ofproto_v1_0_parser.NXTFlowModTableId """ # NX_FLOW_MOD_TABLE_ID_PACK_STR # '!B7x'...set_, zfill set_ = {'buf': b'\x71', 'val': 113} zfill = b'\x00' * 7 class Datapath(object): ofproto = ofproto # copy to class attribute ofproto_parser = ofproto_v1_0_parser c = NXTFlowModTableId(Datapath, set_['val']) def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(self.set_['val'], self.c.set) def test_parser(self): # Not used. pass def test_serialize(self): self.c.serialize() self.assertEqual(ofproto.OFP_VERSION, self.c.version) self.assertEqual(ofproto.OFPT_VENDOR, self.c.msg_type) self.assertEqual(0, self.c.xid) self.assertEqual(ofproto_common.NX_EXPERIMENTER_ID, self.c.vendor) fmt = '!' \ + ofproto.OFP_HEADER_PACK_STR.replace('!', '') \ + ofproto.NICIRA_HEADER_PACK_STR.replace('!', '') \ + ofproto.NX_FLOW_MOD_TABLE_ID_PACK_STR.replace('!', '') res = struct.unpack(fmt, bytes(self.c.buf)) self.assertEqual(ofproto.OFP_VERSION, res[0]) self.assertEqual(ofproto.OFPT_VENDOR, res[1]) self.assertEqual(len(self.c.buf), res[2]) self.assertEqual(0, res[3]) self.assertEqual(ofproto_common.NX_EXPERIMENTER_ID, res[4]) self.assertEqual(ofproto.NXT_FLOW_MOD_TABLE_ID, res[5]) self.assertEqual(self.set_['val'], res[6]) class TestOFPSwitchFeatures(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPSwitchFeatures """ class Datapath(object): ofproto = ofproto # copy to class attribute ofproto_parser = ofproto_v1_0_parser c = OFPSwitchFeatures(Datapath) def setUp(self): pass def tearDown(self): pass def test_init(self): pass def test_parser(self): version = {'buf': b'\x01', 'val': ofproto.OFP_VERSION} msg_type = {'buf': b'\x06', 'val': ofproto.OFPT_FEATURES_REPLY} msg_len_val = ofproto.OFP_SWITCH_FEATURES_SIZE \ + ofproto.OFP_PHY_PORT_SIZE msg_len = {'buf': b'\x00\x4c', 'val': msg_len_val} xid = {'buf': b'\xcc\x0a\x41\xd4', 'val': 3423224276} # OFP_SWITCH_FEATURES_PACK_STR # '!QIB3xII'...datapath_id, n_buffers, n_tables, # zfill, capabilities, actions datapath_id = {'buf': b'\x11\xa3\x72\x63\x61\xde\x39\x81', 'val': 1270985291017894273} n_buffers = {'buf': b'\x80\x14\xd7\xf6', 'val': 2148849654} n_tables = {'buf': b'\xe4', 'val': 228} zfill = b'\x00' * 3 capabilities = {'buf': b'\x69\x4f\xe4\xc2', 'val': 1766843586} actions = {'buf': b'\x78\x06\xd9\x0c', 'val': 2013714700} # OFP_PHY_PORT_PACK_STR # '!H6s16sIIIIII'... port_no, hw_addr, name, config, state # curr, advertised, supported, peer port_no = {'buf': b'\xe7\x6b', 'val': 59243} hw_addr = '3c:d1:2b:8d:3f:d6' name = b'name'.ljust(16) config = {'buf': b'\x84\xb6\x8c\x53', 'val': 2226555987} state = {'buf': b'\x64\x07\xfb\xc9', 'val': 1678244809} curr = {'buf': b'\xa9\xe8\x0a\x2b', 'val': 2850556459} advertised = {'buf': b'\x78\xb9\x7b\x72', 'val': 2025421682} supported = {'buf': b'\x7e\x65\x68\xad', 'val': 2120575149} peer = {'buf': b'\xa4\x5b\x8b\xed', 'val': 2757463021} buf = version['buf'] \ + msg_type['buf'] \ + msg_len['buf'] \ + xid['buf'] \ + datapath_id['buf'] \ + n_buffers['buf'] \ + n_tables['buf'] \ + zfill \ + capabilities['buf'] \ + actions['buf'] \ + port_no['buf'] \ + addrconv.mac.text_to_bin(hw_addr) \ + name \ + config['buf'] \ + state['buf'] \ + curr['buf'] \ + advertised['buf'] \ + supported['buf'] \ + peer['buf'] res = OFPSwitchFeatures.parser(object, version['val'], msg_type['val'], msg_len['val'], xid['val'], buf) self.assertEqual(version['val'], res.version) self.assertEqual(msg_type['val'], res.msg_type) self.assertEqual(msg_len['val'], res.msg_len) self.assertEqual(xid['val'], res.xid) self.assertEqual(datapath_id['val'], res.datapath_id) self.assertEqual(n_buffers['val'], res.n_buffers) self.assertEqual(n_tables['val'], res.n_tables) self.assertEqual(capabilities['val'], res.capabilities) self.assertEqual(actions['val'], res.actions) # port port = res.ports[port_no['val']] self.assertEqual(port_no['val'], port.port_no) self.assertEqual(hw_addr, hw_addr) self.assertEqual(name, port.name) self.assertEqual(config['val'], port.config) self.assertEqual(state['val'], port.state) self.assertEqual(curr['val'], port.curr) self.assertEqual(advertised['val'], port.advertised) self.assertEqual(supported['val'], port.supported) self.assertEqual(peer['val'], port.peer) def test_serialize(self): # Not used. pass class TestOFPPortStatus(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPPortStatus """ class Datapath(object): ofproto = ofproto # copy to class attribute ofproto_parser = ofproto_v1_0_parser c = OFPPortStatus(Datapath) def setUp(self): pass def tearDown(self): pass def test_init(self): pass def test_parser(self): version = {'buf': b'\x01', 'val': ofproto.OFP_VERSION} msg_type = {'buf': b'\x0c', 'val': ofproto.OFPT_PORT_STATUS} msg_len = {'buf': b'\x00\x40', 'val': ofproto.OFP_PORT_STATUS_SIZE} xid = {'buf': b'\x06\x27\x8b\x7b', 'val': 103254907} # OFP_PORT_STATUS_PACK_STR # '!B7xH6s16sIIIIII'...reason, zfill, port_no, hw_addr, # name, config, state, curr, # advertised, supported, peer reason = {'buf': b'\x71', 'val': 113} zfill = b'\x00' * 7 port_no = {'buf': b'\x48\xd8', 'val': 18648} hw_addr = '41:f7:a3:52:8f:6b' name = b'name'.ljust(16) config = {'buf': b'\xae\x73\x90\xec', 'val': 2926809324} state = {'buf': b'\x41\x37\x32\x1d', 'val': 1094136349} curr = {'buf': b'\xa9\x47\x13\x2c', 'val': 2840007468} advertised = {'buf': b'\xce\x6b\x4a\x87', 'val': 3463137927} supported = {'buf': b'\xb8\x06\x65\xa1', 'val': 3087426977} peer = {'buf': b'\x6a\x11\x52\x39', 'val': 1779520057} buf = version['buf'] \ + msg_type['buf'] \ + msg_len['buf'] \ + xid['buf'] \ + reason['buf'] \ + zfill \ + port_no['buf'] \ + addrconv.mac.text_to_bin(hw_addr) \ + name \ + config['buf'] \ + state['buf'] \ + curr['buf'] \ + advertised['buf'] \ + supported['buf'] \ + peer['buf'] res = OFPPortStatus.parser(object, version['val'], msg_type['val'], msg_len['val'], xid['val'], buf) self.assertEqual(version['val'], res.version) self.assertEqual(msg_type['val'], res.msg_type) self.assertEqual(msg_len['val'], res.msg_len) self.assertEqual(xid['val'], res.xid) self.assertEqual(reason['val'], res.reason) # desc desc = res.desc self.assertEqual(port_no['val'], desc.port_no) self.assertEqual(hw_addr, desc.hw_addr) self.assertEqual(name, desc.name) self.assertEqual(config['val'], desc.config) self.assertEqual(state['val'], desc.state) self.assertEqual(curr['val'], desc.curr) self.assertEqual(advertised['val'], desc.advertised) self.assertEqual(supported['val'], desc.supported) self.assertEqual(peer['val'], desc.peer) def test_serialize(self): # Not used. pass class TestOFPPacketIn(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPPacketIn """ class Datapath(object): ofproto = ofproto # copy to class attribute ofproto_parser = ofproto_v1_0_parser c = OFPPacketIn(Datapath) def setUp(self): pass def tearDown(self): pass def test_init(self): pass def _test_parser(self, padding=False): version = {'buf': b'\x01', 'val': ofproto.OFP_VERSION} msg_type = {'buf': b'\x0a', 'val': ofproto.OFPT_PACKET_IN} msg_len = {'buf': b'\x00\x14', 'val': ofproto.OFP_PACKET_IN_SIZE} xid = {'buf': b'\xd0\x23\x8c\x34', 'val': 3491990580} # OFP_PACKET_IN_PACK_STR # '!IHHBx2x'...buffer_id, total_len, # in_port, reason, zfill, data buffer_id = {'buf': b'\xae\x73\x90\xec', 'val': 2926809324} total_len = {'buf': b'\x00\x10', 'val': 16} in_port = {'buf': b'\x08\x42', 'val': 2114} reason = {'buf': b'\x43', 'val': 67} zfill = b'\x00' * 1 if padding: data = b'PACKET IN'.ljust(20) else: data = b'PACKET IN'.ljust(16) buf = version['buf'] \ + msg_type['buf'] \ + msg_len['buf'] \ + xid['buf'] \ + buffer_id['buf'] \ + total_len['buf'] \ + in_port['buf'] \ + reason['buf'] \ + zfill \ + data res = OFPPacketIn.parser(object, version['val'], msg_type['val'], msg_len['val'], xid['val'], buf) self.assertEqual(version['val'], res.version) self.assertEqual(msg_type['val'], res.msg_type) self.assertEqual(msg_len['val'], res.msg_len) self.assertEqual(xid['val'], res.xid) self.assertEqual(buffer_id['val'], res.buffer_id) self.assertEqual(total_len['val'], res.total_len) self.assertEqual(in_port['val'], res.in_port) self.assertEqual(reason['val'], res.reason) self.assertEqual(data[0:16], res.data) return True def test_parser(self): self.assertTrue(self._test_parser()) def test_parser_padding(self): self.assertTrue(self._test_parser(True)) def test_serialize(self): # Not used. pass class TestOFPGetConfigReply(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPGetConfigReply """ class Datapath(object): ofproto = ofproto # copy to class attribute ofproto_parser = ofproto_v1_0_parser c = OFPGetConfigReply(Datapath) def setUp(self): pass def tearDown(self): pass def test_init(self): pass def test_parser(self): version = {'buf': b'\x01', 'val': ofproto.OFP_VERSION} msg_type = {'buf': b'\x0a', 'val': ofproto.OFPT_GET_CONFIG_REPLY} msg_len = {'buf': b'\x00\x14', 'val': ofproto.OFP_SWITCH_CONFIG_SIZE} xid = {'buf': b'\x94\xc4\xd2\xcd', 'val': 2495926989} # OFP_SWITCH_CONFIG_PACK_STR # '!HH'...flags, miss_send_len flags = {'buf': b'\xa0\xe2', 'val': 41186} miss_send_len = {'buf': b'\x36\x0e', 'val': 13838} buf = version['buf'] \ + msg_type['buf'] \ + msg_len['buf'] \ + xid['buf'] \ + flags['buf'] \ + miss_send_len['buf'] res = OFPGetConfigReply.parser(object, version['val'], msg_type['val'], msg_len['val'], xid['val'], buf) self.assertEqual(version['val'], res.version) self.assertEqual(msg_type['val'], res.msg_type) self.assertEqual(msg_len['val'], res.msg_len) self.assertEqual(xid['val'], res.xid) self.assertEqual(flags['val'], res.flags) self.assertEqual(miss_send_len['val'], res.miss_send_len) def test_serialize(self): # Not used. pass class TestOFPBarrierReply(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPBarrierReply """ class Datapath(object): ofproto = ofproto # copy to class attribute ofproto_parser = ofproto_v1_0_parser c = OFPBarrierReply(Datapath) def setUp(self): pass def tearDown(self): pass def test_init(self): pass def test_parser(self): version = {'buf': b'\x01', 'val': ofproto.OFP_VERSION} msg_type = {'buf': b'\x13', 'val': ofproto.OFPT_BARRIER_REPLY} msg_len = {'buf': b'\x00\x08', 'val': ofproto.OFP_HEADER_SIZE} xid = {'buf': b'\x66\xc4\xc3\xac', 'val': 1724171180} buf = version['buf'] \ + msg_type['buf'] \ + msg_len['buf'] \ + xid['buf'] res = OFPBarrierReply.parser(object, version['val'], msg_type['val'], msg_len['val'], xid['val'], buf) self.assertEqual(version['val'], res.version) self.assertEqual(msg_type['val'], res.msg_type) self.assertEqual(msg_len['val'], res.msg_len) self.assertEqual(xid['val'], res.xid) def test_serialize(self): # Not used. pass class TestOFPFlowRemoved(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPFlowRemoved """ class Datapath(object): ofproto = ofproto # copy to class attribute ofproto_parser = ofproto_v1_0_parser c = OFPFlowRemoved(Datapath) def setUp(self): pass def tearDown(self): pass def test_init(self): pass def test_parser(self): version = {'buf': b'\x01', 'val': ofproto.OFP_VERSION} msg_type = {'buf': b'\x0a', 'val': ofproto.OFPT_FLOW_REMOVED} msg_len = {'buf': b'\x00\x14', 'val': ofproto.OFP_FLOW_REMOVED_SIZE} xid = {'buf': b'\x94\xc4\xd2\xcd', 'val': 2495926989} buf = version['buf'] \ + msg_type['buf'] \ + msg_len['buf'] \ + xid['buf'] # OFP_MATCH_PACK_STR # '!IH6s6sHBxHBB2xIIHH'...wildcards, in_port, dl_src, dl_dst, dl_vlan, # dl_vlan_pcp, dl_type, nw_tos, nw_proto, # nw_src, nw_dst, tp_src, tp_dst wildcards = {'buf': b'\xd2\x71\x25\x23', 'val': 3530630435} in_port = {'buf': b'\x37\x8b', 'val': 14219} dl_src = b'\x7f\x85\xc4\x70\x12\xda' dl_dst = b'\x0a\x51\x17\x58\xb0\xbb' dl_vlan = {'buf': b'\xc1\xf9', 'val': 49657} dl_vlan_pcp = {'buf': b'\x79', 'val': 121} zfill0 = b'\x00' dl_type = {'buf': b'\xa6\x9e', 'val': 42654} nw_tos = {'buf': b'\xde', 'val': 222} nw_proto = {'buf': b'\xe5', 'val': 229} zfil11 = b'\x00' * 2 nw_src = {'buf': b'\x1b\x6d\x8d\x4b', 'val': 460164427} nw_dst = {'buf': b'\xab\x25\xe1\x20', 'val': 2871386400} tp_src = {'buf': b'\xd5\xc3', 'val': 54723} tp_dst = {'buf': b'\x78\xb9', 'val': 30905} buf += wildcards['buf'] \ + in_port['buf'] \ + dl_src \ + dl_dst \ + dl_vlan['buf'] \ + dl_vlan_pcp['buf'] \ + zfill0 \ + dl_type['buf'] \ + nw_tos['buf'] \ + nw_proto['buf'] \ + zfil11 \ + nw_src['buf'] \ + nw_dst['buf'] \ + tp_src['buf'] \ + tp_dst['buf'] # OFP_FLOW_REMOVED_PACK_STR0 # '!QHBxIIH2xQQ'...cookie, priority, reason, zfill, # duration_sec, duration_nsec, idle_timeout, # zfill, packet_count, byte_count cookie = {'buf': b'\x02\x79\xba\x00\xef\xab\xee\x44', 'val': 178378173441633860} priority = {'buf': b'\x02\xce', 'val': 718} reason = {'buf': b'\xa9', 'val': 169} zfill0 = b'\x00' * 1 duration_sec = {'buf': b'\x86\x24\xa3\xba', 'val': 2250548154} duration_nsec = {'buf': b'\x94\x94\xc2\x23', 'val': 2492776995} idle_timeout = {'buf': b'\xeb\x7c', 'val': 60284} zfill1 = b'\x00' * 2 packet_count = {'buf': b'\x5a\x0d\xf2\x03\x8e\x0a\xbb\x8d', 'val': 6489108735192644493} byte_count = {'buf': b'\x65\xc8\xd3\x72\x51\xb5\xbb\x7c', 'val': 7334344481123449724} buf += cookie['buf'] \ + priority['buf'] \ + reason['buf'] \ + zfill0 \ + duration_sec['buf'] \ + duration_nsec['buf'] \ + idle_timeout['buf'] \ + zfill1 \ + packet_count['buf'] \ + byte_count['buf'] res = OFPFlowRemoved.parser(object, version['val'], msg_type['val'], msg_len['val'], xid['val'], buf) self.assertEqual(version['val'], res.version) self.assertEqual(msg_type['val'], res.msg_type) self.assertEqual(msg_len['val'], res.msg_len) self.assertEqual(xid['val'], res.xid) self.assertEqual(cookie['val'], res.cookie) self.assertEqual(priority['val'], res.priority) self.assertEqual(reason['val'], res.reason) self.assertEqual(duration_sec['val'], res.duration_sec) self.assertEqual(duration_nsec['val'], res.duration_nsec) self.assertEqual(idle_timeout['val'], res.idle_timeout) self.assertEqual(packet_count['val'], res.packet_count) self.assertEqual(byte_count['val'], res.byte_count) # match match = res.match self.assertEqual(wildcards['val'], match.wildcards) self.assertEqual(in_port['val'], match.in_port) self.assertEqual(dl_src, match.dl_src) self.assertEqual(dl_dst, match.dl_dst) self.assertEqual(dl_vlan['val'], match.dl_vlan) self.assertEqual(dl_vlan_pcp['val'], match.dl_vlan_pcp) self.assertEqual(dl_type['val'], match.dl_type) self.assertEqual(nw_tos['val'], match.nw_tos) self.assertEqual(nw_proto['val'], match.nw_proto) self.assertEqual(nw_src['val'], match.nw_src) self.assertEqual(nw_dst['val'], match.nw_dst) self.assertEqual(tp_src['val'], match.tp_src) self.assertEqual(tp_dst['val'], match.tp_dst) def test_serialize(self): # Not used. pass class TestOFPQueueGetConfigReply(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPQueueGetConfigReply """ class Datapath(object): ofproto = ofproto # copy to class attribute ofproto_parser = ofproto_v1_0_parser c = OFPQueueGetConfigReply(Datapath) def setUp(self): pass def tearDown(self): pass def test_init(self): pass def test_parser(self): version = {'buf': b'\x01', 'val': ofproto.OFP_VERSION} msg_type = {'buf': b'\x0a', 'val': ofproto.OFPT_QUEUE_GET_CONFIG_REPLY} msg_len_val = ofproto.OFP_QUEUE_GET_CONFIG_REPLY_SIZE \ + ofproto.OFP_PACKET_QUEUE_SIZE msg_len = {'buf': b'\x00\x14', 'val': msg_len_val} xid = {'buf': b'\x94\xc4\xd2\xcd', 'val': 2495926989} buf = version['buf'] \ + msg_type['buf'] \ + msg_len['buf'] \ + xid['buf'] # OFP_QUEUE_GET_CONFIG_REPLY_PACK_STR # '!H6x'...port, zfill port = {'buf': b'\xfe\x66', 'val': 65126} zfill = b'\x00' * 6 buf += port['buf'] \ + zfill # OFP_PACKET_QUEUE_PQCK_STR # '!IH2x'...queue_id, len_, zfill queue_id = {'buf': b'\x4d\x4b\x3a\xd1', 'val': 1296775889} len_ = {'buf': b'\x00\x08', 'val': ofproto.OFP_QUEUE_PROP_HEADER_SIZE} zfill = b'\x00' * 2 buf += queue_id['buf'] \ + len_['buf'] \ + zfill res = OFPQueueGetConfigReply.parser(object, version['val'], msg_type['val'], msg_len['val'], xid['val'], buf) self.assertEqual(version['val'], res.version) self.assertEqual(msg_type['val'], res.msg_type) self.assertEqual(msg_len['val'], res.msg_len) self.assertEqual(xid['val'], res.xid) self.assertEqual(port['val'], res.port) # queue queue = res.queues[0] self.assertEqual(queue_id['val'], queue.queue_id) self.assertEqual(len_['val'], queue.len) def test_serialize(self): # Not used. pass class TestOFPDescStatsReply(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPDescStatsReply """ class Datapath(object): ofproto = ofproto # copy to class attribute ofproto_parser = ofproto_v1_0_parser c = OFPDescStatsReply(Datapath) def setUp(self): pass def tearDown(self): pass def test_init(self): pass def test_parser(self): version = {'buf': b'\x01', 'val': ofproto.OFP_VERSION} msg_type = {'buf': b'\x11', 'val': ofproto.OFPT_STATS_REPLY} msg_len_val = ofproto.OFP_STATS_MSG_SIZE \ + ofproto.OFP_DESC_STATS_SIZE msg_len = {'buf': b'\x04\x38', 'val': msg_len_val} xid = {'buf': b'\x94\xc4\xd2\xcd', 'val': 2495926989} buf = version['buf'] \ + msg_type['buf'] \ + msg_len['buf'] \ + xid['buf'] # OFP_STATS_MSG_PACK_STR # '!HH'...type_, flags type_ = {'buf': b'\x00\x00', 'val': ofproto.OFPST_DESC} flags = {'buf': b'\x30\xd9', 'val': 12505} buf += type_['buf'] \ + flags['buf'] # stats_type_cls = OFPDescStats # OFP_DESC_STATS_PACK_STR # '!256s256s256s32s256s'...mfr_desc, hw_desc, sw_desc, # serial_num, dp_desc mfr_desc = b'mfr_desc'.ljust(256) hw_desc = b'hw_desc'.ljust(256) sw_desc = b'sw_desc'.ljust(256) serial_num = b'serial_num'.ljust(32) dp_desc = b'dp_desc'.ljust(256) buf += mfr_desc \ + hw_desc \ + sw_desc \ + serial_num \ + dp_desc res = OFPDescStatsReply.parser(object, version['val'], msg_type['val'], msg_len['val'], xid['val'], buf) self.assertEqual(version['val'], res.version) self.assertEqual(msg_type['val'], res.msg_type) self.assertEqual(msg_len['val'], res.msg_len) self.assertEqual(xid['val'], res.xid) self.assertEqual(type_['val'], res.type) self.assertEqual(flags['val'], res.flags) # body body = res.body self.assertEqual(mfr_desc, body.mfr_desc) self.assertEqual(hw_desc, body.hw_desc) self.assertEqual(sw_desc, body.sw_desc) self.assertEqual(serial_num, body.serial_num) self.assertEqual(dp_desc, body.dp_desc) def test_serialize(self): # Not used. pass class TestOFPFlowStatsReply(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPFlowStatsReply """ class Datapath(object): ofproto = ofproto # copy to class attribute ofproto_parser = ofproto_v1_0_parser c = OFPFlowStatsReply(Datapath) def setUp(self): pass def tearDown(self): pass def test_init(self): pass def test_parser(self): version = {'buf': b'\x01', 'val': ofproto.OFP_VERSION} msg_type = {'buf': b'\x11', 'val': ofproto.OFPT_STATS_REPLY} msg_len_val = ofproto.OFP_STATS_MSG_SIZE \ + ofproto.OFP_FLOW_STATS_SIZE msg_len = {'buf': b'\x00\x64', 'val': msg_len_val} xid = {'buf': b'\x94\xc4\xd2\xcd', 'val': 2495926989} buf = version['buf'] \ + msg_type['buf'] \ + msg_len['buf'] \ + xid['buf'] # OFP_STATS_MSG_PACK_STR # '!HH'...type_, flags type_ = {'buf': b'\x00\x01', 'val': ofproto.OFPST_FLOW} flags = {'buf': b'\x95\xf4', 'val': 38388} buf += type_['buf'] \ + flags['buf'] # stats_type_cls = OFPFlowStats # OFP_FLOW_STATS_0_PACK_STR # '!HBx'...length, table_id, zfill length = {'buf': b'\x00\x60', 'val': 96} table_id = {'buf': b'\x51', 'val': 81} zfill = b'\x00' buf += length['buf'] \ + table_id['buf'] \ + zfill # OFP_MATCH_PACK_STR # '!IH6s6sHBxHBB2xIIHH'... match = b'\x97\x7c\xa6\x1e' \ + b'\x5e\xa0' \ + b'\x70\x17\xdc\x80\x59\x9e' \ + b'\x79\xc6\x56\x87\x92\x28' \ + b'\xb1\x81' \ + b'\xbe' \ + b'\x00' \ + b'\x01\xab' \ + b'\x42' \ + b'\xfe' \ + b'\x00\x00' \ + b'\xa4\x5d\x5c\x42' \ + b'\xa2\x5c\x2e\x05' \ + b'\x5a\x94' \ + b'\x64\xd4' buf += match # OFP_FLOW_STATS_1_PACK_STR # '!IIHHH6xQQQ'...duration_sec, duration_nsec, priority, # idle_timeout, hard_timeout, zfill, # cookie, packet_count, byte_count duration_sec = {'buf': b'\x94\x19\xb3\xd2', 'val': 2484712402} duration_nsec = {'buf': b'\xee\x66\xcf\x7c', 'val': 3999715196} priority = {'buf': b'\xe1\xc0', 'val': 57792} idle_timeout = {'buf': b'\x8e\x10', 'val': 36368} hard_timeout = {'buf': b'\xd4\x99', 'val': 54425} zfill = b'\x00' * 6 cookie = {'buf': b'\x0b\x01\xe8\xe5\xf0\x84\x8a\xe0', 'val': 793171083674290912} packet_count = {'buf': b'\x47\x5c\xc6\x05\x28\xff\x7c\xdb', 'val': 5142202600015232219} byte_count = {'buf': b'\x24\xe9\x4b\xee\xcb\x57\xd9\xc3', 'val': 2659740543924820419} buf += duration_sec['buf'] buf += duration_nsec['buf'] buf += priority['buf'] buf += idle_timeout['buf'] buf += hard_timeout['buf'] buf += zfill buf += cookie['buf'] buf += packet_count['buf'] buf += byte_count['buf'] # _PACK_STR...type_, len_ [others...] type = {'buf': b'\x00\x00', 'val': ofproto.OFPAT_OUTPUT} len = {'buf': b'\x00\x08', 'val': ofproto.OFP_ACTION_OUTPUT_SIZE} port = {'buf': b'\x59\x2a', 'val': 22826} max_len = {'buf': b'\x00\x08', 'val': ofproto.OFP_ACTION_OUTPUT_SIZE} buf += type['buf'] \ + len['buf'] \ + port['buf'] \ + max_len['buf'] res = OFPFlowStatsReply.parser(object, version['val'], msg_type['val'], msg_len['val'], xid['val'], buf) self.assertEqual(version['val'], res.version) self.assertEqual(msg_type['val'], res.msg_type) self.assertEqual(msg_len['val'], res.msg_len) self.assertEqual(xid['val'], res.xid) self.assertEqual(type_['val'], res.type) self.assertEqual(flags['val'], res.flags) # body body = res.body[0] self.assertEqual(length['val'], body.length) self.assertEqual(table_id['val'], body.table_id) self.assertEqual(duration_sec['val'], body.duration_sec) self.assertEqual(duration_nsec['val'], body.duration_nsec) self.assertEqual(priority['val'], body.priority) self.assertEqual(idle_timeout['val'], body.idle_timeout) self.assertEqual(hard_timeout['val'], body.hard_timeout) self.assertEqual(cookie['val'], body.cookie) self.assertEqual(packet_count['val'], body.packet_count) self.assertEqual(byte_count['val'], body.byte_count) # action action = body.actions[0] self.assertEqual(type['val'], action.type) self.assertEqual(len['val'], action.len) self.assertEqual(port['val'], action.port) self.assertEqual(max_len['val'], action.max_len) def test_serialize(self): # Not used. pass class TestOFPAggregateStatsReply(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPAggregateStatsReply """ class Datapath(object): ofproto = ofproto # copy to class attribute ofproto_parser = ofproto_v1_0_parser c = OFPAggregateStatsReply(Datapath) def setUp(self): pass def tearDown(self): pass def test_init(self): pass def test_parser(self): version = {'buf': b'\x01', 'val': ofproto.OFP_VERSION} msg_type = {'buf': b'\x11', 'val': ofproto.OFPT_STATS_REPLY} msg_len_val = ofproto.OFP_STATS_MSG_SIZE \ + ofproto.OFP_AGGREGATE_STATS_REPLY_SIZE msg_len = {'buf': b'\x00\x4c', 'val': msg_len_val} xid = {'buf': b'\xc6\xd6\xce\x38', 'val': 3335966264} buf = version['buf'] \ + msg_type['buf'] \ + msg_len['buf'] \ + xid['buf'] # OFP_STATS_MSG_PACK_STR # '!HH'...type_, flags type_ = {'buf': b'\x00\x02', 'val': ofproto.OFPST_AGGREGATE} flags = {'buf': b'\x65\x66', 'val': 25958} buf += type_['buf'] \ + flags['buf'] # stats_type_cls = OFPAggregateStats # OFP_AGGREGATE_STATS_REPLY_PACK_STR # '!QQI4x'...packet_count, byte_count, flow_count, zfill packet_count = {'buf': b'\x43\x95\x1b\xfb\x0f\xf6\xa7\xdd', 'val': 4869829337189623773} byte_count = {'buf': b'\x36\xda\x2d\x80\x2a\x95\x35\xdd', 'val': 3952521651464517085} flow_count = {'buf': b'\xc3\x0d\xc3\xed', 'val': 3272459245} zfill = b'\x00' * 4 buf += packet_count['buf'] \ + byte_count['buf'] \ + flow_count['buf'] \ + zfill res = OFPAggregateStatsReply.parser(object, version['val'], msg_type['val'], msg_len['val'], xid['val'], buf) self.assertEqual(version['val'], res.version) self.assertEqual(msg_type['val'], res.msg_type) self.assertEqual(msg_len['val'], res.msg_len) self.assertEqual(xid['val'], res.xid) self.assertEqual(type_['val'], res.type) self.assertEqual(flags['val'], res.flags) # body body = res.body[0] self.assertEqual(packet_count['val'], body.packet_count) self.assertEqual(byte_count['val'], body.byte_count) self.assertEqual(flow_count['val'], body.flow_count) def test_serialize(self): # Not used. pass class TestOFPTableStatsReply(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPTableStatsReply """ class Datapath(object): ofproto = ofproto # copy to class attribute ofproto_parser = ofproto_v1_0_parser c = OFPTableStatsReply(Datapath) def setUp(self): pass def tearDown(self): pass def test_init(self): pass def test_parser(self): version = {'buf': b'\x01', 'val': ofproto.OFP_VERSION} msg_type = {'buf': b'\x11', 'val': ofproto.OFPT_STATS_REPLY} msg_len_val = ofproto.OFP_STATS_MSG_SIZE \ + ofproto.OFP_TABLE_STATS_SIZE msg_len = {'buf': b'\x00\x4c', 'val': msg_len_val} xid = {'buf': b'\xd6\xb4\x8d\xe6', 'val': 3602157030} buf = version['buf'] \ + msg_type['buf'] \ + msg_len['buf'] \ + xid['buf'] # OFP_STATS_MSG_PACK_STR # '!HH'...type_, flags type_ = {'buf': b'\x00\x03', 'val': ofproto.OFPST_TABLE} flags = {'buf': b'\xb3\xf0', 'val': 46064} buf += type_['buf'] \ + flags['buf'] # stats_type_cls = OFPTableStats # OFP_TABLE_STATS_PACK_STR # '!B3x32sIIIQQ'...table_id, zfill, name, wildcards, max_entries, # active_count, lookup_count, matched_count table_id = {'buf': b'\x5b', 'val': 91} zfill = b'\x00' * 3 name = b'name'.ljust(32) wildcards = {'buf': b'\xc5\xaf\x6e\x12', 'val': 3316608530} max_entries = {'buf': b'\x95\x6c\x78\x4d', 'val': 2506913869} active_count = {'buf': b'\x78\xac\xa8\x1e', 'val': 2024581150} lookup_count = {'buf': b'\x40\x1d\x9c\x39\x19\xec\xd4\x1c', 'val': 4620020561814017052} matched_count = {'buf': b'\x27\x35\x02\xb6\xc5\x5e\x17\x65', 'val': 2825167325263435621} buf += table_id['buf'] \ + zfill \ + name \ + wildcards['buf'] \ + max_entries['buf'] \ + active_count['buf'] \ + lookup_count['buf'] \ + matched_count['buf'] res = OFPTableStatsReply.parser(object, version['val'], msg_type['val'], msg_len['val'], xid['val'], buf) self.assertEqual(version['val'], res.version) self.assertEqual(msg_type['val'], res.msg_type) self.assertEqual(msg_len['val'], res.msg_len) self.assertEqual(xid['val'], res.xid) self.assertEqual(type_['val'], res.type) self.assertEqual(flags['val'], res.flags) # body body = res.body[0] self.assertEqual(table_id['val'], body.table_id) self.assertEqual(name, body.name) self.assertEqual(wildcards['val'], body.wildcards) self.assertEqual(max_entries['val'], body.max_entries) self.assertEqual(active_count['val'], body.active_count) self.assertEqual(lookup_count['val'], body.lookup_count) self.assertEqual(matched_count['val'], body.matched_count) def test_serialize(self): # Not used. pass class TestOFPPortStatsReply(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPPortStatsReply """ class Datapath(object): ofproto = ofproto # copy to class attribute ofproto_parser = ofproto_v1_0_parser c = OFPPortStatsReply(Datapath) def setUp(self): pass def tearDown(self): pass def test_init(self): pass def test_parser(self): version = {'buf': b'\x01', 'val': ofproto.OFP_VERSION} msg_type = {'buf': b'\x11', 'val': ofproto.OFPT_STATS_REPLY} msg_len_val = ofproto.OFP_STATS_MSG_SIZE \ + ofproto.OFP_PORT_STATS_SIZE msg_len = {'buf': b'\x00\x74', 'val': msg_len_val} xid = {'buf': b'\xc2\xaf\x3d\xff', 'val': 3266264575} buf = version['buf'] \ + msg_type['buf'] \ + msg_len['buf'] \ + xid['buf'] # OFP_STATS_MSG_PACK_STR # '!HH'...type_, flags type_ = {'buf': b'\x00\x04', 'val': ofproto.OFPST_PORT} flags = {'buf': b'\xda\xde', 'val': 56030} buf += type_['buf'] \ + flags['buf'] # stats_type_cls = OFPPortStats # OFP_PORT_STATS_PACK_STR # '!H6xQQQQQQQQQQQQ'... port_no, zfill, rx_packets, tx_packets, # rx_bytes, tx_bytes, rx_dropped, tx_dropped, # rx_errors, tx_errors, rx_frame_err, # rx_over_err, rx_crc_err, collisions port_no = {'buf': b'\xe7\x6b', 'val': 59243} zfill = b'\x00' * 6 rx_packets = {'buf': b'\x53\x44\x36\x61\xc4\x86\xc0\x37', 'val': 5999980397101236279} tx_packets = {'buf': b'\x27\xa4\x41\xd7\xd4\x53\x9e\x42', 'val': 2856480458895760962} rx_bytes = {'buf': b'\x55\xa1\x38\x60\x43\x97\x0d\x89', 'val': 6170274950576278921} tx_bytes = {'buf': b'\x77\xe1\xd5\x63\x18\xae\x63\xaa', 'val': 8638420181865882538} rx_dropped = {'buf': b'\x60\xe6\x20\x01\x24\xda\x4e\x5a', 'val': 6982303461569875546} tx_dropped = {'buf': b'\x09\x2d\x5d\x71\x71\xb6\x8e\xc7', 'val': 661287462113808071} rx_errors = {'buf': b'\x2f\x7e\x35\xb3\x66\x3c\x19\x0d', 'val': 3422231811478788365} tx_errors = {'buf': b'\x57\x32\x08\x2f\x88\x32\x40\x6b', 'val': 6283093430376743019} rx_frame_err = {'buf': b'\x0c\x28\x6f\xad\xce\x66\x6e\x8b', 'val': 876072919806406283} rx_over_err = {'buf': b'\x5a\x90\x8f\x9b\xfc\x82\x2e\xa0', 'val': 6525873760178941600} rx_crc_err = {'buf': b'\x73\x3a\x71\x17\xd6\x74\x69\x47', 'val': 8303073210207070535} collisions = {'buf': b'\x2f\x52\x0c\x79\x96\x03\x6e\x79', 'val': 3409801584220270201} buf += port_no['buf'] \ + zfill \ + rx_packets['buf'] \ + tx_packets['buf'] \ + rx_bytes['buf'] \ + tx_bytes['buf'] \ + rx_dropped['buf'] \ + tx_dropped['buf'] \ + rx_errors['buf'] \ + tx_errors['buf'] \ + rx_frame_err['buf'] \ + rx_over_err['buf'] \ + rx_crc_err['buf'] \ + collisions['buf'] res = OFPPortStatsReply.parser(object, version['val'], msg_type['val'], msg_len['val'], xid['val'], buf) self.assertEqual(version['val'], res.version) self.assertEqual(msg_type['val'], res.msg_type) self.assertEqual(msg_len['val'], res.msg_len) self.assertEqual(xid['val'], res.xid) self.assertEqual(type_['val'], res.type) self.assertEqual(flags['val'], res.flags) # body body = res.body[0] self.assertEqual(port_no['val'], body.port_no) self.assertEqual(rx_packets['val'], body.rx_packets) self.assertEqual(tx_packets['val'], body.tx_packets) self.assertEqual(rx_bytes['val'], body.rx_bytes) self.assertEqual(tx_bytes['val'], body.tx_bytes) self.assertEqual(rx_dropped['val'], body.rx_dropped) self.assertEqual(tx_dropped['val'], body.tx_dropped) self.assertEqual(rx_errors['val'], body.rx_errors) self.assertEqual(tx_errors['val'], body.tx_errors) self.assertEqual(rx_frame_err['val'], body.rx_frame_err) self.assertEqual(rx_over_err['val'], body.rx_over_err) self.assertEqual(rx_crc_err['val'], body.rx_crc_err) self.assertEqual(collisions['val'], body.collisions) def test_serialize(self): # Not used. pass class TestOFPQueueStatsReply(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPQueueStatsReply """ class Datapath(object): ofproto = ofproto # copy to class attribute ofproto_parser = ofproto_v1_0_parser c = OFPQueueStatsReply(Datapath) def setUp(self): pass def tearDown(self): pass def test_init(self): pass def test_parser(self): version = {'buf': b'\x01', 'val': ofproto.OFP_VERSION} msg_type = {'buf': b'\x11', 'val': ofproto.OFPT_STATS_REPLY} msg_len_val = ofproto.OFP_STATS_MSG_SIZE \ + ofproto.OFP_QUEUE_STATS_SIZE msg_len = {'buf': b'\x00\x2c', 'val': msg_len_val} xid = {'buf': b'\x19\xfc\x28\x6c', 'val': 435955820} buf = version['buf'] \ + msg_type['buf'] \ + msg_len['buf'] \ + xid['buf'] # OFP_STATS_MSG_PACK_STR # '!HH'...type_, flags type_ = {'buf': b'\x00\x05', 'val': ofproto.OFPST_QUEUE} flags = {'buf': b'\x3b\x2b', 'val': 15147} buf += type_['buf'] \ + flags['buf'] # stats_type_cls = OFPQueueStats # OFP_QUEUE_STATS_PACK_STR # '!H2xIQQQ...port_no, queue_id, tx_bytes, tx_packets, tx_errors port_no = {'buf': b'\xe7\x6b', 'val': 59243} zfill = b'\x00' * 2 queue_id = {'buf': b'\x2a\xa8\x7f\x32', 'val': 715685682} tx_bytes = {'buf': b'\x77\xe1\xd5\x63\x18\xae\x63\xaa', 'val': 8638420181865882538} tx_packets = {'buf': b'\x27\xa4\x41\xd7\xd4\x53\x9e\x42', 'val': 2856480458895760962} tx_errors = {'buf': b'\x57\x32\x08\x2f\x88\x32\x40\x6b', 'val': 6283093430376743019} buf += port_no['buf'] \ + zfill \ + queue_id['buf'] \ + tx_bytes['buf'] \ + tx_packets['buf'] \ + tx_errors['buf'] res = OFPQueueStatsReply.parser(object, version['val'], msg_type['val'], msg_len['val'], xid['val'], buf) self.assertEqual(version['val'], res.version) self.assertEqual(msg_type['val'], res.msg_type) self.assertEqual(msg_len['val'], res.msg_len) self.assertEqual(xid['val'], res.xid) self.assertEqual(type_['val'], res.type) self.assertEqual(flags['val'], res.flags) # body body = res.body[0] self.assertEqual(port_no['val'], body.port_no) self.assertEqual(queue_id['val'], body.queue_id) self.assertEqual(tx_bytes['val'], body.tx_bytes) self.assertEqual(tx_packets['val'], body.tx_packets) self.assertEqual(tx_errors['val'], body.tx_errors) def test_serialize(self): # Not used. pass class TestOFPVendorStatsReply(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPVendorStatsReply """ class Datapath(object): ofproto = ofproto # copy to class attribute ofproto_parser = ofproto_v1_0_parser c = OFPVendorStatsReply(Datapath) def setUp(self): pass def tearDown(self): pass def test_init(self): pass def test_parser(self): version = {'buf': b'\x01', 'val': ofproto.OFP_VERSION} msg_type = {'buf': b'\x11', 'val': ofproto.OFPT_STATS_REPLY} # ofproto.OFP_STATS_MSG_SIZE + len(specific_data) msg_len = {'buf': b'\x00\x18', 'val': ofproto.OFP_STATS_MSG_SIZE + 12} xid = {'buf': b'\x94\xc4\xd2\xcd', 'val': 2495926989} buf = version['buf'] \ + msg_type['buf'] \ + msg_len['buf'] \ + xid['buf'] # OFP_STATS_MSG_PACK_STR # '!HH'...type_, flags type_ = {'buf': b'\xff\xff', 'val': ofproto.OFPST_VENDOR} flags = {'buf': b'\x30\xd9', 'val': 12505} buf += type_['buf'] \ + flags['buf'] # stats_type_cls = OFPVendorStats specific_data = b'specific_data' buf += specific_data res = OFPVendorStatsReply.parser(object, version['val'], msg_type['val'], msg_len['val'], xid['val'], buf) self.assertEqual(version['val'], res.version) self.assertEqual(msg_type['val'], res.msg_type) self.assertEqual(msg_len['val'], res.msg_len) self.assertEqual(xid['val'], res.xid) self.assertEqual(type_['val'], res.type) self.assertEqual(flags['val'], res.flags) # body body = res.body[0] self.assertEqual(specific_data, body) def test_serialize(self): # Not used. pass class TestOFPFeaturesRequest(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPFeaturesRequest """ class Datapath(object): ofproto = ofproto # copy to class attribute ofproto_parser = ofproto_v1_0_parser c = OFPFeaturesRequest(Datapath) def setUp(self): pass def tearDown(self): pass def test_init(self): pass def test_parser(self): # Not used. pass def test_serialize(self): self.c.serialize() self.assertEqual(ofproto.OFP_VERSION, self.c.version) self.assertEqual(ofproto.OFPT_FEATURES_REQUEST, self.c.msg_type) self.assertEqual(0, self.c.xid) fmt = ofproto.OFP_HEADER_PACK_STR res = struct.unpack(fmt, bytes(self.c.buf)) self.assertEqual(ofproto.OFP_VERSION, res[0]) self.assertEqual(ofproto.OFPT_FEATURES_REQUEST, res[1]) self.assertEqual(len(self.c.buf), res[2]) self.assertEqual(0, res[3]) class TestOFPGetConfigRequest(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPGetConfigRequest """ class Datapath(object): ofproto = ofproto # copy to class attribute ofproto_parser = ofproto_v1_0_parser c = OFPGetConfigRequest(Datapath) def setUp(self): pass def tearDown(self): pass def test_init(self): pass def test_parser(self): # Not used. pass def test_serialize(self): self.c.serialize() self.assertEqual(ofproto.OFP_VERSION, self.c.version) self.assertEqual(ofproto.OFPT_GET_CONFIG_REQUEST, self.c.msg_type) self.assertEqual(0, self.c.xid) fmt = ofproto.OFP_HEADER_PACK_STR res = struct.unpack(fmt, bytes(self.c.buf)) self.assertEqual(ofproto.OFP_VERSION, res[0]) self.assertEqual(ofproto.OFPT_GET_CONFIG_REQUEST, res[1]) self.assertEqual(len(self.c.buf), res[2]) self.assertEqual(0, res[3]) class TestOFPSetConfig(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPSetConfig """ class Datapath(object): ofproto = ofproto # copy to class attribute ofproto_parser = ofproto_v1_0_parser # OFP_SWITCH_CONFIG_PACK_STR # '!HH'...flags, miss_send_len flags = {'buf': b'\xa0\xe2', 'val': 41186} miss_send_len = {'buf': b'\x36\x0e', 'val': 13838} c = OFPSetConfig(Datapath, flags['val'], miss_send_len['val']) def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(self.flags['val'], self.c.flags) self.assertEqual(self.miss_send_len['val'], self.c.miss_send_len) def test_parser(self): # Not used. pass def test_serialize(self): self.c.serialize() self.assertEqual(ofproto.OFP_VERSION, self.c.version) self.assertEqual(ofproto.OFPT_SET_CONFIG, self.c.msg_type) self.assertEqual(0, self.c.xid) fmt = '!' \ + ofproto.OFP_HEADER_PACK_STR.replace('!', '') \ + ofproto.OFP_SWITCH_CONFIG_PACK_STR.replace('!', '') res = struct.unpack(fmt, bytes(self.c.buf)) self.assertEqual(ofproto.OFP_VERSION, res[0]) self.assertEqual(ofproto.OFPT_SET_CONFIG, res[1]) self.assertEqual(len(self.c.buf), res[2]) self.assertEqual(0, res[3]) self.assertEqual(self.flags['val'], res[4]) self.assertEqual(self.miss_send_len['val'], res[5]) class TestOFPPacketOut(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPPacketOut """ port = 0x2ae0 actions = [OFPActionOutput(port, max_len=0)] def setUp(self): pass def tearDown(self): pass def _get_obj(self, buffer_id, in_port, data=None): class Datapath(object): ofproto = ofproto # copy to class attribute ofproto_parser = ofproto_v1_0_parser c = OFPPacketOut(Datapath, buffer_id, in_port, self.actions, data) return c def test_init(self): buffer_id = 0xffffffff in_port = 0x40455 data = 'Message' c = self._get_obj(buffer_id, in_port, data) self.assertEqual(buffer_id, c.buffer_id) self.assertEqual(in_port, c.in_port) self.assertEqual(data, c.data) def test_parser(self): # Not used. pass def test_serialize(self): buffer_id = 0xffffffff in_port = 0x9e07 data = b'Message' c = self._get_obj(buffer_id, in_port, data) c.serialize() self.assertEqual(ofproto.OFP_VERSION, c.version) self.assertEqual(ofproto.OFPT_PACKET_OUT, c.msg_type) self.assertEqual(0, c.xid) fmt = '!' \ + ofproto.OFP_HEADER_PACK_STR.replace('!', '') \ + ofproto.OFP_PACKET_OUT_PACK_STR.replace('!', '') \ + ofproto.OFP_ACTION_OUTPUT_PACK_STR.replace('!', '') \ + str(len(data)) + 's' res = struct.unpack(fmt, bytes(c.buf)) # OFP_HEADER_PACK_STR self.assertEqual(ofproto.OFP_VERSION, res[0]) self.assertEqual(ofproto.OFPT_PACKET_OUT, res[1]) self.assertEqual(len(c.buf), res[2]) self.assertEqual(0, res[3]) # OFP_PACKET_OUT_PACK_STR self.assertEqual(buffer_id, res[4]) self.assertEqual(in_port, res[5]) self.assertEqual(ofproto.OFP_ACTION_OUTPUT_SIZE, res[6]) # OFP_ACTION_OUTPUT_PACK_STR self.assertEqual(ofproto.OFPAT_OUTPUT, res[7]) self.assertEqual(ofproto.OFP_ACTION_OUTPUT_SIZE, res[8]) self.assertEqual(self.port, res[9]) self.assertEqual(0, res[10]) # data self.assertEqual(data, res[11]) def test_serialize_check_buffer_id(self): buffer_id = 0xffffff00 in_port = 0xaa92 data = 'Message' c = self._get_obj(buffer_id, in_port, data) self.assertRaises(AssertionError, c.serialize) class TestOFPFlowMod(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPFlowMod """ # OFP_FLOW_MOD_PACK_STR0 # '!QHHHHIHH'...cookie, command, idle_timeout, hard_timeout, # priority, buffer_id, out_port, flags cookie = {'buf': b'\x1d\x86\xce\x6e\x8d\xc0\xbe\xa8', 'val': 2127614848199081640} command = {'buf': b'\xe1\x55', 'val': 57685} idle_timeout = {'buf': b'\xf3\x6d', 'val': 62317} hard_timeout = {'buf': b'\x1c\xc5', 'val': 7365} priority = {'buf': b'\x9c\xe3', 'val': 40163} buffer_id = {'buf': b'\xf0\xa1\x80\x33', 'val': 4037115955} out_port = {'buf': b'\xfe\x0d', 'val': 65037} flags = {'buf': b'\x00\x87', 'val': 135} # OFP_MATCH_PACK_STR # '!IH6s6sHBxHBB2xIIHH'...wildcards, in_port, dl_src, dl_dst, dl_vlan, # dl_vlan_pcp, dl_type, nw_tos, nw_proto, # nw_src, nw_dst, tp_src, tp_dst wildcards = {'buf': b'\xd2\x71\x25\x23', 'val': 3530630435} in_port = {'buf': b'\x37\x8b', 'val': 14219} dl_src = b'\xdf\xcf\xe1\x5d\xcf\xc0' dl_dst = b'\x76\xb3\xfb\xc6\x21\x2f' dl_vlan = {'buf': b'\xc1\xf9', 'val': 49657} dl_vlan_pcp = {'buf': b'\x79', 'val': 121} zfill0 = b'\x00' dl_type = {'buf': b'\xa6\x9e', 'val': 42654} nw_tos = {'buf': b'\xde', 'val': 222} nw_proto = {'buf': b'\xe5', 'val': 229} zfil11 = b'\x00' * 2 nw_src = {'buf': b'\x1b\x6d\x8d\x4b', 'val': 460164427} nw_dst = {'buf': b'\xab\x25\xe1\x20', 'val': 2871386400} tp_src = {'buf': b'\xd5\xc3', 'val': 54723} tp_dst = {'buf': b'\x78\xb9', 'val': 30905} match = OFPMatch(wildcards['val'], in_port['val'], dl_src, dl_dst, dl_vlan['val'], dl_vlan_pcp['val'], dl_type['val'], nw_tos['val'], nw_proto['val'], nw_src['val'], nw_dst['val'], tp_src['val'], tp_dst['val']) port = 0x2ae0 actions = [OFPActionOutput(port, max_len=1000)] def setUp(self): pass def tearDown(self): pass def _get_obj(self, actions=None): class Datapath(object): ofproto = ofproto # copy to class attribute ofproto_parser = ofproto_v1_0_parser c = OFPFlowMod(Datapath, self.match, self.cookie['val'], self.command['val'], self.idle_timeout['val'], self.hard_timeout['val'], self.priority['val'], self.buffer_id['val'], self.out_port['val'], self.flags['val'], actions) return c def test_init(self): c = self._get_obj() self.assertEqual(self.cookie['val'], c.cookie) self.assertEqual(self.command['val'], c.command) self.assertEqual(self.idle_timeout['val'], c.idle_timeout) self.assertEqual(self.hard_timeout['val'], c.hard_timeout) self.assertEqual(self.priority['val'], c.priority) self.assertEqual(self.buffer_id['val'], c.buffer_id) self.assertEqual(self.out_port['val'], c.out_port) self.assertEqual(self.flags['val'], c.flags) def test_init_actions(self): c = self._get_obj(self.actions) action = c.actions[0] self.assertEqual(self.port, action.port) def test_parser(self): # Not used. pass def test_serialize(self): c = self._get_obj(self.actions) c.serialize() self.assertEqual(ofproto.OFP_VERSION, c.version) self.assertEqual(ofproto.OFPT_FLOW_MOD, c.msg_type) self.assertEqual(0, c.xid) fmt = '!' \ + ofproto.OFP_HEADER_PACK_STR.replace('!', '') \ + ofproto.OFP_MATCH_PACK_STR.replace('!', '') \ + ofproto.OFP_FLOW_MOD_PACK_STR0.replace('!', '') \ + ofproto.OFP_ACTION_OUTPUT_PACK_STR.replace('!', '') res = struct.unpack(fmt, bytes(c.buf)) # OFP_HEADER_PACK_STR self.assertEqual(ofproto.OFP_VERSION, res[0]) self.assertEqual(ofproto.OFPT_FLOW_MOD, res[1]) self.assertEqual(len(c.buf), res[2]) self.assertEqual(0, res[3]) # OFP_MATCH_PACK_STR self.assertEqual(self.wildcards['val'], res[4]) self.assertEqual(self.in_port['val'], res[5]) self.assertEqual(self.dl_src, res[6]) self.assertEqual(self.dl_dst, res[7]) self.assertEqual(self.dl_vlan['val'], res[8]) self.assertEqual(self.dl_vlan_pcp['val'], res[9]) self.assertEqual(self.dl_type['val'], res[10]) self.assertEqual(self.nw_tos['val'], res[11]) self.assertEqual(self.nw_proto['val'], res[12]) self.assertEqual(self.nw_src['val'], res[13]) self.assertEqual(self.nw_dst['val'], res[14]) self.assertEqual(self.tp_src['val'], res[15]) self.assertEqual(self.tp_dst['val'], res[16]) # OFP_FLOW_MOD_PACK_STR0 self.assertEqual(self.cookie['val'], res[17]) self.assertEqual(self.command['val'], res[18]) self.assertEqual(self.idle_timeout['val'], res[19]) self.assertEqual(self.hard_timeout['val'], res[20]) self.assertEqual(self.priority['val'], res[21]) self.assertEqual(self.buffer_id['val'], res[22]) self.assertEqual(self.out_port['val'], res[23]) self.assertEqual(self.flags['val'], res[24]) # OFP_ACTION_OUTPUT_PACK_STR self.assertEqual(ofproto.OFPAT_OUTPUT, res[25]) self.assertEqual(ofproto.OFP_ACTION_OUTPUT_SIZE, res[26]) self.assertEqual(self.port, res[27]) self.assertEqual(1000, res[28]) class TestOFPBarrierRequest(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPBarrierRequest """ class Datapath(object): ofproto = ofproto # copy to class attribute ofproto_parser = ofproto_v1_0_parser c = OFPBarrierRequest(Datapath) def setUp(self): pass def tearDown(self): pass def test_init(self): pass def test_parser(self): # Not used. pass def test_serialize(self): self.c.serialize() self.assertEqual(ofproto.OFP_VERSION, self.c.version) self.assertEqual(ofproto.OFPT_BARRIER_REQUEST, self.c.msg_type) self.assertEqual(0, self.c.xid) fmt = ofproto.OFP_HEADER_PACK_STR res = struct.unpack(fmt, bytes(self.c.buf)) self.assertEqual(ofproto.OFP_VERSION, res[0]) self.assertEqual(ofproto.OFPT_BARRIER_REQUEST, res[1]) self.assertEqual(len(self.c.buf), res[2]) self.assertEqual(0, res[3]) class TestOFPQueueGetConfigRequest(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPQueueGetConfigRequest """ class Datapath(object): ofproto = ofproto # copy to class attribute ofproto_parser = ofproto_v1_0_parser # OFP_QUEUE_GET_CONFIG_REQUEST_PACK_STR # '!H2x'...port, zfill port = {'buf': b'\xa0\xe2', 'val': 41186} zfill = b'\x00' * 2 c = OFPQueueGetConfigRequest(Datapath, port['val']) def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(self.port['val'], self.c.port) def test_parser(self): # Not used. pass def test_serialize(self): self.c.serialize() self.assertEqual(ofproto.OFP_VERSION, self.c.version) self.assertEqual(ofproto.OFPT_QUEUE_GET_CONFIG_REQUEST, self.c.msg_type) self.assertEqual(0, self.c.xid) a = ofproto.OFP_HEADER_PACK_STR.replace('!', '') b = ofproto.OFP_QUEUE_GET_CONFIG_REQUEST_PACK_STR.replace('!', '') fmt = '!' + a + b res = struct.unpack(fmt, bytes(self.c.buf)) self.assertEqual(ofproto.OFP_VERSION, res[0]) self.assertEqual(ofproto.OFPT_QUEUE_GET_CONFIG_REQUEST, res[1]) self.assertEqual(len(self.c.buf), res[2]) self.assertEqual(0, res[3]) self.assertEqual(self.port['val'], res[4]) class TestOFPDescStatsRequest(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPDescStatsRequest """ class Datapath(object): ofproto = ofproto # copy to class attribute ofproto_parser = ofproto_v1_0_parser flags = {'buf': b'\x00\x00', 'val': 0} c = OFPDescStatsRequest(Datapath, flags['val']) def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(ofproto.OFPST_DESC, self.c.type) self.assertEqual(self.flags['val'], self.c.flags) def test_parser(self): # Not used. pass def test_serialize(self): self.c.serialize() self.assertEqual(ofproto.OFP_VERSION, self.c.version) self.assertEqual(ofproto.OFPT_STATS_REQUEST, self.c.msg_type) self.assertEqual(0, self.c.xid) fmt = '!' \ + ofproto.OFP_HEADER_PACK_STR.replace('!', '') \ + ofproto.OFP_STATS_MSG_PACK_STR.replace('!', '') res = struct.unpack(fmt, bytes(self.c.buf)) # OFP_HEADER_PACK_STR self.assertEqual(ofproto.OFP_VERSION, res[0]) self.assertEqual(ofproto.OFPT_STATS_REQUEST, res[1]) self.assertEqual(len(self.c.buf), res[2]) self.assertEqual(0, res[3]) # OFP_STATS_MSG_PACK_STR self.assertEqual(ofproto.OFPST_DESC, res[4]) self.assertEqual(self.flags['val'], res[5]) class TestOFPFlowStatsRequest(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPFlowStatsRequest """ class Datapath(object): ofproto = ofproto # copy to class attribute ofproto_parser = ofproto_v1_0_parser flags = {'buf': b'\x00\x00', 'val': 0} # OFP_MATCH_PACK_STR # '!IH6s6sHBxHBB2xIIHH'...wildcards, in_port, dl_src, dl_dst, dl_vlan, # dl_vlan_pcp, dl_type, nw_tos, nw_proto, # nw_src, nw_dst, tp_src, tp_dst wildcards = {'buf': b'\xd2\x71\x25\x23', 'val': 3530630435} in_port = {'buf': b'\x37\x8b', 'val': 14219} dl_src = b'\x58\xd0\x8a\x69\xa4\xfc' dl_dst = b'\xb6\xe2\xef\xb1\xa6\x2d' dl_vlan = {'buf': b'\xc1\xf9', 'val': 49657} dl_vlan_pcp = {'buf': b'\x79', 'val': 121} zfill0 = b'\x00' dl_type = {'buf': b'\xa6\x9e', 'val': 42654} nw_tos = {'buf': b'\xde', 'val': 222} nw_proto = {'buf': b'\xe5', 'val': 229} zfil11 = b'\x00' * 2 nw_src = {'buf': b'\x1b\x6d\x8d\x4b', 'val': 460164427} nw_dst = {'buf': b'\xab\x25\xe1\x20', 'val': 2871386400} tp_src = {'buf': b'\xd5\xc3', 'val': 54723} tp_dst = {'buf': b'\x78\xb9', 'val': 30905} match = OFPMatch(wildcards['val'], in_port['val'], dl_src, dl_dst, dl_vlan['val'], dl_vlan_pcp['val'], dl_type['val'], nw_tos['val'], nw_proto['val'], nw_src['val'], nw_dst['val'], tp_src['val'], tp_dst['val']) # OFP_FLOW_STATS_REQUEST_ID_PORT_STR # '!BxH'...table_id, zfill, out_port table_id = {'buf': b'\xd1', 'val': 209} zfill = b'\x00' * 1 out_port = {'buf': b'\xe4\x9a', 'val': 58522} c = OFPFlowStatsRequest(Datapath, flags['val'], match, table_id['val'], out_port['val']) def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(ofproto.OFPST_FLOW, self.c.type) self.assertEqual(self.flags['val'], self.c.flags) self.assertEqual(self.table_id['val'], self.c.table_id) self.assertEqual(self.out_port['val'], self.c.out_port) # match match = self.c.match self.assertEqual(self.match.__hash__(), match.__hash__()) def test_parser(self): # Not used. pass def test_serialize(self): self.c.serialize() self.assertEqual(ofproto.OFP_VERSION, self.c.version) self.assertEqual(ofproto.OFPT_STATS_REQUEST, self.c.msg_type) self.assertEqual(0, self.c.xid) fmt = '!' \ + ofproto.OFP_HEADER_PACK_STR.replace('!', '') \ + ofproto.OFP_STATS_MSG_PACK_STR.replace('!', '') \ + ofproto.OFP_MATCH_PACK_STR.replace('!', '') \ + ofproto.OFP_FLOW_STATS_REQUEST_ID_PORT_STR.replace('!', '') res = struct.unpack(fmt, bytes(self.c.buf)) # OFP_HEADER_PACK_STR self.assertEqual(ofproto.OFP_VERSION, res[0]) self.assertEqual(ofproto.OFPT_STATS_REQUEST, res[1]) self.assertEqual(len(self.c.buf), res[2]) self.assertEqual(0, res[3]) # OFP_STATS_MSG_PACK_STR self.assertEqual(ofproto.OFPST_FLOW, res[4]) self.assertEqual(self.flags['val'], res[5]) # OFP_MATCH_PACK_STR self.assertEqual(self.wildcards['val'], res[6]) self.assertEqual(self.in_port['val'], res[7]) self.assertEqual(self.dl_src, res[8]) self.assertEqual(self.dl_dst, res[9]) self.assertEqual(self.dl_vlan['val'], res[10]) self.assertEqual(self.dl_vlan_pcp['val'], res[11]) self.assertEqual(self.dl_type['val'], res[12]) self.assertEqual(self.nw_tos['val'], res[13]) self.assertEqual(self.nw_proto['val'], res[14]) self.assertEqual(self.nw_src['val'], res[15]) self.assertEqual(self.nw_dst['val'], res[16]) self.assertEqual(self.tp_src['val'], res[17]) self.assertEqual(self.tp_dst['val'], res[18]) # OFP_FLOW_STATS_REQUEST_ID_PORT_STR self.assertEqual(self.table_id['val'], res[19]) self.assertEqual(self.out_port['val'], res[20]) class TestOFPAggregateStatsRequest(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPAggregateStatsRequest """ class Datapath(object): ofproto = ofproto # copy to class attribute ofproto_parser = ofproto_v1_0_parser flags = {'buf': b'\x00\x00', 'val': 0} # OFP_MATCH_PACK_STR # '!IH6s6sHBxHBB2xIIHH'...wildcards, in_port, dl_src, dl_dst, dl_vlan, # dl_vlan_pcp, dl_type, nw_tos, nw_proto, # nw_src, nw_dst, tp_src, tp_dst wildcards = {'buf': b'\xea\x66\x4a\xd4', 'val': 3932572372} in_port = {'buf': b'\x64\xac', 'val': 25772} dl_src = b'\x90\x13\x60\x5e\x20\x4d' dl_dst = b'\xb5\x5d\x14\x5e\xb9\x22' dl_vlan = {'buf': b'\x8b\xeb', 'val': 35819} dl_vlan_pcp = {'buf': b'\xe8', 'val': 232} zfill0 = b'\x00' dl_type = {'buf': b'\62\xc9', 'val': 25289} nw_tos = {'buf': b'\xb5', 'val': 181} nw_proto = {'buf': b'\xc4', 'val': 196} zfil11 = b'\x00' * 2 nw_src = {'buf': b'\xb7\xd1\xb7\xef', 'val': 3083974639} nw_dst = {'buf': b'\x7c\xc6\x18\x15', 'val': 2093357077} tp_src = {'buf': b'\x26\x9a', 'val': 9882} tp_dst = {'buf': b'\x7a\x89', 'val': 31369} match = OFPMatch(wildcards['val'], in_port['val'], dl_src, dl_dst, dl_vlan['val'], dl_vlan_pcp['val'], dl_type['val'], nw_tos['val'], nw_proto['val'], nw_src['val'], nw_dst['val'], tp_src['val'], tp_dst['val']) # OFP_FLOW_STATS_REQUEST_ID_PORT_STR # '!BxH'...table_id, zfill, out_port table_id = {'buf': b'\xd1', 'val': 209} zfill = b'\x00' * 1 out_port = {'buf': b'\xb5\xe8', 'val': 46568} c = OFPAggregateStatsRequest(Datapath, flags['val'], match, table_id['val'], out_port['val']) def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(ofproto.OFPST_AGGREGATE, self.c.type) self.assertEqual(self.flags['val'], self.c.flags) self.assertEqual(self.table_id['val'], self.c.table_id) self.assertEqual(self.out_port['val'], self.c.out_port) # match match = self.c.match self.assertEqual(self.match.__hash__(), match.__hash__()) def test_parser(self): # Not used. pass def test_serialize(self): self.c.serialize() self.assertEqual(ofproto.OFP_VERSION, self.c.version) self.assertEqual(ofproto.OFPT_STATS_REQUEST, self.c.msg_type) self.assertEqual(0, self.c.xid) fmt = '!' \ + ofproto.OFP_HEADER_PACK_STR.replace('!', '') \ + ofproto.OFP_STATS_MSG_PACK_STR.replace('!', '') \ + ofproto.OFP_MATCH_PACK_STR.replace('!', '') \ + ofproto.OFP_FLOW_STATS_REQUEST_ID_PORT_STR.replace('!', '') res = struct.unpack(fmt, bytes(self.c.buf)) # OFP_HEADER_PACK_STR self.assertEqual(ofproto.OFP_VERSION, res[0]) self.assertEqual(ofproto.OFPT_STATS_REQUEST, res[1]) self.assertEqual(len(self.c.buf), res[2]) self.assertEqual(0, res[3]) # OFP_STATS_MSG_PACK_STR self.assertEqual(ofproto.OFPST_AGGREGATE, res[4]) self.assertEqual(self.flags['val'], res[5]) # OFP_MATCH_PACK_STR self.assertEqual(self.wildcards['val'], res[6]) self.assertEqual(self.in_port['val'], res[7]) self.assertEqual(self.dl_src, res[8]) self.assertEqual(self.dl_dst, res[9]) self.assertEqual(self.dl_vlan['val'], res[10]) self.assertEqual(self.dl_vlan_pcp['val'], res[11]) self.assertEqual(self.dl_type['val'], res[12]) self.assertEqual(self.nw_tos['val'], res[13]) self.assertEqual(self.nw_proto['val'], res[14]) self.assertEqual(self.nw_src['val'], res[15]) self.assertEqual(self.nw_dst['val'], res[16]) self.assertEqual(self.tp_src['val'], res[17]) self.assertEqual(self.tp_dst['val'], res[18]) # OFP_FLOW_STATS_REQUEST_ID_PORT_STR self.assertEqual(self.table_id['val'], res[19]) self.assertEqual(self.out_port['val'], res[20]) class TestOFPTableStatsRequest(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPTableStatsRequest """ class Datapath(object): ofproto = ofproto # copy to class attribute ofproto_parser = ofproto_v1_0_parser flags = {'buf': b'\x00\x00', 'val': 0} c = OFPTableStatsRequest(Datapath, flags['val']) def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(ofproto.OFPST_TABLE, self.c.type) self.assertEqual(self.flags['val'], self.c.flags) def test_parser(self): # Not used. pass def test_serialize(self): self.c.serialize() self.assertEqual(ofproto.OFP_VERSION, self.c.version) self.assertEqual(ofproto.OFPT_STATS_REQUEST, self.c.msg_type) self.assertEqual(0, self.c.xid) fmt = '!' \ + ofproto.OFP_HEADER_PACK_STR.replace('!', '') \ + ofproto.OFP_STATS_MSG_PACK_STR.replace('!', '') res = struct.unpack(fmt, bytes(self.c.buf)) # OFP_HEADER_PACK_STR self.assertEqual(ofproto.OFP_VERSION, res[0]) self.assertEqual(ofproto.OFPT_STATS_REQUEST, res[1]) self.assertEqual(len(self.c.buf), res[2]) self.assertEqual(0, res[3]) # OFP_STATS_MSG_PACK_STR self.assertEqual(ofproto.OFPST_TABLE, res[4]) self.assertEqual(self.flags['val'], res[5]) class TestOFPPortStatsRequest(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPPortStatsRequest """ class Datapath(object): ofproto = ofproto # copy to class attribute ofproto_parser = ofproto_v1_0_parser flags = {'buf': b'\x00\x00', 'val': 0} # OFP_PORT_STATS_REQUEST_PACK_STR # '!H6x'...port_no, zfill port_no = {'buf': b'\x6d\x27', 'val': 27943} c = OFPPortStatsRequest(Datapath, flags['val'], port_no['val']) def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(ofproto.OFPST_PORT, self.c.type) self.assertEqual(self.flags['val'], self.c.flags) self.assertEqual(self.port_no['val'], self.c.port_no) def test_parser(self): # Not used. pass def test_serialize(self): self.c.serialize() self.assertEqual(ofproto.OFP_VERSION, self.c.version) self.assertEqual(ofproto.OFPT_STATS_REQUEST, self.c.msg_type) self.assertEqual(0, self.c.xid) fmt = '!' \ + ofproto.OFP_HEADER_PACK_STR.replace('!', '') \ + ofproto.OFP_STATS_MSG_PACK_STR.replace('!', '') \ + ofproto.OFP_PORT_STATS_REQUEST_PACK_STR.replace('!', '') res = struct.unpack(fmt, bytes(self.c.buf)) # OFP_HEADER_PACK_STR self.assertEqual(ofproto.OFP_VERSION, res[0]) self.assertEqual(ofproto.OFPT_STATS_REQUEST, res[1]) self.assertEqual(len(self.c.buf), res[2]) self.assertEqual(0, res[3]) # OFP_STATS_MSG_PACK_STR self.assertEqual(ofproto.OFPST_PORT, res[4]) self.assertEqual(self.flags['val'], res[5]) # OFP_PORT_STATS_REQUEST_PACK_STR self.assertEqual(self.port_no['val'], res[6]) class TestOFPQueueStatsRequest(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPQueueStatsRequest """ class Datapath(object): ofproto = ofproto # copy to class attribute ofproto_parser = ofproto_v1_0_parser flags = {'buf': b'\x00\x00', 'val': 0} # OFP_QUEUE_STATS_REQUEST_PACK_STR # '!HxxI'...port_no, zfill, zfill, queue_id port_no = {'buf': b'\x0c\x2d', 'val': 3117} queue_id = {'buf': b'\x1b\xe6\xba\x36', 'val': 468105782} c = OFPQueueStatsRequest(Datapath, flags['val'], port_no['val'], queue_id['val']) def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(ofproto.OFPST_QUEUE, self.c.type) self.assertEqual(self.flags['val'], self.c.flags) self.assertEqual(self.port_no['val'], self.c.port_no) self.assertEqual(self.queue_id['val'], self.c.queue_id) def test_parser(self): # Not used. pass def test_serialize(self): self.c.serialize() self.assertEqual(ofproto.OFP_VERSION, self.c.version) self.assertEqual(ofproto.OFPT_STATS_REQUEST, self.c.msg_type) self.assertEqual(0, self.c.xid) fmt = '!' \ + ofproto.OFP_HEADER_PACK_STR.replace('!', '') \ + ofproto.OFP_STATS_MSG_PACK_STR.replace('!', '') \ + ofproto.OFP_QUEUE_STATS_REQUEST_PACK_STR.replace('!', '') res = struct.unpack(fmt, bytes(self.c.buf)) # OFP_HEADER_PACK_STR self.assertEqual(ofproto.OFP_VERSION, res[0]) self.assertEqual(ofproto.OFPT_STATS_REQUEST, res[1]) self.assertEqual(len(self.c.buf), res[2]) self.assertEqual(0, res[3]) # OFP_STATS_MSG_PACK_STR self.assertEqual(ofproto.OFPST_QUEUE, res[4]) self.assertEqual(self.flags['val'], res[5]) # OFP_QUEUE_STATS_REQUEST_PACK_STR self.assertEqual(self.port_no['val'], res[6]) self.assertEqual(self.queue_id['val'], res[7]) class TestOFPVendorStatsRequest(unittest.TestCase): """ Test case for ofproto_v1_0_parser.OFPVendorStatsRequest """ class Datapath(object): ofproto = ofproto # copy to class attribute ofproto_parser = ofproto_v1_0_parser flags = {'buf': b'\x00\x00', 'val': 0} # OFP_VENDOR_STATS_MSG_PACK_STR # '!I'...vendor vendor = {'buf': b'\xff\xff\xff\xff', 'val': ofproto.OFPAT_VENDOR} specific_data = b'specific_data' c = OFPVendorStatsRequest(Datapath, flags['val'], vendor['val'], specific_data) def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(ofproto.OFPST_VENDOR, self.c.type) self.assertEqual(self.flags['val'], self.c.flags) self.assertEqual(self.vendor['val'], self.c.vendor) self.assertEqual(self.specific_data, self.c.specific_data) def test_parser(self): # Not used. pass def test_serialize(self): self.c.serialize() self.assertEqual(ofproto.OFP_VERSION, self.c.version) self.assertEqual(ofproto.OFPT_STATS_REQUEST, self.c.msg_type) self.assertEqual(0, self.c.xid) fmt = '!' \ + ofproto.OFP_HEADER_PACK_STR.replace('!', '') \ + ofproto.OFP_STATS_MSG_PACK_STR.replace('!', '') \ + ofproto.OFP_VENDOR_STATS_MSG_PACK_STR.replace('!', '') \ + str(len(self.specific_data)) + 's' res = struct.unpack(fmt, bytes(self.c.buf)) # OFP_HEADER_PACK_STR self.assertEqual(ofproto.OFP_VERSION, res[0]) self.assertEqual(ofproto.OFPT_STATS_REQUEST, res[1]) self.assertEqual(len(self.c.buf), res[2]) self.assertEqual(0, res[3]) # OFP_STATS_MSG_PACK_STR self.assertEqual(ofproto.OFPST_VENDOR, res[4]) self.assertEqual(self.flags['val'], res[5]) # OFP_VENDOR_STATS_MSG_PACK_STR self.assertEqual(self.vendor['val'], res[6]) # specific_data self.assertEqual(self.specific_data, res[7]) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/test_parser_v12.py0000664000175000017500000076445300000000000023520 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone 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. import unittest import logging import socket from struct import * from os_ken.ofproto.ofproto_v1_2_parser import * from os_ken.ofproto import ofproto_v1_2_parser from os_ken.ofproto import ofproto_v1_2 from os_ken.ofproto import ofproto_protocol from os_ken.ofproto import ether from os_ken.ofproto.ofproto_parser import MsgBase from os_ken import utils from os_ken.lib import addrconv from os_ken.lib import pack_utils LOG = logging.getLogger('test_ofproto_v12') _Datapath = ofproto_protocol.ProtocolDesc(version=ofproto_v1_2.OFP_VERSION) class TestRegisterParser(unittest.TestCase): """ Test case for ofproto_v1_2_parser._register_parser """ class _OFPDummy(MsgBase): def __init__(self, datapath): self.dummy = 'dummy' def parser(self): return self.dummy def test_cls_msg_type(self): msg_type = 0xff cls = self._OFPDummy(_Datapath) cls.cls_msg_type = msg_type res = ofproto_v1_2_parser._register_parser(cls) res_parser = ofproto_v1_2_parser._MSG_PARSERS[msg_type] del ofproto_v1_2_parser._MSG_PARSERS[msg_type] self.assertEqual(res.cls_msg_type, msg_type) self.assertTrue(res.dummy) self.assertEqual(res_parser(), 'dummy') def test_cls_msg_type_none(self): cls = OFPHello(_Datapath) cls.cls_msg_type = None self.assertRaises(AssertionError, ofproto_v1_2_parser._register_parser, cls) def test_cls_msg_type_already_registed(self): cls = OFPHello(_Datapath) self.assertRaises(AssertionError, ofproto_v1_2_parser._register_parser, cls) class TestMsgParser(unittest.TestCase): """ Test case for ofproto_v1_2_parser.msg_parser """ def _test_msg_parser(self, xid, msg_len): # OFP_HEADER_PACK_STR # '!BBHI'...version, msg_type, msg_len, xid version = ofproto.OFP_VERSION msg_type = ofproto.OFPT_HELLO fmt = ofproto.OFP_HEADER_PACK_STR buf = pack(fmt, version, msg_type, msg_len, xid) c = msg_parser(_Datapath, version, msg_type, msg_len, xid, buf) self.assertEqual(version, c.version) self.assertEqual(msg_type, c.msg_type) self.assertEqual(msg_len, c.msg_len) self.assertEqual(xid, c.xid) # buf fmt = ofproto.OFP_HEADER_PACK_STR res = struct.unpack(fmt, c.buf) self.assertEqual(version, res[0]) self.assertEqual(msg_type, res[1]) self.assertEqual(msg_len, res[2]) self.assertEqual(xid, res[3]) def test_parser_mid(self): xid = 2147483648 msg_len = 8 self._test_msg_parser(xid, msg_len) def test_parser_max(self): xid = 4294967295 msg_len = 65535 self._test_msg_parser(xid, msg_len) def test_parser_min(self): xid = 0 msg_len = 0 self._test_msg_parser(xid, msg_len) class TestOFPHello(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPHello """ def _test_parser(self, xid): version = ofproto.OFP_VERSION msg_type = ofproto.OFPT_HELLO msg_len = ofproto.OFP_HEADER_SIZE fmt = ofproto.OFP_HEADER_PACK_STR buf = pack(fmt, version, msg_type, msg_len, xid) res = OFPHello.parser(object, version, msg_type, msg_len, xid, bytearray(buf)) self.assertEqual(version, res.version) self.assertEqual(msg_type, res.msg_type) self.assertEqual(msg_len, res.msg_len) self.assertEqual(xid, res.xid) self.assertEqual(bytes(buf), bytes(res.buf)) def test_parser_xid_min(self): xid = 0 self._test_parser(xid) def test_parser_xid_mid(self): xid = 2183948390 self._test_parser(xid) def test_parser_xid_max(self): xid = 4294967295 self._test_parser(xid) def test_serialize(self): c = OFPHello(_Datapath) c.serialize() self.assertEqual(ofproto.OFP_VERSION, c.version) self.assertEqual(ofproto.OFPT_HELLO, c.msg_type) self.assertEqual(0, c.xid) class TestOFPErrorMsg(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPErrorMsg """ # OFP_HEADER_PACK_STR # '!BBHI'...version, msg_type, msg_len, xid version = ofproto.OFP_VERSION msg_type = ofproto.OFPT_ERROR msg_len = ofproto.OFP_ERROR_MSG_SIZE xid = 2495926989 fmt = ofproto.OFP_HEADER_PACK_STR buf = pack(fmt, version, msg_type, msg_len, xid) def test_init(self): c = OFPErrorMsg(_Datapath) self.assertEqual(c.code, None) self.assertEqual(c.type, None) self.assertEqual(c.data, None) def _test_parser(self, type_, code, data=None): # OFP_ERROR_MSG_PACK_STR = '!HH' fmt = ofproto.OFP_ERROR_MSG_PACK_STR buf = self.buf + pack(fmt, type_, code) if data is not None: buf += data res = OFPErrorMsg.parser(object, self.version, self.msg_type, self.msg_len, self.xid, buf) self.assertEqual(res.version, self.version) self.assertEqual(res.msg_type, self.msg_type) self.assertEqual(res.msg_len, self.msg_len) self.assertEqual(res.xid, self.xid) self.assertEqual(res.type, type_) self.assertEqual(res.code, code) if data is not None: self.assertEqual(res.data, data) def test_parser_mid(self): type_ = 32768 code = 32768 data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_max(self): type_ = 65534 code = 65535 data = b'Error Message.'.ljust(65523) self._test_parser(type_, code, data) def test_parser_min(self): type_ = 0 code = 0 data = None self._test_parser(type_, code, data) def test_parser_p0_1(self): type_ = ofproto.OFPET_HELLO_FAILED code = ofproto.OFPHFC_EPERM data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p1_0(self): type_ = ofproto.OFPET_BAD_REQUEST code = ofproto.OFPBRC_BAD_VERSION data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p1_1(self): type_ = ofproto.OFPET_BAD_REQUEST code = ofproto.OFPBRC_BAD_TYPE data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p1_2(self): type_ = ofproto.OFPET_BAD_REQUEST code = ofproto.OFPBRC_BAD_STAT data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p1_3(self): type_ = ofproto.OFPET_BAD_REQUEST code = ofproto.OFPBRC_BAD_EXPERIMENTER data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p1_4(self): type_ = ofproto.OFPET_BAD_REQUEST code = ofproto.OFPBRC_BAD_EXP_TYPE data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p1_5(self): type_ = ofproto.OFPET_BAD_REQUEST code = ofproto.OFPBRC_EPERM data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p1_6(self): type_ = ofproto.OFPET_BAD_REQUEST code = ofproto.OFPBRC_BAD_LEN data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p1_7(self): type_ = ofproto.OFPET_BAD_REQUEST code = ofproto.OFPBRC_BUFFER_EMPTY data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p1_8(self): type_ = ofproto.OFPET_BAD_REQUEST code = ofproto.OFPBRC_BUFFER_UNKNOWN data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p1_9(self): type_ = ofproto.OFPET_BAD_REQUEST code = ofproto.OFPBRC_BAD_TABLE_ID data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p1_10(self): type_ = ofproto.OFPET_BAD_REQUEST code = ofproto.OFPBRC_IS_SLAVE data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p1_11(self): type_ = ofproto.OFPET_BAD_REQUEST code = ofproto.OFPBRC_BAD_PORT data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p1_12(self): type_ = ofproto.OFPET_BAD_REQUEST code = ofproto.OFPBRC_BAD_PACKET data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p2_0(self): type_ = ofproto.OFPET_BAD_ACTION code = ofproto.OFPBAC_BAD_TYPE data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p2_1(self): type_ = ofproto.OFPET_BAD_ACTION code = ofproto.OFPBAC_BAD_LEN data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p2_2(self): type_ = ofproto.OFPET_BAD_ACTION code = ofproto.OFPBAC_BAD_EXPERIMENTER data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p2_3(self): type_ = ofproto.OFPET_BAD_ACTION code = ofproto.OFPBAC_BAD_EXP_TYPE data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p2_4(self): type_ = ofproto.OFPET_BAD_ACTION code = ofproto.OFPBAC_BAD_OUT_PORT data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p2_5(self): type_ = ofproto.OFPET_BAD_ACTION code = ofproto.OFPBAC_BAD_ARGUMENT data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p2_6(self): type_ = ofproto.OFPET_BAD_ACTION code = ofproto.OFPBAC_EPERM data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p2_7(self): type_ = ofproto.OFPET_BAD_ACTION code = ofproto.OFPBAC_TOO_MANY data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p2_8(self): type_ = ofproto.OFPET_BAD_ACTION code = ofproto.OFPBAC_BAD_QUEUE data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p2_9(self): type_ = ofproto.OFPET_BAD_ACTION code = ofproto.OFPBAC_BAD_OUT_GROUP data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p2_10(self): type_ = ofproto.OFPET_BAD_ACTION code = ofproto.OFPBAC_MATCH_INCONSISTENT data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p2_11(self): type_ = ofproto.OFPET_BAD_ACTION code = ofproto.OFPBAC_UNSUPPORTED_ORDER data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p2_12(self): type_ = ofproto.OFPET_BAD_ACTION code = ofproto.OFPBAC_BAD_TAG data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p2_13(self): type_ = ofproto.OFPET_BAD_ACTION code = ofproto.OFPBAC_BAD_SET_TYPE data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p2_14(self): type_ = ofproto.OFPET_BAD_ACTION code = ofproto.OFPBAC_BAD_SET_LEN data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p2_15(self): type_ = ofproto.OFPET_BAD_ACTION code = ofproto.OFPBAC_BAD_SET_ARGUMENT data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p3_0(self): type_ = ofproto.OFPET_BAD_INSTRUCTION code = ofproto.OFPBIC_UNKNOWN_INST data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p3_1(self): type_ = ofproto.OFPET_BAD_INSTRUCTION code = ofproto.OFPBIC_UNSUP_INST data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p3_2(self): type_ = ofproto.OFPET_BAD_INSTRUCTION code = ofproto.OFPBIC_BAD_TABLE_ID data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p3_3(self): type_ = ofproto.OFPET_BAD_INSTRUCTION code = ofproto.OFPBIC_UNSUP_METADATA data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p3_4(self): type_ = ofproto.OFPET_BAD_INSTRUCTION code = ofproto.OFPBIC_UNSUP_METADATA_MASK data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p3_5(self): type_ = ofproto.OFPET_BAD_INSTRUCTION code = ofproto.OFPBIC_BAD_EXPERIMENTER data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p3_6(self): type_ = ofproto.OFPET_BAD_INSTRUCTION code = ofproto.OFPBIC_BAD_EXP_TYPE data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p3_7(self): type_ = ofproto.OFPET_BAD_INSTRUCTION code = ofproto.OFPBIC_BAD_LEN data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p3_8(self): type_ = ofproto.OFPET_BAD_INSTRUCTION code = ofproto.OFPBIC_EPERM data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p4_0(self): type_ = ofproto.OFPET_BAD_MATCH code = ofproto.OFPBMC_BAD_TYPE data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p4_1(self): type_ = ofproto.OFPET_BAD_MATCH code = ofproto.OFPBMC_BAD_LEN data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p4_2(self): type_ = ofproto.OFPET_BAD_MATCH code = ofproto.OFPBMC_BAD_TAG data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p4_3(self): type_ = ofproto.OFPET_BAD_MATCH code = ofproto.OFPBMC_BAD_DL_ADDR_MASK data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p4_4(self): type_ = ofproto.OFPET_BAD_MATCH code = ofproto.OFPBMC_BAD_NW_ADDR_MASK data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p4_5(self): type_ = ofproto.OFPET_BAD_MATCH code = ofproto.OFPBMC_BAD_WILDCARDS data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p4_6(self): type_ = ofproto.OFPET_BAD_MATCH code = ofproto.OFPBMC_BAD_FIELD data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p4_7(self): type_ = ofproto.OFPET_BAD_MATCH code = ofproto.OFPBMC_BAD_VALUE data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p4_8(self): type_ = ofproto.OFPET_BAD_MATCH code = ofproto.OFPBMC_BAD_MASK data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p4_9(self): type_ = ofproto.OFPET_BAD_MATCH code = ofproto.OFPBMC_BAD_PREREQ data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p4_10(self): type_ = ofproto.OFPET_BAD_MATCH code = ofproto.OFPBMC_DUP_FIELD data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p4_11(self): type_ = ofproto.OFPET_BAD_MATCH code = ofproto.OFPBMC_EPERM data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p5_0(self): type_ = ofproto.OFPET_FLOW_MOD_FAILED code = ofproto.OFPFMFC_UNKNOWN data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p5_1(self): type_ = ofproto.OFPET_FLOW_MOD_FAILED code = ofproto.OFPFMFC_TABLE_FULL data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p5_2(self): type_ = ofproto.OFPET_FLOW_MOD_FAILED code = ofproto.OFPFMFC_BAD_TABLE_ID data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p5_3(self): type_ = ofproto.OFPET_FLOW_MOD_FAILED code = ofproto.OFPFMFC_OVERLAP data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p5_4(self): type_ = ofproto.OFPET_FLOW_MOD_FAILED code = ofproto.OFPFMFC_EPERM data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p5_5(self): type_ = ofproto.OFPET_FLOW_MOD_FAILED code = ofproto.OFPFMFC_BAD_TIMEOUT data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p5_6(self): type_ = ofproto.OFPET_FLOW_MOD_FAILED code = ofproto.OFPFMFC_BAD_COMMAND data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p5_7(self): type_ = ofproto.OFPET_FLOW_MOD_FAILED code = ofproto.OFPFMFC_BAD_FLAGS data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p6_0(self): type_ = ofproto.OFPET_GROUP_MOD_FAILED code = ofproto.OFPGMFC_GROUP_EXISTS data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p6_1(self): type_ = ofproto.OFPET_GROUP_MOD_FAILED code = ofproto.OFPGMFC_INVALID_GROUP data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p6_2(self): type_ = ofproto.OFPET_GROUP_MOD_FAILED code = ofproto.OFPGMFC_WEIGHT_UNSUPPORTED data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p6_3(self): type_ = ofproto.OFPET_GROUP_MOD_FAILED code = ofproto.OFPGMFC_OUT_OF_GROUPS data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p6_4(self): type_ = ofproto.OFPET_GROUP_MOD_FAILED code = ofproto.OFPGMFC_OUT_OF_BUCKETS data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p6_5(self): type_ = ofproto.OFPET_GROUP_MOD_FAILED code = ofproto.OFPGMFC_CHAINING_UNSUPPORTED data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p6_6(self): type_ = ofproto.OFPET_GROUP_MOD_FAILED code = ofproto.OFPGMFC_WATCH_UNSUPPORTED data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p6_7(self): type_ = ofproto.OFPET_GROUP_MOD_FAILED code = ofproto.OFPGMFC_LOOP data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p6_8(self): type_ = ofproto.OFPET_GROUP_MOD_FAILED code = ofproto.OFPGMFC_UNKNOWN_GROUP data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p6_9(self): type_ = ofproto.OFPET_GROUP_MOD_FAILED code = ofproto.OFPGMFC_CHAINED_GROUP data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p6_10(self): type_ = ofproto.OFPET_GROUP_MOD_FAILED code = ofproto.OFPGMFC_BAD_TYPE data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p6_11(self): type_ = ofproto.OFPET_GROUP_MOD_FAILED code = ofproto.OFPGMFC_BAD_COMMAND data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p6_12(self): type_ = ofproto.OFPET_GROUP_MOD_FAILED code = ofproto.OFPGMFC_BAD_BUCKET data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p6_13(self): type_ = ofproto.OFPET_GROUP_MOD_FAILED code = ofproto.OFPGMFC_BAD_WATCH data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p6_14(self): type_ = ofproto.OFPET_GROUP_MOD_FAILED code = ofproto.OFPGMFC_EPERM data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p7_0(self): type_ = ofproto.OFPET_PORT_MOD_FAILED code = ofproto.OFPPMFC_BAD_PORT data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p7_1(self): type_ = ofproto.OFPET_PORT_MOD_FAILED code = ofproto.OFPPMFC_BAD_HW_ADDR data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p7_2(self): type_ = ofproto.OFPET_PORT_MOD_FAILED code = ofproto.OFPPMFC_BAD_CONFIG data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p7_3(self): type_ = ofproto.OFPET_PORT_MOD_FAILED code = ofproto.OFPPMFC_BAD_ADVERTISE data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p7_4(self): type_ = ofproto.OFPET_PORT_MOD_FAILED code = ofproto.OFPPMFC_EPERM data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p8_0(self): type_ = ofproto.OFPET_TABLE_MOD_FAILED code = ofproto.OFPTMFC_BAD_TABLE data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p8_1(self): type_ = ofproto.OFPET_TABLE_MOD_FAILED code = ofproto.OFPTMFC_BAD_CONFIG data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p8_2(self): type_ = ofproto.OFPET_TABLE_MOD_FAILED code = ofproto.OFPTMFC_EPERM data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p9_0(self): type_ = ofproto.OFPET_QUEUE_OP_FAILED code = ofproto.OFPQOFC_BAD_PORT data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p9_1(self): type_ = ofproto.OFPET_QUEUE_OP_FAILED code = ofproto.OFPQOFC_BAD_QUEUE data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p9_2(self): type_ = ofproto.OFPET_QUEUE_OP_FAILED code = ofproto.OFPQOFC_EPERM data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p10_0(self): type_ = ofproto.OFPET_SWITCH_CONFIG_FAILED code = ofproto.OFPSCFC_BAD_FLAGS data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p10_1(self): type_ = ofproto.OFPET_SWITCH_CONFIG_FAILED code = ofproto.OFPSCFC_BAD_LEN data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p10_2(self): type_ = ofproto.OFPET_SWITCH_CONFIG_FAILED code = ofproto.OFPSCFC_EPERM data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p11_0(self): type_ = ofproto.OFPET_ROLE_REQUEST_FAILED code = ofproto.OFPRRFC_STALE data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p11_1(self): type_ = ofproto.OFPET_ROLE_REQUEST_FAILED code = ofproto.OFPRRFC_UNSUP data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_p11_2(self): type_ = ofproto.OFPET_ROLE_REQUEST_FAILED code = ofproto.OFPRRFC_BAD_ROLE data = b'Error Message.' self._test_parser(type_, code, data) def test_parser_experimenter(self): type_ = 0xffff exp_type = 1 experimenter = 1 data = b'Error Experimenter Message.' # OFP_ERROR_EXPERIMENTER_MSG_PACK_STR = '!HHI' fmt = ofproto.OFP_ERROR_EXPERIMENTER_MSG_PACK_STR buf = self.buf + pack(fmt, type_, exp_type, experimenter) \ + data res = OFPErrorMsg.parser(object, self.version, self.msg_type, self.msg_len, self.xid, buf) self.assertEqual(res.version, self.version) self.assertEqual(res.msg_type, self.msg_type) self.assertEqual(res.msg_len, self.msg_len) self.assertEqual(res.xid, self.xid) self.assertEqual(res.type, type_) self.assertEqual(res.exp_type, exp_type) self.assertEqual(res.experimenter, experimenter) self.assertEqual(res.data, data) def _test_serialize(self, type_, code, data): # OFP_ERROR_MSG_PACK_STR = '!HH' fmt = ofproto.OFP_ERROR_MSG_PACK_STR buf = self.buf + pack(fmt, type_, code) + data # initialization c = OFPErrorMsg(_Datapath) c.type = type_ c.code = code c.data = data c.serialize() self.assertEqual(ofproto.OFP_VERSION, c.version) self.assertEqual(ofproto.OFPT_ERROR, c.msg_type) self.assertEqual(0, c.xid) self.assertEqual(len(buf), c.msg_len) fmt = '!' \ + ofproto.OFP_HEADER_PACK_STR.replace('!', '') \ + ofproto.OFP_ERROR_MSG_PACK_STR.replace('!', '') \ + str(len(c.data)) + 's' res = struct.unpack(fmt, bytes(c.buf)) self.assertEqual(res[0], ofproto.OFP_VERSION) self.assertEqual(res[1], ofproto.OFPT_ERROR) self.assertEqual(res[2], len(buf)) self.assertEqual(res[3], 0) self.assertEqual(res[4], type_) self.assertEqual(res[5], code) self.assertEqual(res[6], data) def test_serialize_mid(self): type_ = 32768 code = 32768 data = b'Error Message.' self._test_serialize(type_, code, data) def test_serialize_max(self): type_ = 65534 # 65535 collides OFPET_EXPERIMENTER code = 65535 data = b'Error Message.'.ljust(65523) self._test_serialize(type_, code, data) def test_serialize_min_except_data(self): type_ = ofproto.OFPET_HELLO_FAILED code = ofproto.OFPHFC_INCOMPATIBLE data = b'Error Message.' self._test_serialize(type_, code, data) def test_serialize_check_data(self): c = OFPErrorMsg(_Datapath) self.assertRaises(AssertionError, c.serialize) def _test_serialize_p(self, type_, code): self._test_serialize(type_, code, b'Error Message.') def test_serialize_p0_1(self): self._test_serialize_p(ofproto.OFPET_HELLO_FAILED, ofproto.OFPHFC_EPERM) def test_serialize_p1_0(self): self._test_serialize_p(ofproto.OFPET_BAD_REQUEST, ofproto.OFPBRC_BAD_VERSION) def test_serialize_p1_1(self): self._test_serialize_p(ofproto.OFPET_BAD_REQUEST, ofproto.OFPBRC_BAD_TYPE) def test_serialize_p1_2(self): self._test_serialize_p(ofproto.OFPET_BAD_REQUEST, ofproto.OFPBRC_BAD_STAT) def test_serialize_p1_3(self): self._test_serialize_p(ofproto.OFPET_BAD_REQUEST, ofproto.OFPBRC_BAD_EXPERIMENTER) def test_serialize_p1_4(self): self._test_serialize_p(ofproto.OFPET_BAD_REQUEST, ofproto.OFPBRC_BAD_EXP_TYPE) def test_serialize_p1_5(self): self._test_serialize_p(ofproto.OFPET_BAD_REQUEST, ofproto.OFPBRC_EPERM) def test_serialize_p1_6(self): self._test_serialize_p(ofproto.OFPET_BAD_REQUEST, ofproto.OFPBRC_BAD_LEN) def test_serialize_p1_7(self): self._test_serialize_p(ofproto.OFPET_BAD_REQUEST, ofproto.OFPBRC_BUFFER_EMPTY) def test_serialize_p1_8(self): self._test_serialize_p(ofproto.OFPET_BAD_REQUEST, ofproto.OFPBRC_BUFFER_UNKNOWN) def test_serialize_p1_9(self): self._test_serialize_p(ofproto.OFPET_BAD_REQUEST, ofproto.OFPBRC_BAD_TABLE_ID) def test_serialize_p1_10(self): self._test_serialize_p(ofproto.OFPET_BAD_REQUEST, ofproto.OFPBRC_IS_SLAVE) def test_serialize_p1_11(self): self._test_serialize_p(ofproto.OFPET_BAD_REQUEST, ofproto.OFPBRC_BAD_PORT) def test_serialize_p1_12(self): self._test_serialize_p(ofproto.OFPET_BAD_REQUEST, ofproto.OFPBRC_BAD_PACKET) def test_serialize_p2_0(self): self._test_serialize_p(ofproto.OFPET_BAD_ACTION, ofproto.OFPBAC_BAD_TYPE) def test_serialize_p2_1(self): self._test_serialize_p(ofproto.OFPET_BAD_ACTION, ofproto.OFPBAC_BAD_LEN) def test_serialize_p2_2(self): self._test_serialize_p(ofproto.OFPET_BAD_ACTION, ofproto.OFPBAC_BAD_EXPERIMENTER) def test_serialize_p2_3(self): self._test_serialize_p(ofproto.OFPET_BAD_ACTION, ofproto.OFPBAC_BAD_EXP_TYPE) def test_serialize_p2_4(self): self._test_serialize_p(ofproto.OFPET_BAD_ACTION, ofproto.OFPBAC_BAD_OUT_PORT) def test_serialize_p2_5(self): self._test_serialize_p(ofproto.OFPET_BAD_ACTION, ofproto.OFPBAC_BAD_ARGUMENT) def test_serialize_p2_6(self): self._test_serialize_p(ofproto.OFPET_BAD_ACTION, ofproto.OFPBAC_EPERM) def test_serialize_p2_7(self): self._test_serialize_p(ofproto.OFPET_BAD_ACTION, ofproto.OFPBAC_TOO_MANY) def test_serialize_p2_8(self): self._test_serialize_p(ofproto.OFPET_BAD_ACTION, ofproto.OFPBAC_BAD_QUEUE) def test_serialize_p2_9(self): self._test_serialize_p(ofproto.OFPET_BAD_ACTION, ofproto.OFPBAC_BAD_OUT_GROUP) def test_serialize_p2_10(self): self._test_serialize_p(ofproto.OFPET_BAD_ACTION, ofproto.OFPBAC_MATCH_INCONSISTENT) def test_serialize_p2_11(self): self._test_serialize_p(ofproto.OFPET_BAD_ACTION, ofproto.OFPBAC_UNSUPPORTED_ORDER) def test_serialize_p2_12(self): self._test_serialize_p(ofproto.OFPET_BAD_ACTION, ofproto.OFPBAC_BAD_TAG) def test_serialize_p2_13(self): self._test_serialize_p(ofproto.OFPET_BAD_ACTION, ofproto.OFPBAC_BAD_SET_TYPE) def test_serialize_p2_14(self): self._test_serialize_p(ofproto.OFPET_BAD_ACTION, ofproto.OFPBAC_BAD_SET_LEN) def test_serialize_p2_15(self): self._test_serialize_p(ofproto.OFPET_BAD_ACTION, ofproto.OFPBAC_BAD_SET_ARGUMENT) def test_serialize_p3_0(self): self._test_serialize_p(ofproto.OFPET_BAD_INSTRUCTION, ofproto.OFPBIC_UNKNOWN_INST) def test_serialize_p3_1(self): self._test_serialize_p(ofproto.OFPET_BAD_INSTRUCTION, ofproto.OFPBIC_UNSUP_INST) def test_serialize_p3_2(self): self._test_serialize_p(ofproto.OFPET_BAD_INSTRUCTION, ofproto.OFPBIC_BAD_TABLE_ID) def test_serialize_p3_3(self): self._test_serialize_p(ofproto.OFPET_BAD_INSTRUCTION, ofproto.OFPBIC_UNSUP_METADATA) def test_serialize_p3_4(self): self._test_serialize_p(ofproto.OFPET_BAD_INSTRUCTION, ofproto.OFPBIC_UNSUP_METADATA_MASK) def test_serialize_p3_5(self): self._test_serialize_p(ofproto.OFPET_BAD_INSTRUCTION, ofproto.OFPBIC_BAD_EXPERIMENTER) def test_serialize_p3_6(self): self._test_serialize_p(ofproto.OFPET_BAD_INSTRUCTION, ofproto.OFPBIC_BAD_EXP_TYPE) def test_serialize_p3_7(self): self._test_serialize_p(ofproto.OFPET_BAD_INSTRUCTION, ofproto.OFPBIC_BAD_LEN) def test_serialize_p3_8(self): self._test_serialize_p(ofproto.OFPET_BAD_INSTRUCTION, ofproto.OFPBIC_EPERM) def test_serialize_p4_0(self): self._test_serialize_p(ofproto.OFPET_BAD_MATCH, ofproto.OFPBMC_BAD_TYPE) def test_serialize_p4_1(self): self._test_serialize_p(ofproto.OFPET_BAD_MATCH, ofproto.OFPBMC_BAD_LEN) def test_serialize_p4_2(self): self._test_serialize_p(ofproto.OFPET_BAD_MATCH, ofproto.OFPBMC_BAD_TAG) def test_serialize_p4_3(self): self._test_serialize_p(ofproto.OFPET_BAD_MATCH, ofproto.OFPBMC_BAD_DL_ADDR_MASK) def test_serialize_p4_4(self): self._test_serialize_p(ofproto.OFPET_BAD_MATCH, ofproto.OFPBMC_BAD_NW_ADDR_MASK) def test_serialize_p4_5(self): self._test_serialize_p(ofproto.OFPET_BAD_MATCH, ofproto.OFPBMC_BAD_WILDCARDS) def test_serialize_p4_6(self): self._test_serialize_p(ofproto.OFPET_BAD_MATCH, ofproto.OFPBMC_BAD_FIELD) def test_serialize_p4_7(self): self._test_serialize_p(ofproto.OFPET_BAD_MATCH, ofproto.OFPBMC_BAD_VALUE) def test_serialize_p4_8(self): self._test_serialize_p(ofproto.OFPET_BAD_MATCH, ofproto.OFPBMC_BAD_MASK) def test_serialize_p4_9(self): self._test_serialize_p(ofproto.OFPET_BAD_MATCH, ofproto.OFPBMC_BAD_PREREQ) def test_serialize_p4_10(self): self._test_serialize_p(ofproto.OFPET_BAD_MATCH, ofproto.OFPBMC_DUP_FIELD) def test_serialize_p4_11(self): self._test_serialize_p(ofproto.OFPET_BAD_MATCH, ofproto.OFPBMC_EPERM) def test_serialize_p5_0(self): self._test_serialize_p(ofproto.OFPET_FLOW_MOD_FAILED, ofproto.OFPFMFC_UNKNOWN) def test_serialize_p5_1(self): self._test_serialize_p(ofproto.OFPET_FLOW_MOD_FAILED, ofproto.OFPFMFC_TABLE_FULL) def test_serialize_p5_2(self): self._test_serialize_p(ofproto.OFPET_FLOW_MOD_FAILED, ofproto.OFPFMFC_BAD_TABLE_ID) def test_serialize_p5_3(self): self._test_serialize_p(ofproto.OFPET_FLOW_MOD_FAILED, ofproto.OFPFMFC_OVERLAP) def test_serialize_p5_4(self): self._test_serialize_p(ofproto.OFPET_FLOW_MOD_FAILED, ofproto.OFPFMFC_EPERM) def test_serialize_p5_5(self): self._test_serialize_p(ofproto.OFPET_FLOW_MOD_FAILED, ofproto.OFPFMFC_BAD_TIMEOUT) def test_serialize_p5_6(self): self._test_serialize_p(ofproto.OFPET_FLOW_MOD_FAILED, ofproto.OFPFMFC_BAD_COMMAND) def test_serialize_p5_7(self): self._test_serialize_p(ofproto.OFPET_FLOW_MOD_FAILED, ofproto.OFPFMFC_BAD_FLAGS) def test_serialize_p6_0(self): self._test_serialize_p(ofproto.OFPET_GROUP_MOD_FAILED, ofproto.OFPGMFC_GROUP_EXISTS) def test_serialize_p6_1(self): self._test_serialize_p(ofproto.OFPET_GROUP_MOD_FAILED, ofproto.OFPGMFC_INVALID_GROUP) def test_serialize_p6_2(self): self._test_serialize_p(ofproto.OFPET_GROUP_MOD_FAILED, ofproto.OFPGMFC_WEIGHT_UNSUPPORTED) def test_serialize_p6_3(self): self._test_serialize_p(ofproto.OFPET_GROUP_MOD_FAILED, ofproto.OFPGMFC_OUT_OF_GROUPS) def test_serialize_p6_4(self): self._test_serialize_p(ofproto.OFPET_GROUP_MOD_FAILED, ofproto.OFPGMFC_OUT_OF_BUCKETS) def test_serialize_p6_5(self): self._test_serialize_p(ofproto.OFPET_GROUP_MOD_FAILED, ofproto.OFPGMFC_CHAINING_UNSUPPORTED) def test_serialize_p6_6(self): self._test_serialize_p(ofproto.OFPET_GROUP_MOD_FAILED, ofproto.OFPGMFC_WATCH_UNSUPPORTED) def test_serialize_p6_7(self): self._test_serialize_p(ofproto.OFPET_GROUP_MOD_FAILED, ofproto.OFPGMFC_LOOP) def test_serialize_p6_8(self): self._test_serialize_p(ofproto.OFPET_GROUP_MOD_FAILED, ofproto.OFPGMFC_UNKNOWN_GROUP) def test_serialize_p6_9(self): self._test_serialize_p(ofproto.OFPET_GROUP_MOD_FAILED, ofproto.OFPGMFC_CHAINED_GROUP) def test_serialize_p6_10(self): self._test_serialize_p(ofproto.OFPET_GROUP_MOD_FAILED, ofproto.OFPGMFC_BAD_TYPE) def test_serialize_p6_11(self): self._test_serialize_p(ofproto.OFPET_GROUP_MOD_FAILED, ofproto.OFPGMFC_BAD_COMMAND) def test_serialize_p6_12(self): self._test_serialize_p(ofproto.OFPET_GROUP_MOD_FAILED, ofproto.OFPGMFC_BAD_BUCKET) def test_serialize_p6_13(self): self._test_serialize_p(ofproto.OFPET_GROUP_MOD_FAILED, ofproto.OFPGMFC_BAD_WATCH) def test_serialize_p6_14(self): self._test_serialize_p(ofproto.OFPET_GROUP_MOD_FAILED, ofproto.OFPGMFC_EPERM) def test_serialize_p7_0(self): self._test_serialize_p(ofproto.OFPET_PORT_MOD_FAILED, ofproto.OFPPMFC_BAD_PORT) def test_serialize_p7_1(self): self._test_serialize_p(ofproto.OFPET_PORT_MOD_FAILED, ofproto.OFPPMFC_BAD_HW_ADDR) def test_serialize_p7_2(self): self._test_serialize_p(ofproto.OFPET_PORT_MOD_FAILED, ofproto.OFPPMFC_BAD_CONFIG) def test_serialize_p7_3(self): self._test_serialize_p(ofproto.OFPET_PORT_MOD_FAILED, ofproto.OFPPMFC_BAD_ADVERTISE) def test_serialize_p7_4(self): self._test_serialize_p(ofproto.OFPET_PORT_MOD_FAILED, ofproto.OFPPMFC_EPERM) def test_serialize_p8_0(self): self._test_serialize_p(ofproto.OFPET_TABLE_MOD_FAILED, ofproto.OFPTMFC_BAD_TABLE) def test_serialize_p8_1(self): self._test_serialize_p(ofproto.OFPET_TABLE_MOD_FAILED, ofproto.OFPTMFC_BAD_CONFIG) def test_serialize_p8_2(self): self._test_serialize_p(ofproto.OFPET_TABLE_MOD_FAILED, ofproto.OFPTMFC_EPERM) def test_serialize_p9_0(self): self._test_serialize_p(ofproto.OFPET_QUEUE_OP_FAILED, ofproto.OFPQOFC_BAD_PORT) def test_serialize_p9_1(self): self._test_serialize_p(ofproto.OFPET_QUEUE_OP_FAILED, ofproto.OFPQOFC_BAD_QUEUE) def test_serialize_p9_2(self): self._test_serialize_p(ofproto.OFPET_QUEUE_OP_FAILED, ofproto.OFPQOFC_EPERM) def test_serialize_p10_0(self): self._test_serialize_p(ofproto.OFPET_SWITCH_CONFIG_FAILED, ofproto.OFPSCFC_BAD_FLAGS) def test_serialize_p10_1(self): self._test_serialize_p(ofproto.OFPET_SWITCH_CONFIG_FAILED, ofproto.OFPSCFC_BAD_LEN) def test_serialize_p10_2(self): self._test_serialize_p(ofproto.OFPET_SWITCH_CONFIG_FAILED, ofproto.OFPSCFC_EPERM) def test_serialize_p11_0(self): self._test_serialize_p(ofproto.OFPET_ROLE_REQUEST_FAILED, ofproto.OFPRRFC_STALE) def test_serialize_p11_1(self): self._test_serialize_p(ofproto.OFPET_ROLE_REQUEST_FAILED, ofproto.OFPRRFC_UNSUP) def test_serialize_p11_2(self): self._test_serialize_p(ofproto.OFPET_ROLE_REQUEST_FAILED, ofproto.OFPRRFC_BAD_ROLE) class TestOFPErrorExperimenterMsg(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPErrorExperimenterMsg """ def test_init(self): c = OFPErrorExperimenterMsg(_Datapath) self.assertEqual(c.type, 65535) self.assertEqual(c.exp_type, None) self.assertEqual(c.experimenter, None) self.assertEqual(c.data, None) def _test_parser(self, exp_type, experimenter, data=None): # OFP_HEADER_PACK_STR # '!BBHI'...version, msg_type, msg_len, xid version = ofproto.OFP_VERSION msg_type = ofproto.OFPT_ERROR msg_len = ofproto.OFP_ERROR_MSG_SIZE xid = 2495926989 fmt = ofproto.OFP_HEADER_PACK_STR buf = pack(fmt, version, msg_type, msg_len, xid) # OFP_ERROR_EXPERIMENTER_MSG_PACK_STR = '!HHI' type_ = 0xffff fmt = ofproto.OFP_ERROR_EXPERIMENTER_MSG_PACK_STR buf += pack(fmt, type_, exp_type, experimenter) if data is not None: buf += data res = OFPErrorMsg.parser( object, version, msg_type, msg_len, xid, buf) self.assertEqual(res.version, version) self.assertEqual(res.msg_type, msg_type) self.assertEqual(res.msg_len, msg_len) self.assertEqual(res.xid, xid) self.assertEqual(res.type, type_) self.assertEqual(res.exp_type, exp_type) self.assertEqual(res.experimenter, experimenter) if data is not None: self.assertEqual(res.data, data) def test_parser_mid(self): exp_type = 32768 experimenter = 2147483648 data = b'Error Experimenter Message.' self._test_parser(exp_type, experimenter, data) def test_parser_max(self): exp_type = 65535 experimenter = 4294967295 data = b'Error Experimenter Message.'.ljust(65519) self._test_parser(exp_type, experimenter, data) def test_parser_min(self): exp_type = 0 experimenter = 0 self._test_parser(exp_type, experimenter) class TestOFPEchoRequest(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPEchoRequest """ # OFP_HEADER_PACK_STR # '!BBHI'...version, msg_type, msg_len, xid version = ofproto.OFP_VERSION msg_type = ofproto.OFPT_ECHO_REQUEST msg_len = ofproto.OFP_HEADER_SIZE xid = 2495926989 def test_init(self): c = OFPEchoRequest(_Datapath) self.assertEqual(c.data, None) def _test_parser(self, data=None): fmt = ofproto.OFP_HEADER_PACK_STR buf = pack(fmt, self.version, self.msg_type, self.msg_len, self.xid) if data is not None: buf += data res = OFPEchoRequest.parser(object, self.version, self.msg_type, self.msg_len, self.xid, buf) self.assertEqual(res.version, self.version) self.assertEqual(res.msg_type, self.msg_type) self.assertEqual(res.msg_len, self.msg_len) self.assertEqual(res.xid, self.xid) if data is not None: self.assertEqual(res.data, data) def test_parser_mid(self): data = b'Request Message.' self._test_parser(data) def test_parser_max(self): data = b'Request Message.'.ljust(65527) self._test_parser(data) def test_parser_min(self): data = None self._test_parser(data) def _test_serialize(self, data): c = OFPEchoRequest(_Datapath) c.data = data c.serialize() self.assertEqual(ofproto.OFP_VERSION, c.version) self.assertEqual(ofproto.OFPT_ECHO_REQUEST, c.msg_type) self.assertEqual(0, c.xid) fmt = ofproto.OFP_HEADER_PACK_STR if data is not None: fmt += str(len(c.data)) + 's' res = struct.unpack(fmt, bytes(c.buf)) self.assertEqual(res[0], ofproto.OFP_VERSION) self.assertEqual(res[1], ofproto.OFPT_ECHO_REQUEST) self.assertEqual(res[2], len(c.buf)) self.assertEqual(res[3], 0) if data is not None: self.assertEqual(res[4], data) def test_serialize_mid(self): data = b'Request Message.' self._test_serialize(data) def test_serialize_max(self): data = b'Request Message.'.ljust(65527) self._test_serialize(data) def test_serialize_min(self): data = None self._test_serialize(data) class TestOFPEchoReply(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPEchoReply """ # OFP_HEADER_PACK_STR # '!BBHI'...version, msg_type, msg_len, xid version = ofproto.OFP_VERSION msg_type = ofproto.OFPT_ECHO_REPLY msg_len = ofproto.OFP_HEADER_SIZE xid = 2495926989 def test_init(self): c = OFPEchoReply(_Datapath) self.assertEqual(c.data, None) def _test_parser(self, data): fmt = ofproto.OFP_HEADER_PACK_STR buf = pack(fmt, self.version, self.msg_type, self.msg_len, self.xid) if data is not None: buf += data res = OFPEchoReply.parser(object, self.version, self.msg_type, self.msg_len, self.xid, buf) self.assertEqual(res.version, self.version) self.assertEqual(res.msg_type, self.msg_type) self.assertEqual(res.msg_len, self.msg_len) self.assertEqual(res.xid, self.xid) if data is not None: self.assertEqual(res.data, data) def test_parser_mid(self): data = b'Reply Message.' self._test_parser(data) def test_parser_max(self): data = b'Reply Message.'.ljust(65527) self._test_parser(data) def test_parser_min(self): data = None self._test_parser(data) def _test_serialize(self, data): fmt = ofproto.OFP_HEADER_PACK_STR buf = pack(fmt, self.version, self.msg_type, self.msg_len, self.xid) + data c = OFPEchoReply(_Datapath) c.data = data c.serialize() self.assertEqual(ofproto.OFP_VERSION, c.version) self.assertEqual(ofproto.OFPT_ECHO_REPLY, c.msg_type) self.assertEqual(0, c.xid) fmt = '!' \ + ofproto.OFP_HEADER_PACK_STR.replace('!', '') \ + str(len(c.data)) + 's' res = struct.unpack(fmt, bytes(c.buf)) self.assertEqual(res[0], ofproto.OFP_VERSION) self.assertEqual(res[1], ofproto.OFPT_ECHO_REPLY) self.assertEqual(res[2], len(buf)) self.assertEqual(res[3], 0) self.assertEqual(res[4], data) def test_serialize_mid(self): data = b'Reply Message.' self._test_serialize(data) def test_serialize_max(self): data = b'Reply Message.'.ljust(65527) self._test_serialize(data) def test_serialize_check_data(self): c = OFPEchoReply(_Datapath) self.assertRaises(AssertionError, c.serialize) class TestOFPExperimenter(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPExperimenter """ c = OFPExperimenter(_Datapath) def _test_parser(self, xid, experimenter, exp_type): # OFP_HEADER_PACK_STR # '!BBHI'...version, msg_type, msg_len, xid version = ofproto.OFP_VERSION msg_type = ofproto.OFPT_EXPERIMENTER msg_len = ofproto.OFP_EXPERIMENTER_HEADER_SIZE fmt = ofproto.OFP_HEADER_PACK_STR buf = pack(fmt, version, msg_type, msg_len, xid) # OFP_EXPERIMENTER_HEADER_PACK_STR # '!II'...experimenter, exp_type fmt = ofproto.OFP_EXPERIMENTER_HEADER_PACK_STR buf += pack(fmt, experimenter, exp_type) res = OFPExperimenter.parser(object, version, msg_type, msg_len, xid, buf) self.assertEqual(version, res.version) self.assertEqual(msg_type, res.msg_type) self.assertEqual(msg_len, res.msg_len) self.assertEqual(xid, res.xid) self.assertEqual(experimenter, res.experimenter) self.assertEqual(exp_type, res.exp_type) def test_parser_mid(self): xid = 2495926989 experimenter = 2147483648 exp_type = 1 self._test_parser(xid, experimenter, exp_type) def test_parser_max(self): xid = 4294967295 experimenter = 4294967295 exp_type = 65535 self._test_parser(xid, experimenter, exp_type) def test_parser_min(self): xid = 0 experimenter = 0 exp_type = 0 self._test_parser(xid, experimenter, exp_type) class TestOFPPort(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPPort """ def test_init(self): # OFP_PORT_PACK_STR # '!I4x6s2x16sIIIIIIII'... port_no, pad(4), hw_addr, pad(2), # name, config, state, curr, advertised, # peer, curr_speed, max_speed port_no = 1119692796 hw_addr = 'c0:26:53:c4:29:e2' name = b'name'.ljust(16) config = 2226555987 state = 1678244809 curr = 2850556459 advertised = 2025421682 supported = 2120575149 peer = 2757463021 curr_speed = 2641353507 max_speed = 1797291672 fmt = ofproto.OFP_PORT_PACK_STR c = OFPPort(port_no, hw_addr, name, config, state, curr, advertised, supported, peer, curr_speed, max_speed) self.assertEqual(port_no, c.port_no) self.assertEqual(hw_addr, c.hw_addr) self.assertEqual(name, c.name) self.assertEqual(config, c.config) self.assertEqual(state, c.state) self.assertEqual(curr, c.curr) self.assertEqual(advertised, c.advertised) self.assertEqual(supported, c.supported) self.assertEqual(peer, c.peer) self.assertEqual(curr_speed, c.curr_speed) self.assertEqual(max_speed, c.max_speed) def _test_parser(self, port_no, hw_addr, config, state, curr, advertised, supported, peer, curr_speed, max_speed): name = b'name'.ljust(16) fmt = ofproto.OFP_PORT_PACK_STR buf = pack(fmt, port_no, addrconv.mac.text_to_bin(hw_addr), name, config, state, curr, advertised, supported, peer, curr_speed, max_speed) res = OFPPort.parser(buf, 0) self.assertEqual(port_no, res.port_no) self.assertEqual(hw_addr, res.hw_addr) self.assertEqual(name, res.name) self.assertEqual(config, res.config) self.assertEqual(state, res.state) self.assertEqual(curr, res.curr) self.assertEqual(advertised, res.advertised) self.assertEqual(supported, res.supported) self.assertEqual(peer, res.peer) self.assertEqual(curr_speed, res.curr_speed) self.assertEqual(max_speed, res.max_speed) def test_parser_mid(self): port_no = 1119692796 hw_addr = 'c0:26:53:c4:29:e2' config = 2226555987 state = 1678244809 curr = 2850556459 advertised = 2025421682 supported = 2120575149 peer = 2757463021 curr_speed = 2641353507 max_speed = 1797291672 self._test_parser(port_no, hw_addr, config, state, curr, advertised, supported, peer, curr_speed, max_speed) def test_parser_max(self): port_no = ofproto.OFPP_ANY hw_addr = 'ff:ff:ff:ff:ff:ff' config = 4294967295 state = 4294967295 curr = 4294967295 advertised = 4294967295 supported = 4294967295 peer = 4294967295 curr_speed = 4294967295 max_speed = 4294967295 self._test_parser(port_no, hw_addr, config, state, curr, advertised, supported, peer, curr_speed, max_speed) def test_parser_min(self): port_no = 0 hw_addr = '00:00:00:00:00:00' config = 0 state = 0 curr = 0 advertised = 0 supported = 0 peer = 0 curr_speed = 0 max_speed = 0 self._test_parser(port_no, hw_addr, config, state, curr, advertised, supported, peer, curr_speed, max_speed) def test_parser_p1(self): port_no = ofproto.OFPP_MAX hw_addr = 'c0:26:53:c4:29:e2' config = ofproto.OFPPC_PORT_DOWN state = ofproto.OFPPS_LINK_DOWN curr = advertised = supported \ = peer = curr_speed = max_speed \ = ofproto.OFPPF_10MB_HD self._test_parser(port_no, hw_addr, config, state, curr, advertised, supported, peer, curr_speed, max_speed) def test_parser_p2(self): port_no = ofproto.OFPP_IN_PORT hw_addr = 'c0:26:53:c4:29:e2' config = ofproto.OFPPC_NO_RECV state = ofproto.OFPPS_BLOCKED curr = advertised = supported \ = peer = curr_speed = max_speed \ = ofproto.OFPPF_10MB_FD self._test_parser(port_no, hw_addr, config, state, curr, advertised, supported, peer, curr_speed, max_speed) def test_parser_p3(self): port_no = ofproto.OFPP_TABLE hw_addr = 'c0:26:53:c4:29:e2' config = ofproto.OFPPC_NO_FWD state = ofproto.OFPPS_LIVE curr = advertised = supported \ = peer = curr_speed = max_speed \ = ofproto.OFPPF_100MB_HD self._test_parser(port_no, hw_addr, config, state, curr, advertised, supported, peer, curr_speed, max_speed) def test_parser_p4(self): port_no = ofproto.OFPP_NORMAL hw_addr = 'c0:26:53:c4:29:e2' config = ofproto.OFPPC_NO_PACKET_IN state = ofproto.OFPPS_LIVE curr = advertised = supported \ = peer = curr_speed = max_speed \ = ofproto.OFPPF_100MB_FD self._test_parser(port_no, hw_addr, config, state, curr, advertised, supported, peer, curr_speed, max_speed) def test_parser_p5(self): port_no = ofproto.OFPP_FLOOD hw_addr = 'c0:26:53:c4:29:e2' config = ofproto.OFPPC_NO_PACKET_IN state = ofproto.OFPPS_LIVE curr = advertised = supported \ = peer = curr_speed = max_speed \ = ofproto.OFPPF_1GB_HD self._test_parser(port_no, hw_addr, config, state, curr, advertised, supported, peer, curr_speed, max_speed) def test_parser_p6(self): port_no = ofproto.OFPP_ALL hw_addr = 'c0:26:53:c4:29:e2' config = ofproto.OFPPC_NO_PACKET_IN state = ofproto.OFPPS_LIVE curr = advertised = supported \ = peer = curr_speed = max_speed \ = ofproto.OFPPF_1GB_FD self._test_parser(port_no, hw_addr, config, state, curr, advertised, supported, peer, curr_speed, max_speed) def test_parser_p7(self): port_no = ofproto.OFPP_CONTROLLER hw_addr = 'c0:26:53:c4:29:e2' config = ofproto.OFPPC_NO_PACKET_IN state = ofproto.OFPPS_LIVE curr = advertised = supported \ = peer = curr_speed = max_speed \ = ofproto.OFPPF_10GB_FD self._test_parser(port_no, hw_addr, config, state, curr, advertised, supported, peer, curr_speed, max_speed) def test_parser_p8(self): port_no = ofproto.OFPP_LOCAL hw_addr = 'c0:26:53:c4:29:e2' config = ofproto.OFPPC_NO_PACKET_IN state = ofproto.OFPPS_LIVE curr = advertised = supported \ = peer = curr_speed = max_speed \ = ofproto.OFPPF_40GB_FD self._test_parser(port_no, hw_addr, config, state, curr, advertised, supported, peer, curr_speed, max_speed) def test_parser_p9(self): port_no = ofproto.OFPP_LOCAL hw_addr = 'c0:26:53:c4:29:e2' config = ofproto.OFPPC_NO_PACKET_IN state = ofproto.OFPPS_LIVE curr = advertised = supported \ = peer = curr_speed = max_speed \ = ofproto.OFPPF_100GB_FD self._test_parser(port_no, hw_addr, config, state, curr, advertised, supported, peer, curr_speed, max_speed) def test_parser_p10(self): port_no = ofproto.OFPP_LOCAL hw_addr = 'c0:26:53:c4:29:e2' config = ofproto.OFPPC_NO_PACKET_IN state = ofproto.OFPPS_LIVE curr = advertised = supported \ = peer = curr_speed = max_speed \ = ofproto.OFPPF_1TB_FD self._test_parser(port_no, hw_addr, config, state, curr, advertised, supported, peer, curr_speed, max_speed) def test_parser_p11(self): port_no = ofproto.OFPP_LOCAL hw_addr = 'c0:26:53:c4:29:e2' config = ofproto.OFPPC_NO_PACKET_IN state = ofproto.OFPPS_LIVE curr = advertised = supported \ = peer = curr_speed = max_speed \ = ofproto.OFPPF_OTHER self._test_parser(port_no, hw_addr, config, state, curr, advertised, supported, peer, curr_speed, max_speed) def test_parser_p12(self): port_no = ofproto.OFPP_LOCAL hw_addr = 'c0:26:53:c4:29:e2' config = ofproto.OFPPC_NO_PACKET_IN state = ofproto.OFPPS_LIVE curr = advertised = supported \ = peer = curr_speed = max_speed \ = ofproto.OFPPF_COPPER self._test_parser(port_no, hw_addr, config, state, curr, advertised, supported, peer, curr_speed, max_speed) def test_parser_p13(self): port_no = ofproto.OFPP_LOCAL hw_addr = 'c0:26:53:c4:29:e2' config = ofproto.OFPPC_NO_PACKET_IN state = ofproto.OFPPS_LIVE curr = advertised = supported \ = peer = curr_speed = max_speed \ = ofproto.OFPPF_FIBER self._test_parser(port_no, hw_addr, config, state, curr, advertised, supported, peer, curr_speed, max_speed) def test_parser_p14(self): port_no = ofproto.OFPP_LOCAL hw_addr = 'c0:26:53:c4:29:e2' config = ofproto.OFPPC_NO_PACKET_IN state = ofproto.OFPPS_LIVE curr = advertised = supported \ = peer = curr_speed = max_speed \ = ofproto.OFPPF_AUTONEG self._test_parser(port_no, hw_addr, config, state, curr, advertised, supported, peer, curr_speed, max_speed) def test_parser_p15(self): port_no = ofproto.OFPP_LOCAL hw_addr = 'c0:26:53:c4:29:e2' config = ofproto.OFPPC_NO_PACKET_IN state = ofproto.OFPPS_LIVE curr = advertised = supported \ = peer = curr_speed = max_speed \ = ofproto.OFPPF_PAUSE self._test_parser(port_no, hw_addr, config, state, curr, advertised, supported, peer, curr_speed, max_speed) def test_parser_p16(self): port_no = ofproto.OFPP_LOCAL hw_addr = 'c0:26:53:c4:29:e2' config = ofproto.OFPPC_NO_PACKET_IN state = ofproto.OFPPS_LIVE curr = advertised = supported \ = peer = curr_speed = max_speed \ = ofproto.OFPPF_PAUSE_ASYM self._test_parser(port_no, hw_addr, config, state, curr, advertised, supported, peer, curr_speed, max_speed) class TestOFPFeaturesRequest(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPFeaturesRequest """ def test_serialize(self): c = OFPFeaturesRequest(_Datapath) c.serialize() self.assertEqual(ofproto.OFP_VERSION, c.version) self.assertEqual(ofproto.OFPT_FEATURES_REQUEST, c.msg_type) self.assertEqual(0, c.xid) fmt = ofproto.OFP_HEADER_PACK_STR res = struct.unpack(fmt, bytes(c.buf)) self.assertEqual(res[0], ofproto.OFP_VERSION) self.assertEqual(res[1], ofproto.OFPT_FEATURES_REQUEST) self.assertEqual(res[2], len(c.buf)) self.assertEqual(res[3], 0) class TestOFPSwitchFeatures(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPSwitchFeatures """ def _test_parser(self, xid, datapath_id, n_buffers, n_tables, capabilities, reserved, port_cnt=0): # OFP_HEADER_PACK_STR # '!BBHI'...version, msg_type, msg_len, xid version = ofproto.OFP_VERSION msg_type = ofproto.OFPT_FEATURES_REPLY msg_len = ofproto.OFP_SWITCH_FEATURES_SIZE \ + ofproto.OFP_PORT_SIZE * port_cnt fmt = ofproto.OFP_HEADER_PACK_STR buf = pack(fmt, version, msg_type, msg_len, xid) # OFP_SWITCH_FEATURES_PACK_STR # '!QIB3xII'...datapath_id, n_buffers, n_tables, # pad(3), capabilities, reserved fmt = ofproto.OFP_SWITCH_FEATURES_PACK_STR buf += pack(fmt, datapath_id, n_buffers, n_tables, capabilities, reserved) for i in range(port_cnt): # OFP_PORT_PACK_STR # '!I4x6s2x16sIIIIIIII'... port_no, pad(4), hw_addr, pad(2), # name, config, state, curr, advertised, # peer, curr_speed, max_speed port_no = i fmt = ofproto.OFP_PORT_PACK_STR buf += pack(fmt, port_no, b'\x00' * 6, b'\x00' * 16, 0, 0, 0, 0, 0, 0, 0, 0) res = OFPSwitchFeatures.parser(object, version, msg_type, msg_len, xid, buf) self.assertEqual(res.version, version) self.assertEqual(res.msg_type, msg_type) self.assertEqual(res.msg_len, msg_len) self.assertEqual(res.xid, xid) self.assertEqual(res.datapath_id, datapath_id) self.assertEqual(res.n_buffers, n_buffers) self.assertEqual(res.n_tables, n_tables) self.assertEqual(res.capabilities, capabilities) self.assertEqual(res._reserved, reserved) for i in range(port_cnt): self.assertEqual(res.ports[i].port_no, i) def test_parser_mid(self): xid = 2495926989 datapath_id = 1270985291017894273 n_buffers = 2148849654 n_tables = 228 capabilities = 1766843586 reserved = 2013714700 port_cnt = 1 self._test_parser(xid, datapath_id, n_buffers, n_tables, capabilities, reserved, port_cnt) def test_parser_max(self): xid = 4294967295 datapath_id = 18446744073709551615 n_buffers = 4294967295 n_tables = 255 capabilities = 4294967295 reserved = 4294967295 port_cnt = 1023 self._test_parser(xid, datapath_id, n_buffers, n_tables, capabilities, reserved, port_cnt) def test_parser_min(self): xid = 0 datapath_id = 0 n_buffers = 0 n_tables = 0 capabilities = 0 reserved = 0 port_cnt = 0 self._test_parser(xid, datapath_id, n_buffers, n_tables, capabilities, reserved, port_cnt) class TestOFPGetConfigRequest(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPGetConfigRequest """ def test_serialize(self): c = OFPGetConfigRequest(_Datapath) c.serialize() self.assertEqual(ofproto.OFP_VERSION, c.version) self.assertEqual(ofproto.OFPT_GET_CONFIG_REQUEST, c.msg_type) self.assertEqual(0, c.xid) fmt = ofproto.OFP_HEADER_PACK_STR res = struct.unpack(fmt, bytes(c.buf)) self.assertEqual(res[0], ofproto.OFP_VERSION) self.assertEqual(res[1], ofproto.OFPT_GET_CONFIG_REQUEST) self.assertEqual(res[2], len(c.buf)) self.assertEqual(res[3], 0) class TestOFPGetConfigReply(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPGetConfigReply """ def _test_parser(self, xid, flags, miss_send_len): # OFP_HEADER_PACK_STR # '!BBHI'...version, msg_type, msg_len, xid version = ofproto.OFP_VERSION msg_type = ofproto.OFPT_GET_CONFIG_REPLY msg_len = ofproto.OFP_SWITCH_CONFIG_SIZE fmt = ofproto.OFP_HEADER_PACK_STR buf = pack(fmt, version, msg_type, msg_len, xid) # OFP_SWITCH_CONFIG_PACK_STR # '!HH'...flags, miss_send_len fmt = ofproto.OFP_SWITCH_CONFIG_PACK_STR buf += pack(fmt, flags, miss_send_len) res = OFPGetConfigReply.parser(object, version, msg_type, msg_len, xid, buf) self.assertEqual(version, res.version) self.assertEqual(msg_type, res.msg_type) self.assertEqual(msg_len, res.msg_len) self.assertEqual(xid, res.xid) self.assertEqual(flags, res.flags) self.assertEqual(miss_send_len, res.miss_send_len) def test_parser_mid(self): xid = 3423224276 flags = 41186 miss_send_len = 13838 self._test_parser(xid, flags, miss_send_len) def test_parser_max(self): xid = 4294967295 flags = 65535 miss_send_len = 65535 self._test_parser(xid, flags, miss_send_len) def test_parser_min(self): xid = 0 flags = ofproto.OFPC_FRAG_NORMAL miss_send_len = 0 self._test_parser(xid, flags, miss_send_len) def test_parser_p1(self): xid = 3423224276 flags = ofproto.OFPC_FRAG_DROP miss_send_len = 13838 self._test_parser(xid, flags, miss_send_len) def test_parser_p2(self): xid = 3423224276 flags = ofproto.OFPC_FRAG_REASM miss_send_len = 13838 self._test_parser(xid, flags, miss_send_len) def test_parser_p3(self): xid = 3423224276 flags = ofproto.OFPC_FRAG_MASK miss_send_len = 13838 self._test_parser(xid, flags, miss_send_len) def test_parser_p4(self): xid = 3423224276 flags = ofproto.OFPC_INVALID_TTL_TO_CONTROLLER miss_send_len = 13838 self._test_parser(xid, flags, miss_send_len) class TestOFPSetConfig(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPSetConfig """ def test_init(self): # OFP_SWITCH_CONFIG_PACK_STR # '!HH'...flags, miss_send_len flags = 41186 miss_send_len = 13838 c = OFPSetConfig(_Datapath, flags, miss_send_len) self.assertEqual(flags, c.flags) self.assertEqual(miss_send_len, c.miss_send_len) def _test_serialize(self, flags, miss_send_len): c = OFPSetConfig(_Datapath, flags, miss_send_len) c.serialize() self.assertEqual(ofproto.OFP_VERSION, c.version) self.assertEqual(ofproto.OFPT_SET_CONFIG, c.msg_type) self.assertEqual(0, c.xid) fmt = '!' \ + ofproto.OFP_HEADER_PACK_STR.replace('!', '') \ + ofproto.OFP_SWITCH_CONFIG_PACK_STR.replace('!', '') res = struct.unpack(fmt, bytes(c.buf)) self.assertEqual(res[0], ofproto.OFP_VERSION) self.assertEqual(res[1], ofproto.OFPT_SET_CONFIG) self.assertEqual(res[2], len(c.buf)) self.assertEqual(res[3], 0) self.assertEqual(res[4], flags) self.assertEqual(res[5], miss_send_len) def test_serialize_mid(self): flags = 41186 miss_send_len = 13838 self._test_serialize(flags, miss_send_len) def test_serialize_max(self): flags = 65535 miss_send_len = 65535 self._test_serialize(flags, miss_send_len) def test_serialize_min(self): flags = ofproto.OFPC_FRAG_NORMAL miss_send_len = 0 self._test_serialize(flags, miss_send_len) def test_serialize_p1(self): flags = ofproto.OFPC_FRAG_DROP miss_send_len = 13838 self._test_serialize(flags, miss_send_len) def test_serialize_p2(self): flags = ofproto.OFPC_FRAG_REASM miss_send_len = 13838 self._test_serialize(flags, miss_send_len) def test_serialize_p3(self): flags = ofproto.OFPC_FRAG_MASK miss_send_len = 13838 self._test_serialize(flags, miss_send_len) def test_serialize_p4(self): flags = ofproto.OFPC_INVALID_TTL_TO_CONTROLLER miss_send_len = 13838 self._test_serialize(flags, miss_send_len) def test_serialize_check_flags(self): flags = None miss_send_len = 13838 c = OFPSetConfig(_Datapath, flags, miss_send_len) self.assertRaises(AssertionError, c.serialize) def test_serialize_check_miss_send_len(self): flags = 41186 miss_send_len = None c = OFPSetConfig(_Datapath, flags, miss_send_len) self.assertRaises(AssertionError, c.serialize) class TestOFPPacketIn(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPPacketIn """ def _test_parser(self, xid, buffer_id, total_len=0, reason=0, table_id=0, data=None): if data is None: data = b'' # OFP_HEADER_PACK_STR # '!BBHI'...version, msg_type, msg_len, xid version = ofproto.OFP_VERSION msg_type = ofproto.OFPT_PACKET_IN msg_len = ofproto.OFP_PACKET_IN_SIZE + len(data) fmt = ofproto.OFP_HEADER_PACK_STR buf = pack(fmt, version, msg_type, msg_len, xid) # OFP_PACKET_IN_PACK_STR fmt = ofproto.OFP_PACKET_IN_PACK_STR buf += pack(fmt, buffer_id, total_len, reason, table_id) # match buf_match = bytearray() match = OFPMatch() match.serialize(buf_match, 0) buf += bytes(buf_match) # data buf += b'\x00' * 2 buf += data res = OFPPacketIn.parser(object, version, msg_type, msg_len, xid, buf) self.assertEqual(version, res.version) self.assertEqual(msg_type, res.msg_type) self.assertEqual(msg_len, res.msg_len) self.assertEqual(xid, res.xid) self.assertEqual(buffer_id, res.buffer_id) self.assertEqual(total_len, res.total_len) self.assertEqual(reason, res.reason) self.assertEqual(table_id, res.table_id) self.assertTrue(hasattr(res, 'match')) self.assertEqual(ofproto.OFPMT_OXM, res.match.type) if data: self.assertEqual(data[:total_len], res.data) def test_data_is_total_len(self): xid = 3423224276 buffer_id = 2926809324 reason = 128 table_id = 3 data = b'PacketIn' total_len = len(data) self._test_parser(xid, buffer_id, total_len, reason, table_id, data) def test_data_is_not_total_len(self): xid = 3423224276 buffer_id = 2926809324 reason = 128 table_id = 3 data = b'PacketIn' total_len = len(data) - 1 self._test_parser(xid, buffer_id, total_len, reason, table_id, data) def test_parser_max(self): # 65535(!H max) - 24(without data) = 65511 xid = 4294967295 buffer_id = 4294967295 reason = 255 table_id = 255 data = b'data'.ljust(65511) total_len = len(data) self._test_parser(xid, buffer_id, total_len, reason, table_id, data) def test_parser_min(self): xid = 0 buffer_id = 0 reason = ofproto.OFPR_NO_MATCH table_id = 0 total_len = 0 self._test_parser(xid, buffer_id, total_len, reason, table_id) def test_parser_p1(self): data = b'data'.ljust(8) xid = 3423224276 buffer_id = 2926809324 total_len = len(data) reason = ofproto.OFPR_ACTION table_id = 3 self._test_parser(xid, buffer_id, total_len, reason, table_id, data) def test_parser_p2(self): data = b'data'.ljust(8) xid = 3423224276 buffer_id = 2926809324 total_len = len(data) reason = ofproto.OFPR_INVALID_TTL table_id = 3 self._test_parser(xid, buffer_id, total_len, reason, table_id, data) class TestOFPFlowRemoved(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPFlowRemoved """ def _test_parser(self, xid, cookie, priority, reason, table_id, duration_sec, duration_nsec, idle_timeout, hard_timeout, packet_count, byte_count): # OFP_HEADER_PACK_STR # '!BBHI'...version, msg_type, msg_len, xid version = ofproto.OFP_VERSION msg_type = ofproto.OFPT_FLOW_REMOVED msg_len = ofproto.OFP_FLOW_REMOVED_SIZE fmt = ofproto.OFP_HEADER_PACK_STR buf = pack(fmt, version, msg_type, msg_len, xid) # OFP_FLOW_REMOVED_PACK_STR0 # '!QHBBIIHHQQ' ...cookie, priority, reason, table_id, # duration_sec, duration_nsec, idle_timeout, # hard_timeout, packet_count, byte_count fmt = ofproto.OFP_FLOW_REMOVED_PACK_STR0 buf += pack(fmt, cookie, priority, reason, table_id, duration_sec, duration_nsec, idle_timeout, hard_timeout, packet_count, byte_count) # OFP_MATCH_PACK_STR match = OFPMatch() buf_match = bytearray() match.serialize(buf_match, 0) buf += bytes(buf_match) res = OFPFlowRemoved.parser(object, version, msg_type, msg_len, xid, buf) self.assertEqual(version, res.version) self.assertEqual(msg_type, res.msg_type) self.assertEqual(msg_len, res.msg_len) self.assertEqual(xid, res.xid) self.assertEqual(cookie, res.cookie) self.assertEqual(priority, res.priority) self.assertEqual(reason, res.reason) self.assertEqual(table_id, res.table_id) self.assertEqual(duration_sec, res.duration_sec) self.assertEqual(duration_nsec, res.duration_nsec) self.assertEqual(idle_timeout, res.idle_timeout) self.assertEqual(hard_timeout, res.hard_timeout) self.assertEqual(packet_count, res.packet_count) self.assertEqual(byte_count, res.byte_count) self.assertTrue(hasattr(res, 'match')) self.assertEqual(ofproto.OFPMT_OXM, res.match.type) def test_parser_mid(self): xid = 3423224276 cookie = 178378173441633860 priority = 718 reason = 128 table_id = 169 duration_sec = 2250548154 duration_nsec = 2492776995 idle_timeout = 60284 hard_timeout = 60285 packet_count = 6489108735192644493 byte_count = 7334344481123449724 self._test_parser(xid, cookie, priority, reason, table_id, duration_sec, duration_nsec, idle_timeout, hard_timeout, packet_count, byte_count) def test_parser_max(self): xid = 4294967295 cookie = 18446744073709551615 priority = 65535 reason = 255 table_id = 255 duration_sec = 4294967295 duration_nsec = 4294967295 idle_timeout = 65535 hard_timeout = 65535 packet_count = 18446744073709551615 byte_count = 18446744073709551615 self._test_parser(xid, cookie, priority, reason, table_id, duration_sec, duration_nsec, idle_timeout, hard_timeout, packet_count, byte_count) def test_parser_min(self): xid = 0 cookie = 0 priority = 0 reason = ofproto.OFPRR_IDLE_TIMEOUT table_id = 0 duration_sec = 0 duration_nsec = 0 idle_timeout = 0 hard_timeout = 0 packet_count = 0 byte_count = 0 self._test_parser(xid, cookie, priority, reason, table_id, duration_sec, duration_nsec, idle_timeout, hard_timeout, packet_count, byte_count) def test_parser_p1(self): xid = 3423224276 cookie = 178378173441633860 priority = 718 reason = ofproto.OFPRR_HARD_TIMEOUT table_id = 169 duration_sec = 2250548154 duration_nsec = 2492776995 idle_timeout = 60284 hard_timeout = 60285 packet_count = 6489108735192644493 byte_count = 7334344481123449724 self._test_parser(xid, cookie, priority, reason, table_id, duration_sec, duration_nsec, idle_timeout, hard_timeout, packet_count, byte_count) def test_parser_p2(self): xid = 3423224276 cookie = 178378173441633860 priority = 718 reason = ofproto.OFPRR_DELETE table_id = 169 duration_sec = 2250548154 duration_nsec = 2492776995 idle_timeout = 60284 hard_timeout = 60285 packet_count = 6489108735192644493 byte_count = 7334344481123449724 self._test_parser(xid, cookie, priority, reason, table_id, duration_sec, duration_nsec, idle_timeout, hard_timeout, packet_count, byte_count) def test_parser_p3(self): xid = 3423224276 cookie = 178378173441633860 priority = 718 reason = ofproto.OFPRR_GROUP_DELETE table_id = 169 duration_sec = 2250548154 duration_nsec = 2492776995 idle_timeout = 60284 hard_timeout = 60285 packet_count = 6489108735192644493 byte_count = 7334344481123449724 self._test_parser(xid, cookie, priority, reason, table_id, duration_sec, duration_nsec, idle_timeout, hard_timeout, packet_count, byte_count) class TestOFPPortStatus(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPPortStatus """ def _test_parser(self, xid, reason, port_no, config, state, curr, advertised, supported, peer, curr_speed, max_speed): # OFP_HEADER_PACK_STR # '!BBHI'...version, msg_type, msg_len, xid version = ofproto.OFP_VERSION msg_type = ofproto.OFPT_PORT_STATUS msg_len = ofproto.OFP_PORT_STATUS_SIZE fmt = ofproto.OFP_HEADER_PACK_STR buf = pack(fmt, version, msg_type, msg_len, xid) # OFP_PORT_STATUS_PACK_STR = '!B7x' + _OFP_PORT_PACK_STR # '!B7x'...reason, pad(7) # OFP_PORT_PACK_STR # '!I4x6s2x16sIIIIIIII'... port_no, pad(4), hw_addr, pad(2), # name, config, state, curr, advertised, # peer, curr_speed, max_speed hw_addr = '80:ff:9a:e3:72:85' name = b'name'.ljust(16) fmt = ofproto.OFP_PORT_STATUS_PACK_STR buf += pack(fmt, reason, port_no, addrconv.mac.text_to_bin(hw_addr), name, config, state, curr, advertised, supported, peer, curr_speed, max_speed) res = OFPPortStatus.parser(object, version, msg_type, msg_len, xid, buf) self.assertEqual(reason, res.reason) self.assertEqual(port_no, res.desc.port_no) self.assertEqual(hw_addr, res.desc.hw_addr) self.assertEqual(name, res.desc.name) self.assertEqual(config, res.desc.config) self.assertEqual(state, res.desc.state) self.assertEqual(curr, res.desc.curr) self.assertEqual(advertised, res.desc.advertised) self.assertEqual(supported, res.desc.supported) self.assertEqual(peer, res.desc.peer) self.assertEqual(curr_speed, res.desc.curr_speed) self.assertEqual(max_speed, res.desc.max_speed) def test_parser_mid(self): xid = 3423224276 reason = 128 port_no = 1119692796 config = 2226555987 state = 1678244809 curr = 2850556459 advertised = 2025421682 supported = 2120575149 peer = 2757463021 curr_speed = 2641353507 max_speed = 1797291672 self._test_parser(xid, reason, port_no, config, state, curr, advertised, supported, peer, curr_speed, max_speed) def test_parser_max(self): xid = 4294967295 reason = 255 port_no = ofproto.OFPP_ANY config = 4294967295 state = 4294967295 curr = 4294967295 advertised = 4294967295 supported = 4294967295 peer = 4294967295 curr_speed = 4294967295 max_speed = 4294967295 self._test_parser(xid, reason, port_no, config, state, curr, advertised, supported, peer, curr_speed, max_speed) def test_parser_min(self): xid = 0 reason = 0 port_no = 0 config = 0 state = 0 curr = 0 advertised = 0 supported = 0 peer = 0 curr_speed = 0 max_speed = 0 self._test_parser(xid, reason, port_no, config, state, curr, advertised, supported, peer, curr_speed, max_speed) def test_parser_p1(self): xid = 3423224276 reason = ofproto.OFPPR_DELETE port_no = ofproto.OFPP_MAX config = ofproto.OFPPC_PORT_DOWN state = ofproto.OFPPS_LINK_DOWN curr = advertised = supported \ = peer = curr_speed = max_speed \ = ofproto.OFPPF_10MB_HD self._test_parser(xid, reason, port_no, config, state, curr, advertised, supported, peer, curr_speed, max_speed) def test_parser_p2(self): xid = 3423224276 reason = ofproto.OFPPR_MODIFY port_no = ofproto.OFPP_MAX config = ofproto.OFPPC_PORT_DOWN state = ofproto.OFPPS_LINK_DOWN curr = advertised = supported \ = peer = curr_speed = max_speed \ = ofproto.OFPPF_10MB_HD self._test_parser(xid, reason, port_no, config, state, curr, advertised, supported, peer, curr_speed, max_speed) class TestOFPPacketOut(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPPacketOut """ def _test_init(self, in_port): buffer_id = 0xffffffff data = b'Message' out_port = 0x00002ae0 actions = [OFPActionOutput(out_port, 0)] c = OFPPacketOut(_Datapath, buffer_id, in_port, actions, data) self.assertEqual(buffer_id, c.buffer_id) self.assertEqual(in_port, c.in_port) self.assertEqual(0, c.actions_len) self.assertEqual(data, c.data) self.assertEqual(actions, c.actions) def test_init(self): in_port = 0x00040455 self._test_init(in_port) def test_init_check_in_port(self): in_port = None self.assertRaises(AssertionError, self._test_init, in_port) def _test_serialize(self, buffer_id, in_port, action_cnt=0, data=None): actions = [] for i in range(action_cnt): actions.append(ofproto_v1_2_parser.OFPActionOutput(i, 0)) c = OFPPacketOut(_Datapath, buffer_id, in_port, actions, data) c.serialize() self.assertEqual(ofproto.OFP_VERSION, c.version) self.assertEqual(ofproto.OFPT_PACKET_OUT, c.msg_type) self.assertEqual(0, c.xid) fmt = ofproto.OFP_HEADER_PACK_STR \ + ofproto.OFP_PACKET_OUT_PACK_STR[1:] \ + ofproto.OFP_ACTION_OUTPUT_PACK_STR[1:] * action_cnt if data is not None: fmt += str(len(data)) + 's' res = struct.unpack(fmt, bytes(c.buf)) self.assertEqual(res[0], ofproto.OFP_VERSION) self.assertEqual(res[1], ofproto.OFPT_PACKET_OUT) self.assertEqual(res[2], len(c.buf)) self.assertEqual(res[3], 0) self.assertEqual(res[4], buffer_id) self.assertEqual(res[5], in_port) self.assertEqual(res[6], ofproto.OFP_ACTION_OUTPUT_SIZE * action_cnt) for i in range(action_cnt): index = 7 + i * 4 self.assertEqual(res[index], ofproto.OFPAT_OUTPUT) self.assertEqual(res[index + 1], ofproto.OFP_ACTION_OUTPUT_SIZE) self.assertEqual(res[index + 2], i) self.assertEqual(res[index + 3], 0) if data: self.assertEqual(res[-1], data) def test_serialize_true(self): buffer_id = 0xffffffff in_port = 0x00040455 action_cnt = 2 data = b'Message' self._test_serialize(buffer_id, in_port, action_cnt, data) def test_serialize_none(self): buffer_id = 0xffffffff in_port = 0x00040455 self._test_serialize(buffer_id, in_port) def test_serialize_max(self): buffer_id = 0xffffffff in_port = 4294967295 action_cnt = 1 data = b'Message'.ljust(65495) self._test_serialize(buffer_id, in_port, action_cnt, data) def test_serialize_min(self): buffer_id = 0 in_port = 0 self._test_serialize(buffer_id, in_port) def test_serialize_p1(self): buffer_id = 2147483648 in_port = ofproto.OFPP_CONTROLLER self._test_serialize(buffer_id, in_port) def test_serialize_check_buffer_id(self): buffer_id = 2147483648 in_port = 1 action_cnt = 0 data = b'DATA' self.assertRaises(AssertionError, self._test_serialize, buffer_id, in_port, action_cnt, data) class TestOFPFlowMod(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPFlowMod """ def test_init(self): # OFP_FLOW_MOD_PACK_STR0 # '!QQBBHHHIIIH2x'...cookie, cookie_mask, table_id, command, # idle_timeout, hard_timeout, priority, buffer_id, # out_port, out_group, flags cookie = 2127614848199081640 cookie_mask = 2127614848199081641 table_id = 3 command = 0 idle_timeout = 62317 hard_timeout = 7365 priority = 40163 buffer_id = 4037115955 out_port = 65037 out_group = 6606 flags = 135 instructions = [OFPInstructionGotoTable(table_id)] in_port = 1 match = OFPMatch() match.set_in_port(in_port) c = OFPFlowMod(_Datapath, cookie, cookie_mask, table_id, command, idle_timeout, hard_timeout, priority, buffer_id, out_port, out_group, flags, match, instructions) self.assertEqual(cookie, c.cookie) self.assertEqual(cookie_mask, c.cookie_mask) self.assertEqual(table_id, c.table_id) self.assertEqual(command, c.command) self.assertEqual(idle_timeout, c.idle_timeout) self.assertEqual(hard_timeout, c.hard_timeout) self.assertEqual(priority, c.priority) self.assertEqual(buffer_id, c.buffer_id) self.assertEqual(out_port, c.out_port) self.assertEqual(out_group, c.out_group) self.assertEqual(flags, c.flags) self.assertEqual(in_port, c.match._flow.in_port) self.assertEqual(instructions[0], c.instructions[0]) def _test_serialize(self, cookie, cookie_mask, table_id, command, idle_timeout, hard_timeout, priority, buffer_id, out_port, out_group, flags, inst_cnt=0): dl_type = 0x0800 match = OFPMatch() match.set_dl_type(dl_type) insts = [] for i in range(inst_cnt): insts.append(OFPInstructionGotoTable(i)) c = OFPFlowMod(_Datapath, cookie, cookie_mask, table_id, command, idle_timeout, hard_timeout, priority, buffer_id, out_port, out_group, flags, match, insts) c.serialize() self.assertEqual(ofproto.OFP_VERSION, c.version) self.assertEqual(ofproto.OFPT_FLOW_MOD, c.msg_type) self.assertEqual(0, c.xid) fmt = ofproto.OFP_HEADER_PACK_STR \ + ofproto.OFP_FLOW_MOD_PACK_STR0[1:] \ + 'HHHBB' \ + MTEthType.pack_str[1:] + '6x' \ + ofproto.OFP_INSTRUCTION_GOTO_TABLE_PACK_STR[1:] * inst_cnt res = struct.unpack(fmt, bytes(c.buf)) self.assertEqual(res[0], ofproto.OFP_VERSION) self.assertEqual(res[1], ofproto.OFPT_FLOW_MOD) self.assertEqual(res[2], len(c.buf)) self.assertEqual(res[3], 0) self.assertEqual(res[4], cookie) self.assertEqual(res[5], cookie_mask) self.assertEqual(res[6], table_id) self.assertEqual(res[7], command) self.assertEqual(res[8], idle_timeout) self.assertEqual(res[9], hard_timeout) self.assertEqual(res[10], priority) self.assertEqual(res[11], buffer_id) self.assertEqual(res[12], out_port) self.assertEqual(res[13], out_group) self.assertEqual(res[14], flags) # OFP_MATCH (type, length, class, [field, hashmask], n_byte, ip_proto) self.assertEqual(res[15], ofproto.OFPMT_OXM) self.assertEqual(res[16], 10) # OFP_MATCH_STR + MTEthType.pack_str self.assertEqual(res[17], ofproto.OFPXMC_OPENFLOW_BASIC) self.assertEqual(res[18] >> 1, ofproto.OFPXMT_OFB_ETH_TYPE) self.assertEqual(res[18] & 0b0001, 0) self.assertEqual(res[19], calcsize(MTEthType.pack_str)) self.assertEqual(res[20], dl_type) # insts (type, length, table_id) for i in range(inst_cnt): index = 21 + 3 * i self.assertEqual(res[index], ofproto.OFPIT_GOTO_TABLE) self.assertEqual(res[index + 1], ofproto.OFP_INSTRUCTION_GOTO_TABLE_SIZE) self.assertEqual(res[index + 2], i) def test_serialize_mid(self): cookie = 2127614848199081640 cookie_mask = 2127614848199081641 table_id = 3 command = 128 idle_timeout = 62317 hard_timeout = 7365 priority = 40163 buffer_id = 4037115955 out_port = 65037 out_group = 6606 flags = 135 inst_cnt = 1 self._test_serialize(cookie, cookie_mask, table_id, command, idle_timeout, hard_timeout, priority, buffer_id, out_port, out_group, flags, inst_cnt) def test_serialize_max(self): cookie = 18446744073709551615 cookie_mask = 18446744073709551615 table_id = 255 command = 255 idle_timeout = 65535 hard_timeout = 65535 priority = 65535 buffer_id = 0xffffffff out_port = 0xffffffff out_group = 0xffffffff flags = 65535 inst_cnt = 0xff self._test_serialize(cookie, cookie_mask, table_id, command, idle_timeout, hard_timeout, priority, buffer_id, out_port, out_group, flags, inst_cnt) def test_serialize_min(self): cookie = 0 cookie_mask = 0 table_id = 0 command = ofproto.OFPFC_ADD idle_timeout = 0 hard_timeout = 0 priority = 0 buffer_id = 0 out_port = 0 out_group = 0 flags = 0 self._test_serialize(cookie, cookie_mask, table_id, command, idle_timeout, hard_timeout, priority, buffer_id, out_port, out_group, flags) def test_serialize_p1(self): cookie = 2127614848199081640 cookie_mask = 2127614848199081641 table_id = 3 command = 1 idle_timeout = 62317 hard_timeout = 7365 priority = 40163 buffer_id = 4037115955 out_port = 65037 out_group = 6606 flags = 1 << 0 self._test_serialize(cookie, cookie_mask, table_id, command, idle_timeout, hard_timeout, priority, buffer_id, out_port, out_group, flags) def test_serialize_p2(self): cookie = 2127614848199081640 cookie_mask = 2127614848199081641 table_id = 3 command = 2 idle_timeout = 62317 hard_timeout = 7365 priority = 40163 buffer_id = 4037115955 out_port = 65037 out_group = 6606 flags = 1 << 0 self._test_serialize(cookie, cookie_mask, table_id, command, idle_timeout, hard_timeout, priority, buffer_id, out_port, out_group, flags) def test_serialize_p3(self): cookie = 2127614848199081640 cookie_mask = 2127614848199081641 table_id = 3 command = 3 idle_timeout = 62317 hard_timeout = 7365 priority = 40163 buffer_id = 4037115955 out_port = 65037 out_group = 6606 flags = 1 << 1 self._test_serialize(cookie, cookie_mask, table_id, command, idle_timeout, hard_timeout, priority, buffer_id, out_port, out_group, flags) def test_serialize_p4(self): cookie = 2127614848199081640 cookie_mask = 2127614848199081641 table_id = 3 command = 4 idle_timeout = 62317 hard_timeout = 7365 priority = 40163 buffer_id = 4037115955 out_port = 65037 out_group = 6606 flags = 1 << 2 self._test_serialize(cookie, cookie_mask, table_id, command, idle_timeout, hard_timeout, priority, buffer_id, out_port, out_group, flags) class TestOFPInstructionGotoTable(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPInstructionGotoTable """ # OFP_INSTRUCTION_GOTO_TABLE_PACK_STR # '!HHB3x'...type, len, table_id, pad(3) type_ = ofproto.OFPIT_GOTO_TABLE len_ = ofproto.OFP_INSTRUCTION_GOTO_TABLE_SIZE fmt = ofproto.OFP_INSTRUCTION_GOTO_TABLE_PACK_STR def test_init(self): table_id = 3 c = OFPInstructionGotoTable(table_id) self.assertEqual(self.type_, c.type) self.assertEqual(self.len_, c.len) self.assertEqual(table_id, c.table_id) def _test_parser(self, table_id): buf = pack(self.fmt, self.type_, self.len_, table_id) res = OFPInstructionGotoTable.parser(buf, 0) self.assertEqual(res.len, self.len_) self.assertEqual(res.type, self.type_) self.assertEqual(res.table_id, table_id) def test_parser_mid(self): self._test_parser(3) def test_parser_max(self): self._test_parser(255) def test_parser_min(self): self._test_parser(0) def _test_serialize(self, table_id): c = OFPInstructionGotoTable(table_id) buf = bytearray() c.serialize(buf, 0) res = struct.unpack(self.fmt, bytes(buf)) self.assertEqual(res[0], self.type_) self.assertEqual(res[1], self.len_) self.assertEqual(res[2], table_id) def test_serialize_mid(self): self._test_serialize(3) def test_serialize_max(self): self._test_serialize(255) def test_serialize_min(self): self._test_serialize(0) class TestOFPInstructionWriteMetadata(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPInstructionWriteMetadata """ # OFP_INSTRUCTION_WRITE_METADATA_PACK_STR # '!HH4xQQ'...type, len, pad(4), metadata, metadata_mask type_ = ofproto.OFPIT_WRITE_METADATA len_ = ofproto.OFP_INSTRUCTION_WRITE_METADATA_SIZE metadata = 0x1212121212121212 metadata_mask = 0xff00ff00ff00ff00 fmt = ofproto.OFP_INSTRUCTION_WRITE_METADATA_PACK_STR def test_init(self): c = OFPInstructionWriteMetadata(self.metadata, self.metadata_mask) self.assertEqual(self.type_, c.type) self.assertEqual(self.len_, c.len) self.assertEqual(self.metadata, c.metadata) self.assertEqual(self.metadata_mask, c.metadata_mask) def _test_parser(self, metadata, metadata_mask): buf = pack(self.fmt, self.type_, self.len_, metadata, metadata_mask) res = OFPInstructionWriteMetadata.parser(buf, 0) self.assertEqual(res.len, self.len_) self.assertEqual(res.type, self.type_) self.assertEqual(res.metadata, metadata) self.assertEqual(res.metadata_mask, metadata_mask) def test_parser_metadata_mid(self): self._test_parser(self.metadata, self.metadata_mask) def test_parser_metadata_max(self): metadata = 0xffffffffffffffff self._test_parser(metadata, self.metadata_mask) def test_parser_metadata_min(self): metadata = 0 self._test_parser(metadata, self.metadata_mask) def test_parser_metadata_mask_max(self): metadata_mask = 0xffffffffffffffff self._test_parser(self.metadata, metadata_mask) def test_parser_metadata_mask_min(self): metadata_mask = 0 self._test_parser(self.metadata, metadata_mask) def _test_serialize(self, metadata, metadata_mask): c = OFPInstructionWriteMetadata(metadata, metadata_mask) buf = bytearray() c.serialize(buf, 0) res = struct.unpack(self.fmt, bytes(buf)) self.assertEqual(res[0], self.type_) self.assertEqual(res[1], self.len_) self.assertEqual(res[2], metadata) self.assertEqual(res[3], metadata_mask) def test_serialize_metadata_mid(self): self._test_serialize(self.metadata, self.metadata_mask) def test_serialize_metadata_max(self): metadata = 0xffffffffffffffff self._test_serialize(metadata, self.metadata_mask) def test_serialize_metadata_min(self): metadata = 0 self._test_serialize(metadata, self.metadata_mask) def test_serialize_metadata_mask_max(self): metadata_mask = 0xffffffffffffffff self._test_serialize(self.metadata, metadata_mask) def test_serialize_metadata_mask_min(self): metadata_mask = 0 self._test_serialize(self.metadata, metadata_mask) class TestOFPInstructionActions(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPInstructionActions """ # OFP_INSTRUCTION_ACTIONS_PACK_STR # '!HH4x'...type, len, pad(4) type_ = ofproto.OFPIT_WRITE_ACTIONS len_ = ofproto.OFP_INSTRUCTION_ACTIONS_SIZE \ + ofproto.OFP_ACTION_OUTPUT_SIZE fmt = ofproto.OFP_INSTRUCTION_ACTIONS_PACK_STR buf = pack(fmt, type_, len_) # OFP_ACTION (OFP_ACTION_OUTPUT) port = 0x00002ae0 max_len = ofproto.OFP_ACTION_OUTPUT_SIZE actions = [OFPActionOutput(port, max_len)] buf_actions = bytearray() actions[0].serialize(buf_actions, 0) buf += bytes(buf_actions) def test_init(self): c = OFPInstructionActions(self.type_, self.actions) self.assertEqual(self.type_, c.type) self.assertEqual(self.actions, c.actions) def _test_parser(self, action_cnt): # OFP_INSTRUCTION_ACTIONS_PACK_STR # '!HH4x'...type, len, pad(4) len_ = ofproto.OFP_INSTRUCTION_ACTIONS_SIZE \ + (ofproto.OFP_ACTION_OUTPUT_SIZE * action_cnt) fmt = ofproto.OFP_INSTRUCTION_ACTIONS_PACK_STR buf = pack(fmt, self.type_, len_) actions = [] for a in range(action_cnt): # OFP_ACTION (OFP_ACTION_OUTPUT) port = a action = OFPActionOutput(port, self.max_len) actions.append(action) buf_actions = bytearray() actions[a].serialize(buf_actions, 0) buf += bytes(buf_actions) res = OFPInstructionActions.parser(buf, 0) # 8 self.assertEqual(res.len, len_) self.assertEqual(res.type, self.type_) # 8 + 16 * action_cnt < 65535 byte # action_cnt <= 4095 for a in range(action_cnt): self.assertEqual(res.actions[a].type, actions[a].type) self.assertEqual(res.actions[a].len, actions[a].len) self.assertEqual(res.actions[a].port, actions[a].port) self.assertEqual(res.actions[a].max_len, actions[a].max_len) def test_parser_mid(self): self._test_parser(2047) def test_parser_max(self): self._test_parser(4095) def test_parser_min(self): self._test_parser(0) def _test_serialize(self, action_cnt): # OFP_INSTRUCTION_ACTIONS_PACK_STR # '!HH4x'...type, len, pad(4) len_ = ofproto.OFP_INSTRUCTION_ACTIONS_SIZE \ + (ofproto.OFP_ACTION_OUTPUT_SIZE * action_cnt) actions = [] for a in range(action_cnt): # OFP_ACTION (OFP_ACTION_OUTPUT) port = a action = OFPActionOutput(port, self.max_len) actions.append(action) c = OFPInstructionActions(self.type_, actions) buf = bytearray() c.serialize(buf, 0) fmt = '!' \ + ofproto.OFP_INSTRUCTION_ACTIONS_PACK_STR.replace('!', '') for a in range(action_cnt): fmt += ofproto.OFP_ACTION_OUTPUT_PACK_STR.replace('!', '') res = struct.unpack(fmt, bytes(buf)) self.assertEqual(res[0], self.type_) self.assertEqual(res[1], len_) for a in range(action_cnt): d = 2 + a * 4 self.assertEqual(res[d], actions[a].type) self.assertEqual(res[d + 1], actions[a].len) self.assertEqual(res[d + 2], actions[a].port) self.assertEqual(res[d + 3], actions[a].max_len) def test_serialize_mid(self): self._test_serialize(2047) def test_serialize_max(self): self._test_serialize(4095) def test_serialize_min(self): self._test_serialize(0) class TestOFPActionHeader(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPActionHeader """ def test_init(self): # OFP_ACTION_HEADER_PACK_STR # '!HH4x'...type, len, pad(4) type_ = ofproto.OFPAT_OUTPUT len_ = ofproto.OFP_ACTION_HEADER_SIZE fmt = ofproto.OFP_ACTION_HEADER_PACK_STR buf = pack(fmt, type_, len_) c = OFPActionHeader(type_, len_) self.assertEqual(type_, c.type) self.assertEqual(len_, c.len) def _test_serialize(self, type_, len_): # OFP_ACTION_HEADER_PACK_STR # '!HH4x'...type, len, pad(4) fmt = ofproto.OFP_ACTION_HEADER_PACK_STR buf = pack(fmt, type_, len_) c = OFPActionHeader(type_, len_) buf = bytearray() c.serialize(buf, 0) fmt = ofproto.OFP_ACTION_HEADER_PACK_STR res = struct.unpack(fmt, bytes(buf)) self.assertEqual(res[0], type_) self.assertEqual(res[1], len_) def test_serialize_mid(self): type_ = 11 len_ = 8 self._test_serialize(type_, len_) def test_serialize_max(self): type_ = 0xffff len_ = 0xffff self._test_serialize(type_, len_) def test_serialize_min(self): type_ = 0 len_ = 0 self._test_serialize(type_, len_) class TestOFPActionOutput(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPActionOutput """ # OFP_ACTION_OUTPUT_PACK_STR # '!HHIH6x'...type, len, port, max_len, pad(6) type_ = ofproto.OFPAT_OUTPUT len_ = ofproto.OFP_ACTION_OUTPUT_SIZE def test_init(self): port = 6606 max_len = 1500 fmt = ofproto.OFP_ACTION_OUTPUT_PACK_STR c = OFPActionOutput(port, max_len) self.assertEqual(port, c.port) self.assertEqual(max_len, c.max_len) def _test_parser(self, port, max_len): fmt = ofproto.OFP_ACTION_OUTPUT_PACK_STR buf = pack(fmt, self.type_, self.len_, port, max_len) c = OFPActionOutput(port, max_len) res = c.parser(buf, 0) self.assertEqual(res.len, self.len_) self.assertEqual(res.type, self.type_) self.assertEqual(res.port, port) self.assertEqual(res.max_len, max_len) def test_parser_mid(self): port = 6606 max_len = 16 self._test_parser(port, max_len) def test_parser_max(self): port = 4294967295 max_len = 0xffff self._test_parser(port, max_len) def test_parser_min(self): port = 0 max_len = 0 self._test_parser(port, max_len) def test_parser_p1(self): port = 6606 max_len = 0xffe5 self._test_parser(port, max_len) def _test_serialize(self, port, max_len): c = OFPActionOutput(port, max_len) buf = bytearray() c.serialize(buf, 0) fmt = ofproto.OFP_ACTION_OUTPUT_PACK_STR res = struct.unpack(fmt, bytes(buf)) self.assertEqual(res[0], self.type_) self.assertEqual(res[1], self.len_) self.assertEqual(res[2], port) self.assertEqual(res[3], max_len) def test_serialize_mid(self): port = 6606 max_len = 16 self._test_serialize(port, max_len) def test_serialize_max(self): port = 4294967295 max_len = 0xffff self._test_serialize(port, max_len) def test_serialize_min(self): port = 0 max_len = 0 self._test_serialize(port, max_len) def test_serialize_p1(self): port = 6606 max_len = 0xffe5 self._test_serialize(port, max_len) class TestOFPActionGroup(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPActionGroup """ # OFP_ACTION_GROUP_PACK_STR # '!HHI'...type, len, group_id type_ = ofproto.OFPAT_GROUP len_ = ofproto.OFP_ACTION_GROUP_SIZE group_id = 6606 fmt = ofproto.OFP_ACTION_GROUP_PACK_STR def test_init(self): c = OFPActionGroup(self.group_id) self.assertEqual(self.group_id, c.group_id) def _test_parser(self, group_id): buf = pack(self.fmt, self.type_, self.len_, group_id) res = OFPActionGroup.parser(buf, 0) self.assertEqual(res.len, self.len_) self.assertEqual(res.type, self.type_) self.assertEqual(res.group_id, group_id) def test_parser_mid(self): self._test_parser(self.group_id) def test_parser_max(self): self._test_parser(4294967295) def test_parser_min(self): self._test_parser(0) def _test_serialize(self, group_id): c = OFPActionGroup(group_id) buf = bytearray() c.serialize(buf, 0) res = struct.unpack(self.fmt, bytes(buf)) self.assertEqual(res[0], self.type_) self.assertEqual(res[1], self.len_) self.assertEqual(res[2], group_id) def test_serialize_mid(self): self._test_serialize(self.group_id) def test_serialize_max(self): self._test_serialize(4294967295) def test_serialize_min(self): self._test_serialize(0) class TestOFPActionSetQueue(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPActionSetQueue """ # OFP_ACTION_SET_QUEUE_PACK_STR # '!HHI'...type, len, queue_id type_ = ofproto.OFPAT_SET_QUEUE len_ = ofproto.OFP_ACTION_SET_QUEUE_SIZE queue_id = 6606 fmt = ofproto.OFP_ACTION_SET_QUEUE_PACK_STR def test_init(self): c = OFPActionSetQueue(self.queue_id) self.assertEqual(self.queue_id, c.queue_id) def _test_parser(self, queue_id): buf = pack(self.fmt, self.type_, self.len_, queue_id) res = OFPActionSetQueue.parser(buf, 0) self.assertEqual(res.len, self.len_) self.assertEqual(res.type, self.type_) self.assertEqual(res.queue_id, queue_id) def test_parser_mid(self): self._test_parser(self.queue_id) def test_parser_max(self): self._test_parser(4294967295) def test_parser_min(self): self._test_parser(0) def _test_serialize(self, queue_id): c = OFPActionSetQueue(queue_id) buf = bytearray() c.serialize(buf, 0) res = struct.unpack(self.fmt, bytes(buf)) self.assertEqual(res[0], self.type_) self.assertEqual(res[1], self.len_) self.assertEqual(res[2], queue_id) def test_serialize_mid(self): self._test_serialize(self.queue_id) def test_serialize_max(self): self._test_serialize(4294967295) def test_serialize_min(self): self._test_serialize(0) class TestOFPActionSetMplsTtl(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPActionSetMplsTtl """ # OFP_ACTION_MPLS_TTL_PACK_STR # '!HHB3x'...type, len, mpls_ttl, pad(3) type_ = ofproto.OFPAT_SET_MPLS_TTL len_ = ofproto.OFP_ACTION_MPLS_TTL_SIZE mpls_ttl = 254 fmt = ofproto.OFP_ACTION_MPLS_TTL_PACK_STR def test_init(self): c = OFPActionSetMplsTtl(self.mpls_ttl) self.assertEqual(self.mpls_ttl, c.mpls_ttl) def _test_parser(self, mpls_ttl): buf = pack(self.fmt, self.type_, self.len_, mpls_ttl) res = OFPActionSetMplsTtl.parser(buf, 0) self.assertEqual(res.len, self.len_) self.assertEqual(res.type, self.type_) self.assertEqual(res.mpls_ttl, mpls_ttl) def test_parser_mid(self): self._test_parser(self.mpls_ttl) def test_parser_max(self): self._test_parser(255) def test_parser_min(self): self._test_parser(0) def _test_serialize(self, mpls_ttl): c = OFPActionSetMplsTtl(mpls_ttl) buf = bytearray() c.serialize(buf, 0) res = struct.unpack(self.fmt, bytes(buf)) self.assertEqual(res[0], self.type_) self.assertEqual(res[1], self.len_) self.assertEqual(res[2], mpls_ttl) def test_serialize_mid(self): self._test_serialize(self.mpls_ttl) def test_serialize_max(self): self._test_serialize(255) def test_serialize_min(self): self._test_serialize(0) class TestOFPActionDecMplsTtl(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPActionDecMplsTtl """ type_ = ofproto.OFPAT_DEC_MPLS_TTL len_ = ofproto.OFP_ACTION_MPLS_TTL_SIZE fmt = ofproto.OFP_ACTION_HEADER_PACK_STR buf = pack(fmt, type_, len_) c = OFPActionDecMplsTtl() def test_parser(self): res = self.c.parser(self.buf, 0) self.assertEqual(res.len, self.len_) self.assertEqual(res.type, self.type_) def test_serialize(self): buf = bytearray() self.c.serialize(buf, 0) res = struct.unpack(self.fmt, bytes(buf)) self.assertEqual(res[0], self.type_) self.assertEqual(res[1], self.len_) class TestOFPActionSetNwTtl(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPActionSetNwTtl """ # OFP_ACTION_NW_TTL_PACK_STR # '!HHB3x'...type, len, nw_ttl, pad(3) type_ = ofproto.OFPAT_SET_NW_TTL len_ = ofproto.OFP_ACTION_NW_TTL_SIZE nw_ttl = 240 fmt = ofproto.OFP_ACTION_NW_TTL_PACK_STR def test_init(self): c = OFPActionSetNwTtl(self.nw_ttl) self.assertEqual(self.nw_ttl, c.nw_ttl) def _test_parser(self, nw_ttl): buf = pack(self.fmt, self.type_, self.len_, nw_ttl) res = OFPActionSetNwTtl.parser(buf, 0) self.assertEqual(res.type, self.type_) self.assertEqual(res.len, self.len_) self.assertEqual(res.nw_ttl, nw_ttl) def test_parser_mid(self): self._test_parser(self.nw_ttl) def test_parser_max(self): self._test_parser(255) def test_parser_min(self): self._test_parser(0) def _test_serialize(self, nw_ttl): c = OFPActionSetNwTtl(nw_ttl) buf = bytearray() c.serialize(buf, 0) res = struct.unpack(self.fmt, bytes(buf)) self.assertEqual(res[0], self.type_) self.assertEqual(res[1], self.len_) self.assertEqual(res[2], nw_ttl) def test_serialize_mid(self): self._test_serialize(self.nw_ttl) def test_serialize_max(self): self._test_serialize(255) def test_serialize_min(self): self._test_serialize(0) class TestOFPActionDecNwTtl(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPActionDecNwTtl """ type_ = ofproto.OFPAT_DEC_NW_TTL len_ = ofproto.OFP_ACTION_NW_TTL_SIZE fmt = ofproto.OFP_ACTION_HEADER_PACK_STR buf = pack(fmt, type_, len_) c = OFPActionDecNwTtl() def test_parser(self): res = self.c.parser(self.buf, 0) self.assertEqual(res.len, self.len_) self.assertEqual(res.type, self.type_) def test_serialize(self): buf = bytearray() self.c.serialize(buf, 0) res = struct.unpack(self.fmt, bytes(buf)) self.assertEqual(res[0], self.type_) self.assertEqual(res[1], self.len_) class TestOFPActionCopyTtlOut(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPActionCopyTtlOut """ type_ = ofproto.OFPAT_COPY_TTL_OUT len_ = ofproto.OFP_ACTION_HEADER_SIZE fmt = ofproto.OFP_ACTION_HEADER_PACK_STR buf = pack(fmt, type_, len_) c = OFPActionCopyTtlOut() def test_parser(self): res = self.c.parser(self.buf, 0) self.assertEqual(res.len, self.len_) self.assertEqual(res.type, self.type_) def test_serialize(self): buf = bytearray() self.c.serialize(buf, 0) res = struct.unpack(self.fmt, bytes(buf)) self.assertEqual(res[0], self.type_) self.assertEqual(res[1], self.len_) class TestOFPActionCopyTtlIn(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPActionCopyTtlIn """ # OFP_ACTION_HEADER_PACK_STR # '!HH'...type, len type_ = ofproto.OFPAT_COPY_TTL_IN len_ = ofproto.OFP_ACTION_HEADER_SIZE fmt = ofproto.OFP_ACTION_HEADER_PACK_STR buf = pack(fmt, type_, len_) c = OFPActionCopyTtlIn() def test_parser(self): res = self.c.parser(self.buf, 0) self.assertEqual(res.len, self.len_) self.assertEqual(res.type, self.type_) def test_serialize(self): buf = bytearray() self.c.serialize(buf, 0) res = struct.unpack(self.fmt, bytes(buf)) self.assertEqual(res[0], self.type_) self.assertEqual(res[1], self.len_) class TestOFPActionPushVlan(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPActionPushVlan """ # OFP_ACTION_PUSH_PACK_STR # '!HHH2x'...type, len, ethertype, pad(2) type_ = ofproto.OFPAT_PUSH_VLAN len_ = ofproto.OFP_ACTION_PUSH_SIZE fmt = ofproto.OFP_ACTION_PUSH_PACK_STR def test_init(self): ethertype = 0x8100 c = OFPActionPushVlan(ethertype) self.assertEqual(ethertype, c.ethertype) def _test_parser(self, ethertype): buf = pack(self.fmt, self.type_, self.len_, ethertype) res = OFPActionPushVlan.parser(buf, 0) self.assertEqual(res.type, self.type_) self.assertEqual(res.len, self.len_) self.assertEqual(res.ethertype, ethertype) def test_parser_mid(self): self._test_parser(0x8100) def test_parser_max(self): self._test_parser(0xffff) def test_parser_min(self): self._test_parser(0) def _test_serialize(self, ethertype): c = OFPActionPushVlan(ethertype) buf = bytearray() c.serialize(buf, 0) res = struct.unpack(self.fmt, bytes(buf)) self.assertEqual(res[0], self.type_) self.assertEqual(res[1], self.len_) self.assertEqual(res[2], ethertype) def test_serialize_mid(self): self._test_serialize(0x8100) def test_serialize_max(self): self._test_serialize(0xffff) def test_serialize_min(self): self._test_serialize(0) class TestOFPActionPushMpls(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPActionPushMpls """ # OFP_ACTION_PUSH_PACK_STR # '!HHH2x'...type, len, ethertype, pad(2) type_ = ofproto.OFPAT_PUSH_MPLS len_ = ofproto.OFP_ACTION_PUSH_SIZE fmt = ofproto.OFP_ACTION_PUSH_PACK_STR def test_init(self): ethertype = 0x8100 c = OFPActionPushMpls(ethertype) self.assertEqual(ethertype, c.ethertype) def _test_parser(self, ethertype): buf = pack(self.fmt, self.type_, self.len_, ethertype) res = OFPActionPushMpls.parser(buf, 0) self.assertEqual(res.type, self.type_) self.assertEqual(res.len, self.len_) self.assertEqual(res.ethertype, ethertype) def test_parser_mid(self): self._test_parser(0x8100) def test_parser_max(self): self._test_parser(0xffff) def test_parser_min(self): self._test_parser(0) def _test_serialize(self, ethertype): c = OFPActionPushMpls(ethertype) buf = bytearray() c.serialize(buf, 0) res = struct.unpack(self.fmt, bytes(buf)) self.assertEqual(res[0], self.type_) self.assertEqual(res[1], self.len_) self.assertEqual(res[2], ethertype) def test_serialize_mid(self): self._test_serialize(0x8100) def test_serialize_max(self): self._test_serialize(0xffff) def test_serialize_min(self): self._test_serialize(0) class TestOFPActionPopVlan(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPActionPopVlan """ # OFP_ACTION_HEADER_PACK_STR # '!HH'...type, len type_ = ofproto.OFPAT_POP_VLAN len_ = ofproto.OFP_ACTION_HEADER_SIZE fmt = ofproto.OFP_ACTION_HEADER_PACK_STR buf = pack(fmt, type_, len_) c = OFPActionPopVlan() def test_parser(self): res = self.c.parser(self.buf, 0) self.assertEqual(self.type_, res.type) self.assertEqual(self.len_, res.len) def test_serialize(self): buf = bytearray() self.c.serialize(buf, 0) res = struct.unpack(self.fmt, bytes(buf)) self.assertEqual(res[0], self.type_) self.assertEqual(res[1], self.len_) class TestOFPActionPopMpls(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPActionPopMpls """ # OFP_ACTION_POP_MPLS_PACK_STR # '!HHH2x'...type, len, ethertype, pad(2) type_ = ofproto.OFPAT_POP_MPLS len_ = ofproto.OFP_ACTION_POP_MPLS_SIZE fmt = ofproto.OFP_ACTION_POP_MPLS_PACK_STR def test_init(self): ethertype = 0x8100 c = OFPActionPopMpls(ethertype) self.assertEqual(ethertype, c.ethertype) def _test_parser(self, ethertype): buf = pack(self.fmt, self.type_, self.len_, ethertype) res = OFPActionPopMpls.parser(buf, 0) self.assertEqual(res.type, self.type_) self.assertEqual(res.len, self.len_) self.assertEqual(res.ethertype, ethertype) def test_parser_mid(self): self._test_parser(0x8100) def test_parser_max(self): self._test_parser(0xffff) def test_parser_min(self): self._test_parser(0) def _test_serialize(self, ethertype): c = OFPActionPopMpls(ethertype) buf = bytearray() c.serialize(buf, 0) res = struct.unpack(self.fmt, bytes(buf)) self.assertEqual(res[0], self.type_) self.assertEqual(res[1], self.len_) self.assertEqual(res[2], ethertype) def test_serialize_mid(self): self._test_serialize(0x8100) def test_serialize_max(self): self._test_serialize(0xffff) def test_serialize_min(self): self._test_serialize(0) class TestOFPActionSetField(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPActionSetField """ type_ = ofproto.OFPAT_SET_FIELD header = ofproto.OXM_OF_IN_PORT in_port = 6606 field = MTInPort(header, in_port) length = ofproto.OFP_ACTION_SET_FIELD_SIZE + field.oxm_len() len_ = utils.round_up(length, 8) fmt = '!HHII4x' buf = pack(fmt, type_, len_, header, in_port) c = OFPActionSetField(field) def test_init(self): self.assertEqual(self.field, self.c.field) def test_parser(self): res = self.c.parser(self.buf, 0) self.assertEqual(res.type, self.type_) self.assertEqual(res.len, self.len_) self.assertEqual(res.field.header, self.header) self.assertEqual(res.field.value, self.in_port) def test_serialize(self): buf = bytearray() self.c.serialize(buf, 0) res = struct.unpack(self.fmt, bytes(buf)) self.assertEqual(res[0], self.type_) self.assertEqual(res[1], self.len_) self.assertEqual(res[2], self.header) self.assertEqual(res[3], self.in_port) class TestOFPActionExperimenter(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPActionExperimenter """ # OFP_ACTION_EXPERIMENTER_HEADER_PACK_STR v1.2 # '!HHI'...type, len, experimenter type_ = ofproto.OFPAT_EXPERIMENTER len_ = ofproto.OFP_ACTION_EXPERIMENTER_HEADER_SIZE fmt = ofproto.OFP_ACTION_EXPERIMENTER_HEADER_PACK_STR def test_init(self): experimenter = 4294967295 c = OFPActionExperimenter(experimenter) self.assertEqual(experimenter, c.experimenter) def _test_parser(self, experimenter): buf = pack(self.fmt, self.type_, self.len_, experimenter) res = OFPActionExperimenter.parser(buf, 0) self.assertEqual(res.type, self.type_) self.assertEqual(res.len, self.len_) self.assertEqual(res.experimenter, experimenter) def test_parser_mid(self): experimenter = 2147483648 self._test_parser(experimenter) def test_parser_max(self): experimenter = 4294967295 self._test_parser(experimenter) def test_parser_min(self): experimenter = 0 self._test_parser(experimenter) def _test_serialize(self, experimenter): c = OFPActionExperimenter(experimenter) buf = bytearray() c.serialize(buf, 0) res = struct.unpack(self.fmt, bytes(buf)) self.assertEqual(res[0], self.type_) self.assertEqual(res[1], self.len_) self.assertEqual(res[2], experimenter) def test_serialize_mid(self): experimenter = 2147483648 self._test_serialize(experimenter) def test_serialize_max(self): experimenter = 4294967295 self._test_serialize(experimenter) def test_serialize_min(self): experimenter = 0 self._test_serialize(experimenter) class TestOFPBucket(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPBucket """ def test_init(self): # OFP_BUCKET_PACK_STR # '!HHII4x'...len, weight, watch_port, watch_group, pad(4) weight = 4386 watch_port = 6606 watch_group = 3 # OFP_ACTION (OFP_ACTION_OUTPUT) port = 3 max_len = 1500 actions = [OFPActionOutput(port, max_len)] c = OFPBucket(weight, watch_port, watch_group, actions) self.assertEqual(weight, c.weight) self.assertEqual(watch_port, c.watch_port) self.assertEqual(watch_group, c.watch_group) self.assertEqual(1, len(c.actions)) self.assertEqual(port, c.actions[0].port) self.assertEqual(max_len, c.actions[0].max_len) def _test_parser(self, weight, watch_port, watch_group, action_cnt): # OFP_BUCKET_PACK_STR # '!HHII4x'...len, weight, watch_port, watch_group, pad(4) len_ = ofproto.OFP_BUCKET_SIZE \ + (ofproto.OFP_ACTION_OUTPUT_SIZE * action_cnt) fmt = ofproto.OFP_BUCKET_PACK_STR buf = pack(fmt, len_, weight, watch_port, watch_group) actions = [] for a in range(action_cnt): # OFP_ACTION (OFP_ACTION_OUTPUT) port = a max_len = ofproto.OFP_ACTION_OUTPUT_SIZE action = OFPActionOutput(port, max_len) actions.append(action) buf_actions = bytearray() actions[a].serialize(buf_actions, 0) buf += bytes(buf_actions) res = OFPBucket.parser(buf, 0) # 16 self.assertEqual(weight, res.weight) self.assertEqual(watch_port, res.watch_port) self.assertEqual(watch_group, res.watch_group) # 16 + 16 * action_cnt < 65535 byte # action_cnt <= 4094 for a in range(action_cnt): self.assertEqual(actions[a].type, res.actions[a].type) self.assertEqual(actions[a].len, res.actions[a].len) self.assertEqual(actions[a].port, res.actions[a].port) self.assertEqual(actions[a].max_len, res.actions[a].max_len) def test_parser_mid(self): weight = 4386 watch_port = 6606 watch_group = 3 action_cnt = 2047 self._test_parser(weight, watch_port, watch_group, action_cnt) def test_parser_max(self): weight = 65535 watch_port = 4294967295 watch_group = 4294967295 action_cnt = 4094 self._test_parser(weight, watch_port, watch_group, action_cnt) def test_parser_min(self): weight = 0 watch_port = 0 watch_group = 0 action_cnt = 0 self._test_parser(weight, watch_port, watch_group, action_cnt) def _test_serialize(self, weight, watch_port, watch_group, action_cnt): # OFP_BUCKET_PACK_STR # '!HHII4x'...len, weight, watch_port, watch_group, pad(4) len_ = ofproto.OFP_BUCKET_SIZE \ + (ofproto.OFP_ACTION_OUTPUT_SIZE * action_cnt) actions = [] for a in range(action_cnt): # OFP_ACTION (OFP_ACTION_OUTPUT) port = a max_len = ofproto.OFP_ACTION_OUTPUT_SIZE action = OFPActionOutput(port, max_len) actions.append(action) c = OFPBucket(weight, watch_port, watch_group, actions) buf = bytearray() c.serialize(buf, 0) fmt = ofproto.OFP_BUCKET_PACK_STR for a in range(action_cnt): fmt += ofproto.OFP_ACTION_OUTPUT_PACK_STR[1:] res = struct.unpack(fmt, bytes(buf)) self.assertEqual(res[0], len_) self.assertEqual(res[1], weight) self.assertEqual(res[2], watch_port) self.assertEqual(res[3], watch_group) for a in range(action_cnt): d = 4 + a * 4 self.assertEqual(res[d], actions[a].type) self.assertEqual(res[d + 1], actions[a].len) self.assertEqual(res[d + 2], actions[a].port) self.assertEqual(res[d + 3], actions[a].max_len) def test_serialize_mid(self): weight = 4386 watch_port = 6606 watch_group = 3 action_cnt = 2047 self._test_serialize(weight, watch_port, watch_group, action_cnt) def test_serialize_max(self): weight = 65535 watch_port = 4294967295 watch_group = 4294967295 action_cnt = 4094 self._test_serialize(weight, watch_port, watch_group, action_cnt) def test_serialize_min(self): weight = 0 watch_port = 0 watch_group = 0 action_cnt = 0 self._test_serialize(weight, watch_port, watch_group, action_cnt) class TestOFPGroupMod(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPGroupMod """ def test_init(self): # OFP_GROUP_MOD_PACK_STR # '!HBBI'...command, type, pad, group_id command = ofproto.OFPFC_ADD type_ = ofproto.OFPGT_SELECT group_id = 6606 # OFP_BUCKET weight = 4386 watch_port = 8006 watch_group = 3 # OFP_ACTION (OFP_ACTION_OUTPUT) port = 10 max_len = 2000 actions = [OFPActionOutput(port, max_len)] buckets = [OFPBucket(weight, watch_port, watch_group, actions)] c = OFPGroupMod(_Datapath, command, type_, group_id, buckets) self.assertEqual(command, c.command) self.assertEqual(type_, c.type) self.assertEqual(group_id, c.group_id) self.assertEqual(1, len(c.buckets)) self.assertEqual(1, len(c.buckets[0].actions)) self.assertEqual(port, c.buckets[0].actions[0].port) self.assertEqual(max_len, c.buckets[0].actions[0].max_len) def _test_serialize(self, command, type_, group_id, bucket_cnt): len_ = ofproto.OFP_BUCKET_SIZE \ + ofproto.OFP_ACTION_OUTPUT_SIZE buckets = [] for b in range(bucket_cnt): # OFP_BUCKET weight = watch_port = watch_group = port = b actions = [OFPActionOutput(port, 0)] bucket = OFPBucket(weight, watch_port, watch_group, actions) buckets.append(bucket) c = OFPGroupMod(_Datapath, command, type_, group_id, buckets) c.serialize() self.assertEqual(ofproto.OFP_VERSION, c.version) self.assertEqual(ofproto.OFPT_GROUP_MOD, c.msg_type) self.assertEqual(0, c.xid) self.assertEqual(len(c.buf), c.msg_len) # 16 byte fmt = ofproto.OFP_HEADER_PACK_STR \ + ofproto.OFP_GROUP_MOD_PACK_STR[1:] # 16 + (16 + 16) * bucket_cnt < 65535 byte # bucket_cnt <= 2047 for b in range(bucket_cnt): fmt += ofproto.OFP_BUCKET_PACK_STR[1:] \ + ofproto.OFP_ACTION_OUTPUT_PACK_STR[1:] res = struct.unpack(fmt, bytes(c.buf)) msg_len = ofproto.OFP_GROUP_MOD_SIZE \ + (len_ * bucket_cnt) self.assertEqual(res[0], ofproto.OFP_VERSION) self.assertEqual(res[1], ofproto.OFPT_GROUP_MOD) self.assertEqual(res[2], msg_len) self.assertEqual(res[3], 0) self.assertEqual(res[4], command) self.assertEqual(res[5], type_) self.assertEqual(res[6], group_id) for d in range(bucket_cnt): e = 7 + d * 8 self.assertEqual(res[e + 1], buckets[d].weight) self.assertEqual(res[e + 2], buckets[d].watch_port) self.assertEqual(res[e + 3], buckets[d].watch_group) self.assertEqual(res[e + 4], buckets[d].actions[0].type) self.assertEqual(res[e + 5], buckets[d].actions[0].len) self.assertEqual(res[e + 6], buckets[d].actions[0].port) self.assertEqual(res[e + 7], buckets[d].actions[0].max_len) def test_serialize_mid(self): command = 32768 type_ = 128 group_id = 6606 bucket_cnt = 1023 self._test_serialize(command, type_, group_id, bucket_cnt) def test_serialize_max(self): command = 65535 type_ = 255 group_id = 4294967295 bucket_cnt = 2047 self._test_serialize(command, type_, group_id, bucket_cnt) def test_serialize_min(self): command = 0 type_ = 0 group_id = 0 bucket_cnt = 0 self._test_serialize(command, type_, group_id, bucket_cnt) def test_serialize_p1(self): command = 1 type_ = 1 group_id = 6606 bucket_cnt = 1023 self._test_serialize(command, type_, group_id, bucket_cnt) def test_serialize_p2(self): command = 1 type_ = 2 group_id = 6606 bucket_cnt = 1023 self._test_serialize(command, type_, group_id, bucket_cnt) def test_serialize_p3(self): command = 2 type_ = 3 group_id = 6606 bucket_cnt = 1023 self._test_serialize(command, type_, group_id, bucket_cnt) class TestOFPPortMod(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPPortMod """ # OFP_PORT_MOD_PACK_STR v1.2 # '!I4xs2xIII4x'...port_no, pad(4), hw_addr, pad(2), # config, mask, advertise, pad(4) port_no = 1119692796 hw_addr = 'e8:fe:5e:a9:68:6c' config = 2226555987 mask = 1678244809 advertise = 2025421682 def test_init(self): c = OFPPortMod(_Datapath, self.port_no, self.hw_addr, self.config, self.mask, self.advertise) self.assertEqual(self.port_no, c.port_no) self.assertEqual(self.hw_addr, c.hw_addr) self.assertEqual(self.config, c.config) self.assertEqual(self.mask, c.mask) self.assertEqual(self.advertise, c.advertise) def _test_serialize(self, port_no, hw_addr, config, mask, advertise): c = OFPPortMod(_Datapath, port_no, hw_addr, config, mask, advertise) c.serialize() self.assertEqual(ofproto.OFP_VERSION, c.version) self.assertEqual(ofproto.OFPT_PORT_MOD, c.msg_type) self.assertEqual(0, c.xid) fmt = '!' \ + ofproto.OFP_HEADER_PACK_STR.replace('!', '') \ + ofproto.OFP_PORT_MOD_PACK_STR.replace('!', '') res = struct.unpack(fmt, bytes(c.buf)) self.assertEqual(res[0], ofproto.OFP_VERSION) self.assertEqual(res[1], ofproto.OFPT_PORT_MOD) self.assertEqual(res[2], len(c.buf)) self.assertEqual(res[3], 0) self.assertEqual(res[4], port_no) self.assertEqual(res[5], addrconv.mac.text_to_bin(hw_addr)) self.assertEqual(res[6], config) self.assertEqual(res[7], mask) self.assertEqual(res[8], advertise) def test_serialize_mid(self): self._test_serialize(self.port_no, self.hw_addr, self.config, self.mask, self.advertise) def test_serialize_max(self): port_no = ofproto.OFPP_ANY hw_addr = 'ff:ff:ff:ff:ff:ff' config = 0xffffffff mask = 0xffffffff advertise = 0xffffffff self._test_serialize(port_no, hw_addr, config, mask, advertise) def test_serialize_min(self): port_no = 0 hw_addr = '00:00:00:00:00:00' config = 0 mask = 0 advertise = 0 self._test_serialize(port_no, hw_addr, config, mask, advertise) def test_serialize_p1(self): port_no = ofproto.OFPP_MAX hw_addr = self.hw_addr config = ofproto.OFPPC_PORT_DOWN mask = ofproto.OFPPC_PORT_DOWN advertise = ofproto.OFPPF_10MB_HD self._test_serialize(port_no, hw_addr, config, mask, advertise) def test_serialize_p2(self): port_no = ofproto.OFPP_IN_PORT hw_addr = self.hw_addr config = ofproto.OFPPC_NO_RECV mask = ofproto.OFPPC_NO_RECV advertise = ofproto.OFPPF_10MB_FD self._test_serialize(port_no, hw_addr, config, mask, advertise) def test_serialize_p3(self): port_no = ofproto.OFPP_TABLE hw_addr = self.hw_addr config = ofproto.OFPPC_NO_FWD mask = ofproto.OFPPC_NO_FWD advertise = ofproto.OFPPF_100MB_HD self._test_serialize(port_no, hw_addr, config, mask, advertise) def test_serialize_p4(self): port_no = ofproto.OFPP_NORMAL hw_addr = self.hw_addr config = ofproto.OFPPC_NO_PACKET_IN mask = ofproto.OFPPC_NO_PACKET_IN advertise = ofproto.OFPPF_100MB_FD self._test_serialize(port_no, hw_addr, config, mask, advertise) def test_serialize_p5(self): port_no = ofproto.OFPP_FLOOD hw_addr = self.hw_addr config = ofproto.OFPPC_NO_PACKET_IN mask = ofproto.OFPPC_NO_PACKET_IN advertise = ofproto.OFPPF_1GB_HD self._test_serialize(port_no, hw_addr, config, mask, advertise) def test_serialize_p6(self): port_no = ofproto.OFPP_ALL hw_addr = self.hw_addr config = ofproto.OFPPC_NO_PACKET_IN mask = ofproto.OFPPC_NO_PACKET_IN advertise = ofproto.OFPPF_1GB_FD self._test_serialize(port_no, hw_addr, config, mask, advertise) def test_serialize_p7(self): port_no = ofproto.OFPP_CONTROLLER hw_addr = self.hw_addr config = ofproto.OFPPC_NO_PACKET_IN mask = ofproto.OFPPC_NO_PACKET_IN advertise = ofproto.OFPPF_10GB_FD self._test_serialize(port_no, hw_addr, config, mask, advertise) def test_serialize_p8(self): port_no = ofproto.OFPP_LOCAL hw_addr = self.hw_addr config = ofproto.OFPPC_NO_PACKET_IN mask = ofproto.OFPPC_NO_PACKET_IN advertise = ofproto.OFPPF_40GB_FD self._test_serialize(port_no, hw_addr, config, mask, advertise) def test_serialize_p9(self): port_no = ofproto.OFPP_LOCAL hw_addr = self.hw_addr config = ofproto.OFPPC_NO_PACKET_IN mask = ofproto.OFPPC_NO_PACKET_IN advertise = ofproto.OFPPF_100GB_FD self._test_serialize(port_no, hw_addr, config, mask, advertise) def test_serialize_p10(self): port_no = ofproto.OFPP_LOCAL hw_addr = self.hw_addr config = ofproto.OFPPC_NO_PACKET_IN mask = ofproto.OFPPC_NO_PACKET_IN advertise = ofproto.OFPPF_1TB_FD self._test_serialize(port_no, hw_addr, config, mask, advertise) def test_serialize_p11(self): port_no = ofproto.OFPP_LOCAL hw_addr = self.hw_addr config = ofproto.OFPPC_NO_PACKET_IN mask = ofproto.OFPPC_NO_PACKET_IN advertise = ofproto.OFPPF_OTHER self._test_serialize(port_no, hw_addr, config, mask, advertise) def test_serialize_p12(self): port_no = ofproto.OFPP_LOCAL hw_addr = self.hw_addr config = ofproto.OFPPC_NO_PACKET_IN mask = ofproto.OFPPC_NO_PACKET_IN advertise = ofproto.OFPPF_COPPER self._test_serialize(port_no, hw_addr, config, mask, advertise) def test_serialize_p13(self): port_no = ofproto.OFPP_LOCAL hw_addr = self.hw_addr config = ofproto.OFPPC_NO_PACKET_IN mask = ofproto.OFPPC_NO_PACKET_IN advertise = ofproto.OFPPF_FIBER self._test_serialize(port_no, hw_addr, config, mask, advertise) def test_serialize_p14(self): port_no = ofproto.OFPP_LOCAL hw_addr = self.hw_addr config = ofproto.OFPPC_NO_PACKET_IN mask = ofproto.OFPPC_NO_PACKET_IN advertise = ofproto.OFPPF_AUTONEG self._test_serialize(port_no, hw_addr, config, mask, advertise) def test_serialize_p15(self): port_no = ofproto.OFPP_LOCAL hw_addr = self.hw_addr config = ofproto.OFPPC_NO_PACKET_IN mask = ofproto.OFPPC_NO_PACKET_IN advertise = ofproto.OFPPF_PAUSE self._test_serialize(port_no, hw_addr, config, mask, advertise) def test_serialize_p16(self): port_no = ofproto.OFPP_LOCAL hw_addr = self.hw_addr config = ofproto.OFPPC_NO_PACKET_IN mask = ofproto.OFPPC_NO_PACKET_IN advertise = ofproto.OFPPF_PAUSE_ASYM self._test_serialize(port_no, hw_addr, config, mask, advertise) class TestOFPTableMod(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPTableMod """ # OFP_PORT_TABLE_PACK_STR v1.2 # '!B3xI'...table_id, pad(3), config table_id = 3 config = 2226555987 def test_init(self): c = OFPTableMod(_Datapath, self.table_id, self.config) self.assertEqual(self.table_id, c.table_id) self.assertEqual(self.config, c.config) def _test_serialize(self, table_id, config): c = OFPTableMod(_Datapath, table_id, config) c.serialize() self.assertEqual(ofproto.OFP_VERSION, c.version) self.assertEqual(ofproto.OFPT_TABLE_MOD, c.msg_type) self.assertEqual(0, c.xid) fmt = '!' \ + ofproto.OFP_HEADER_PACK_STR.replace('!', '') \ + ofproto.OFP_TABLE_MOD_PACK_STR.replace('!', '') res = struct.unpack(fmt, bytes(c.buf)) self.assertEqual(res[0], ofproto.OFP_VERSION) self.assertEqual(res[1], ofproto.OFPT_TABLE_MOD) self.assertEqual(res[2], len(c.buf)) self.assertEqual(res[3], 0) self.assertEqual(res[4], table_id) self.assertEqual(res[5], config) def test_serialize_mid(self): self._test_serialize(self.table_id, self.config) def test_serialize_max(self): table_id = ofproto.OFPTT_ALL config = 0xffffffff self._test_serialize(table_id, config) def test_serialize_min(self): table_id = 0 config = 0 self._test_serialize(table_id, config) def test_serialize_p1(self): table_id = ofproto.OFPTT_MAX config = ofproto.OFPTC_TABLE_MISS_CONTINUE self._test_serialize(table_id, config) def test_serialize_p2(self): table_id = ofproto.OFPTT_MAX config = ofproto.OFPTC_TABLE_MISS_DROP self._test_serialize(table_id, config) def test_serialize_p3(self): table_id = ofproto.OFPTT_MAX config = ofproto.OFPTC_TABLE_MISS_MASK self._test_serialize(table_id, config) class TestOFPStatsRequest(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPStatsRequest """ type_ = ofproto.OFPST_DESC c = OFPStatsRequest(_Datapath, type_) def test_init(self): self.assertEqual(self.type_, self.c.type) self.assertEqual(0, self.c.flags) def test_serialize_body(self): len_ = ofproto.OFP_HEADER_SIZE \ + ofproto.OFP_STATS_REQUEST_SIZE self.c.buf = bytearray(len_) self.c._serialize_body() fmt = ofproto.OFP_STATS_REQUEST_PACK_STR res = struct.unpack_from(fmt, bytes(self.c.buf), ofproto.OFP_HEADER_SIZE) self.assertEqual(res[0], self.type_) self.assertEqual(res[1], 0) class TestOFPStatsReply(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPStatsReply """ c = OFPStatsReply(_Datapath) def test_parser_single_struct_true(self): # OFP_HEADER_PACK_STR # '!BBHI'...version, msg_type, msg_len, xid version = ofproto.OFP_VERSION msg_type = ofproto.OFPT_STATS_REPLY msg_len = ofproto.OFP_STATS_REPLY_SIZE \ + ofproto.OFP_AGGREGATE_STATS_REPLY_SIZE xid = 2495926989 fmt = ofproto.OFP_HEADER_PACK_STR buf = pack(fmt, version, msg_type, msg_len, xid) # OFP_STATS_REPLY_PACK_STR # '!HH4x'...type, flags, pad(4) type_ = ofproto.OFPST_AGGREGATE flags = 41802 fmt = ofproto.OFP_STATS_REPLY_PACK_STR buf += pack(fmt, type_, flags) # OFP_AGGREGATE_STATS_REPLY_PACK_STR packet_count = 5142202600015232219 byte_count = 2659740543924820419 flow_count = 1344694860 body = OFPAggregateStatsReply(packet_count, byte_count, flow_count) fmt = ofproto.OFP_AGGREGATE_STATS_REPLY_PACK_STR buf += pack(fmt, packet_count, byte_count, flow_count) res = self.c.parser(object, version, msg_type, msg_len, xid, buf) self.assertEqual(version, res.version) self.assertEqual(msg_type, res.msg_type) self.assertEqual(msg_len, res.msg_len) self.assertEqual(xid, res.xid) self.assertEqual(type_, res.type) self.assertEqual(flags, res.flags) self.assertEqual(packet_count, res.body.packet_count) self.assertEqual(byte_count, res.body.byte_count) self.assertEqual(flow_count, res.body.flow_count) def test_parser_single_struct_flase(self): # OFP_HEADER_PACK_STR # '!BBHI'...version, msg_type, msg_len, xid version = ofproto.OFP_VERSION msg_type = ofproto.OFPT_STATS_REPLY msg_len = ofproto.OFP_STATS_REPLY_SIZE \ + ofproto.OFP_QUEUE_STATS_SIZE xid = 2495926989 fmt = ofproto.OFP_HEADER_PACK_STR buf = pack(fmt, version, msg_type, msg_len, xid) # OFP_STATS_REPLY_PACK_STR # '!HH4x'...type, flags, pad(4) type_ = ofproto.OFPST_QUEUE flags = 11884 fmt = ofproto.OFP_STATS_REPLY_PACK_STR buf += pack(fmt, type_, flags) # OFP_QUEUE_STATS_PACK_STR port_no = 41186 queue_id = 6606 tx_bytes = 8638420181865882538 tx_packets = 2856480458895760962 tx_errors = 6283093430376743019 body = [OFPQueueStats(port_no, queue_id, tx_bytes, tx_packets, tx_errors)] fmt = ofproto.OFP_QUEUE_STATS_PACK_STR buf += pack(fmt, port_no, queue_id, tx_bytes, tx_packets, tx_errors) res = self.c.parser(object, version, msg_type, msg_len, xid, buf) self.assertEqual(version, res.version) self.assertEqual(msg_type, res.msg_type) self.assertEqual(msg_len, res.msg_len) self.assertEqual(xid, res.xid) self.assertEqual(type_, res.type) self.assertEqual(flags, res.flags) self.assertEqual(port_no, res.body[0].port_no) self.assertEqual(queue_id, res.body[0].queue_id) self.assertEqual(tx_bytes, res.body[0].tx_bytes) self.assertEqual(tx_packets, res.body[0].tx_packets) self.assertEqual(tx_errors, res.body[0].tx_errors) def test_parser_max(self): # OFP_HEADER_PACK_STR # '!BBHI'...version, msg_type, msg_len, xid version = ofproto.OFP_VERSION msg_type = ofproto.OFPT_STATS_REPLY msg_len = ofproto.OFP_STATS_REPLY_SIZE xid = 0xffffffff fmt = ofproto.OFP_HEADER_PACK_STR buf = pack(fmt, version, msg_type, msg_len, xid) # OFP_STATS_REPLY_PACK_STR # '!HH4x'...type, flags, pad(4) type_ = ofproto.OFPST_QUEUE flags = 0xffff fmt = ofproto.OFP_STATS_REPLY_PACK_STR buf += pack(fmt, type_, flags) res = self.c.parser(object, version, msg_type, msg_len, xid, buf) self.assertEqual(version, res.version) self.assertEqual(msg_type, res.msg_type) self.assertEqual(msg_len, res.msg_len) self.assertEqual(xid, res.xid) self.assertEqual(type_, res.type) self.assertEqual(flags, res.flags) def test_parser_min(self): # OFP_HEADER_PACK_STR # '!BBHI'...version, msg_type, msg_len, xid version = ofproto.OFP_VERSION msg_type = ofproto.OFPT_STATS_REPLY msg_len = ofproto.OFP_STATS_REPLY_SIZE xid = 0 fmt = ofproto.OFP_HEADER_PACK_STR buf = pack(fmt, version, msg_type, msg_len, xid) # OFP_STATS_REPLY_PACK_STR # '!HH4x'...type, flags, pad(4) type_ = ofproto.OFPST_QUEUE flags = 0 fmt = ofproto.OFP_STATS_REPLY_PACK_STR buf += pack(fmt, type_, flags) res = self.c.parser(object, version, msg_type, msg_len, xid, buf) self.assertEqual(version, res.version) self.assertEqual(msg_type, res.msg_type) self.assertEqual(msg_len, res.msg_len) self.assertEqual(xid, res.xid) self.assertEqual(type_, res.type) self.assertEqual(flags, res.flags) class TestOFPDescStatsRequest(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPDescStatsRequest """ def test_serialize(self): c = OFPDescStatsRequest(_Datapath) c.serialize() fmt = '!' \ + ofproto.OFP_HEADER_PACK_STR.replace('!', '') \ + ofproto.OFP_STATS_REQUEST_PACK_STR.replace('!', '') res = struct.unpack(fmt, bytes(c.buf)) self.assertEqual(res[0], ofproto.OFP_VERSION) self.assertEqual(res[1], ofproto.OFPT_STATS_REQUEST) self.assertEqual(res[2], len(c.buf)) self.assertEqual(res[3], 0) self.assertEqual(res[4], ofproto.OFPST_DESC) self.assertEqual(res[5], 0) class TestOFPDescStats(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPDescStats """ # OFP_DESC_STATS_PACK_STR # '!256s256s256s32s256s'...mfr_desc, hw_desc, sw_desc, serial_num, dp_desc mfr_desc = b'mfr_desc'.ljust(256) hw_desc = b'hw_desc'.ljust(256) sw_desc = b'sw_desc'.ljust(256) serial_num = b'serial_num'.ljust(32) dp_desc = b'dp_desc'.ljust(256) buf = mfr_desc \ + hw_desc \ + sw_desc \ + serial_num \ + dp_desc c = OFPDescStats(mfr_desc, hw_desc, sw_desc, serial_num, dp_desc) def test_init(self): self.assertEqual(self.mfr_desc, self.c.mfr_desc) self.assertEqual(self.hw_desc, self.c.hw_desc) self.assertEqual(self.sw_desc, self.c.sw_desc) self.assertEqual(self.serial_num, self.c.serial_num) self.assertEqual(self.dp_desc, self.c.dp_desc) def test_parser(self): res = self.c.parser(self.buf, 0) self.assertEqual(self.mfr_desc, res.mfr_desc) self.assertEqual(self.hw_desc, res.hw_desc) self.assertEqual(self.sw_desc, res.sw_desc) self.assertEqual(self.serial_num, res.serial_num) self.assertEqual(self.dp_desc, res.dp_desc) class TestOFPFlowStatsRequest(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPFlowStatsRequest """ # OFP_FLOW_STATS_REQUEST_PACK_STR # '!B3xII4xQQ'...table_id, pad(3), out_port, out_group, pad(4), # cookie, cookie_mask table_id = 3 out_port = 65037 out_group = 6606 cookie = 2127614848199081640 cookie_mask = 2127614848199081641 def test_init(self): match = OFPMatch() in_port = 3 match.set_in_port(in_port) c = OFPFlowStatsRequest(_Datapath, self.table_id, self.out_port, self.out_group, self.cookie, self.cookie_mask, match) self.assertEqual(self.table_id, c.table_id) self.assertEqual(self.out_port, c.out_port) self.assertEqual(self.out_group, c.out_group) self.assertEqual(self.cookie, c.cookie) self.assertEqual(self.cookie_mask, c.cookie_mask) self.assertEqual(in_port, c.match._flow.in_port) def _test_serialize(self, table_id, out_port, out_group, cookie, cookie_mask): match = OFPMatch() dl_type = 0x800 match.set_dl_type(dl_type) c = OFPFlowStatsRequest(_Datapath, table_id, out_port, out_group, cookie, cookie_mask, match) c.serialize() self.assertEqual(ofproto.OFP_VERSION, c.version) self.assertEqual(ofproto.OFPT_STATS_REQUEST, c.msg_type) self.assertEqual(0, c.xid) fmt = ofproto.OFP_HEADER_PACK_STR \ + ofproto.OFP_STATS_REQUEST_PACK_STR[1:] \ + ofproto.OFP_FLOW_STATS_REQUEST_PACK_STR[1:] \ + 'HHHBB' \ + MTEthType.pack_str[1:] + '6x' res = struct.unpack(fmt, bytes(c.buf)) self.assertEqual(res[0], ofproto.OFP_VERSION) self.assertEqual(res[1], ofproto.OFPT_STATS_REQUEST) size = ofproto.OFP_STATS_REPLY_SIZE \ + ofproto.OFP_FLOW_STATS_REQUEST_SIZE \ + calcsize(MTEthType.pack_str + '6x') self.assertEqual(res[2], size) self.assertEqual(res[3], 0) self.assertEqual(res[4], ofproto.OFPST_FLOW) self.assertEqual(res[5], 0) self.assertEqual(res[6], table_id) self.assertEqual(res[7], out_port) self.assertEqual(res[8], out_group) self.assertEqual(res[9], cookie) self.assertEqual(res[10], cookie_mask) # match self.assertEqual(res[11], ofproto.OFPMT_OXM) self.assertEqual(res[12], 10) self.assertEqual(res[13], ofproto.OFPXMC_OPENFLOW_BASIC) self.assertEqual(res[14] >> 1, ofproto.OFPXMT_OFB_ETH_TYPE) self.assertEqual(res[14] & 0b0001, 0) self.assertEqual(res[15], calcsize(MTEthType.pack_str)) self.assertEqual(res[16], dl_type) def test_serialize_mid(self): self._test_serialize(self.table_id, self.out_port, self.out_group, self.cookie, self.cookie_mask) def test_serialize_max(self): table_id = 0xff out_port = 0xffff out_group = 0xffff cookie = 0xffffffff cookie_mask = 0xffffffff self._test_serialize(table_id, out_port, out_group, cookie, cookie_mask) def test_serialize_min(self): table_id = 0 out_port = 0 out_group = 0 cookie = 0 cookie_mask = 0 self._test_serialize(table_id, out_port, out_group, cookie, cookie_mask) def test_serialize_p1(self): table_id = ofproto.OFPTT_MAX self._test_serialize(table_id, self.out_port, self.out_group, self.cookie, self.cookie_mask) class TestOFPFlowStats(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPFlowStats """ def test_init(self): length = ofproto.OFP_FLOW_STATS_SIZE table_id = 81 duration_sec = 2484712402 duration_nsec = 3999715196 priority = 57792 idle_timeout = 36368 hard_timeout = 54425 cookie = 793171083674290912 packet_count = 5142202600015232219 byte_count = 2659740543924820419 match = OFPMatch() in_port = 2 match.set_in_port(in_port) goto_table = 3 instructions = [OFPInstructionGotoTable(goto_table)] c = OFPFlowStats(table_id, duration_sec, duration_nsec, priority, idle_timeout, hard_timeout, cookie, packet_count, byte_count, match, instructions) self.assertEqual(table_id, c.table_id) self.assertEqual(duration_sec, c.duration_sec) self.assertEqual(duration_nsec, c.duration_nsec) self.assertEqual(priority, c.priority) self.assertEqual(idle_timeout, c.idle_timeout) self.assertEqual(hard_timeout, c.hard_timeout) self.assertEqual(cookie, c.cookie) self.assertEqual(packet_count, c.packet_count) self.assertEqual(byte_count, c.byte_count) self.assertEqual(in_port, c.match._flow.in_port) self.assertEqual(goto_table, c.instructions[0].table_id) def _test_parser(self, table_id, duration_sec, duration_nsec, priority, idle_timeout, hard_timeout, cookie, packet_count, byte_count, inst_cnt=0): length = ofproto.OFP_FLOW_STATS_SIZE \ + calcsize(MTEthType.pack_str[1:] + '6x') \ + ofproto.OFP_INSTRUCTION_GOTO_TABLE_SIZE * inst_cnt # OFP_FLOW_STATS_PACK_STR buf = pack(ofproto.OFP_FLOW_STATS_PACK_STR, length, table_id, duration_sec, duration_nsec, priority, idle_timeout, hard_timeout, cookie, packet_count, byte_count) # match match = OFPMatch() dl_type = 0x0800 match.set_dl_type(dl_type) match_buf = bytearray() match.serialize(match_buf, 0) buf += bytes(match_buf) # instructions # 56 + 8 + 8 * inst_cnt <= 65535 # inst_cnt <= 8183 for i in range(inst_cnt): inst = OFPInstructionGotoTable(1) inst_buf = bytearray() inst.serialize(inst_buf, 0) buf += bytes(inst_buf) # parse res = OFPFlowStats.parser(buf, 0) self.assertEqual(length, res.length) self.assertEqual(table_id, res.table_id) self.assertEqual(duration_sec, res.duration_sec) self.assertEqual(duration_nsec, res.duration_nsec) self.assertEqual(priority, res.priority) self.assertEqual(idle_timeout, res.idle_timeout) self.assertEqual(hard_timeout, res.hard_timeout) self.assertEqual(cookie, res.cookie) self.assertEqual(packet_count, res.packet_count) self.assertEqual(byte_count, res.byte_count) self.assertEqual(dl_type, res.match.fields[0].value) for i in range(inst_cnt): self.assertEqual(1, res.instructions[i].table_id) def test_parser_mid(self): table_id = 81 duration_sec = 2484712402 duration_nsec = 3999715196 priority = 57792 idle_timeout = 36368 hard_timeout = 54425 cookie = 793171083674290912 packet_count = 5142202600015232219 byte_count = 2659740543924820419 inst_cnt = 2 self._test_parser(table_id, duration_sec, duration_nsec, priority, idle_timeout, hard_timeout, cookie, packet_count, byte_count, inst_cnt) def test_parser_max(self): table_id = 0xff duration_sec = 0xffff duration_nsec = 0xffff priority = 0xffff idle_timeout = 0xff hard_timeout = 0xff cookie = 0xffffffffffffffff packet_count = 0xffffffffffffffff byte_count = 0xffffffffffffffff inst_cnt = 8183 self._test_parser(table_id, duration_sec, duration_nsec, priority, idle_timeout, hard_timeout, cookie, packet_count, byte_count, inst_cnt) def test_parser_min(self): self._test_parser(0, 0, 0, 0, 0, 0, 0, 0, 0) class TestOFPAggregateStatsRequest(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPAggregateStatsRequest """ # OFP_AGGREGATE_STATS_REQUEST_PACK_STR # '!B3xII4xQQ'...table_id, pad(3), out_port, out_group, pad(4), # cookie, cookie_mask table_id = 3 out_port = 65037 out_group = 6606 cookie = 2127614848199081640 cookie_mask = 2127614848199081641 def test_init(self): match = OFPMatch() dl_type = 0x800 match.set_dl_type(dl_type) c = OFPAggregateStatsRequest(_Datapath, self.table_id, self.out_port, self.out_group, self.cookie, self.cookie_mask, match) self.assertEqual(self.table_id, c.table_id) self.assertEqual(self.out_port, c.out_port) self.assertEqual(self.out_group, c.out_group) self.assertEqual(self.cookie, c.cookie) self.assertEqual(self.cookie_mask, c.cookie_mask) self.assertEqual(dl_type, c.match._flow.dl_type) def _test_serialize(self, table_id, out_port, out_group, cookie, cookie_mask): match = OFPMatch() dl_type = 0x800 match.set_dl_type(dl_type) c = OFPAggregateStatsRequest(_Datapath, table_id, out_port, out_group, cookie, cookie_mask, match) c.serialize() self.assertEqual(ofproto.OFP_VERSION, c.version) self.assertEqual(ofproto.OFPT_STATS_REQUEST, c.msg_type) self.assertEqual(0, c.xid) fmt = ofproto.OFP_HEADER_PACK_STR \ + ofproto.OFP_STATS_REQUEST_PACK_STR[1:] \ + ofproto.OFP_AGGREGATE_STATS_REQUEST_PACK_STR[1:] \ + 'HHHBB' \ + MTEthType.pack_str[1:] + '6x' res = struct.unpack(fmt, bytes(c.buf)) self.assertEqual(res[0], ofproto.OFP_VERSION) self.assertEqual(res[1], ofproto.OFPT_STATS_REQUEST) self.assertEqual(res[2], len(c.buf)) self.assertEqual(res[3], 0) self.assertEqual(res[4], ofproto.OFPST_AGGREGATE) self.assertEqual(res[5], 0) self.assertEqual(res[6], table_id) self.assertEqual(res[7], out_port) self.assertEqual(res[8], out_group) self.assertEqual(res[9], cookie) self.assertEqual(res[10], cookie_mask) # match self.assertEqual(res[11], ofproto.OFPMT_OXM) self.assertEqual(res[12], 10) self.assertEqual(res[13], ofproto.OFPXMC_OPENFLOW_BASIC) self.assertEqual(res[14] >> 1, ofproto.OFPXMT_OFB_ETH_TYPE) self.assertEqual(res[14] & 0b0001, 0) self.assertEqual(res[15], calcsize(MTEthType.pack_str)) self.assertEqual(res[16], dl_type) def test_serialize_mid(self): self._test_serialize(self.table_id, self.out_port, self.out_group, self.cookie, self.cookie_mask) def test_serialize_max(self): table_id = 0xff out_port = 0xffffffff out_group = 0xffffffff cookie = 0xffffffff cookie_mask = 0xffffffff self._test_serialize(table_id, out_port, out_group, cookie, cookie_mask) def test_serialize_min(self): table_id = 0 out_port = 0 out_group = 0 cookie = 0 cookie_mask = 0 self._test_serialize(table_id, out_port, out_group, cookie, cookie_mask) def test_serialize_p1(self): table_id = ofproto.OFPTT_MAX self._test_serialize(table_id, self.out_port, self.out_group, self.cookie, self.cookie_mask) class TestOFPAggregateStatsReply(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPAggregateStatsReply """ # OFP_AGGREGATE_STATS_REPLY_PACK_STR # '!QQI4x'...packet_count, byte_count, flow_count, pad(4) packet_count = 5142202600015232219 byte_count = 2659740543924820419 flow_count = 1344694860 def test_init(self): c = OFPAggregateStatsReply(self.packet_count, self.byte_count, self.flow_count) self.assertEqual(c.packet_count, self.packet_count) self.assertEqual(c.byte_count, self.byte_count) self.assertEqual(c.flow_count, self.flow_count) def _test_parser(self, packet_count, byte_count, flow_count): fmt = ofproto.OFP_AGGREGATE_STATS_REPLY_PACK_STR buf = pack(fmt, packet_count, byte_count, flow_count) res = OFPAggregateStatsReply.parser(buf, 0) self.assertEqual(packet_count, res.packet_count) self.assertEqual(byte_count, res.byte_count) self.assertEqual(flow_count, res.flow_count) def test_parser_mid(self): self._test_parser(self.packet_count, self.byte_count, self.flow_count) def test_parser_max(self): packet_count = 18446744073709551615 byte_count = 18446744073709551615 flow_count = 4294967295 self._test_parser(packet_count, byte_count, flow_count) def test_parser_min(self): packet_count = 0 byte_count = 0 flow_count = 0 self._test_parser(packet_count, byte_count, flow_count) class TestOFPTableStatsRequest(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPTableStatsRequest """ def test_serialize(self): c = OFPTableStatsRequest(_Datapath) c.serialize() fmt = '!' \ + ofproto.OFP_HEADER_PACK_STR.replace('!', '') \ + ofproto.OFP_STATS_REQUEST_PACK_STR.replace('!', '') res = struct.unpack(fmt, bytes(c.buf)) self.assertEqual(res[0], ofproto.OFP_VERSION) self.assertEqual(res[1], ofproto.OFPT_STATS_REQUEST) self.assertEqual(res[2], len(c.buf)) self.assertEqual(res[3], 0) self.assertEqual(res[4], ofproto.OFPST_TABLE) self.assertEqual(res[5], 0) class TestOFPTableStats(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPTableStats """ def test_init(self): table_id = 91 name = 'name' match = 1270985291017894273 wildcards = 3316608530 write_actions = 2484712402 apply_actions = 3999715196 write_setfields = 5142202600015232219 apply_setfields = 2659740543924820419 metadata_match = 2127614848199081640 metadata_write = 2127614848199081641 instructions = 1119692796 config = 2226555987 max_entries = 2506913869 active_count = 2024581150 lookup_count = 4620020561814017052 matched_count = 2825167325263435621 res = OFPTableStats(table_id, name, match, wildcards, write_actions, apply_actions, write_setfields, apply_setfields, metadata_match, metadata_write, instructions, config, max_entries, active_count, lookup_count, matched_count) self.assertEqual(table_id, res.table_id) self.assertEqual(name, res.name) self.assertEqual(match, res.match) self.assertEqual(wildcards, res.wildcards) self.assertEqual(write_actions, res.write_actions) self.assertEqual(apply_actions, res.apply_actions) self.assertEqual(write_setfields, res.write_setfields) self.assertEqual(apply_setfields, res.apply_setfields) self.assertEqual(metadata_match, res.metadata_match) self.assertEqual(metadata_write, res.metadata_write) self.assertEqual(instructions, res.instructions) self.assertEqual(config, res.config) self.assertEqual(max_entries, res.max_entries) self.assertEqual(active_count, res.active_count) self.assertEqual(lookup_count, res.lookup_count) self.assertEqual(matched_count, res.matched_count) def _test_parser(self, table_id, name, match, wildcards, write_actions, apply_actions, write_setfields, apply_setfields, metadata_match, metadata_write, instructions, config, max_entries, active_count, lookup_count, matched_count): # OFP_TABLE_STATS_PACK_STR # '!B7x32sQQIIQQQQIIIIQQ' # ...table_id, name, match, wildcards, write_actions, apply_actions, # write_setfields, apply_setfields', metadata_match, metadata_write, # instructions, config, max_entries, # active_count, lookup_count, matched_count fmt = ofproto.OFP_TABLE_STATS_PACK_STR buf = pack(fmt, table_id, name, match, wildcards, write_actions, apply_actions, write_setfields, apply_setfields, metadata_match, metadata_write, instructions, config, max_entries, active_count, lookup_count, matched_count) res = OFPTableStats.parser(buf, 0) self.assertEqual(table_id, res.table_id) self.assertEqual(name, res.name.replace(b'\x00', b'')) self.assertEqual(match, res.match) self.assertEqual(wildcards, res.wildcards) self.assertEqual(write_actions, res.write_actions) self.assertEqual(apply_actions, res.apply_actions) self.assertEqual(write_setfields, res.write_setfields) self.assertEqual(apply_setfields, res.apply_setfields) self.assertEqual(metadata_match, res.metadata_match) self.assertEqual(metadata_write, res.metadata_write) self.assertEqual(instructions, res.instructions) self.assertEqual(config, res.config) self.assertEqual(max_entries, res.max_entries) self.assertEqual(active_count, res.active_count) self.assertEqual(lookup_count, res.lookup_count) self.assertEqual(matched_count, res.matched_count) def test_parser_mid(self): table_id = 91 name = b'name' match = 1270985291017894273 wildcards = 3316608530 write_actions = 2484712402 apply_actions = 3999715196 write_setfields = 5142202600015232219 apply_setfields = 2659740543924820419 metadata_match = 2127614848199081640 metadata_write = 2127614848199081641 instructions = 1119692796 config = 2226555987 max_entries = 2506913869 active_count = 2024581150 lookup_count = 4620020561814017052 matched_count = 2825167325263435621 self._test_parser(table_id, name, match, wildcards, write_actions, apply_actions, write_setfields, apply_setfields, metadata_match, metadata_write, instructions, config, max_entries, active_count, lookup_count, matched_count) def test_parser_max(self): # '!B7x32sQQIIQQQQIIIIQQ' table_id = 0xff name = b'a' * 32 match = 0xffffffffffffffff wildcards = 0xffffffffffffffff write_actions = 0xffffffff apply_actions = 0xffffffff write_setfields = 0xffffffffffffffff apply_setfields = 0xffffffffffffffff metadata_match = 0xffffffffffffffff metadata_write = 0xffffffffffffffff instructions = 0xffffffff config = 0xffffffff max_entries = 0xffffffff active_count = 0xffffffff lookup_count = 0xffffffffffffffff matched_count = 0xffffffffffffffff self._test_parser(table_id, name, match, wildcards, write_actions, apply_actions, write_setfields, apply_setfields, metadata_match, metadata_write, instructions, config, max_entries, active_count, lookup_count, matched_count) def test_parser_min(self): table_id = 0 name = b'' match = 0 wildcards = 0 write_actions = 0 apply_actions = 0 write_setfields = 0 apply_setfields = 0 metadata_match = 0 metadata_write = 0 instructions = 0 config = 0 max_entries = 0 active_count = 0 lookup_count = 0 matched_count = 0 self._test_parser(table_id, name, match, wildcards, write_actions, apply_actions, write_setfields, apply_setfields, metadata_match, metadata_write, instructions, config, max_entries, active_count, lookup_count, matched_count) def _test_parser_p(self, ofpxmt, ofpit, ofptc): table_id = 91 name = b'name' match = ofpxmt wildcards = ofpxmt write_actions = 2484712402 apply_actions = 3999715196 write_setfields = ofpxmt apply_setfields = ofpxmt metadata_match = 2127614848199081640 metadata_write = 2127614848199081641 instructions = ofpit config = ofptc max_entries = 2506913869 active_count = 2024581150 lookup_count = 4620020561814017052 matched_count = 2825167325263435621 self._test_parser(table_id, name, match, wildcards, write_actions, apply_actions, write_setfields, apply_setfields, metadata_match, metadata_write, instructions, config, max_entries, active_count, lookup_count, matched_count) def test_parser_p1(self): self._test_parser_p(ofproto.OFPXMT_OFB_IN_PORT, ofproto.OFPIT_GOTO_TABLE, ofproto.OFPTC_TABLE_MISS_CONTINUE) def test_parser_p2(self): self._test_parser_p(ofproto.OFPXMT_OFB_IN_PHY_PORT, ofproto.OFPIT_WRITE_METADATA, ofproto.OFPTC_TABLE_MISS_DROP) def test_parser_p3(self): self._test_parser_p(ofproto.OFPXMT_OFB_METADATA, ofproto.OFPIT_WRITE_ACTIONS, ofproto.OFPTC_TABLE_MISS_MASK) def test_parser_p4(self): self._test_parser_p(ofproto.OFPXMT_OFB_ETH_DST, ofproto.OFPIT_APPLY_ACTIONS, ofproto.OFPTC_TABLE_MISS_MASK) def test_parser_p5(self): self._test_parser_p(ofproto.OFPXMT_OFB_ETH_SRC, ofproto.OFPIT_CLEAR_ACTIONS, ofproto.OFPTC_TABLE_MISS_MASK) def test_parser_p6(self): self._test_parser_p(ofproto.OFPXMT_OFB_ETH_TYPE, ofproto.OFPIT_EXPERIMENTER, ofproto.OFPTC_TABLE_MISS_MASK) def test_parser_p7(self): self._test_parser_p(ofproto.OFPXMT_OFB_VLAN_VID, ofproto.OFPIT_EXPERIMENTER, ofproto.OFPTC_TABLE_MISS_MASK) def test_parser_p8(self): self._test_parser_p(ofproto.OFPXMT_OFB_VLAN_PCP, ofproto.OFPIT_EXPERIMENTER, ofproto.OFPTC_TABLE_MISS_MASK) def test_parser_p9(self): self._test_parser_p(ofproto.OFPXMT_OFB_IP_DSCP, ofproto.OFPIT_EXPERIMENTER, ofproto.OFPTC_TABLE_MISS_MASK) def test_parser_p10(self): self._test_parser_p(ofproto.OFPXMT_OFB_IP_ECN, ofproto.OFPIT_EXPERIMENTER, ofproto.OFPTC_TABLE_MISS_MASK) def test_parser_p11(self): self._test_parser_p(ofproto.OFPXMT_OFB_IP_PROTO, ofproto.OFPIT_EXPERIMENTER, ofproto.OFPTC_TABLE_MISS_MASK) def test_parser_p12(self): self._test_parser_p(ofproto.OFPXMT_OFB_IPV4_SRC, ofproto.OFPIT_EXPERIMENTER, ofproto.OFPTC_TABLE_MISS_MASK) def test_parser_p13(self): self._test_parser_p(ofproto.OFPXMT_OFB_IPV4_DST, ofproto.OFPIT_EXPERIMENTER, ofproto.OFPTC_TABLE_MISS_MASK) def test_parser_p14(self): self._test_parser_p(ofproto.OFPXMT_OFB_TCP_SRC, ofproto.OFPIT_EXPERIMENTER, ofproto.OFPTC_TABLE_MISS_MASK) def test_parser_p15(self): self._test_parser_p(ofproto.OFPXMT_OFB_TCP_DST, ofproto.OFPIT_EXPERIMENTER, ofproto.OFPTC_TABLE_MISS_MASK) def test_parser_p16(self): self._test_parser_p(ofproto.OFPXMT_OFB_UDP_SRC, ofproto.OFPIT_EXPERIMENTER, ofproto.OFPTC_TABLE_MISS_MASK) def test_parser_p17(self): self._test_parser_p(ofproto.OFPXMT_OFB_UDP_DST, ofproto.OFPIT_EXPERIMENTER, ofproto.OFPTC_TABLE_MISS_MASK) def test_parser_p18(self): self._test_parser_p(ofproto.OFPXMT_OFB_SCTP_SRC, ofproto.OFPIT_EXPERIMENTER, ofproto.OFPTC_TABLE_MISS_MASK) def test_parser_p19(self): self._test_parser_p(ofproto.OFPXMT_OFB_SCTP_DST, ofproto.OFPIT_EXPERIMENTER, ofproto.OFPTC_TABLE_MISS_MASK) def test_parser_p20(self): self._test_parser_p(ofproto.OFPXMT_OFB_ICMPV4_TYPE, ofproto.OFPIT_EXPERIMENTER, ofproto.OFPTC_TABLE_MISS_MASK) def test_parser_p21(self): self._test_parser_p(ofproto.OFPXMT_OFB_ICMPV4_CODE, ofproto.OFPIT_EXPERIMENTER, ofproto.OFPTC_TABLE_MISS_MASK) def test_parser_p22(self): self._test_parser_p(ofproto.OFPXMT_OFB_ARP_OP, ofproto.OFPIT_EXPERIMENTER, ofproto.OFPTC_TABLE_MISS_MASK) def test_parser_p23(self): self._test_parser_p(ofproto.OFPXMT_OFB_ARP_SPA, ofproto.OFPIT_EXPERIMENTER, ofproto.OFPTC_TABLE_MISS_MASK) def test_parser_p24(self): self._test_parser_p(ofproto.OFPXMT_OFB_ARP_TPA, ofproto.OFPIT_EXPERIMENTER, ofproto.OFPTC_TABLE_MISS_MASK) def test_parser_p25(self): self._test_parser_p(ofproto.OFPXMT_OFB_ARP_SHA, ofproto.OFPIT_EXPERIMENTER, ofproto.OFPTC_TABLE_MISS_MASK) def test_parser_p26(self): self._test_parser_p(ofproto.OFPXMT_OFB_ARP_THA, ofproto.OFPIT_EXPERIMENTER, ofproto.OFPTC_TABLE_MISS_MASK) def test_parser_p27(self): self._test_parser_p(ofproto.OFPXMT_OFB_IPV6_SRC, ofproto.OFPIT_EXPERIMENTER, ofproto.OFPTC_TABLE_MISS_MASK) def test_parser_p28(self): self._test_parser_p(ofproto.OFPXMT_OFB_IPV6_DST, ofproto.OFPIT_EXPERIMENTER, ofproto.OFPTC_TABLE_MISS_MASK) def test_parser_p29(self): self._test_parser_p(ofproto.OFPXMT_OFB_IPV6_FLABEL, ofproto.OFPIT_EXPERIMENTER, ofproto.OFPTC_TABLE_MISS_MASK) def test_parser_p30(self): self._test_parser_p(ofproto.OFPXMT_OFB_ICMPV6_TYPE, ofproto.OFPIT_EXPERIMENTER, ofproto.OFPTC_TABLE_MISS_MASK) def test_parser_p31(self): self._test_parser_p(ofproto.OFPXMT_OFB_ICMPV6_CODE, ofproto.OFPIT_EXPERIMENTER, ofproto.OFPTC_TABLE_MISS_MASK) def test_parser_p32(self): self._test_parser_p(ofproto.OFPXMT_OFB_IPV6_ND_TARGET, ofproto.OFPIT_EXPERIMENTER, ofproto.OFPTC_TABLE_MISS_MASK) def test_parser_p33(self): self._test_parser_p(ofproto.OFPXMT_OFB_IPV6_ND_SLL, ofproto.OFPIT_EXPERIMENTER, ofproto.OFPTC_TABLE_MISS_MASK) def test_parser_p34(self): self._test_parser_p(ofproto.OFPXMT_OFB_IPV6_ND_TLL, ofproto.OFPIT_EXPERIMENTER, ofproto.OFPTC_TABLE_MISS_MASK) def test_parser_p35(self): self._test_parser_p(ofproto.OFPXMT_OFB_MPLS_LABEL, ofproto.OFPIT_EXPERIMENTER, ofproto.OFPTC_TABLE_MISS_MASK) def test_parser_p36(self): self._test_parser_p(ofproto.OFPXMT_OFB_MPLS_TC, ofproto.OFPIT_EXPERIMENTER, ofproto.OFPTC_TABLE_MISS_MASK) class TestOFPPortStatsRequest(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPPortStatsRequest """ # OFP_PORT_STATS_REQUEST_PACK_STR # '!I4x'...port_no, pad(4) port_no = 41186 def test_init(self): c = OFPPortStatsRequest(_Datapath, self.port_no) self.assertEqual(self.port_no, c.port_no) def _test_serialize(self, port_no): c = OFPPortStatsRequest(_Datapath, port_no) c.serialize() self.assertEqual(ofproto.OFP_VERSION, c.version) self.assertEqual(ofproto.OFPT_STATS_REQUEST, c.msg_type) self.assertEqual(0, c.xid) fmt = '!' \ + ofproto.OFP_HEADER_PACK_STR.replace('!', '') \ + ofproto.OFP_STATS_REQUEST_PACK_STR.replace('!', '') \ + ofproto.OFP_PORT_STATS_REQUEST_PACK_STR.replace('!', '') res = struct.unpack(fmt, bytes(c.buf)) self.assertEqual(res[0], ofproto.OFP_VERSION) self.assertEqual(res[1], ofproto.OFPT_STATS_REQUEST) self.assertEqual(res[2], len(c.buf)) self.assertEqual(res[3], 0) self.assertEqual(res[4], ofproto.OFPST_PORT) self.assertEqual(res[5], 0) self.assertEqual(res[6], port_no) def test_serialize_mid(self): self._test_serialize(self.port_no) def test_serialize_max(self): self._test_serialize(ofproto.OFPP_ANY) def test_serialize_min(self): self._test_serialize(0) def test_serialize_p1(self): self._test_serialize(ofproto.OFPP_MAX) def test_serialize_p2(self): self._test_serialize(ofproto.OFPP_IN_PORT) def test_serialize_p3(self): self._test_serialize(ofproto.OFPP_TABLE) def test_serialize_p4(self): self._test_serialize(ofproto.OFPP_NORMAL) def test_serialize_p5(self): self._test_serialize(ofproto.OFPP_FLOOD) def test_serialize_p6(self): self._test_serialize(ofproto.OFPP_ALL) def test_serialize_p7(self): self._test_serialize(ofproto.OFPP_CONTROLLER) def test_serialize_p8(self): self._test_serialize(ofproto.OFPP_LOCAL) class TestOFPPortStats(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPPortStats """ def test_init(self): port_no = 6606 rx_packets = 5999980397101236279 tx_packets = 2856480458895760962 rx_bytes = 6170274950576278921 tx_bytes = 8638420181865882538 rx_dropped = 6982303461569875546 tx_dropped = 661287462113808071 rx_errors = 3422231811478788365 tx_errors = 6283093430376743019 rx_frame_err = 876072919806406283 rx_over_err = 6525873760178941600 rx_crc_err = 8303073210207070535 collisions = 3409801584220270201 res = OFPPortStats(port_no, rx_packets, tx_packets, rx_bytes, tx_bytes, rx_dropped, tx_dropped, rx_errors, tx_errors, rx_frame_err, rx_over_err, rx_crc_err, collisions) self.assertEqual(port_no, res.port_no) self.assertEqual(rx_packets, res.rx_packets) self.assertEqual(tx_packets, res.tx_packets) self.assertEqual(rx_bytes, res.rx_bytes) self.assertEqual(tx_bytes, res.tx_bytes) self.assertEqual(rx_dropped, res.rx_dropped) self.assertEqual(tx_dropped, res.tx_dropped) self.assertEqual(rx_errors, res.rx_errors) self.assertEqual(tx_errors, res.tx_errors) self.assertEqual(rx_frame_err, res.rx_frame_err) self.assertEqual(rx_over_err, res.rx_over_err) self.assertEqual(rx_crc_err, res.rx_crc_err) self.assertEqual(collisions, res.collisions) def _test_parser(self, port_no, rx_packets, tx_packets, rx_bytes, tx_bytes, rx_dropped, tx_dropped, rx_errors, tx_errors, rx_frame_err, rx_over_err, rx_crc_err, collisions): # OFP_PORT_STATS_PACK_STR = '!H6xQQQQQQQQQQQQ' fmt = ofproto.OFP_PORT_STATS_PACK_STR buf = pack(fmt, port_no, rx_packets, tx_packets, rx_bytes, tx_bytes, rx_dropped, tx_dropped, rx_errors, tx_errors, rx_frame_err, rx_over_err, rx_crc_err, collisions) res = OFPPortStats.parser(buf, 0) self.assertEqual(port_no, res.port_no) self.assertEqual(rx_packets, res.rx_packets) self.assertEqual(tx_packets, res.tx_packets) self.assertEqual(rx_bytes, res.rx_bytes) self.assertEqual(tx_bytes, res.tx_bytes) self.assertEqual(rx_dropped, res.rx_dropped) self.assertEqual(tx_dropped, res.tx_dropped) self.assertEqual(rx_errors, res.rx_errors) self.assertEqual(tx_errors, res.tx_errors) self.assertEqual(rx_frame_err, res.rx_frame_err) self.assertEqual(rx_over_err, res.rx_over_err) self.assertEqual(rx_crc_err, res.rx_crc_err) self.assertEqual(collisions, res.collisions) def test_parser_mid(self): port_no = 6606 rx_packets = 5999980397101236279 tx_packets = 2856480458895760962 rx_bytes = 6170274950576278921 tx_bytes = 8638420181865882538 rx_dropped = 6982303461569875546 tx_dropped = 661287462113808071 rx_errors = 3422231811478788365 tx_errors = 6283093430376743019 rx_frame_err = 876072919806406283 rx_over_err = 6525873760178941600 rx_crc_err = 8303073210207070535 collisions = 3409801584220270201 self._test_parser(port_no, rx_packets, tx_packets, rx_bytes, tx_bytes, rx_dropped, tx_dropped, rx_errors, tx_errors, rx_frame_err, rx_over_err, rx_crc_err, collisions) def test_parser_max(self): port_no = 0xffffffff rx_packets = 0xffffffffffffffff tx_packets = 0xffffffffffffffff rx_bytes = 0xffffffffffffffff tx_bytes = 0xffffffffffffffff rx_dropped = 0xffffffffffffffff tx_dropped = 0xffffffffffffffff rx_errors = 0xffffffffffffffff tx_errors = 0xffffffffffffffff rx_frame_err = 0xffffffffffffffff rx_over_err = 0xffffffffffffffff rx_crc_err = 0xffffffffffffffff collisions = 0xffffffffffffffff self._test_parser(port_no, rx_packets, tx_packets, rx_bytes, tx_bytes, rx_dropped, tx_dropped, rx_errors, tx_errors, rx_frame_err, rx_over_err, rx_crc_err, collisions) def test_parser_min(self): port_no = 0 rx_packets = 0 tx_packets = 0 rx_bytes = 0 tx_bytes = 0 rx_dropped = 0 tx_dropped = 0 rx_errors = 0 tx_errors = 0 rx_frame_err = 0 rx_over_err = 0 rx_crc_err = 0 collisions = 0 self._test_parser(port_no, rx_packets, tx_packets, rx_bytes, tx_bytes, rx_dropped, tx_dropped, rx_errors, tx_errors, rx_frame_err, rx_over_err, rx_crc_err, collisions) def _test_parser_p(self, port_no): port_no = port_no rx_packets = 5999980397101236279 tx_packets = 2856480458895760962 rx_bytes = 6170274950576278921 tx_bytes = 8638420181865882538 rx_dropped = 6982303461569875546 tx_dropped = 661287462113808071 rx_errors = 3422231811478788365 tx_errors = 6283093430376743019 rx_frame_err = 876072919806406283 rx_over_err = 6525873760178941600 rx_crc_err = 8303073210207070535 collisions = 3409801584220270201 self._test_parser(port_no, rx_packets, tx_packets, rx_bytes, tx_bytes, rx_dropped, tx_dropped, rx_errors, tx_errors, rx_frame_err, rx_over_err, rx_crc_err, collisions) def test_parser_p1(self): self._test_parser_p(ofproto.OFPP_MAX) def test_parser_p2(self): self._test_parser_p(ofproto.OFPP_IN_PORT) def test_parser_p3(self): self._test_parser_p(ofproto.OFPP_TABLE) def test_parser_p4(self): self._test_parser_p(ofproto.OFPP_NORMAL) def test_parser_p5(self): self._test_parser_p(ofproto.OFPP_FLOOD) def test_parser_p6(self): self._test_parser_p(ofproto.OFPP_ALL) def test_parser_p7(self): self._test_parser_p(ofproto.OFPP_CONTROLLER) def test_parser_p8(self): self._test_parser_p(ofproto.OFPP_LOCAL) class TestOFPQueueStatsRequest(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPQueueStatsRequest """ # OFP_QUEUE_STATS_REQUEST_PACK_STR # '!II'...port_no, queue_id port_no = 41186 queue_id = 6606 def test_init(self): c = OFPQueueStatsRequest(_Datapath, self.port_no, self.queue_id) self.assertEqual(self.port_no, c.port_no) self.assertEqual(self.queue_id, c.queue_id) def _test_serialize(self, port_no, queue_id): c = OFPQueueStatsRequest(_Datapath, port_no, queue_id) c.serialize() self.assertEqual(ofproto.OFP_VERSION, c.version) self.assertEqual(ofproto.OFPT_STATS_REQUEST, c.msg_type) self.assertEqual(0, c.xid) fmt = '!' \ + ofproto.OFP_HEADER_PACK_STR.replace('!', '') \ + ofproto.OFP_STATS_REQUEST_PACK_STR.replace('!', '') \ + ofproto.OFP_QUEUE_STATS_REQUEST_PACK_STR.replace('!', '') res = struct.unpack(fmt, bytes(c.buf)) self.assertEqual(res[0], ofproto.OFP_VERSION) self.assertEqual(res[1], ofproto.OFPT_STATS_REQUEST) self.assertEqual(res[2], len(c.buf)) self.assertEqual(res[3], 0) self.assertEqual(res[4], ofproto.OFPST_QUEUE) self.assertEqual(res[5], 0) self.assertEqual(res[6], port_no) self.assertEqual(res[7], queue_id) def test_serialize_mid(self): self._test_serialize(self.port_no, self.queue_id) def test_serialize_max(self): self._test_serialize(0xffffffff, 0xffffffff) def test_serialize_min(self): self._test_serialize(0, 0) def test_serialize_p1(self): self._test_serialize(ofproto.OFPP_MAX, self.queue_id) def test_serialize_p2(self): self._test_serialize(ofproto.OFPP_IN_PORT, self.queue_id) def test_serialize_p3(self): self._test_serialize(ofproto.OFPP_NORMAL, self.queue_id) def test_serialize_p4(self): self._test_serialize(ofproto.OFPP_TABLE, self.queue_id) def test_serialize_p5(self): self._test_serialize(ofproto.OFPP_FLOOD, self.queue_id) def test_serialize_p6(self): self._test_serialize(ofproto.OFPP_ALL, self.queue_id) def test_serialize_p7(self): self._test_serialize(ofproto.OFPP_CONTROLLER, self.queue_id) def test_serialize_p8(self): self._test_serialize(ofproto.OFPP_LOCAL, self.queue_id) class TestOFPQueueStats(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPQueueStats """ def test_init(self): port_no = 41186 queue_id = 6606 tx_bytes = 8638420181865882538 tx_packets = 2856480458895760962 tx_errors = 6283093430376743019 res = OFPQueueStats(port_no, queue_id, tx_bytes, tx_packets, tx_errors) self.assertEqual(port_no, res.port_no) self.assertEqual(queue_id, res.queue_id) self.assertEqual(tx_bytes, res.tx_bytes) self.assertEqual(tx_packets, res.tx_packets) self.assertEqual(tx_errors, res.tx_errors) def _test_parser(self, port_no, queue_id, tx_bytes, tx_packets, tx_errors): # OFP_QUEUE_STATS_PACK_STR = '!IIQQQ' fmt = ofproto.OFP_QUEUE_STATS_PACK_STR buf = pack(fmt, port_no, queue_id, tx_bytes, tx_packets, tx_errors) res = OFPQueueStats.parser(buf, 0) self.assertEqual(port_no, res.port_no) self.assertEqual(queue_id, res.queue_id) self.assertEqual(tx_bytes, res.tx_bytes) self.assertEqual(tx_packets, res.tx_packets) self.assertEqual(tx_errors, res.tx_errors) def test_parser_mid(self): port_no = 41186 queue_id = 6606 tx_bytes = 8638420181865882538 tx_packets = 2856480458895760962 tx_errors = 6283093430376743019 self._test_parser(port_no, queue_id, tx_bytes, tx_packets, tx_errors) def test_parser_max(self): port_no = 0xffffffff queue_id = 0xffffffff tx_bytes = 0xffffffffffffffff tx_packets = 0xffffffffffffffff tx_errors = 0xffffffffffffffff self._test_parser(port_no, queue_id, tx_bytes, tx_packets, tx_errors) def test_parser_min(self): port_no = 0 queue_id = 0 tx_bytes = 0 tx_packets = 0 tx_errors = 0 self._test_parser(port_no, queue_id, tx_bytes, tx_packets, tx_errors) def _test_parser_p(self, port_no): queue_id = 6606 tx_bytes = 8638420181865882538 tx_packets = 2856480458895760962 tx_errors = 6283093430376743019 self._test_parser(port_no, queue_id, tx_bytes, tx_packets, tx_errors) def test_parser_p1(self): self._test_parser_p(ofproto.OFPP_MAX) def test_parser_p2(self): self._test_parser_p(ofproto.OFPP_IN_PORT) def test_parser_p3(self): self._test_parser_p(ofproto.OFPP_TABLE) def test_parser_p4(self): self._test_parser_p(ofproto.OFPP_NORMAL) def test_parser_p5(self): self._test_parser_p(ofproto.OFPP_FLOOD) def test_parser_p6(self): self._test_parser_p(ofproto.OFPP_ALL) def test_parser_p7(self): self._test_parser_p(ofproto.OFPP_CONTROLLER) def test_parser_p8(self): self._test_parser_p(ofproto.OFPP_LOCAL) class TestOFPBucketCounter(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPBucketCounter """ # OFP_BUCKET_COUNTER_PACK_STR = '!QQ' packet_count = 6489108735192644493 byte_count = 7334344481123449724 def test_init(self): c = OFPBucketCounter(self.packet_count, self.byte_count) self.assertEqual(self.packet_count, c.packet_count) self.assertEqual(self.byte_count, c.byte_count) def _test_parser(self, packet_count, byte_count): fmt = ofproto.OFP_BUCKET_COUNTER_PACK_STR buf = pack(fmt, packet_count, byte_count) res = OFPBucketCounter.parser(buf, 0) self.assertEqual(packet_count, res.packet_count) self.assertEqual(byte_count, res.byte_count) def test_parser_mid(self): self._test_parser(self.packet_count, self.byte_count) def test_parser_max(self): packet_count = 18446744073709551615 byte_count = 18446744073709551615 self._test_parser(packet_count, byte_count) def test_parser_min(self): packet_count = 0 byte_count = 0 self._test_parser(packet_count, byte_count) class TestOFPGroupStatsRequest(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPGroupStatsRequest """ # OFP_GROUP_STATS_REQUEST_PACK_STR # '!I4x'...group_id, pad(4) group_id = 6606 def test_init(self): c = OFPGroupStatsRequest(_Datapath, self.group_id) self.assertEqual(self.group_id, c.group_id) def _test_serialize(self, group_id): c = OFPGroupStatsRequest(_Datapath, group_id) c.serialize() self.assertEqual(ofproto.OFP_VERSION, c.version) self.assertEqual(ofproto.OFPT_STATS_REQUEST, c.msg_type) self.assertEqual(0, c.xid) fmt = '!' \ + ofproto.OFP_HEADER_PACK_STR.replace('!', '') \ + ofproto.OFP_STATS_REQUEST_PACK_STR.replace('!', '') \ + ofproto.OFP_GROUP_STATS_REQUEST_PACK_STR.replace('!', '') res = struct.unpack(fmt, bytes(c.buf)) self.assertEqual(res[0], ofproto.OFP_VERSION) self.assertEqual(res[1], ofproto.OFPT_STATS_REQUEST) self.assertEqual(res[2], len(c.buf)) self.assertEqual(res[3], 0) self.assertEqual(res[4], ofproto.OFPST_GROUP) self.assertEqual(res[5], 0) self.assertEqual(res[6], group_id) def test_serialize_mid(self): self._test_serialize(self.group_id) def test_serialize_max(self): self._test_serialize(0xffffffff) def test_serialize_min(self): self._test_serialize(0) def test_serialize_p1(self): self._test_serialize(ofproto.OFPG_MAX) def test_serialize_p2(self): self._test_serialize(ofproto.OFPG_ALL) class TestOFPGroupStats(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPGroupStats """ # OFP_GROUP_STATS_PACK_STR = '!H2xII4xQQ' length = ofproto.OFP_GROUP_STATS_SIZE \ + ofproto.OFP_BUCKET_COUNTER_SIZE group_id = 6606 ref_count = 2102 packet_count = 6489108735192644493 byte_count = 7334344481123449724 # OFP_BUCKET_COUNTER_PACK_STR = '!QQ' buck_packet_count = 3519264449364891087 buck_byte_count = 3123449724733434448 bucket_counters = [OFPBucketCounter(buck_packet_count, buck_byte_count)] buf_bucket_counters = pack(ofproto.OFP_BUCKET_COUNTER_PACK_STR, buck_packet_count, buck_byte_count) fmt = ofproto.OFP_GROUP_STATS_PACK_STR buf = pack(fmt, length, group_id, ref_count, packet_count, byte_count) \ + buf_bucket_counters def test_init(self): c = OFPGroupStats(self.group_id, self.ref_count, self.packet_count, self.byte_count, self.bucket_counters) self.assertEqual(self.group_id, c.group_id) self.assertEqual(self.ref_count, c.ref_count) self.assertEqual(self.packet_count, c.packet_count) self.assertEqual(self.byte_count, c.byte_count) self.assertEqual(self.bucket_counters, c.bucket_counters) def _test_parser(self, group_id, ref_count, packet_count, byte_count, bucket_counter_cnt): # OFP_GROUP_STATS_PACK_STR = '!H2xII4xQQ' length = ofproto.OFP_GROUP_STATS_SIZE \ + (ofproto.OFP_BUCKET_COUNTER_SIZE * bucket_counter_cnt) fmt = ofproto.OFP_GROUP_STATS_PACK_STR buf = pack(fmt, length, group_id, ref_count, packet_count, byte_count) bucket_counters = [] for b in range(bucket_counter_cnt): # OFP_BUCKET_COUNTER_PACK_STR = '!QQ' buck_packet_count = b buck_byte_count = b bucket_counter = OFPBucketCounter(buck_packet_count, buck_byte_count) bucket_counters.append(bucket_counter) buf_bucket_counters = \ pack(ofproto.OFP_BUCKET_COUNTER_PACK_STR, buck_packet_count, buck_byte_count) buf += buf_bucket_counters res = OFPGroupStats.parser(buf, 0) # 32 self.assertEqual(length, res.length) self.assertEqual(group_id, res.group_id) self.assertEqual(ref_count, res.ref_count) self.assertEqual(packet_count, res.packet_count) self.assertEqual(byte_count, res.byte_count) # 32 + 16 * bucket_counter_cnt < 65535 byte # bucket_counter_cnt <= 4093 for b in range(bucket_counter_cnt): self.assertEqual(bucket_counters[b].packet_count, res.bucket_counters[b].packet_count) self.assertEqual(bucket_counters[b].byte_count, res.bucket_counters[b].byte_count) def test_parser_mid(self): bucket_counter_cnt = 2046 self._test_parser(self.group_id, self.ref_count, self.packet_count, self.byte_count, bucket_counter_cnt) def test_parser_max(self): group_id = 4294967295 ref_count = 4294967295 packet_count = 18446744073709551615 byte_count = 18446744073709551615 bucket_counter_cnt = 4093 self._test_parser(group_id, ref_count, packet_count, byte_count, bucket_counter_cnt) def test_parser_min(self): group_id = 0 ref_count = 0 packet_count = 0 byte_count = 0 bucket_counter_cnt = 0 self._test_parser(group_id, ref_count, packet_count, byte_count, bucket_counter_cnt) class TestOFPGroupDescStatsRequest(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPGroupDescStatsRequest """ def test_serialize(self): c = OFPGroupDescStatsRequest(_Datapath) c.serialize() fmt = '!' \ + ofproto.OFP_HEADER_PACK_STR.replace('!', '') \ + ofproto.OFP_STATS_REQUEST_PACK_STR.replace('!', '') res = struct.unpack(fmt, bytes(c.buf)) self.assertEqual(res[0], ofproto.OFP_VERSION) self.assertEqual(res[1], ofproto.OFPT_STATS_REQUEST) self.assertEqual(res[2], len(c.buf)) self.assertEqual(res[3], 0) self.assertEqual(res[4], ofproto.OFPST_GROUP_DESC) self.assertEqual(res[5], 0) class TestOFPGroupDescStats(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPGroupDescStats """ # OFP_GROUP_DESC_STATS_PACK_STR = '!HBxI' length = ofproto.OFP_GROUP_DESC_STATS_SIZE \ + ofproto.OFP_BUCKET_SIZE \ + ofproto.OFP_ACTION_OUTPUT_SIZE type_ = 128 group_id = 6606 # OFP_ACTION (OFP_ACTION_OUTPUT) port = 0x00002ae0 max_len = ofproto.OFP_ACTION_OUTPUT_SIZE actions = [OFPActionOutput(port, max_len)] buf_actions = bytearray() actions[0].serialize(buf_actions, 0) # OFP_BUCKET weight = 4386 watch_port = 8006 watch_group = 3 buckets = [OFPBucket(weight, watch_port, watch_group, actions)] bucket_cnt = 1024 def test_init(self): c = OFPGroupDescStats(self.type_, self.group_id, self.buckets) self.assertEqual(self.type_, c.type) self.assertEqual(self.group_id, c.group_id) self.assertEqual(self.buckets, c.buckets) def _test_parser(self, type_, group_id, bucket_cnt): # OFP_GROUP_DESC_STATS_PACK_STR = '!HBxI' length = ofproto.OFP_GROUP_DESC_STATS_SIZE \ + (ofproto.OFP_BUCKET_SIZE + ofproto.OFP_ACTION_OUTPUT_SIZE) * bucket_cnt fmt = ofproto.OFP_GROUP_DESC_STATS_PACK_STR buf = pack(fmt, length, type_, group_id) buckets = [] for b in range(bucket_cnt): # OFP_BUCKET weight = watch_port = watch_group = b bucket = OFPBucket(weight, watch_port, watch_group, self.actions) buckets.append(bucket) buf_buckets = bytearray() buckets[b].serialize(buf_buckets, 0) buf += bytes(buf_buckets) res = OFPGroupDescStats.parser(buf, 0) # 8 byte self.assertEqual(type_, res.type) self.assertEqual(group_id, res.group_id) # 8 + ( 16 + 16 ) * b < 65535 byte # b <= 2047 byte for b in range(bucket_cnt): self.assertEqual(buckets[b].weight, res.buckets[b].weight) self.assertEqual(buckets[b].watch_port, res.buckets[b].watch_port) self.assertEqual(buckets[b].watch_group, res.buckets[b].watch_group) self.assertEqual(buckets[b].actions[0].port, res.buckets[b].actions[0].port) self.assertEqual(buckets[b].actions[0].max_len, res.buckets[b].actions[0].max_len) def test_parser_mid(self): self._test_parser(self.type_, self.group_id, self.bucket_cnt) def test_parser_max(self): group_id = 4294967295 type_ = 255 bucket_cnt = 2047 self._test_parser(type_, group_id, bucket_cnt) def test_parser_min(self): group_id = 0 type_ = ofproto.OFPGT_ALL bucket_cnt = 0 self._test_parser(type_, group_id, bucket_cnt) def test_parser_p1(self): type_ = ofproto.OFPGT_SELECT self._test_parser(type_, self.group_id, self.bucket_cnt) def test_parser_p2(self): type_ = ofproto.OFPGT_INDIRECT self._test_parser(type_, self.group_id, self.bucket_cnt) def test_parser_p3(self): type_ = ofproto.OFPGT_FF self._test_parser(type_, self.group_id, self.bucket_cnt) class TestOFPGroupFeaturesStatsRequest(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPGroupFeaturesStatsRequest """ def test_serialize(self): c = OFPGroupFeaturesStatsRequest(_Datapath) c.serialize() fmt = '!' \ + ofproto.OFP_HEADER_PACK_STR.replace('!', '') \ + ofproto.OFP_STATS_REQUEST_PACK_STR.replace('!', '') res = struct.unpack(fmt, bytes(c.buf)) self.assertEqual(res[0], ofproto.OFP_VERSION) self.assertEqual(res[1], ofproto.OFPT_STATS_REQUEST) self.assertEqual(res[2], len(c.buf)) self.assertEqual(res[3], 0) self.assertEqual(res[4], ofproto.OFPST_GROUP_FEATURES) self.assertEqual(res[5], 0) class TestOFPGroupFeaturesStats(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPGroupFeaturesStats """ # OFP_GROUP_FEATURES_STATS_PACK_STR = '!II4I4I' types = ofproto.OFPGT_ALL capabilities = ofproto.OFPGFC_SELECT_WEIGHT max_groups = [1, 2, 3, 4] actions = [1 << ofproto.OFPAT_OUTPUT, 1 << ofproto.OFPAT_COPY_TTL_OUT, 1 << ofproto.OFPAT_SET_MPLS_TTL, 1 << ofproto.OFPAT_PUSH_VLAN] def test_init(self): c = OFPGroupFeaturesStats(self.types, self.capabilities, self.max_groups, self.actions) self.assertEqual(self.types, c.types) self.assertEqual(self.capabilities, c.capabilities) self.assertEqual(self.max_groups, c.max_groups) self.assertEqual(self.actions, c.actions) def _test_parser(self, types, capabilities, max_groups, actions): buf = pack('!I', types) \ + pack('!I', capabilities) \ + pack('!I', max_groups[0]) \ + pack('!I', max_groups[1]) \ + pack('!I', max_groups[2]) \ + pack('!I', max_groups[3]) \ + pack('!I', actions[0]) \ + pack('!I', actions[1]) \ + pack('!I', actions[2]) \ + pack('!I', actions[3]) res = OFPGroupFeaturesStats.parser(buf, 0) # max_groups and actions after the parser is tuple self.assertEqual(types, res.types) self.assertEqual(capabilities, res.capabilities) self.assertEqual(max_groups, res.max_groups) self.assertEqual(actions, res.actions) def test_parser_mid(self): self._test_parser(self.types, self.capabilities, self.max_groups, self.actions) def test_parser_max(self): types = 0b11111111111111111111111111111111 capabilities = 0b11111111111111111111111111111111 max_groups = [4294967295] * 4 actions = [0b11111111111111111111111111111111] * 4 self._test_parser(types, capabilities, max_groups, actions) def test_parser_min(self): types = 0b00000000000000000000000000000000 capabilities = 0b00000000000000000000000000000000 max_groups = [0] * 4 actions = [0b00000000000000000000000000000000] * 4 self._test_parser(types, capabilities, max_groups, actions) def _test_parser_p(self, types, capabilities, actions): self._test_parser(types, capabilities, self.max_groups, actions) def test_parser_p1(self): actions = [1 << ofproto.OFPAT_COPY_TTL_IN, 1 << ofproto.OFPAT_DEC_MPLS_TTL, 1 << ofproto.OFPAT_POP_VLAN, 1 << ofproto.OFPAT_PUSH_MPLS] self._test_parser_p(1 << ofproto.OFPGT_ALL, ofproto.OFPGFC_CHAINING, actions) def test_parser_p2(self): actions = [1 << ofproto.OFPAT_POP_MPLS, 1 << ofproto.OFPAT_SET_QUEUE, 1 << ofproto.OFPAT_GROUP, 1 << ofproto.OFPAT_SET_NW_TTL] self._test_parser_p(1 << ofproto.OFPGT_SELECT, ofproto.OFPGFC_SELECT_WEIGHT, actions) def test_parser_p3(self): actions = [1 << ofproto.OFPAT_DEC_NW_TTL, 1 << ofproto.OFPAT_SET_FIELD, 1 << ofproto.OFPAT_GROUP, 1 << ofproto.OFPAT_SET_NW_TTL] self._test_parser_p(1 << ofproto.OFPGT_SELECT, ofproto.OFPGFC_SELECT_LIVENESS, actions) def test_parser_p4(self): self._test_parser_p(1 << ofproto.OFPGT_INDIRECT, ofproto.OFPGFC_CHAINING, self.actions) def test_parser_p5(self): self._test_parser_p(1 << ofproto.OFPGT_FF, ofproto.OFPGFC_CHAINING_CHECKS, self.actions) class TestOFPQueueGetConfigRequest(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPQueueGetConfigRequest """ # OFP_QUEUE_GET_CONFIG_REQUEST_PACK_STR v1.2 # '!I4x'...port, pad(4) port = 41186 def test_init(self): c = OFPQueueGetConfigRequest(_Datapath, self.port) self.assertEqual(self.port, c.port) def _test_serialize(self, port): c = OFPQueueGetConfigRequest(_Datapath, port) c.serialize() self.assertEqual(ofproto.OFP_VERSION, c.version) self.assertEqual(ofproto.OFPT_QUEUE_GET_CONFIG_REQUEST, c.msg_type) self.assertEqual(0, c.xid) fmt = ofproto.OFP_HEADER_PACK_STR \ + ofproto.OFP_QUEUE_GET_CONFIG_REQUEST_PACK_STR[1:] res = struct.unpack(fmt, bytes(c.buf)) self.assertEqual(res[0], ofproto.OFP_VERSION) self.assertEqual(res[1], ofproto.OFPT_QUEUE_GET_CONFIG_REQUEST) self.assertEqual(res[2], len(c.buf)) self.assertEqual(res[3], 0) self.assertEqual(res[4], port) def test_serialize_mid(self): self._test_serialize(self.port) def test_serialize_max(self): self._test_serialize(0xffffffff) def test_serialize_min(self): self._test_serialize(0) def test_serialize_p1(self): self._test_serialize(ofproto.OFPP_MAX) class TestOFPQueuePropHeader(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPQueuePropHeader """ # OFP_QUEUE_PROP_HEADER_PACK_STR = '!HH4x' property_ = 1 len_ = 10 def test_init(self): c = OFPQueuePropHeader(self.property_, self.len_) self.assertEqual(self.property_, c.property) self.assertEqual(self.len_, c.len) def _test_serialize(self, property_, len_): c = OFPQueuePropHeader(property_, len_) buf = bytearray() c.serialize(buf, 0) fmt = ofproto.OFP_QUEUE_PROP_HEADER_PACK_STR res = struct.unpack(fmt, bytes(buf)) self.assertEqual(res[0], property_) self.assertEqual(res[1], len_) def test_serialize_mid(self): self._test_serialize(self.property_, self.len_) def test_serialize_max(self): self._test_serialize(0xffff, 0xffff) def test_serialize_min(self): self._test_serialize(0, 0) class TestOFPPacketQueue(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPPacketQueue """ def test_init(self): queue_id = 1 port = 2 len_ = 3 properties = [4, 5, 6] c = OFPPacketQueue(queue_id, port, properties) self.assertEqual(queue_id, c.queue_id) self.assertEqual(port, c.port) self.assertEqual(properties, c.properties) def _test_parser(self, queue_id, port, prop_cnt): # OFP_PACKET_QUEUE_PACK_STR = '!IIH6x' fmt = ofproto.OFP_PACKET_QUEUE_PACK_STR queue_len = ofproto.OFP_PACKET_QUEUE_SIZE \ + ofproto.OFP_QUEUE_PROP_MIN_RATE_SIZE * prop_cnt buf = pack(fmt, queue_id, port, queue_len) for rate in range(prop_cnt): # OFP_QUEUE_PROP_HEADER_PACK_STR = '!HH4x' fmt = ofproto.OFP_QUEUE_PROP_HEADER_PACK_STR prop_type = ofproto.OFPQT_MIN_RATE prop_len = ofproto.OFP_QUEUE_PROP_MIN_RATE_SIZE buf += pack(fmt, prop_type, prop_len) # OFP_QUEUE_PROP_MIN_RATE_PACK_STR = '!H6x' fmt = ofproto.OFP_QUEUE_PROP_MIN_RATE_PACK_STR prop_rate = rate buf += pack(fmt, prop_rate) res = OFPPacketQueue.parser(buf, 0) self.assertEqual(queue_id, res.queue_id) self.assertEqual(port, res.port) self.assertEqual(queue_len, res.len) self.assertEqual(prop_cnt, len(res.properties)) for rate, p in enumerate(res.properties): self.assertEqual(prop_type, p.property) self.assertEqual(prop_len, p.len) self.assertEqual(rate, p.rate) def test_parser_mid(self): queue_id = 1 port = 2 prop_cnt = 2 self._test_parser(queue_id, port, prop_cnt) def test_parser_max(self): # queue_len format is 'H' < number 65535 # # queue_len = OFP_PACKET_QUEUE_SIZE(16) # + OFP_QUEUE_PROP_MIN_RATE_SIZE(16) * N # max_prop_cnt = (65535 - 16) / 16 = 4094 queue_id = 0xffffffff port = 0xffffffff prop_cnt = 4094 self._test_parser(queue_id, port, prop_cnt) def test_parser_min(self): queue_id = 0 port = 0 prop_cnt = 0 self._test_parser(queue_id, port, prop_cnt) class TestOFPQueuePropMinRate(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPQueuePropMinRate """ def _test_parser(self, rate): # OFP_QUEUE_PROP_MIN_RATE_PACK_STR...H6x buf = pack(ofproto.OFP_QUEUE_PROP_MIN_RATE_PACK_STR, rate) res = OFPQueuePropMinRate.parser(buf, 0) self.assertEqual(rate, res.rate) def test_parser_mid(self): self._test_parser(32768) def test_parser_max(self): self._test_parser(0xffff) def test_parser_min(self): self._test_parser(0) class TestOFPQueuePropMaxRate(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPQueuePropMaxRate """ rate = 100 buf = pack(ofproto.OFP_QUEUE_PROP_MAX_RATE_PACK_STR, rate) c = OFPQueuePropMaxRate(rate) def _test_parser(self, rate): # OFP_QUEUE_PROP_MAX_RATE_PACK_STR...H6x buf = pack(ofproto.OFP_QUEUE_PROP_MAX_RATE_PACK_STR, rate) res = OFPQueuePropMaxRate.parser(buf, 0) self.assertEqual(rate, res.rate) def test_parser_mid(self): self._test_parser(100) def test_parser_max(self): self._test_parser(0xffff) def test_parser_min(self): self._test_parser(0) class TestOFPQueueGetConfigReply(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPQueueGetConfigReply """ def _test_parser(self, xid, port, queue_cnt): version = ofproto.OFP_VERSION msg_type = ofproto.OFPT_QUEUE_GET_CONFIG_REPLY queues_len = 0 for q in range(queue_cnt): queues_len += ofproto.OFP_PACKET_QUEUE_SIZE queues_len += ofproto.OFP_QUEUE_PROP_MIN_RATE_SIZE msg_len = ofproto.OFP_QUEUE_GET_CONFIG_REPLY_SIZE \ + queues_len # OFP_HEADER_PACK_STR = '!BBHI' fmt = ofproto.OFP_HEADER_PACK_STR buf = pack(fmt, version, msg_type, msg_len, xid) # OFP_QUEUE_GET_CONFIG_REPLY_PACK_STR = '!I4x' fmt = ofproto.OFP_QUEUE_GET_CONFIG_REPLY_PACK_STR buf += pack(fmt, port) queues = [] for q in range(1, queue_cnt + 1): # OFP_PACKET_QUEUE_PACK_STR = '!IIH6x' fmt = ofproto.OFP_PACKET_QUEUE_PACK_STR queue_id = q * 100 queue_port = q queue_len = ofproto.OFP_PACKET_QUEUE_SIZE \ + ofproto.OFP_QUEUE_PROP_MIN_RATE_SIZE buf += pack(fmt, queue_id, queue_port, queue_len) # OFP_QUEUE_PROP_HEADER_PACK_STR = '!HH4x' fmt = ofproto.OFP_QUEUE_PROP_HEADER_PACK_STR prop_type = ofproto.OFPQT_MIN_RATE prop_len = ofproto.OFP_QUEUE_PROP_MIN_RATE_SIZE buf += pack(fmt, prop_type, prop_len) # OFP_QUEUE_PROP_MIN_RATE_PACK_STR = '!H6x' fmt = ofproto.OFP_QUEUE_PROP_MIN_RATE_PACK_STR prop_rate = q * 10 buf += pack(fmt, prop_rate) queue = {'queue_id': queue_id, 'queue_port': queue_port, 'queue_len': queue_len, 'prop_type': prop_type, 'prop_len': prop_len, 'prop_rate': prop_rate} queues.append(queue) res = OFPQueueGetConfigReply.parser(object, version, msg_type, msg_len, xid, buf) self.assertEqual(version, res.version) self.assertEqual(msg_type, res.msg_type) self.assertEqual(msg_len, res.msg_len) self.assertEqual(xid, res.xid) self.assertEqual(port, res.port) self.assertEqual(queue_cnt, len(res.queues)) for i, val in enumerate(res.queues): c = queues[i] self.assertEqual(c['queue_id'], val.queue_id) self.assertEqual(c['queue_port'], val.port) self.assertEqual(c['queue_len'], val.len) self.assertEqual(1, len(val.properties)) prop = val.properties[0] self.assertEqual(c['prop_type'], prop.property) self.assertEqual(c['prop_len'], prop.len) self.assertEqual(c['prop_rate'], prop.rate) def test_parser_mid(self): self._test_parser(2495926989, 65037, 2) def test_parser_max(self): # total msg_len = 65520 self._test_parser(0xffffffff, 0xffffffff, 2047) def test_parser_min(self): self._test_parser(0, 0, 0) class TestOFPBarrierRequest(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPBarrierRequest """ def test_serialize(self): c = OFPBarrierRequest(_Datapath) c.serialize() self.assertEqual(ofproto.OFP_VERSION, c.version) self.assertEqual(ofproto.OFPT_BARRIER_REQUEST, c.msg_type) self.assertEqual(ofproto.OFP_HEADER_SIZE, c.msg_len) self.assertEqual(0, c.xid) fmt = ofproto.OFP_HEADER_PACK_STR res = unpack(fmt, bytes(c.buf)) self.assertEqual(ofproto.OFP_VERSION, res[0]) self.assertEqual(ofproto.OFPT_BARRIER_REQUEST, res[1]) self.assertEqual(len(c.buf), res[2]) self.assertEqual(0, c.xid) class TestOFPBarrierReply(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPBarrierReply """ def _test_parser(self, xid): version = ofproto.OFP_VERSION msg_type = ofproto.OFPT_BARRIER_REPLY msg_len = ofproto.OFP_HEADER_SIZE fmt = ofproto.OFP_HEADER_PACK_STR buf = pack(fmt, version, msg_type, msg_len, xid) res = OFPBarrierReply.parser(object, version, msg_type, msg_len, xid, buf) self.assertEqual(version, res.version) self.assertEqual(msg_type, res.msg_type) self.assertEqual(msg_len, res.msg_len) self.assertEqual(xid, res.xid) def test_parser_mid(self): self._test_parser(2147483648) def test_parser_max(self): self._test_parser(0xffffffff) def test_parser_min(self): self._test_parser(0) class TestOFPRoleRequest(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPRoleRequest """ # OFP_ROLE_REQUEST_PACK_STR # '!I4xQ'...role, pad(4), generation_id role = 2147483648 generation_id = 1270985291017894273 def test_init(self): c = OFPRoleRequest(_Datapath, self.role, self.generation_id) self.assertEqual(self.role, c.role) self.assertEqual(self.generation_id, c.generation_id) def _test_serialize(self, role, generation_id): c = OFPRoleRequest(_Datapath, role, generation_id) c.serialize() self.assertEqual(ofproto.OFP_VERSION, c.version) self.assertEqual(ofproto.OFPT_ROLE_REQUEST, c.msg_type) self.assertEqual(0, c.xid) fmt = '!' \ + ofproto.OFP_HEADER_PACK_STR.replace('!', '') \ + ofproto.OFP_ROLE_REQUEST_PACK_STR.replace('!', '') res = struct.unpack(fmt, bytes(c.buf)) self.assertEqual(ofproto.OFP_VERSION, res[0]) self.assertEqual(ofproto.OFPT_ROLE_REQUEST, res[1]) self.assertEqual(len(c.buf), res[2]) self.assertEqual(0, res[3]) self.assertEqual(role, res[4]) self.assertEqual(generation_id, res[5]) def test_serialize_mid(self): self._test_serialize(self.role, self.generation_id) def test_serialize_max(self): role = 0xffffffff generation_id = 0xffffffffffffffff self._test_serialize(role, generation_id) def test_serialize_min(self): role = 0 generation_id = 0 self._test_serialize(role, generation_id) def test_serialize_p1(self): role = ofproto.OFPCR_ROLE_EQUAL self._test_serialize(role, self.generation_id) def test_serialize_p2(self): role = ofproto.OFPCR_ROLE_MASTER self._test_serialize(role, self.generation_id) def test_serialize_p3(self): role = ofproto.OFPCR_ROLE_SLAVE self._test_serialize(role, self.generation_id) class TestOFPRoleReply(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPRoleReply """ # OFP_ROLE_REQUEST_PACK_STR # '!I4xQ'...role, pad(4), generation_id # role = ofproto.OFPCR_ROLE_NOCHANGE role = 2147483648 generation_id = 1270985291017894273 def _test_parser(self, role, generation_id): # OFP_HEADER_PACK_STR version = ofproto.OFP_VERSION msg_type = ofproto.OFPT_ROLE_REPLY msg_len = ofproto.OFP_ROLE_REQUEST_SIZE xid = 2495926989 fmt = ofproto.OFP_HEADER_PACK_STR buf = pack(fmt, version, msg_type, msg_len, xid) fmt = ofproto.OFP_ROLE_REQUEST_PACK_STR buf += pack(fmt, role, generation_id) res = OFPRoleReply.parser(object, version, msg_type, msg_len, xid, buf) # OFP_HEADER_PACK_STR self.assertEqual(version, res.version) self.assertEqual(msg_type, res.msg_type) self.assertEqual(msg_len, res.msg_len) self.assertEqual(xid, res.xid) # OFP_ROLE_REQUEST_PACK_STR self.assertEqual(role, res.role) self.assertEqual(generation_id, res.generation_id) def test_parser_mid(self): self._test_parser(self.role, self.generation_id) def test_parser_max(self): role = 0xffffffff generation_id = 0xffffffffffffffff self._test_parser(role, generation_id) def test_parser_min(self): role = ofproto.OFPCR_ROLE_NOCHANGE generation_id = 0 self._test_parser(role, generation_id) def test_parser_p1(self): role = ofproto.OFPCR_ROLE_EQUAL self._test_parser(role, self.generation_id) def test_parser_p2(self): role = ofproto.OFPCR_ROLE_MASTER self._test_parser(role, self.generation_id) def test_parser_p3(self): role = ofproto.OFPCR_ROLE_SLAVE self._test_parser(role, self.generation_id) class TestOFPMatch(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPMatch """ def test_init(self): res = OFPMatch() # wc check self.assertEqual(res._wc.metadata_mask, 0) self.assertEqual(res._wc.dl_dst_mask, 0) self.assertEqual(res._wc.dl_src_mask, 0) self.assertEqual(res._wc.vlan_vid_mask, 0) self.assertEqual(res._wc.ipv4_src_mask, 0) self.assertEqual(res._wc.ipv4_dst_mask, 0) self.assertEqual(res._wc.arp_spa_mask, 0) self.assertEqual(res._wc.arp_tpa_mask, 0) self.assertEqual(res._wc.arp_sha_mask, 0) self.assertEqual(res._wc.arp_tha_mask, 0) self.assertEqual(res._wc.ipv6_src_mask, []) self.assertEqual(res._wc.ipv6_dst_mask, []) self.assertEqual(res._wc.ipv6_flabel_mask, 0) self.assertEqual(res._wc.wildcards, (1 << 64) - 1) # flow check self.assertEqual(res._flow.in_port, 0) self.assertEqual(res._flow.in_phy_port, 0) self.assertEqual(res._flow.metadata, 0) self.assertEqual(res._flow.dl_dst, mac.DONTCARE) self.assertEqual(res._flow.dl_src, mac.DONTCARE) self.assertEqual(res._flow.dl_type, 0) self.assertEqual(res._flow.vlan_vid, 0) self.assertEqual(res._flow.vlan_pcp, 0) self.assertEqual(res._flow.ip_dscp, 0) self.assertEqual(res._flow.ip_ecn, 0) self.assertEqual(res._flow.ip_proto, 0) self.assertEqual(res._flow.ipv4_src, 0) self.assertEqual(res._flow.ipv4_dst, 0) self.assertEqual(res._flow.tcp_src, 0) self.assertEqual(res._flow.tcp_dst, 0) self.assertEqual(res._flow.udp_src, 0) self.assertEqual(res._flow.udp_dst, 0) self.assertEqual(res._flow.sctp_src, 0) self.assertEqual(res._flow.sctp_dst, 0) self.assertEqual(res._flow.icmpv4_type, 0) self.assertEqual(res._flow.icmpv4_code, 0) self.assertEqual(res._flow.arp_op, 0) self.assertEqual(res._flow.arp_spa, 0) self.assertEqual(res._flow.arp_tpa, 0) self.assertEqual(res._flow.arp_sha, 0) self.assertEqual(res._flow.arp_tha, 0) self.assertEqual(res._flow.ipv6_src, []) self.assertEqual(res._flow.ipv6_dst, []) self.assertEqual(res._flow.ipv6_flabel, 0) self.assertEqual(res._flow.icmpv6_type, 0) self.assertEqual(res._flow.icmpv6_code, 0) self.assertEqual(res._flow.ipv6_nd_target, []) self.assertEqual(res._flow.ipv6_nd_sll, 0) self.assertEqual(res._flow.ipv6_nd_tll, 0) self.assertEqual(res._flow.mpls_label, 0) self.assertEqual(res._flow.mpls_tc, 0) # flow check self.assertEqual(res.fields, []) def _test_serialize_and_parser(self, match, header, value, mask=None): cls_ = OFPMatchField._FIELDS_HEADERS.get(header) pack_str = cls_.pack_str.replace('!', '') fmt = '!HHI' + pack_str # serialize buf = bytearray() length = match.serialize(buf, 0) self.assertEqual(length, len(buf)) if mask and len(buf) > calcsize(fmt): fmt += pack_str res = list(unpack_from(fmt, bytes(buf), 0)[3:]) if type(value) is list: res_value = res[:calcsize(pack_str) // 2] self.assertEqual(res_value, value) if mask: res_mask = res[calcsize(pack_str) // 2:] self.assertEqual(res_mask, mask) else: res_value = res.pop(0) if cls_.__name__ == 'MTVlanVid': self.assertEqual(res_value, value | ofproto.OFPVID_PRESENT) else: self.assertEqual(res_value, value) if mask and res and res[0]: res_mask = res[0] self.assertEqual(res_mask, mask) # parser res = match.parser(bytes(buf), 0) self.assertEqual(res.type, ofproto.OFPMT_OXM) self.assertEqual(res.fields[0].header, header) self.assertEqual(res.fields[0].value, value) if mask and res.fields[0].mask is not None: self.assertEqual(res.fields[0].mask, mask) # to_jsondict jsondict = match.to_jsondict() # from_jsondict match2 = match.from_jsondict(jsondict["OFPMatch"]) buf2 = bytearray() match2.serialize(buf2, 0) self.assertEqual(str(match), str(match2)) self.assertEqual(buf, buf2) def test_parse_unknown_field(self): buf = bytearray() pack_utils.msg_pack_into('!HH', buf, 0, ofproto.OFPMT_OXM, 4 + 6) header = ofproto.oxm_tlv_header(36, 2) pack_utils.msg_pack_into('!IH', buf, 4, header, 1) header = ofproto.OXM_OF_ETH_TYPE pack_utils.msg_pack_into('!IH', buf, 10, header, 1) match = OFPMatch() res = match.parser(bytes(buf), 0) # set_in_port def _test_set_in_port(self, in_port): header = ofproto.OXM_OF_IN_PORT match = OFPMatch() match.set_in_port(in_port) self._test_serialize_and_parser(match, header, in_port) def test_set_in_port_mid(self): self._test_set_in_port(0xff8) def test_set_in_port_max(self): self._test_set_in_port(0xffffffff) def test_set_in_port_min(self): self._test_set_in_port(0) # set_in_phy_port def _test_set_in_phy_port(self, phy_port): header = ofproto.OXM_OF_IN_PHY_PORT match = OFPMatch() match.set_in_phy_port(phy_port) self._test_serialize_and_parser(match, header, phy_port) def test_set_in_phy_port_mid(self): self._test_set_in_phy_port(1) def test_set_in_phy_port_max(self): self._test_set_in_phy_port(0xffffffff) def test_set_in_phy_port_min(self): self._test_set_in_phy_port(0) # set_metadata def _test_set_metadata(self, metadata, mask=None): header = ofproto.OXM_OF_METADATA match = OFPMatch() if mask is None: match.set_metadata(metadata) else: if (mask + 1) >> 64 != 1: header = ofproto.OXM_OF_METADATA_W match.set_metadata_masked(metadata, mask) metadata &= mask self._test_serialize_and_parser(match, header, metadata, mask) def test_set_metadata_mid(self): self._test_set_metadata(0x1212121212121212) def test_set_metadata_max(self): self._test_set_metadata(0xffffffffffffffff) def test_set_metadata_min(self): self._test_set_metadata(0) def test_set_metadata_masked_mid(self): self._test_set_metadata(0x1212121212121212, 0xff00ff00ff00ff00) def test_set_metadata_masked_max(self): self._test_set_metadata(0x1212121212121212, 0xffffffffffffffff) def test_set_metadata_masked_min(self): self._test_set_metadata(0x1212121212121212, 0) # set_dl_dst def _test_set_dl_dst(self, dl_dst, mask=None): header = ofproto.OXM_OF_ETH_DST match = OFPMatch() dl_dst = mac.haddr_to_bin(dl_dst) if mask is None: match.set_dl_dst(dl_dst) else: header = ofproto.OXM_OF_ETH_DST_W mask = mac.haddr_to_bin(mask) match.set_dl_dst_masked(dl_dst, mask) dl_dst = mac.haddr_bitand(dl_dst, mask) self._test_serialize_and_parser(match, header, dl_dst, mask) def test_set_dl_dst_mid(self): self._test_set_dl_dst('e2:7a:09:79:0b:0f') def test_set_dl_dst_max(self): self._test_set_dl_dst('ff:ff:ff:ff:ff:ff') def test_set_dl_dst_min(self): self._test_set_dl_dst('00:00:00:00:00:00') def test_set_dl_dst_masked_mid(self): self._test_set_dl_dst('e2:7a:09:79:0b:0f', 'ff:00:ff:00:ff:00') def test_set_dl_dst_masked_max(self): self._test_set_dl_dst('e2:7a:09:79:0b:0f', 'ff:ff:ff:ff:ff:ff') def test_set_dl_dst_masked_min(self): self._test_set_dl_dst('e2:7a:09:79:0b:0f', '00:00:00:00:00:00') # set_dl_src def _test_set_dl_src(self, dl_src, mask=None): header = ofproto.OXM_OF_ETH_SRC match = OFPMatch() dl_src = mac.haddr_to_bin(dl_src) if mask is None: match.set_dl_src(dl_src) else: header = ofproto.OXM_OF_ETH_SRC_W mask = mac.haddr_to_bin(mask) match.set_dl_src_masked(dl_src, mask) dl_src = mac.haddr_bitand(dl_src, mask) self._test_serialize_and_parser(match, header, dl_src, mask) def test_set_dl_src_mid(self): self._test_set_dl_src('d0:98:79:b4:75:b5') def test_set_dl_src_max(self): self._test_set_dl_src('ff:ff:ff:ff:ff:ff') def test_set_dl_src_min(self): self._test_set_dl_src('00:00:00:00:00:00') def test_set_dl_src_masked_mid(self): self._test_set_dl_src('d0:98:79:b4:75:b5', 'f0:f0:f0:f0:f0:f0') def test_set_dl_src_masked_max(self): self._test_set_dl_src('d0:98:79:b4:75:b5', 'ff:ff:ff:ff:ff:ff') def test_set_dl_src_masked_min(self): self._test_set_dl_src('d0:98:79:b4:75:b5', '00:00:00:00:00:00') # set_dl_type def _test_set_dl_type(self, value): header = ofproto.OXM_OF_ETH_TYPE match = OFPMatch() match.set_dl_type(value) self._test_serialize_and_parser(match, header, value) def test_set_dl_type_mid(self): self._test_set_dl_type(0x7fb6) def test_set_dl_type_max(self): self._test_set_dl_type(0xffff) def test_set_dl_type_min(self): self._test_set_dl_type(0) def test_set_dl_type_ip(self): value = ether.ETH_TYPE_IP self._test_set_dl_type(value) def test_set_dl_type_arp(self): value = ether.ETH_TYPE_ARP self._test_set_dl_type(value) def test_set_dl_type_ipv6(self): value = ether.ETH_TYPE_IPV6 self._test_set_dl_type(value) def test_set_dl_type_slow(self): value = ether.ETH_TYPE_SLOW self._test_set_dl_type(value) # set_vlan_vid def _test_set_vlan_vid(self, vid, mask=None): header = ofproto.OXM_OF_VLAN_VID match = OFPMatch() if mask is None: match.set_vlan_vid(vid) else: header = ofproto.OXM_OF_VLAN_VID_W match.set_vlan_vid_masked(vid, mask) self._test_serialize_and_parser(match, header, vid, mask) def _test_set_vlan_vid_none(self): header = ofproto.OXM_OF_VLAN_VID match = OFPMatch() match.set_vlan_vid_none() value = ofproto.OFPVID_NONE cls_ = OFPMatchField._FIELDS_HEADERS.get(header) pack_str = cls_.pack_str.replace('!', '') fmt = '!HHI' + pack_str # serialize buf = bytearray() length = match.serialize(buf, 0) self.assertEqual(length, len(buf)) res = list(unpack_from(fmt, bytes(buf), 0)[3:]) res_value = res.pop(0) self.assertEqual(res_value, value) # parser res = match.parser(bytes(buf), 0) self.assertEqual(res.type, ofproto.OFPMT_OXM) self.assertEqual(res.fields[0].header, header) self.assertEqual(res.fields[0].value, value) # to_jsondict jsondict = match.to_jsondict() # from_jsondict match2 = match.from_jsondict(jsondict["OFPMatch"]) buf2 = bytearray() match2.serialize(buf2, 0) self.assertEqual(str(match), str(match2)) self.assertEqual(buf, buf2) def test_set_vlan_vid_mid(self): self._test_set_vlan_vid(2047) def test_set_vlan_vid_max(self): self._test_set_vlan_vid(0xfff) def test_set_vlan_vid_min(self): self._test_set_vlan_vid(0) def test_set_vlan_vid_masked_mid(self): self._test_set_vlan_vid(2047, 0xf0f) def test_set_vlan_vid_masked_max(self): self._test_set_vlan_vid(2047, 0xfff) def test_set_vlan_vid_masked_min(self): self._test_set_vlan_vid(2047, 0) def test_set_vlan_vid_none(self): self._test_set_vlan_vid_none() # set_vlan_pcp def _test_set_vlan_pcp(self, pcp): header = ofproto.OXM_OF_VLAN_PCP match = OFPMatch() match.set_vlan_pcp(pcp) self._test_serialize_and_parser(match, header, pcp) def test_set_vlan_pcp_mid(self): self._test_set_vlan_pcp(5) def test_set_vlan_pcp_max(self): self._test_set_vlan_pcp(7) def test_set_vlan_pcp_min(self): self._test_set_vlan_pcp(0) # set_ip_dscp def _test_set_ip_dscp(self, ip_dscp): header = ofproto.OXM_OF_IP_DSCP match = OFPMatch() match.set_ip_dscp(ip_dscp) self._test_serialize_and_parser(match, header, ip_dscp) def test_set_ip_dscp_mid(self): self._test_set_ip_dscp(36) def test_set_ip_dscp_max(self): self._test_set_ip_dscp(63) def test_set_ip_dscp_min(self): self._test_set_ip_dscp(0) # set_ip_ecn def _test_set_ip_ecn(self, ip_ecn): header = ofproto.OXM_OF_IP_ECN match = OFPMatch() match.set_ip_ecn(ip_ecn) self._test_serialize_and_parser(match, header, ip_ecn) def test_set_ip_ecn_mid(self): self._test_set_ip_ecn(1) def test_set_ip_ecn_max(self): self._test_set_ip_ecn(3) def test_set_ip_ecn_min(self): self._test_set_ip_ecn(0) # set_ip_proto def _test_set_ip_proto(self, ip_proto): header = ofproto.OXM_OF_IP_PROTO match = OFPMatch() match.set_ip_proto(ip_proto) self._test_serialize_and_parser(match, header, ip_proto) def test_set_ip_proto_mid(self): self._test_set_ip_proto(6) def test_set_ip_proto_max(self): self._test_set_ip_proto(0xff) def test_set_ip_proto_min(self): self._test_set_ip_proto(0) # set_ipv4_src def _test_set_ipv4_src(self, ip, mask=None): header = ofproto.OXM_OF_IPV4_SRC match = OFPMatch() ip = unpack('!I', socket.inet_aton(ip))[0] if mask is None: match.set_ipv4_src(ip) else: mask = unpack('!I', socket.inet_aton(mask))[0] if (mask + 1) >> 32 != 1: header = ofproto.OXM_OF_IPV4_SRC_W match.set_ipv4_src_masked(ip, mask) self._test_serialize_and_parser(match, header, ip, mask) def test_set_ipv4_src_mid(self): self._test_set_ipv4_src('192.168.196.250') def test_set_ipv4_src_max(self): self._test_set_ipv4_src('255.255.255.255') def test_set_ipv4_src_min(self): self._test_set_ipv4_src('0.0.0.0') def test_set_ipv4_src_masked_mid(self): self._test_set_ipv4_src('192.168.196.250', '255.255.0.0') def test_set_ipv4_src_masked_max(self): self._test_set_ipv4_src('192.168.196.250', '255.255.255.255') def test_set_ipv4_src_masked_min(self): self._test_set_ipv4_src('192.168.196.250', '0.0.0.0') # set_ipv4_dst def _test_set_ipv4_dst(self, ip, mask=None): header = ofproto.OXM_OF_IPV4_DST match = OFPMatch() ip = unpack('!I', socket.inet_aton(ip))[0] if mask is None: match.set_ipv4_dst(ip) else: mask = unpack('!I', socket.inet_aton(mask))[0] if (mask + 1) >> 32 != 1: header = ofproto.OXM_OF_IPV4_DST_W match.set_ipv4_dst_masked(ip, mask) self._test_serialize_and_parser(match, header, ip, mask) def test_set_ipv4_dst_mid(self): self._test_set_ipv4_dst('192.168.196.250') def test_set_ipv4_dst_max(self): self._test_set_ipv4_dst('255.255.255.255') def test_set_ipv4_dst_min(self): self._test_set_ipv4_dst('0.0.0.0') def test_set_ipv4_dst_masked_mid(self): self._test_set_ipv4_dst('192.168.196.250', '255.255.0.0') def test_set_ipv4_dst_masked_max(self): self._test_set_ipv4_dst('192.168.196.250', '255.255.255.255') def test_set_ipv4_dst_masked_min(self): self._test_set_ipv4_dst('192.168.196.250', '0.0.0.0') # set_tcp_src def _test_set_tcp_src(self, tcp_src): header = ofproto.OXM_OF_TCP_SRC match = OFPMatch() match.set_tcp_src(tcp_src) self._test_serialize_and_parser(match, header, tcp_src) def test_set_tcp_src_mid(self): self._test_set_tcp_src(1103) def test_set_tcp_src_max(self): self._test_set_tcp_src(0xffff) def test_set_tcp_src_min(self): self._test_set_tcp_src(0) # set_tcp_dst def _test_set_tcp_dst(self, tcp_dst): header = ofproto.OXM_OF_TCP_DST match = OFPMatch() match.set_tcp_dst(tcp_dst) self._test_serialize_and_parser(match, header, tcp_dst) def test_set_tcp_dst_mid(self): self._test_set_tcp_dst(236) def test_set_tcp_dst_max(self): self._test_set_tcp_dst(0xffff) def test_set_tcp_dst_min(self): self._test_set_tcp_dst(0) # set_udp_src def _test_set_udp_src(self, udp_src): header = ofproto.OXM_OF_UDP_SRC match = OFPMatch() match.set_udp_src(udp_src) self._test_serialize_and_parser(match, header, udp_src) def test_set_udp_src_mid(self): self._test_set_udp_src(56617) def test_set_udp_src_max(self): self._test_set_udp_src(0xffff) def test_set_udp_src_min(self): self._test_set_udp_src(0) # set_udp_dst def _test_set_udp_dst(self, udp_dst): header = ofproto.OXM_OF_UDP_DST match = OFPMatch() match.set_udp_dst(udp_dst) self._test_serialize_and_parser(match, header, udp_dst) def test_set_udp_dst_mid(self): self._test_set_udp_dst(61278) def test_set_udp_dst_max(self): self._test_set_udp_dst(0xffff) def test_set_udp_dst_min(self): self._test_set_udp_dst(0) # set_sctp_src def _test_set_sctp_src(self, sctp_src): header = ofproto.OXM_OF_SCTP_SRC match = OFPMatch() match.set_sctp_src(sctp_src) self._test_serialize_and_parser(match, header, sctp_src) def test_set_sctp_src_mid(self): self._test_set_sctp_src(9999) def test_set_sctp_src_max(self): self._test_set_sctp_src(0xffff) def test_set_sctp_src_min(self): self._test_set_sctp_src(0) # set_sctp_dst def _test_set_sctp_dst(self, sctp_dst): header = ofproto.OXM_OF_SCTP_DST match = OFPMatch() match.set_sctp_dst(sctp_dst) self._test_serialize_and_parser(match, header, sctp_dst) def test_set_sctp_dst_mid(self): self._test_set_sctp_dst(1234) def test_set_sctp_dst_max(self): self._test_set_sctp_dst(0xffff) def test_set_sctp_dst_min(self): self._test_set_sctp_dst(0) # set_icmpv4_type def _test_set_icmpv4_type(self, icmpv4_type): header = ofproto.OXM_OF_ICMPV4_TYPE match = OFPMatch() match.set_icmpv4_type(icmpv4_type) self._test_serialize_and_parser(match, header, icmpv4_type) def test_set_icmpv4_type_mid(self): self._test_set_icmpv4_type(8) def test_set_icmpv4_type_max(self): self._test_set_icmpv4_type(0xff) def test_set_icmpv4_type_min(self): self._test_set_icmpv4_type(0) # set_icmpv4_code def _test_set_icmpv4_code(self, icmpv4_code): header = ofproto.OXM_OF_ICMPV4_CODE match = OFPMatch() match.set_icmpv4_code(icmpv4_code) self._test_serialize_and_parser(match, header, icmpv4_code) def test_set_icmpv4_code_mid(self): self._test_set_icmpv4_code(1) def test_set_icmpv4_code_max(self): self._test_set_icmpv4_code(0xff) def test_set_icmpv4_code_min(self): self._test_set_icmpv4_code(0) # set_arp_opcode def _test_set_arp_opcode(self, arp_op): header = ofproto.OXM_OF_ARP_OP match = OFPMatch() match.set_arp_opcode(arp_op) self._test_serialize_and_parser(match, header, arp_op) def test_set_arp_opcode_mid(self): self._test_set_arp_opcode(1) def test_set_arp_opcode_max(self): self._test_set_arp_opcode(0xffff) def test_set_arp_opcode_min(self): self._test_set_arp_opcode(0) # set_arp_spa def _test_set_arp_spa(self, ip, mask=None): header = ofproto.OXM_OF_ARP_SPA match = OFPMatch() ip = unpack('!I', socket.inet_aton(ip))[0] if mask is None: match.set_arp_spa(ip) else: mask = unpack('!I', socket.inet_aton(mask))[0] if (mask + 1) >> 32 != 1: header = ofproto.OXM_OF_ARP_SPA_W match.set_arp_spa_masked(ip, mask) self._test_serialize_and_parser(match, header, ip, mask) def test_set_arp_spa_mid(self): self._test_set_arp_spa('192.168.227.57') def test_set_arp_spa_max(self): self._test_set_arp_spa('255.255.255.255') def test_set_arp_spa_min(self): self._test_set_arp_spa('0.0.0.0') def test_set_arp_spa_masked_mid(self): self._test_set_arp_spa('192.168.227.57', '255.255.0.0') def test_set_arp_spa_masked_max(self): self._test_set_arp_spa('192.168.227.57', '255.255.255.255') def test_set_arp_spa_masked_min(self): self._test_set_arp_spa('192.168.227.57', '0.0.0.0') # set_arp_tpa def _test_set_arp_tpa(self, ip, mask=None): header = ofproto.OXM_OF_ARP_TPA match = OFPMatch() ip = unpack('!I', socket.inet_aton(ip))[0] if mask is None: match.set_arp_tpa(ip) else: mask = unpack('!I', socket.inet_aton(mask))[0] if (mask + 1) >> 32 != 1: header = ofproto.OXM_OF_ARP_TPA_W match.set_arp_tpa_masked(ip, mask) self._test_serialize_and_parser(match, header, ip, mask) def test_set_arp_tpa_mid(self): self._test_set_arp_tpa('192.168.227.57') def test_set_arp_tpa_max(self): self._test_set_arp_tpa('255.255.255.255') def test_set_arp_tpa_min(self): self._test_set_arp_tpa('0.0.0.0') def test_set_arp_tpa_masked_mid(self): self._test_set_arp_tpa('192.168.227.57', '255.255.0.0') def test_set_arp_tpa_masked_max(self): self._test_set_arp_tpa('192.168.227.57', '255.255.255.255') def test_set_arp_tpa_masked_min(self): self._test_set_arp_tpa('192.168.227.57', '0.0.0.0') # set_arp_sha def _test_set_arp_sha(self, arp_sha, mask=None): header = ofproto.OXM_OF_ARP_SHA match = OFPMatch() arp_sha = mac.haddr_to_bin(arp_sha) if mask is None: match.set_arp_sha(arp_sha) else: header = ofproto.OXM_OF_ARP_SHA_W mask = mac.haddr_to_bin(mask) match.set_arp_sha_masked(arp_sha, mask) arp_sha = mac.haddr_bitand(arp_sha, mask) self._test_serialize_and_parser(match, header, arp_sha, mask) def test_set_arp_sha_mid(self): self._test_set_arp_sha('3e:ec:13:9b:f3:0b') def test_set_arp_sha_max(self): self._test_set_arp_sha('ff:ff:ff:ff:ff:ff') def test_set_arp_sha_min(self): self._test_set_arp_sha('00:00:00:00:00:00') def test_set_arp_sha_masked_mid(self): self._test_set_arp_sha('3e:ec:13:9b:f3:0b', 'ff:ff:ff:00:00:00') def test_set_arp_sha_masked_max(self): self._test_set_arp_sha('3e:ec:13:9b:f3:0b', 'ff:ff:ff:ff:ff:ff') def test_set_arp_sha_masked_min(self): self._test_set_arp_sha('3e:ec:13:9b:f3:0b', '00:00:00:00:00:00') # set_arp_tha def _test_set_arp_tha(self, arp_tha, mask=None): header = ofproto.OXM_OF_ARP_THA match = OFPMatch() arp_tha = mac.haddr_to_bin(arp_tha) if mask is None: match.set_arp_tha(arp_tha) else: header = ofproto.OXM_OF_ARP_THA_W mask = mac.haddr_to_bin(mask) match.set_arp_tha_masked(arp_tha, mask) arp_tha = mac.haddr_bitand(arp_tha, mask) self._test_serialize_and_parser(match, header, arp_tha, mask) def test_set_arp_tha_mid(self): self._test_set_arp_tha('83:6c:21:52:49:68') def test_set_arp_tha_max(self): self._test_set_arp_tha('ff:ff:ff:ff:ff:ff') def test_set_arp_tha_min(self): self._test_set_arp_tha('00:00:00:00:00:00') def test_set_arp_tha_masked_mid(self): self._test_set_arp_tha('83:6c:21:52:49:68', 'ff:ff:ff:00:00:00') def test_set_arp_tha_masked_max(self): self._test_set_arp_tha('83:6c:21:52:49:68', 'ff:ff:ff:ff:ff:ff') def test_set_arp_tha_masked_min(self): self._test_set_arp_tha('83:6c:21:52:49:68', '00:00:00:00:00:00') # set_ipv6_src def _test_set_ipv6_src(self, ipv6, mask=None): header = ofproto.OXM_OF_IPV6_SRC match = OFPMatch() ipv6 = [int(x, 16) for x in ipv6.split(":")] if mask is None: match.set_ipv6_src(ipv6) else: header = ofproto.OXM_OF_IPV6_SRC_W mask = [int(x, 16) for x in mask.split(":")] match.set_ipv6_src_masked(ipv6, mask) ipv6 = [x & y for (x, y) in zip(ipv6, mask)] self._test_serialize_and_parser(match, header, ipv6, mask) def test_set_ipv6_src_mid(self): ipv6 = '2001:db8:bd05:1d2:288a:1fc0:1:10ee' self._test_set_ipv6_src(ipv6) def test_set_ipv6_src_max(self): ipv6 = 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff' self._test_set_ipv6_src(ipv6) def test_set_ipv6_src_min(self): ipv6 = '0:0:0:0:0:0:0:0' self._test_set_ipv6_src(ipv6) def test_set_ipv6_src_masked_mid(self): ipv6 = '2001:db8:bd05:1d2:288a:1fc0:1:10ee' mask = 'ffff:ffff:ffff:ffff:0:0:0:0' self._test_set_ipv6_src(ipv6, mask) def test_set_ipv6_src_masked_max(self): ipv6 = '2001:db8:bd05:1d2:288a:1fc0:1:10ee' mask = 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff' self._test_set_ipv6_src(ipv6, mask) def test_set_ipv6_src_masked_min(self): ipv6 = '2001:db8:bd05:1d2:288a:1fc0:1:10ee' mask = '0:0:0:0:0:0:0:0' self._test_set_ipv6_src(ipv6, mask) # set_ipv6_dst def _test_set_ipv6_dst(self, ipv6, mask=None): header = ofproto.OXM_OF_IPV6_DST match = OFPMatch() ipv6 = [int(x, 16) for x in ipv6.split(":")] if mask is None: match.set_ipv6_dst(ipv6) else: header = ofproto.OXM_OF_IPV6_DST_W mask = [int(x, 16) for x in mask.split(":")] match.set_ipv6_dst_masked(ipv6, mask) ipv6 = [x & y for (x, y) in zip(ipv6, mask)] self._test_serialize_and_parser(match, header, ipv6, mask) def test_set_ipv6_dst_mid(self): ipv6 = 'e9e8:9ea5:7d67:82cc:ca54:1fc0:2d24:f038' self._test_set_ipv6_dst(ipv6) def test_set_ipv6_dst_max(self): ipv6 = ':'.join(['ffff'] * 8) self._test_set_ipv6_dst(ipv6) def test_set_ipv6_dst_min(self): ipv6 = ':'.join(['0'] * 8) self._test_set_ipv6_dst(ipv6) def test_set_ipv6_dst_mask_mid(self): ipv6 = 'e9e8:9ea5:7d67:82cc:ca54:1fc0:2d24:f038' mask = ':'.join(['ffff'] * 4 + ['0'] * 4) self._test_set_ipv6_dst(ipv6, mask) def test_set_ipv6_dst_mask_max(self): ipv6 = 'e9e8:9ea5:7d67:82cc:ca54:1fc0:2d24:f038' mask = ':'.join(['ffff'] * 8) self._test_set_ipv6_dst(ipv6, mask) def test_set_ipv6_dst_mask_min(self): ipv6 = 'e9e8:9ea5:7d67:82cc:ca54:1fc0:2d24:f038' mask = ':'.join(['0'] * 8) self._test_set_ipv6_dst(ipv6, mask) # set_ipv6_flabel def _test_set_ipv6_flabel(self, flabel, mask=None): header = ofproto.OXM_OF_IPV6_FLABEL match = OFPMatch() if mask is None: match.set_ipv6_flabel(flabel) else: header = ofproto.OXM_OF_IPV6_FLABEL_W match.set_ipv6_flabel_masked(flabel, mask) self._test_serialize_and_parser(match, header, flabel, mask) def test_set_ipv6_flabel_mid(self): self._test_set_ipv6_flabel(0xc5384) def test_set_ipv6_flabel_max(self): self._test_set_ipv6_flabel(0xfffff) def test_set_ipv6_flabel_min(self): self._test_set_ipv6_flabel(0) def test_set_ipv6_flabel_masked_mid(self): self._test_set_ipv6_flabel(0xc5384, 0xfff00) def test_set_ipv6_flabel_masked_max(self): self._test_set_ipv6_flabel(0xc5384, 0xfffff) def test_set_ipv6_flabel_masked_min(self): self._test_set_ipv6_flabel(0xc5384, 0) # set_icmpv6_type def _test_set_icmpv6_type(self, icmpv6_type): header = ofproto.OXM_OF_ICMPV6_TYPE match = OFPMatch() match.set_icmpv6_type(icmpv6_type) self._test_serialize_and_parser(match, header, icmpv6_type) def test_set_icmpv6_type_mid(self): self._test_set_icmpv6_type(129) def test_set_icmpv6_type_max(self): self._test_set_icmpv6_type(0xff) def test_set_icmpv6_type_min(self): self._test_set_icmpv6_type(0) # set_icmpv6_code def _test_set_icmpv6_code(self, icmpv6_code): header = ofproto.OXM_OF_ICMPV6_CODE match = OFPMatch() match.set_icmpv6_code(icmpv6_code) self._test_serialize_and_parser(match, header, icmpv6_code) def test_set_icmpv6_code_mid(self): self._test_set_icmpv6_code(1) def test_set_icmpv6_code_max(self): self._test_set_icmpv6_code(0xff) def test_set_icmpv6_code_min(self): self._test_set_icmpv6_code(0) # set_ipv6_nd_target def _test_set_ipv6_nd_target(self, ipv6): header = ofproto.OXM_OF_IPV6_ND_TARGET match = OFPMatch() ipv6 = [int(x, 16) for x in ipv6.split(":")] match.set_ipv6_nd_target(ipv6) self._test_serialize_and_parser(match, header, ipv6) def test_set_ipv6_nd_target_mid(self): ip = '5420:db3f:921b:3e33:2791:98f:dd7f:2e19' self._test_set_ipv6_nd_target(ip) def test_set_ipv6_nd_target_max(self): ip = ':'.join(['ffff'] * 8) self._test_set_ipv6_nd_target(ip) def test_set_ipv6_nd_target_min(self): ip = ':'.join(['0'] * 8) self._test_set_ipv6_nd_target(ip) # set_ipv6_nd_sll def _test_set_ipv6_nd_sll(self, nd_sll): header = ofproto.OXM_OF_IPV6_ND_SLL match = OFPMatch() nd_sll = mac.haddr_to_bin(nd_sll) match.set_ipv6_nd_sll(nd_sll) self._test_serialize_and_parser(match, header, nd_sll) def test_set_ipv6_nd_sll_mid(self): self._test_set_ipv6_nd_sll('93:6d:d0:d4:e8:36') def test_set_ipv6_nd_sll_max(self): self._test_set_ipv6_nd_sll('ff:ff:ff:ff:ff:ff') def test_set_ipv6_nd_sll_min(self): self._test_set_ipv6_nd_sll('00:00:00:00:00:00') # set_ipv6_nd_tll def _test_set_ipv6_nd_tll(self, nd_tll): header = ofproto.OXM_OF_IPV6_ND_TLL match = OFPMatch() nd_tll = mac.haddr_to_bin(nd_tll) match.set_ipv6_nd_tll(nd_tll) self._test_serialize_and_parser(match, header, nd_tll) def test_set_ipv6_nd_tll_mid(self): self._test_set_ipv6_nd_tll('18:f6:66:b6:f1:b3') def test_set_ipv6_nd_tll_max(self): self._test_set_ipv6_nd_tll('ff:ff:ff:ff:ff:ff') def test_set_ipv6_nd_tll_min(self): self._test_set_ipv6_nd_tll('00:00:00:00:00:00') # set_mpls_label def _test_set_mpls_label(self, mpls_label): header = ofproto.OXM_OF_MPLS_LABEL match = OFPMatch() match.set_mpls_label(mpls_label) self._test_serialize_and_parser(match, header, mpls_label) def test_set_mpls_label_mid(self): self._test_set_mpls_label(2144) def test_set_mpls_label_max(self): self._test_set_mpls_label(0xfffff) def test_set_mpls_label_min(self): self._test_set_mpls_label(0) # set_mpls_tc def _test_set_mpls_tc(self, mpls_tc): header = ofproto.OXM_OF_MPLS_TC match = OFPMatch() match.set_mpls_tc(mpls_tc) self._test_serialize_and_parser(match, header, mpls_tc) def test_set_mpls_tc_mid(self): self._test_set_mpls_tc(3) def test_set_mpls_tc_max(self): self._test_set_mpls_tc(7) def test_set_mpls_tc_min(self): self._test_set_mpls_tc(0) class TestOFPMatchField(unittest.TestCase): """ Test case for ofproto_v1_2_parser.OFPMatchField """ def test_init_hasmask_true(self): header = 0x0100 res = OFPMatchField(header) self.assertEqual(res.header, header) self.assertEqual(res.n_bytes, (header & 0xff) // 2) self.assertEqual(res.length, 0) def test_init_hasmask_false(self): header = 0x0000 res = OFPMatchField(header) self.assertEqual(res.header, header) self.assertEqual(res.n_bytes, header & 0xff) self.assertEqual(res.length, 0) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/ofproto/test_parser_v13.py0000664000175000017500000001157400000000000023506 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone 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. import unittest import logging import socket from struct import * from os_ken.ofproto.ofproto_v1_3_parser import * from os_ken.ofproto import ofproto_v1_3 from os_ken.ofproto import ofproto_protocol LOG = logging.getLogger('test_ofproto_v13') _Datapath = ofproto_protocol.ProtocolDesc(version=ofproto_v1_3.OFP_VERSION) class TestOFPMatch(unittest.TestCase): """ Test case for ofproto_v1_3_parser.OFPMatch """ def test_init(self): res = OFPMatch() # wc check self.assertEqual(res._wc.vlan_vid_mask, 0) # flow check self.assertEqual(res._flow.vlan_vid, 0) def _test_serialize_and_parser(self, match, header, value, mask=None): cls_ = OFPMatchField._FIELDS_HEADERS.get(header) pack_str = cls_.pack_str.replace('!', '') fmt = '!HHI' + pack_str # serialize buf = bytearray() length = match.serialize(buf, 0) self.assertEqual(length, len(buf)) if mask and len(buf) > calcsize(fmt): fmt += pack_str res = list(unpack_from(fmt, bytes(buf), 0)[3:]) if type(value) is list: res_value = res[:calcsize(pack_str) // 2] self.assertEqual(res_value, value) if mask: res_mask = res[calcsize(pack_str) // 2:] self.assertEqual(res_mask, mask) else: res_value = res.pop(0) if cls_.__name__ == 'MTVlanVid': self.assertEqual(res_value, value | ofproto.OFPVID_PRESENT) else: self.assertEqual(res_value, value) if mask and res and res[0]: res_mask = res[0] self.assertEqual(res_mask, mask) # parser res = match.parser(bytes(buf), 0) self.assertEqual(res.type, ofproto.OFPMT_OXM) self.assertEqual(res.fields[0].header, header) self.assertEqual(res.fields[0].value, value) if mask and res.fields[0].mask is not None: self.assertEqual(res.fields[0].mask, mask) # to_jsondict jsondict = match.to_jsondict() # from_jsondict match2 = match.from_jsondict(jsondict["OFPMatch"]) buf2 = bytearray() match2.serialize(buf2, 0) self.assertEqual(str(match), str(match2)) self.assertEqual(buf, buf2) # set_vlan_vid def _test_set_vlan_vid(self, vid, mask=None): header = ofproto.OXM_OF_VLAN_VID match = OFPMatch() if mask is None: match.set_vlan_vid(vid) else: header = ofproto.OXM_OF_VLAN_VID_W match.set_vlan_vid_masked(vid, mask) self._test_serialize_and_parser(match, header, vid, mask) def _test_set_vlan_vid_none(self): header = ofproto.OXM_OF_VLAN_VID match = OFPMatch() match.set_vlan_vid_none() value = ofproto.OFPVID_NONE cls_ = OFPMatchField._FIELDS_HEADERS.get(header) pack_str = cls_.pack_str.replace('!', '') fmt = '!HHI' + pack_str # serialize buf = bytearray() length = match.serialize(buf, 0) self.assertEqual(length, len(buf)) res = list(unpack_from(fmt, bytes(buf), 0)[3:]) res_value = res.pop(0) self.assertEqual(res_value, value) # parser res = match.parser(bytes(buf), 0) self.assertEqual(res.type, ofproto.OFPMT_OXM) self.assertEqual(res.fields[0].header, header) self.assertEqual(res.fields[0].value, value) # to_jsondict jsondict = match.to_jsondict() # from_jsondict match2 = match.from_jsondict(jsondict["OFPMatch"]) buf2 = bytearray() match2.serialize(buf2, 0) self.assertEqual(str(match), str(match2)) self.assertEqual(buf, buf2) def test_set_vlan_vid_mid(self): self._test_set_vlan_vid(2047) def test_set_vlan_vid_max(self): self._test_set_vlan_vid(0xfff) def test_set_vlan_vid_min(self): self._test_set_vlan_vid(0) def test_set_vlan_vid_masked_mid(self): self._test_set_vlan_vid(2047, 0xf0f) def test_set_vlan_vid_masked_max(self): self._test_set_vlan_vid(2047, 0xfff) def test_set_vlan_vid_masked_min(self): self._test_set_vlan_vid(2047, 0) def test_set_vlan_vid_none(self): self._test_set_vlan_vid_none() ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.3661208 os-ken-2.10.0/os_ken/tests/unit/packet/0000775000175000017500000000000000000000000017657 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/packet/__init__.py0000664000175000017500000000000000000000000021756 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/packet/test_arp.py0000664000175000017500000001351400000000000022056 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone 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. # vim: tabstop=4 shiftwidth=4 softtabstop=4 import unittest import logging import struct from struct import * from os_ken.ofproto import ether from os_ken.lib.packet.ethernet import ethernet from os_ken.lib.packet.packet import Packet from os_ken.lib.packet.arp import arp from os_ken.lib.packet.vlan import vlan from os_ken.lib import addrconv LOG = logging.getLogger('test_arp') class Test_arp(unittest.TestCase): """ Test case for arp """ hwtype = 1 proto = 0x0800 hlen = 6 plen = 4 opcode = 1 src_mac = '00:07:0d:af:f4:54' src_ip = '24.166.172.1' dst_mac = '00:00:00:00:00:00' dst_ip = '24.166.173.159' fmt = arp._PACK_STR buf = pack(fmt, hwtype, proto, hlen, plen, opcode, addrconv.mac.text_to_bin(src_mac), addrconv.ipv4.text_to_bin(src_ip), addrconv.mac.text_to_bin(dst_mac), addrconv.ipv4.text_to_bin(dst_ip)) a = arp(hwtype, proto, hlen, plen, opcode, src_mac, src_ip, dst_mac, dst_ip) def setUp(self): pass def tearDown(self): pass def find_protocol(self, pkt, name): for p in pkt.protocols: if p.protocol_name == name: return p def test_init(self): self.assertEqual(self.hwtype, self.a.hwtype) self.assertEqual(self.proto, self.a.proto) self.assertEqual(self.hlen, self.a.hlen) self.assertEqual(self.plen, self.a.plen) self.assertEqual(self.opcode, self.a.opcode) self.assertEqual(self.src_mac, self.a.src_mac) self.assertEqual(self.src_ip, self.a.src_ip) self.assertEqual(self.dst_mac, self.a.dst_mac) self.assertEqual(self.dst_ip, self.a.dst_ip) def test_parser(self): _res = self.a.parser(self.buf) if type(_res) is tuple: res = _res[0] else: res = _res self.assertEqual(res.hwtype, self.hwtype) self.assertEqual(res.proto, self.proto) self.assertEqual(res.hlen, self.hlen) self.assertEqual(res.plen, self.plen) self.assertEqual(res.opcode, self.opcode) self.assertEqual(res.src_mac, self.src_mac) self.assertEqual(res.src_ip, self.src_ip) self.assertEqual(res.dst_mac, self.dst_mac) self.assertEqual(res.dst_ip, self.dst_ip) def test_serialize(self): data = bytearray() prev = None buf = self.a.serialize(data, prev) fmt = arp._PACK_STR res = struct.unpack(fmt, buf) self.assertEqual(res[0], self.hwtype) self.assertEqual(res[1], self.proto) self.assertEqual(res[2], self.hlen) self.assertEqual(res[3], self.plen) self.assertEqual(res[4], self.opcode) self.assertEqual(res[5], addrconv.mac.text_to_bin(self.src_mac)) self.assertEqual(res[6], addrconv.ipv4.text_to_bin(self.src_ip)) self.assertEqual(res[7], addrconv.mac.text_to_bin(self.dst_mac)) self.assertEqual(res[8], addrconv.ipv4.text_to_bin(self.dst_ip)) def _build_arp(self, vlan_enabled): if vlan_enabled is True: ethertype = ether.ETH_TYPE_8021Q v = vlan(1, 1, 3, ether.ETH_TYPE_ARP) else: ethertype = ether.ETH_TYPE_ARP e = ethernet(self.dst_mac, self.src_mac, ethertype) p = Packet() p.add_protocol(e) if vlan_enabled is True: p.add_protocol(v) p.add_protocol(self.a) p.serialize() return p def test_build_arp_vlan(self): p = self._build_arp(True) e = self.find_protocol(p, "ethernet") self.assertTrue(e) self.assertEqual(e.ethertype, ether.ETH_TYPE_8021Q) v = self.find_protocol(p, "vlan") self.assertTrue(v) self.assertEqual(v.ethertype, ether.ETH_TYPE_ARP) a = self.find_protocol(p, "arp") self.assertTrue(a) self.assertEqual(a.hwtype, self.hwtype) self.assertEqual(a.proto, self.proto) self.assertEqual(a.hlen, self.hlen) self.assertEqual(a.plen, self.plen) self.assertEqual(a.opcode, self.opcode) self.assertEqual(a.src_mac, self.src_mac) self.assertEqual(a.src_ip, self.src_ip) self.assertEqual(a.dst_mac, self.dst_mac) self.assertEqual(a.dst_ip, self.dst_ip) def test_build_arp_novlan(self): p = self._build_arp(False) e = self.find_protocol(p, "ethernet") self.assertTrue(e) self.assertEqual(e.ethertype, ether.ETH_TYPE_ARP) a = self.find_protocol(p, "arp") self.assertTrue(a) self.assertEqual(a.hwtype, self.hwtype) self.assertEqual(a.proto, self.proto) self.assertEqual(a.hlen, self.hlen) self.assertEqual(a.plen, self.plen) self.assertEqual(a.opcode, self.opcode) self.assertEqual(a.src_mac, self.src_mac) self.assertEqual(a.src_ip, self.src_ip) self.assertEqual(a.dst_mac, self.dst_mac) self.assertEqual(a.dst_ip, self.dst_ip) def test_malformed_arp(self): m_short_buf = self.buf[1:arp._MIN_LEN] self.assertRaises(Exception, arp.parser, m_short_buf) def test_json(self): jsondict = self.a.to_jsondict() a = arp.from_jsondict(jsondict['arp']) self.assertEqual(str(self.a), str(a)) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/packet/test_bfd.py0000664000175000017500000003150300000000000022025 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Xinguard, Inc. # # 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. import unittest import logging import struct import inspect from os_ken.ofproto import ether from os_ken.ofproto import inet from os_ken.lib.packet import packet from os_ken.lib.packet import ethernet from os_ken.lib.packet import ipv4 from os_ken.lib.packet import udp from os_ken.lib.packet import bfd from os_ken.lib import addrconv LOG = logging.getLogger(__name__) class TestBFD(unittest.TestCase): def setUp(self): # BFD packet without authentication. self.data = b'\xb0\xa8\x6e\x18\xb8\x08\x64\x87' \ + b'\x88\xe9\xcb\xc8\x08\x00\x45\xc0' \ + b'\x00\x34\x68\x49\x00\x00\xff\x11' \ + b'\xf4\x73\xac\x1c\x03\x01\xac\x1c' \ + b'\x03\x02\xc0\x00\x0e\xc8\x00\x20' \ + b'\xd9\x02\x21\xc0\x03\x18\x00\x00' \ + b'\x00\x06\x00\x00\x00\x07\x00\x00' \ + b'\xea\x60\x00\x00\xea\x60\x00\x00' \ + b'\x00\x00' # BFD packet using simple password authentication. self.data_auth_simple = b'\x08\x00\x27\xd1\x95\x7c\x08\x00' \ + b'\x27\xed\x54\x41\x08\x00\x45\xc0' \ + b'\x00\x3d\x0c\x90\x00\x00\xff\x11' \ + b'\xbb\x0b\xc0\xa8\x39\x02\xc0\xa8' \ + b'\x39\x01\xc0\x00\x0e\xc8\x00\x29' \ + b'\x46\x35\x20\x44\x03\x21\x00\x00' \ + b'\x00\x01\x00\x00\x00\x00\x00\x0f' \ + b'\x42\x40\x00\x0f\x42\x40\x00\x00' \ + b'\x00\x00\x01\x09\x02\x73\x65\x63' \ + b'\x72\x65\x74' # BFD packet using md5 authentication. self.data_auth_md5 = b'\x08\x00\x27\xd1\x95\x7c\x08\x00' \ + b'\x27\xed\x54\x41\x08\x00\x45\xc0' \ + b'\x00\x4c\x0c\x44\x00\x00\xff\x11' \ + b'\xbb\x48\xc0\xa8\x39\x02\xc0\xa8' \ + b'\x39\x01\xc0\x00\x0e\xc8\x00\x38' \ + b'\x51\xbc\x20\x44\x03\x30\x00\x00' \ + b'\x00\x01\x00\x00\x00\x00\x00\x0f' \ + b'\x42\x40\x00\x0f\x42\x40\x00\x00' \ + b'\x00\x00\x02\x18\x02\x00\x00\x00' \ + b'\x41\xdb\x66\xa8\xf9\x25\x5a\x8b' \ + b'\xcb\x7e\x4b\xec\x25\xa6\x2c\x23' \ + b'\xda\x0f' # BFD packet using SHA1 authentication. self.data_auth_sha1 = b'\x08\x00\x27\xd1\x95\x7c\x08\x00' \ + b'\x27\xed\x54\x41\x08\x00\x45\xc0' \ + b'\x00\x50\x0b\x90\x00\x00\xff\x11' \ + b'\xbb\xf8\xc0\xa8\x39\x02\xc0\xa8' \ + b'\x39\x01\xc0\x00\x0e\xc8\x00\x3c' \ + b'\xb9\x92\x20\x44\x03\x34\x00\x00' \ + b'\x00\x01\x00\x00\x00\x00\x00\x0f' \ + b'\x42\x40\x00\x0f\x42\x40\x00\x00' \ + b'\x00\x00\x04\x1c\x02\x00\x00\x00' \ + b'\x41\xb1\x46\x20\x10\x81\x03\xd7' \ + b'\xf4\xde\x87\x61\x4c\x24\x61\x1f' \ + b'\x3c\xc1\x6a\x00\x69\x23' # BFD Key chain {auth_key_id: auth_key/password} self.auth_keys = {2: b"secret"} def tearDown(self): pass def test_parse(self): buf = self.data pkt = packet.Packet(buf) i = iter(pkt) self.assertEqual(type(next(i)), ethernet.ethernet) self.assertEqual(type(next(i)), ipv4.ipv4) self.assertEqual(type(next(i)), udp.udp) self.assertEqual(type(bfd.bfd.parser(next(i))[0]), bfd.bfd) def test_parse_with_auth_simple(self): buf = self.data_auth_simple pkt = packet.Packet(buf) i = iter(pkt) self.assertEqual(type(next(i)), ethernet.ethernet) self.assertEqual(type(next(i)), ipv4.ipv4) self.assertEqual(type(next(i)), udp.udp) bfd_obj = bfd.bfd.parser(next(i))[0] self.assertEqual(type(bfd_obj), bfd.bfd) self.assertEqual(type(bfd_obj.auth_cls), bfd.SimplePassword) self.assertTrue(bfd_obj.authenticate(self.auth_keys)) def test_parse_with_auth_md5(self): buf = self.data_auth_md5 pkt = packet.Packet(buf) i = iter(pkt) self.assertEqual(type(next(i)), ethernet.ethernet) self.assertEqual(type(next(i)), ipv4.ipv4) self.assertEqual(type(next(i)), udp.udp) bfd_obj = bfd.bfd.parser(next(i))[0] self.assertEqual(type(bfd_obj), bfd.bfd) self.assertEqual(type(bfd_obj.auth_cls), bfd.KeyedMD5) self.assertTrue(bfd_obj.authenticate(self.auth_keys)) def test_parse_with_auth_sha1(self): buf = self.data_auth_sha1 pkt = packet.Packet(buf) i = iter(pkt) self.assertEqual(type(next(i)), ethernet.ethernet) self.assertEqual(type(next(i)), ipv4.ipv4) self.assertEqual(type(next(i)), udp.udp) bfd_obj = bfd.bfd.parser(next(i))[0] self.assertEqual(type(bfd_obj), bfd.bfd) self.assertEqual(type(bfd_obj.auth_cls), bfd.KeyedSHA1) self.assertTrue(bfd_obj.authenticate(self.auth_keys)) def test_serialize(self): pkt = packet.Packet() eth_pkt = ethernet.ethernet('b0:a8:6e:18:b8:08', '64:87:88:e9:cb:c8') pkt.add_protocol(eth_pkt) ip_pkt = ipv4.ipv4(src='172.28.3.1', dst='172.28.3.2', tos=192, identification=26697, proto=inet.IPPROTO_UDP) pkt.add_protocol(ip_pkt) udp_pkt = udp.udp(49152, 3784) pkt.add_protocol(udp_pkt) bfd_pkt = bfd.bfd(ver=1, diag=bfd.BFD_DIAG_CTRL_DETECT_TIME_EXPIRED, state=bfd.BFD_STATE_UP, detect_mult=3, my_discr=6, your_discr=7, desired_min_tx_interval=60000, required_min_rx_interval=60000, required_min_echo_rx_interval=0) pkt.add_protocol(bfd_pkt) self.assertEqual(len(pkt.protocols), 4) pkt.serialize() self.assertEqual(pkt.data, self.data) def test_serialize_with_auth_simple(self): pkt = packet.Packet() eth_pkt = ethernet.ethernet('08:00:27:d1:95:7c', '08:00:27:ed:54:41') pkt.add_protocol(eth_pkt) ip_pkt = ipv4.ipv4(src='192.168.57.2', dst='192.168.57.1', tos=192, identification=3216, proto=inet.IPPROTO_UDP) pkt.add_protocol(ip_pkt) udp_pkt = udp.udp(49152, 3784) pkt.add_protocol(udp_pkt) auth_cls = bfd.SimplePassword(auth_key_id=2, password=self.auth_keys[2]) bfd_pkt = bfd.bfd(ver=1, diag=bfd.BFD_DIAG_NO_DIAG, flags=bfd.BFD_FLAG_AUTH_PRESENT, state=bfd.BFD_STATE_DOWN, detect_mult=3, my_discr=1, your_discr=0, desired_min_tx_interval=1000000, required_min_rx_interval=1000000, required_min_echo_rx_interval=0, auth_cls=auth_cls) pkt.add_protocol(bfd_pkt) self.assertEqual(len(pkt.protocols), 4) pkt.serialize() self.assertEqual(pkt.data, self.data_auth_simple) def test_serialize_with_auth_md5(self): pkt = packet.Packet() eth_pkt = ethernet.ethernet('08:00:27:d1:95:7c', '08:00:27:ed:54:41') pkt.add_protocol(eth_pkt) ip_pkt = ipv4.ipv4(src='192.168.57.2', dst='192.168.57.1', tos=192, identification=3140, proto=inet.IPPROTO_UDP) pkt.add_protocol(ip_pkt) udp_pkt = udp.udp(49152, 3784) pkt.add_protocol(udp_pkt) auth_cls = bfd.KeyedMD5(auth_key_id=2, seq=16859, auth_key=self.auth_keys[2]) bfd_pkt = bfd.bfd(ver=1, diag=bfd.BFD_DIAG_NO_DIAG, flags=bfd.BFD_FLAG_AUTH_PRESENT, state=bfd.BFD_STATE_DOWN, detect_mult=3, my_discr=1, your_discr=0, desired_min_tx_interval=1000000, required_min_rx_interval=1000000, required_min_echo_rx_interval=0, auth_cls=auth_cls) pkt.add_protocol(bfd_pkt) self.assertEqual(len(pkt.protocols), 4) pkt.serialize() self.assertEqual(pkt.data, self.data_auth_md5) def test_serialize_with_auth_sha1(self): pkt = packet.Packet() eth_pkt = ethernet.ethernet('08:00:27:d1:95:7c', '08:00:27:ed:54:41') pkt.add_protocol(eth_pkt) ip_pkt = ipv4.ipv4(src='192.168.57.2', dst='192.168.57.1', tos=192, identification=2960, proto=inet.IPPROTO_UDP) pkt.add_protocol(ip_pkt) udp_pkt = udp.udp(49152, 3784) pkt.add_protocol(udp_pkt) auth_cls = bfd.KeyedSHA1(auth_key_id=2, seq=16817, auth_key=self.auth_keys[2]) bfd_pkt = bfd.bfd(ver=1, diag=bfd.BFD_DIAG_NO_DIAG, flags=bfd.BFD_FLAG_AUTH_PRESENT, state=bfd.BFD_STATE_DOWN, detect_mult=3, my_discr=1, your_discr=0, desired_min_tx_interval=1000000, required_min_rx_interval=1000000, required_min_echo_rx_interval=0, auth_cls=auth_cls) pkt.add_protocol(bfd_pkt) self.assertEqual(len(pkt.protocols), 4) pkt.serialize() self.assertEqual(pkt.data, self.data_auth_sha1) def test_json(self): bfd1 = bfd.bfd(ver=1, diag=bfd.BFD_DIAG_CTRL_DETECT_TIME_EXPIRED, state=bfd.BFD_STATE_UP, detect_mult=3, my_discr=6, your_discr=7, desired_min_tx_interval=60000, required_min_rx_interval=60000, required_min_echo_rx_interval=0) jsondict = bfd1.to_jsondict() bfd2 = bfd.bfd.from_jsondict(jsondict['bfd']) self.assertEqual(str(bfd1), str(bfd2)) def test_json_with_auth_simple(self): auth_cls = bfd.SimplePassword(auth_key_id=2, password=self.auth_keys[2]) bfd1 = bfd.bfd(ver=1, diag=bfd.BFD_DIAG_NO_DIAG, flags=bfd.BFD_FLAG_AUTH_PRESENT, state=bfd.BFD_STATE_DOWN, detect_mult=3, my_discr=1, your_discr=0, desired_min_tx_interval=1000000, required_min_rx_interval=1000000, required_min_echo_rx_interval=0, auth_cls=auth_cls) jsondict = bfd1.to_jsondict() bfd2 = bfd.bfd.from_jsondict(jsondict['bfd']) self.assertEqual(str(bfd1), str(bfd2)) def test_json_with_auth_md5(self): auth_cls = bfd.KeyedMD5(auth_key_id=2, seq=16859, auth_key=self.auth_keys[2]) bfd1 = bfd.bfd(ver=1, diag=bfd.BFD_DIAG_NO_DIAG, flags=bfd.BFD_FLAG_AUTH_PRESENT, state=bfd.BFD_STATE_DOWN, detect_mult=3, my_discr=1, your_discr=0, desired_min_tx_interval=1000000, required_min_rx_interval=1000000, required_min_echo_rx_interval=0, auth_cls=auth_cls) jsondict = bfd1.to_jsondict() bfd2 = bfd.bfd.from_jsondict(jsondict['bfd']) self.assertEqual(str(bfd1), str(bfd2)) def test_json_with_auth_sha1(self): auth_cls = bfd.KeyedSHA1(auth_key_id=2, seq=16859, auth_key=self.auth_keys[2]) bfd1 = bfd.bfd(ver=1, diag=bfd.BFD_DIAG_NO_DIAG, flags=bfd.BFD_FLAG_AUTH_PRESENT, state=bfd.BFD_STATE_DOWN, detect_mult=3, my_discr=1, your_discr=0, desired_min_tx_interval=1000000, required_min_rx_interval=1000000, required_min_echo_rx_interval=0, auth_cls=auth_cls) jsondict = bfd1.to_jsondict() bfd2 = bfd.bfd.from_jsondict(jsondict['bfd']) self.assertEqual(str(bfd1), str(bfd2)) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/packet/test_bgp.py0000664000175000017500000010430600000000000022044 0ustar00zuulzuul00000000000000# Copyright (C) 2013,2014 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013,2014 YAMAMOTO Takashi # # 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. import logging import os import sys import unittest from os_ken.utils import binary_str from os_ken.lib import pcaplib from os_ken.lib.packet import packet from os_ken.lib.packet import bgp from os_ken.lib.packet import afi from os_ken.lib.packet import safi LOG = logging.getLogger(__name__) BGP4_PACKET_DATA_DIR = os.path.join( os.path.dirname(sys.modules[__name__].__file__), '../../packet_data/bgp4/') PMSI_TYPE_NO_TUNNEL_INFORMATION_PRESENT = ( bgp.BGPPathAttributePmsiTunnel.TYPE_NO_TUNNEL_INFORMATION_PRESENT ) PMSI_TYPE_INGRESS_REPLICATION = ( bgp.BGPPathAttributePmsiTunnel.TYPE_INGRESS_REPLICATION ) RULES_BASE = [ # port='>=8000' bgp.FlowSpecPort( operator=(bgp.FlowSpecPort.GT | bgp.FlowSpecPort.EQ), value=8000), # port='&<=9000' bgp.FlowSpecPort( operator=(bgp.FlowSpecPort.AND | bgp.FlowSpecPort.LT | bgp.FlowSpecPort.EQ), value=9000), # port='==80' bgp.FlowSpecPort(operator=bgp.FlowSpecPort.EQ, value=80), # dst_port=8080 bgp.FlowSpecDestPort(operator=bgp.FlowSpecDestPort.EQ, value=8080), # dst_port='>9000' bgp.FlowSpecDestPort(operator=bgp.FlowSpecDestPort.GT, value=9000), # dst_port='&<9050' bgp.FlowSpecDestPort( operator=(bgp.FlowSpecDestPort.AND | bgp.FlowSpecDestPort.LT), value=9050), # dst_port='<=1000' bgp.FlowSpecDestPort( operator=(bgp.FlowSpecDestPort.LT | bgp.FlowSpecDestPort.EQ), value=1000), # src_port='<=9090' bgp.FlowSpecSrcPort( operator=(bgp.FlowSpecSrcPort.LT | bgp.FlowSpecSrcPort.EQ), value=9090), # src_port='& >=9080' bgp.FlowSpecSrcPort( operator=(bgp.FlowSpecSrcPort.AND | bgp.FlowSpecSrcPort.GT | bgp.FlowSpecSrcPort.EQ), value=9080), # src_port='<10100' bgp.FlowSpecSrcPort( operator=bgp.FlowSpecSrcPort.LT, value=10100), # src_port='>10000' bgp.FlowSpecSrcPort( operator=(bgp.FlowSpecSrcPort.AND | bgp.FlowSpecSrcPort.GT), value=10000), # icmp_type=0 bgp.FlowSpecIcmpType(operator=bgp.FlowSpecIcmpType.EQ, value=0), # icmp_code=6 bgp.FlowSpecIcmpCode(operator=bgp.FlowSpecIcmpCode.EQ, value=6), # tcp_flags='ACK+FIN' bgp.FlowSpecTCPFlags( operator=0, # Partial match value=(bgp.FlowSpecTCPFlags.SYN | bgp.FlowSpecTCPFlags.ACK)), # tcp_flags='&!=URGENT' bgp.FlowSpecTCPFlags( operator=(bgp.FlowSpecTCPFlags.AND | bgp.FlowSpecTCPFlags.NOT), value=bgp.FlowSpecTCPFlags.URGENT), # packet_len=1000 bgp.FlowSpecPacketLen( operator=bgp.FlowSpecPacketLen.EQ, value=1000), # packet_len=1100 bgp.FlowSpecPacketLen( operator=(bgp.FlowSpecTCPFlags.AND | bgp.FlowSpecPacketLen.EQ), value=1100), # dscp=22 bgp.FlowSpecDSCP(operator=bgp.FlowSpecDSCP.EQ, value=22), # dscp=24 bgp.FlowSpecDSCP(operator=bgp.FlowSpecDSCP.EQ, value=24), ] RULES_L2VPN_BASE = [ # ether_type=0x0800 bgp.FlowSpecEtherType(operator=bgp.FlowSpecEtherType.EQ, value=0x0800), # source_mac='12:34:56:78:90:AB' bgp.FlowSpecSourceMac(addr='12:34:56:78:90:AB', length=6), # dest_mac='DE:EF:C0:FF:EE:DD' bgp.FlowSpecDestinationMac(addr='BE:EF:C0:FF:EE:DD', length=6), # llc_dsap=0x42 bgp.FlowSpecLLCDSAP(operator=bgp.FlowSpecLLCDSAP.EQ, value=0x42), # llc_ssap=0x42 bgp.FlowSpecLLCSSAP(operator=bgp.FlowSpecLLCSSAP.EQ, value=0x42), # llc_control=100 bgp.FlowSpecLLCControl(operator=bgp.FlowSpecLLCControl.EQ, value=100), # snap=0x12345 bgp.FlowSpecSNAP(operator=bgp.FlowSpecSNAP.EQ, value=0x12345), # vlan_id='>4000' bgp.FlowSpecVLANID(operator=bgp.FlowSpecVLANID.GT, value=4000), # vlan_cos='>=3' bgp.FlowSpecVLANCoS( operator=(bgp.FlowSpecVLANCoS.GT | bgp.FlowSpecVLANCoS.EQ), value=3), # inner_vlan_id='<3000' bgp.FlowSpecInnerVLANID(operator=bgp.FlowSpecInnerVLANID.LT, value=3000), # inner_vlan_cos='<=5' bgp.FlowSpecInnerVLANCoS( operator=(bgp.FlowSpecInnerVLANCoS.LT | bgp.FlowSpecInnerVLANCoS.EQ), value=5), ] class Test_bgp(unittest.TestCase): """ Test case for os_ken.lib.packet.bgp """ def setUp(self): pass def tearDown(self): pass def test_open1(self): msg = bgp.BGPOpen(my_as=30000, bgp_identifier='192.0.2.1') binmsg = msg.serialize() msg2, _, rest = bgp.BGPMessage.parser(binmsg) self.assertEqual(str(msg), str(msg2)) self.assertEqual(len(msg), 29) self.assertEqual(rest, b'') def test_open2(self): opt_param = [bgp.BGPOptParamCapabilityUnknown(cap_code=200, cap_value=b'hoge'), bgp.BGPOptParamCapabilityGracefulRestart(flags=0, time=120, tuples=[]), bgp.BGPOptParamCapabilityRouteRefresh(), bgp.BGPOptParamCapabilityCiscoRouteRefresh(), bgp.BGPOptParamCapabilityMultiprotocol( afi=afi.IP, safi=safi.MPLS_VPN), bgp.BGPOptParamCapabilityCarryingLabelInfo(), bgp.BGPOptParamCapabilityFourOctetAsNumber( as_number=1234567), bgp.BGPOptParamUnknown(type_=99, value=b'fuga')] msg = bgp.BGPOpen(my_as=30000, bgp_identifier='192.0.2.2', opt_param=opt_param) binmsg = msg.serialize() msg2, _, rest = bgp.BGPMessage.parser(binmsg) self.assertEqual(str(msg), str(msg2)) self.assertTrue(len(msg) > 29) self.assertEqual(rest, b'') def test_update1(self): msg = bgp.BGPUpdate() binmsg = msg.serialize() msg2, _, rest = bgp.BGPMessage.parser(binmsg) self.assertEqual(str(msg), str(msg2)) self.assertEqual(len(msg), 23) self.assertEqual(rest, b'') def test_update2(self): withdrawn_routes = [bgp.BGPWithdrawnRoute(length=0, addr='192.0.2.13'), bgp.BGPWithdrawnRoute(length=1, addr='192.0.2.13'), bgp.BGPWithdrawnRoute(length=3, addr='192.0.2.13'), bgp.BGPWithdrawnRoute(length=7, addr='192.0.2.13'), bgp.BGPWithdrawnRoute(length=32, addr='192.0.2.13')] mp_nlri = [ bgp.LabelledVPNIPAddrPrefix(24, '192.0.9.0', route_dist='100:100', labels=[1, 2, 3]), bgp.LabelledVPNIPAddrPrefix(26, '192.0.10.192', route_dist='10.0.0.1:10000', labels=[5, 6, 7, 8]), ] mp_nlri2 = [ bgp.LabelledIPAddrPrefix(24, '192.168.0.0', labels=[1, 2, 3]) ] mp_nlri_v6 = [ bgp.LabelledVPNIP6AddrPrefix(64, '2001:db8:1111::', route_dist='200:200', labels=[1, 2, 3]), bgp.LabelledVPNIP6AddrPrefix(64, '2001:db8:2222::', route_dist='10.0.0.1:10000', labels=[5, 6, 7, 8]), ] mp_nlri2_v6 = [ bgp.LabelledIP6AddrPrefix(64, '2001:db8:3333::', labels=[1, 2, 3]) ] communities = [ bgp.BGP_COMMUNITY_NO_EXPORT, bgp.BGP_COMMUNITY_NO_ADVERTISE, ] ecommunities = [ bgp.BGPTwoOctetAsSpecificExtendedCommunity( subtype=1, as_number=65500, local_administrator=3908876543), bgp.BGPFourOctetAsSpecificExtendedCommunity( subtype=2, as_number=10000000, local_administrator=59876), bgp.BGPIPv4AddressSpecificExtendedCommunity( subtype=3, ipv4_address='192.0.2.1', local_administrator=65432), bgp.BGPOpaqueExtendedCommunity(subtype=13, opaque=b'abcdef'), bgp.BGPEncapsulationExtendedCommunity( subtype=0x0c, tunnel_type=10), bgp.BGPEvpnMacMobilityExtendedCommunity( subtype=0, flags=0xff, sequence_number=0x11223344), bgp.BGPEvpnEsiLabelExtendedCommunity( subtype=1, flags=0xff, label=b'\xFF\xFF\xFF'), bgp.BGPEvpnEsiLabelExtendedCommunity( subtype=1, flags=0xff, mpls_label=0xfffff), bgp.BGPEvpnEsiLabelExtendedCommunity( subtype=1, flags=0xff, vni=0xffffff), bgp.BGPEvpnEsImportRTExtendedCommunity( subtype=2, es_import="aa:bb:cc:dd:ee:ff"), bgp.BGPUnknownExtendedCommunity(type_=99, value=b'abcdefg'), ] path_attributes = [ bgp.BGPPathAttributeOrigin(value=1), bgp.BGPPathAttributeAsPath(value=[[1000], {1001, 1002}, [1003, 1004]]), bgp.BGPPathAttributeNextHop(value='192.0.2.199'), bgp.BGPPathAttributeMultiExitDisc(value=2000000000), bgp.BGPPathAttributeLocalPref(value=1000000000), bgp.BGPPathAttributeAtomicAggregate(), bgp.BGPPathAttributeAggregator(as_number=40000, addr='192.0.2.99'), bgp.BGPPathAttributeCommunities(communities=communities), bgp.BGPPathAttributeOriginatorId(value='10.1.1.1'), bgp.BGPPathAttributeClusterList(value=['1.1.1.1', '2.2.2.2']), bgp.BGPPathAttributeExtendedCommunities(communities=ecommunities), bgp.BGPPathAttributePmsiTunnel( pmsi_flags=1, tunnel_type=PMSI_TYPE_NO_TUNNEL_INFORMATION_PRESENT, label=b'\xFF\xFF\xFF'), bgp.BGPPathAttributePmsiTunnel( pmsi_flags=1, tunnel_type=PMSI_TYPE_NO_TUNNEL_INFORMATION_PRESENT, tunnel_id=None), bgp.BGPPathAttributePmsiTunnel( pmsi_flags=1, tunnel_type=PMSI_TYPE_INGRESS_REPLICATION, mpls_label=0xfffff, tunnel_id=bgp.PmsiTunnelIdIngressReplication( tunnel_endpoint_ip="1.1.1.1")), bgp.BGPPathAttributePmsiTunnel( pmsi_flags=1, tunnel_type=PMSI_TYPE_INGRESS_REPLICATION, vni=0xffffff, tunnel_id=bgp.PmsiTunnelIdIngressReplication( tunnel_endpoint_ip="aa:bb:cc::dd:ee:ff")), bgp.BGPPathAttributePmsiTunnel( pmsi_flags=1, tunnel_type=2, label=b'\xFF\xFF\xFF', tunnel_id=bgp.PmsiTunnelIdUnknown(value=b'test')), bgp.BGPPathAttributeAs4Path(value=[[1000000], {1000001, 1002}, [1003, 1000004]]), bgp.BGPPathAttributeAs4Aggregator(as_number=100040000, addr='192.0.2.99'), bgp.BGPPathAttributeMpReachNLRI(afi=afi.IP, safi=safi.MPLS_VPN, next_hop='1.1.1.1', nlri=mp_nlri), bgp.BGPPathAttributeMpReachNLRI(afi=afi.IP, safi=safi.MPLS_LABEL, next_hop='1.1.1.1', nlri=mp_nlri2), bgp.BGPPathAttributeMpReachNLRI(afi=afi.IP6, safi=safi.MPLS_VPN, next_hop=['2001:db8::1'], nlri=mp_nlri_v6), bgp.BGPPathAttributeMpReachNLRI(afi=afi.IP6, safi=safi.MPLS_LABEL, next_hop=['2001:db8::1', 'fe80::1'], nlri=mp_nlri2_v6), bgp.BGPPathAttributeMpUnreachNLRI(afi=afi.IP, safi=safi.MPLS_VPN, withdrawn_routes=mp_nlri), bgp.BGPPathAttributeUnknown(flags=0, type_=100, value=300 * b'bar') ] nlri = [ bgp.BGPNLRI(length=24, addr='203.0.113.1'), bgp.BGPNLRI(length=16, addr='203.0.113.0') ] msg = bgp.BGPUpdate(withdrawn_routes=withdrawn_routes, path_attributes=path_attributes, nlri=nlri) binmsg = msg.serialize() msg2, _, rest = bgp.BGPMessage.parser(binmsg) self.assertEqual(str(msg), str(msg2)) self.assertTrue(len(msg) > 23) self.assertEqual(rest, b'') def test_keepalive(self): msg = bgp.BGPKeepAlive() binmsg = msg.serialize() msg2, _, rest = bgp.BGPMessage.parser(binmsg) self.assertEqual(str(msg), str(msg2)) self.assertEqual(len(msg), 19) self.assertEqual(rest, b'') def test_notification(self): data = b'hoge' msg = bgp.BGPNotification(error_code=1, error_subcode=2, data=data) binmsg = msg.serialize() msg2, _, rest = bgp.BGPMessage.parser(binmsg) self.assertEqual(str(msg), str(msg2)) self.assertEqual(len(msg), 21 + len(data)) self.assertEqual(rest, b'') def test_route_refresh(self): msg = bgp.BGPRouteRefresh(afi=afi.IP, safi=safi.MPLS_VPN) binmsg = msg.serialize() msg2, _, rest = bgp.BGPMessage.parser(binmsg) self.assertEqual(str(msg), str(msg2)) self.assertEqual(len(msg), 23) self.assertEqual(rest, b'') def test_stream_parser(self): msgs = [ bgp.BGPNotification(error_code=1, error_subcode=2, data=b'foo'), bgp.BGPNotification(error_code=3, error_subcode=4, data=b'bar'), bgp.BGPNotification(error_code=5, error_subcode=6, data=b'baz'), ] binmsgs = b''.join([bytes(msg.serialize()) for msg in msgs]) sp = bgp.StreamParser() results = [] for b in binmsgs: for m in sp.parse(b): results.append(m) self.assertEqual(str(results), str(msgs)) def test_parser(self): files = [ 'bgp4-open', 'bgp4-update', 'bgp4-update_ipv6', 'bgp4-update_vpnv6', 'bgp4-keepalive', 'evpn_esi_arbitrary', 'evpn_esi_lacp', 'evpn_esi_l2_bridge', 'evpn_esi_mac_base', 'evpn_esi_router_id', 'evpn_esi_as_based', 'evpn_nlri_eth_a-d', 'evpn_nlri_mac_ip_ad', 'evpn_nlri_inc_multi_eth_tag', 'evpn_nlri_eth_seg', 'evpn_nlri_ip_prefix', 'flowspec_nlri_ipv4', 'flowspec_nlri_vpn4', 'flowspec_nlri_ipv6', 'flowspec_nlri_vpn6', 'flowspec_nlri_l2vpn', 'flowspec_action_traffic_rate', 'flowspec_action_traffic_action', 'flowspec_action_redirect', 'flowspec_action_traffic_marking', ] for f in files: LOG.debug('*** testing %s ...', f) for _, buf in pcaplib.Reader( open(BGP4_PACKET_DATA_DIR + f + '.pcap', 'rb')): # Checks if BGP message can be parsed as expected. pkt = packet.Packet(buf) self.assertTrue(isinstance(pkt.protocols[-1], bgp.BGPMessage), 'Failed to parse BGP message: %s' % pkt) # Checks if BGP message can be serialized as expected. pkt.serialize() self.assertEqual(buf, pkt.data, "b'%s' != b'%s'" % (binary_str(buf), binary_str(pkt.data))) def test_vlan_action_parser(self): action = bgp.BGPFlowSpecVlanActionCommunity( actions_1=(bgp.BGPFlowSpecVlanActionCommunity.POP | bgp.BGPFlowSpecVlanActionCommunity.SWAP), vlan_1=3000, cos_1=3, actions_2=bgp.BGPFlowSpecVlanActionCommunity.PUSH, vlan_2=4000, cos_2=2, ) binmsg = action.serialize() msg, rest = bgp.BGPFlowSpecVlanActionCommunity.parse(binmsg) self.assertEqual(str(action), str(msg)) self.assertEqual(rest, b'') def test_tpid_action_parser(self): action = bgp.BGPFlowSpecTPIDActionCommunity( actions=(bgp.BGPFlowSpecTPIDActionCommunity.TI | bgp.BGPFlowSpecTPIDActionCommunity.TO), tpid_1=5, tpid_2=6, ) binmsg = action.serialize() msg, rest = bgp.BGPFlowSpecTPIDActionCommunity.parse(binmsg) self.assertEqual(str(action), str(msg)) self.assertEqual(rest, b'') def test_json1(self): opt_param = [bgp.BGPOptParamCapabilityUnknown(cap_code=200, cap_value=b'hoge'), bgp.BGPOptParamCapabilityRouteRefresh(), bgp.BGPOptParamCapabilityMultiprotocol( afi=afi.IP, safi=safi.MPLS_VPN), bgp.BGPOptParamCapabilityFourOctetAsNumber( as_number=1234567), bgp.BGPOptParamUnknown(type_=99, value=b'fuga')] msg1 = bgp.BGPOpen(my_as=30000, bgp_identifier='192.0.2.2', opt_param=opt_param) jsondict = msg1.to_jsondict() msg2 = bgp.BGPOpen.from_jsondict(jsondict['BGPOpen']) self.assertEqual(str(msg1), str(msg2)) def test_json2(self): withdrawn_routes = [bgp.BGPWithdrawnRoute(length=0, addr='192.0.2.13'), bgp.BGPWithdrawnRoute(length=1, addr='192.0.2.13'), bgp.BGPWithdrawnRoute(length=3, addr='192.0.2.13'), bgp.BGPWithdrawnRoute(length=7, addr='192.0.2.13'), bgp.BGPWithdrawnRoute(length=32, addr='192.0.2.13')] mp_nlri = [ bgp.LabelledVPNIPAddrPrefix(24, '192.0.9.0', route_dist='100:100', labels=[1, 2, 3]), bgp.LabelledVPNIPAddrPrefix(26, '192.0.10.192', route_dist='10.0.0.1:10000', labels=[5, 6, 7, 8]), ] mp_nlri2 = [ bgp.LabelledIPAddrPrefix(24, '192.168.0.0', labels=[1, 2, 3]) ] mp_nlri_v6 = [ bgp.LabelledVPNIP6AddrPrefix(64, '2001:db8:1111::', route_dist='200:200', labels=[1, 2, 3]), bgp.LabelledVPNIP6AddrPrefix(64, '2001:db8:2222::', route_dist='10.0.0.1:10000', labels=[5, 6, 7, 8]), ] mp_nlri2_v6 = [ bgp.LabelledIP6AddrPrefix(64, '2001:db8:3333::', labels=[1, 2, 3]) ] communities = [ bgp.BGP_COMMUNITY_NO_EXPORT, bgp.BGP_COMMUNITY_NO_ADVERTISE, ] ecommunities = [ bgp.BGPTwoOctetAsSpecificExtendedCommunity( subtype=1, as_number=65500, local_administrator=3908876543), bgp.BGPFourOctetAsSpecificExtendedCommunity( subtype=2, as_number=10000000, local_administrator=59876), bgp.BGPIPv4AddressSpecificExtendedCommunity( subtype=3, ipv4_address='192.0.2.1', local_administrator=65432), bgp.BGPOpaqueExtendedCommunity(subtype=13, opaque=b'abcdef'), bgp.BGPEncapsulationExtendedCommunity( subtype=0x0c, tunnel_type=10), bgp.BGPEvpnMacMobilityExtendedCommunity( subtype=0, flags=0xff, sequence_number=0x11223344), bgp.BGPEvpnEsiLabelExtendedCommunity( subtype=1, flags=0xff, label=b'\xFF\xFF\xFF'), bgp.BGPEvpnEsiLabelExtendedCommunity( subtype=1, flags=0xff, mpls_label=0xfffff), bgp.BGPEvpnEsiLabelExtendedCommunity( subtype=1, flags=0xff, vni=0xffffff), bgp.BGPEvpnEsImportRTExtendedCommunity( subtype=2, es_import="aa:bb:cc:dd:ee:ff"), bgp.BGPUnknownExtendedCommunity(type_=99, value=b'abcdefg'), ] path_attributes = [ bgp.BGPPathAttributeOrigin(value=1), bgp.BGPPathAttributeAsPath(value=[[1000], {1001, 1002}, [1003, 1004]]), bgp.BGPPathAttributeNextHop(value='192.0.2.199'), bgp.BGPPathAttributeMultiExitDisc(value=2000000000), bgp.BGPPathAttributeLocalPref(value=1000000000), bgp.BGPPathAttributeAtomicAggregate(), bgp.BGPPathAttributeAggregator(as_number=40000, addr='192.0.2.99'), bgp.BGPPathAttributeCommunities(communities=communities), bgp.BGPPathAttributeExtendedCommunities(communities=ecommunities), bgp.BGPPathAttributePmsiTunnel( pmsi_flags=1, tunnel_type=PMSI_TYPE_NO_TUNNEL_INFORMATION_PRESENT, label=b'\xFF\xFF\xFF'), bgp.BGPPathAttributePmsiTunnel( pmsi_flags=1, tunnel_type=PMSI_TYPE_NO_TUNNEL_INFORMATION_PRESENT, tunnel_id=None), bgp.BGPPathAttributePmsiTunnel( pmsi_flags=1, tunnel_type=PMSI_TYPE_INGRESS_REPLICATION, mpls_label=0xfffff, tunnel_id=bgp.PmsiTunnelIdIngressReplication( tunnel_endpoint_ip="1.1.1.1")), bgp.BGPPathAttributePmsiTunnel( pmsi_flags=1, tunnel_type=PMSI_TYPE_INGRESS_REPLICATION, vni=0xffffff, tunnel_id=bgp.PmsiTunnelIdIngressReplication( tunnel_endpoint_ip="aa:bb:cc::dd:ee:ff")), bgp.BGPPathAttributePmsiTunnel( pmsi_flags=1, tunnel_type=2, label=b'\xFF\xFF\xFF', tunnel_id=bgp.PmsiTunnelIdUnknown(value=b'test')), bgp.BGPPathAttributeAs4Path(value=[[1000000], {1000001, 1002}, [1003, 1000004]]), bgp.BGPPathAttributeAs4Aggregator(as_number=100040000, addr='192.0.2.99'), bgp.BGPPathAttributeMpReachNLRI(afi=afi.IP, safi=safi.MPLS_VPN, next_hop='1.1.1.1', nlri=mp_nlri), bgp.BGPPathAttributeMpReachNLRI(afi=afi.IP, safi=safi.MPLS_LABEL, next_hop='1.1.1.1', nlri=mp_nlri2), bgp.BGPPathAttributeMpReachNLRI(afi=afi.IP6, safi=safi.MPLS_VPN, next_hop=['2001:db8::1'], nlri=mp_nlri_v6), bgp.BGPPathAttributeMpReachNLRI(afi=afi.IP6, safi=safi.MPLS_LABEL, next_hop=['2001:db8::1', 'fe80::1'], nlri=mp_nlri2_v6), bgp.BGPPathAttributeMpUnreachNLRI(afi=afi.IP, safi=safi.MPLS_VPN, withdrawn_routes=mp_nlri), bgp.BGPPathAttributeUnknown(flags=0, type_=100, value=300 * b'bar') ] nlri = [ bgp.BGPNLRI(length=24, addr='203.0.113.1'), bgp.BGPNLRI(length=16, addr='203.0.113.0') ] msg1 = bgp.BGPUpdate(withdrawn_routes=withdrawn_routes, path_attributes=path_attributes, nlri=nlri) jsondict = msg1.to_jsondict() msg2 = bgp.BGPUpdate.from_jsondict(jsondict['BGPUpdate']) self.assertEqual(str(msg1), str(msg2)) def test_flowspec_user_interface_ipv4(self): rules = RULES_BASE + [ # dst_prefix='10.0.0.0/24 bgp.FlowSpecDestPrefix(addr='10.0.0.0', length=24), # src_prefix='20.0.0.1/24' bgp.FlowSpecSrcPrefix(addr='20.0.0.0', length=24), # ip_proto='6' bgp.FlowSpecIPProtocol( operator=bgp.FlowSpecIPProtocol.EQ, value=6), # fragment='LF' bgp.FlowSpecFragment( operator=0, # Partial match value=bgp.FlowSpecFragment.LF), # fragment='==FF' bgp.FlowSpecFragment( operator=bgp.FlowSpecFragment.MATCH, value=bgp.FlowSpecFragment.FF), # fragment='&==ISF' bgp.FlowSpecFragment( operator=(bgp.FlowSpecFragment.AND | bgp.FlowSpecFragment.MATCH), value=bgp.FlowSpecFragment.ISF), # fragment='!=DF' bgp.FlowSpecFragment( operator=bgp.FlowSpecFragment.NOT, value=bgp.FlowSpecFragment.DF) ] msg = bgp.FlowSpecIPv4NLRI.from_user( dst_prefix='10.0.0.0/24', src_prefix='20.0.0.0/24', ip_proto='6', port='>=8000 & <=9000 | ==80', dst_port='8080 >9000&<9050 | <=1000', src_port='<=9090 & >=9080 <10100 & >10000', icmp_type=0, icmp_code=6, tcp_flags='SYN+ACK & !=URGENT', packet_len='1000 & 1100', dscp='22 24', fragment='LF ==FF&==ISF | !=DF') msg2 = bgp.FlowSpecIPv4NLRI(rules=rules) binmsg = msg.serialize() binmsg2 = msg2.serialize() self.assertEqual(str(msg), str(msg2)) self.assertEqual(binary_str(binmsg), binary_str(binmsg2)) msg3, rest = bgp.FlowSpecIPv4NLRI.parser(binmsg) self.assertEqual(str(msg), str(msg3)) self.assertEqual(rest, b'') def test_flowspec_user_interface_vpv4(self): rules = RULES_BASE + [ # dst_prefix='10.0.0.0/24 bgp.FlowSpecDestPrefix(addr='10.0.0.0', length=24), # src_prefix='20.0.0.1/24' bgp.FlowSpecSrcPrefix(addr='20.0.0.0', length=24), # ip_proto='6' bgp.FlowSpecIPProtocol( operator=bgp.FlowSpecIPProtocol.EQ, value=6), # fragment='LF' bgp.FlowSpecFragment( operator=0, # Partial match value=bgp.FlowSpecFragment.LF), # fragment='==FF' bgp.FlowSpecFragment( operator=bgp.FlowSpecFragment.MATCH, value=bgp.FlowSpecFragment.FF), # fragment='&==ISF' bgp.FlowSpecFragment( operator=(bgp.FlowSpecFragment.AND | bgp.FlowSpecFragment.MATCH), value=bgp.FlowSpecFragment.ISF), # fragment='!=DF' bgp.FlowSpecFragment( operator=bgp.FlowSpecFragment.NOT, value=bgp.FlowSpecFragment.DF) ] msg = bgp.FlowSpecVPNv4NLRI.from_user( route_dist='65001:250', dst_prefix='10.0.0.0/24', src_prefix='20.0.0.0/24', ip_proto='6', port='>=8000 & <=9000 | ==80', dst_port='8080 >9000&<9050 | <=1000', src_port='<=9090 & >=9080 <10100 & >10000', icmp_type=0, icmp_code=6, tcp_flags='SYN+ACK & !=URGENT', packet_len='1000 & 1100', dscp='22 24', fragment='LF ==FF&==ISF | !=DF') msg2 = bgp.FlowSpecVPNv4NLRI(route_dist='65001:250', rules=rules) binmsg = msg.serialize() binmsg2 = msg2.serialize() self.assertEqual(str(msg), str(msg2)) self.assertEqual(binary_str(binmsg), binary_str(binmsg2)) msg3, rest = bgp.FlowSpecVPNv4NLRI.parser(binmsg) self.assertEqual(str(msg), str(msg3)) self.assertEqual(rest, b'') def test_flowspec_user_interface_ipv6(self): rules = RULES_BASE + [ # dst_prefix='2001:2/128/32' bgp.FlowSpecIPv6DestPrefix( addr='2001::2', offset=32, length=128), # src_prefix='3002::3/128' bgp.FlowSpecIPv6SrcPrefix( addr='3002::3', length=128), # ip_proto='6' bgp.FlowSpecNextHeader( operator=bgp.FlowSpecNextHeader.EQ, value=6), # fragment='LF' bgp.FlowSpecIPv6Fragment( operator=0, # Partial match value=bgp.FlowSpecFragment.LF), # fragment='==FF' bgp.FlowSpecIPv6Fragment( operator=bgp.FlowSpecFragment.MATCH, value=bgp.FlowSpecFragment.FF), # fragment='&==ISF' bgp.FlowSpecIPv6Fragment( operator=(bgp.FlowSpecFragment.AND | bgp.FlowSpecFragment.MATCH), value=bgp.FlowSpecFragment.ISF), # fragment='!=LF' bgp.FlowSpecIPv6Fragment( operator=bgp.FlowSpecFragment.NOT, value=bgp.FlowSpecFragment.LF), # flowlabel='100' bgp.FlowSpecIPv6FlowLabel( operator=bgp.FlowSpecIPv6FlowLabel.EQ, value=100), ] msg = bgp.FlowSpecIPv6NLRI.from_user( dst_prefix='2001::2/128/32', src_prefix='3002::3/128', next_header='6', port='>=8000 & <=9000 | ==80', dst_port='8080 >9000&<9050 | <=1000', src_port='<=9090 & >=9080 <10100 & >10000', icmp_type=0, icmp_code=6, tcp_flags='SYN+ACK & !=URGENT', packet_len='1000 & 1100', dscp='22 24', fragment='LF ==FF&==ISF | !=LF', flow_label=100, ) msg2 = bgp.FlowSpecIPv6NLRI(rules=rules) binmsg = msg.serialize() binmsg2 = msg2.serialize() self.assertEqual(str(msg), str(msg2)) self.assertEqual(binary_str(binmsg), binary_str(binmsg2)) msg3, rest = bgp.FlowSpecIPv6NLRI.parser(binmsg) self.assertEqual(str(msg), str(msg3)) self.assertEqual(rest, b'') def test_flowspec_user_interface_vpnv6(self): rules = RULES_BASE + [ # dst_prefix='2001:2/128/32' bgp.FlowSpecIPv6DestPrefix( addr='2001::2', offset=32, length=128), # src_prefix='3002::3/128' bgp.FlowSpecIPv6SrcPrefix( addr='3002::3', length=128), # ip_proto='6' bgp.FlowSpecNextHeader( operator=bgp.FlowSpecNextHeader.EQ, value=6), # fragment='LF' bgp.FlowSpecIPv6Fragment( operator=0, # Partial match value=bgp.FlowSpecFragment.LF), # fragment='==FF' bgp.FlowSpecIPv6Fragment( operator=bgp.FlowSpecFragment.MATCH, value=bgp.FlowSpecFragment.FF), # fragment='&==ISF' bgp.FlowSpecIPv6Fragment( operator=(bgp.FlowSpecFragment.AND | bgp.FlowSpecFragment.MATCH), value=bgp.FlowSpecFragment.ISF), # fragment='!=LF' bgp.FlowSpecIPv6Fragment( operator=bgp.FlowSpecFragment.NOT, value=bgp.FlowSpecFragment.LF), # flowlabel='100' bgp.FlowSpecIPv6FlowLabel( operator=bgp.FlowSpecIPv6FlowLabel.EQ, value=100), ] msg = bgp.FlowSpecVPNv6NLRI.from_user( route_dist='65001:250', dst_prefix='2001::2/128/32', src_prefix='3002::3/128', next_header='6', port='>=8000 & <=9000 | ==80', dst_port='8080 >9000&<9050 | <=1000', src_port='<=9090 & >=9080 <10100 & >10000', icmp_type=0, icmp_code=6, tcp_flags='SYN+ACK & !=URGENT', packet_len='1000 & 1100', dscp='22 24', fragment='LF ==FF&==ISF | !=LF', flow_label=100, ) msg2 = bgp.FlowSpecVPNv6NLRI(route_dist='65001:250', rules=rules) binmsg = msg.serialize() binmsg2 = msg2.serialize() self.assertEqual(str(msg), str(msg2)) self.assertEqual(binary_str(binmsg), binary_str(binmsg2)) msg3, rest = bgp.FlowSpecVPNv6NLRI.parser(binmsg) self.assertEqual(str(msg), str(msg3)) self.assertEqual(rest, b'') def test_flowspec_user_interface_l2vpn(self): rules = RULES_L2VPN_BASE msg = bgp.FlowSpecL2VPNNLRI.from_user( route_dist='65001:250', ether_type=0x0800, src_mac='12:34:56:78:90:AB', dst_mac='BE:EF:C0:FF:EE:DD', llc_dsap=0x42, llc_ssap=0x42, llc_control=100, snap=0x12345, vlan_id='>4000', vlan_cos='>=3', inner_vlan_id='<3000', inner_vlan_cos='<=5', ) msg2 = bgp.FlowSpecL2VPNNLRI(route_dist='65001:250', rules=rules) binmsg = msg.serialize() binmsg2 = msg2.serialize() self.assertEqual(str(msg), str(msg2)) self.assertEqual(binary_str(binmsg), binary_str(binmsg2)) msg3, rest = bgp.FlowSpecL2VPNNLRI.parser(binmsg) self.assertEqual(str(msg), str(msg3)) self.assertEqual(rest, b'') ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/packet/test_bmp.py0000664000175000017500000001623300000000000022053 0ustar00zuulzuul00000000000000# Copyright (C) 2014 Nippon Telegraph and Telephone 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. import unittest from time import time from os_ken.lib.packet import bmp from os_ken.lib.packet import bgp from os_ken.lib.packet import afi from os_ken.lib.packet import safi class Test_bmp(unittest.TestCase): """ Test case for os_ken.lib.packet.bmp """ def setUp(self): pass def tearDown(self): pass def _time(self): # time() can give sub-microsecond precision, which results # in an assertion failure return round(time(), 6) def test_route_monitoring(self): update = bgp.BGPUpdate() msg = bmp.BMPRouteMonitoring(bgp_update=update, peer_type=bmp.BMP_PEER_TYPE_GLOBAL, is_post_policy=True, peer_distinguisher=0, peer_address='192.0.2.1', peer_as=30000, peer_bgp_id='192.0.2.1', timestamp=self._time()) binmsg = msg.serialize() msg2, rest = bmp.BMPMessage.parser(binmsg) self.assertEqual(msg.to_jsondict(), msg2.to_jsondict()) self.assertEqual(rest, b'') def test_route_monitoring_adj_rib_out(self): update = bgp.BGPUpdate() msg = bmp.BMPRouteMonitoring(bgp_update=update, peer_type=bmp.BMP_PEER_TYPE_GLOBAL, is_post_policy=True, is_adj_rib_out=True, peer_distinguisher=0, peer_address='192.0.2.1', peer_as=30000, peer_bgp_id='192.0.2.1', timestamp=self._time()) binmsg = msg.serialize() msg2, rest = bmp.BMPMessage.parser(binmsg) self.assertEqual(msg.to_jsondict(), msg2.to_jsondict()) self.assertEqual(rest, b'') def test_statistics_report(self): stats = [{'type': bmp.BMP_STAT_TYPE_REJECTED, 'value': 100}, {'type': bmp.BMP_STAT_TYPE_DUPLICATE_PREFIX, 'value': 200}, {'type': bmp.BMP_STAT_TYPE_DUPLICATE_WITHDRAW, 'value': 300}, {'type': bmp.BMP_STAT_TYPE_ADJ_RIB_IN, 'value': 100000}, {'type': bmp.BMP_STAT_TYPE_LOC_RIB, 'value': 500000}, {'type': bmp.BMP_STAT_TYPE_ADJ_RIB_OUT, 'value': 95000}, {'type': bmp.BMP_STAT_TYPE_EXPORT_RIB, 'value': 50000}, {'type': bmp.BMP_STAT_TYPE_EXPORT_RIB, 'value': 50000}] msg = bmp.BMPStatisticsReport(stats=stats, peer_type=bmp.BMP_PEER_TYPE_GLOBAL, is_post_policy=True, peer_distinguisher=0, peer_address='192.0.2.1', peer_as=30000, peer_bgp_id='192.0.2.1', timestamp=self._time()) binmsg = msg.serialize() msg2, rest = bmp.BMPMessage.parser(binmsg) self.assertEqual(msg.to_jsondict(), msg2.to_jsondict()) self.assertEqual(rest, b'') def test_peer_down_notification(self): reason = bmp.BMP_PEER_DOWN_REASON_LOCAL_BGP_NOTIFICATION data = b'hoge' data = bgp.BGPNotification(error_code=1, error_subcode=2, data=data) msg = bmp.BMPPeerDownNotification(reason=reason, data=data, peer_type=bmp.BMP_PEER_TYPE_GLOBAL, is_post_policy=True, peer_distinguisher=0, peer_address='192.0.2.1', peer_as=30000, peer_bgp_id='192.0.2.1', timestamp=self._time()) binmsg = msg.serialize() msg2, rest = bmp.BMPMessage.parser(binmsg) self.assertEqual(msg.to_jsondict(), msg2.to_jsondict()) self.assertEqual(rest, b'') def test_peer_up_notification(self): opt_param = [bgp.BGPOptParamCapabilityUnknown(cap_code=200, cap_value=b'hoge'), bgp.BGPOptParamCapabilityRouteRefresh(), bgp.BGPOptParamCapabilityMultiprotocol( afi=afi.IP, safi=safi.MPLS_VPN)] open_message = bgp.BGPOpen(my_as=40000, bgp_identifier='192.0.2.2', opt_param=opt_param) msg = bmp.BMPPeerUpNotification(local_address='192.0.2.2', local_port=179, remote_port=11089, sent_open_message=open_message, received_open_message=open_message, peer_type=bmp.BMP_PEER_TYPE_GLOBAL, is_post_policy=True, peer_distinguisher=0, peer_address='192.0.2.1', peer_as=30000, peer_bgp_id='192.0.2.1', timestamp=self._time()) binmsg = msg.serialize() msg2, rest = bmp.BMPMessage.parser(binmsg) self.assertEqual(msg.to_jsondict(), msg2.to_jsondict()) self.assertEqual(rest, b'') def test_initiation(self): initiation_info = [{'type': bmp.BMP_INIT_TYPE_STRING, 'value': 'This is OSKen BGP BMP message'}] msg = bmp.BMPInitiation(info=initiation_info) binmsg = msg.serialize() msg2, rest = bmp.BMPMessage.parser(binmsg) self.assertEqual(msg.to_jsondict(lambda v: v), msg2.to_jsondict(lambda v: v)) self.assertEqual(rest, b'') def test_termination(self): termination_info = [{'type': bmp.BMP_TERM_TYPE_STRING, 'value': u'Session administatively closed'}, {'type': bmp.BMP_TERM_TYPE_REASON, 'value': bmp.BMP_TERM_REASON_ADMIN}] msg = bmp.BMPTermination(info=termination_info) binmsg = msg.serialize() msg2, rest = bmp.BMPMessage.parser(binmsg) self.assertEqual(msg.to_jsondict(lambda v: v), msg2.to_jsondict(lambda v: v)) self.assertEqual(rest, b'') ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/packet/test_bpdu.py0000664000175000017500000005142600000000000022232 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone 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. # vim: tabstop=4 shiftwidth=4 softtabstop=4 import unittest import logging import struct from os_ken.lib.packet import bpdu LOG = logging.getLogger(__name__) class Test_ConfigurationBPDUs(unittest.TestCase): """ Test case for ConfigurationBPDUs """ def setUp(self): self.protocol_id = bpdu.PROTOCOL_IDENTIFIER self.version_id = bpdu.ConfigurationBPDUs.VERSION_ID self.bpdu_type = bpdu.ConfigurationBPDUs.BPDU_TYPE self.flags = 0b00000001 self.root_priority = 4096 self.root_system_id_extension = 1 self.root_mac_address = '12:34:56:78:9a:bc' self.root_path_cost = 2 self.bridge_priority = 8192 self.bridge_system_id_extension = 3 self.bridge_mac_address = 'aa:aa:aa:aa:aa:aa' self.port_priority = 16 self.port_number = 4 self.message_age = 5 self.max_age = 6 self.hello_time = 7 self.forward_delay = 8 self.msg = bpdu.ConfigurationBPDUs( flags=self.flags, root_priority=self.root_priority, root_system_id_extension=self.root_system_id_extension, root_mac_address=self.root_mac_address, root_path_cost=self.root_path_cost, bridge_priority=self.bridge_priority, bridge_system_id_extension=self.bridge_system_id_extension, bridge_mac_address=self.bridge_mac_address, port_priority=self.port_priority, port_number=self.port_number, message_age=self.message_age, max_age=self.max_age, hello_time=self.hello_time, forward_delay=self.forward_delay) self.fmt = (bpdu.bpdu._PACK_STR + bpdu.ConfigurationBPDUs._PACK_STR[1:]) self.buf = struct.pack(self.fmt, self.protocol_id, self.version_id, self.bpdu_type, self.flags, bpdu.ConfigurationBPDUs.encode_bridge_id( self.root_priority, self.root_system_id_extension, self.root_mac_address), self.root_path_cost, bpdu.ConfigurationBPDUs.encode_bridge_id( self.bridge_priority, self.bridge_system_id_extension, self.bridge_mac_address), bpdu.ConfigurationBPDUs.encode_port_id( self.port_priority, self.port_number), bpdu.ConfigurationBPDUs._encode_timer( self.message_age), bpdu.ConfigurationBPDUs._encode_timer( self.max_age), bpdu.ConfigurationBPDUs._encode_timer( self.hello_time), bpdu.ConfigurationBPDUs._encode_timer( self.forward_delay)) def test_init(self): self.assertEqual(self.protocol_id, self.msg._protocol_id) self.assertEqual(self.version_id, self.msg._version_id) self.assertEqual(self.bpdu_type, self.msg._bpdu_type) self.assertEqual(self.flags, self.msg.flags) self.assertEqual(self.root_priority, self.msg.root_priority) self.assertEqual(self.root_system_id_extension, self.msg.root_system_id_extension) self.assertEqual(self.root_mac_address, self.msg.root_mac_address) self.assertEqual(self.root_path_cost, self.msg.root_path_cost) self.assertEqual(self.bridge_priority, self.msg.bridge_priority) self.assertEqual(self.bridge_system_id_extension, self.msg.bridge_system_id_extension) self.assertEqual(self.bridge_mac_address, self.msg.bridge_mac_address) self.assertEqual(self.port_priority, self.msg.port_priority) self.assertEqual(self.port_number, self.msg.port_number) self.assertEqual(self.message_age, self.msg.message_age) self.assertEqual(self.max_age, self.msg.max_age) self.assertEqual(self.hello_time, self.msg.hello_time) self.assertEqual(self.forward_delay, self.msg.forward_delay) def test_parser(self): r1, r2, _ = bpdu.bpdu.parser(self.buf) self.assertEqual(type(r1), type(self.msg)) self.assertEqual(r1._protocol_id, self.protocol_id) self.assertEqual(r1._version_id, self.version_id) self.assertEqual(r1._bpdu_type, self.bpdu_type) self.assertEqual(r1.flags, self.flags) self.assertEqual(r1.root_priority, self.root_priority) self.assertEqual(r1.root_system_id_extension, self.root_system_id_extension) self.assertEqual(r1.root_mac_address, self.root_mac_address) self.assertEqual(r1.root_path_cost, self.root_path_cost) self.assertEqual(r1.bridge_priority, self.bridge_priority) self.assertEqual(r1.bridge_system_id_extension, self.bridge_system_id_extension) self.assertEqual(r1.bridge_mac_address, self.bridge_mac_address) self.assertEqual(r1.port_priority, self.port_priority) self.assertEqual(r1.port_number, self.port_number) self.assertEqual(r1.message_age, self.message_age) self.assertEqual(r1.max_age, self.max_age) self.assertEqual(r1.hello_time, self.hello_time) self.assertEqual(r1.forward_delay, self.forward_delay) self.assertEqual(r2, None) def test_serialize(self): data = bytearray() prev = None buf = self.msg.serialize(data, prev) res = struct.unpack(self.fmt, buf) self.assertEqual(res[0], self.protocol_id) self.assertEqual(res[1], self.version_id) self.assertEqual(res[2], self.bpdu_type) self.assertEqual(res[3], self.flags) self.assertEqual(bpdu.ConfigurationBPDUs._decode_bridge_id(res[4]), (self.root_priority, self.root_system_id_extension, self.root_mac_address)) self.assertEqual(res[5], self.root_path_cost) self.assertEqual(bpdu.ConfigurationBPDUs._decode_bridge_id(res[6]), (self.bridge_priority, self.bridge_system_id_extension, self.bridge_mac_address)) self.assertEqual(bpdu.ConfigurationBPDUs._decode_port_id(res[7]), (self.port_priority, self.port_number)) self.assertEqual(bpdu.ConfigurationBPDUs._decode_timer(res[8]), self.message_age) self.assertEqual(bpdu.ConfigurationBPDUs._decode_timer(res[9]), self.max_age) self.assertEqual(bpdu.ConfigurationBPDUs._decode_timer(res[10]), self.hello_time) self.assertEqual(bpdu.ConfigurationBPDUs._decode_timer(res[11]), self.forward_delay) def test_json(self): jsondict = self.msg.to_jsondict() msg = bpdu.ConfigurationBPDUs.from_jsondict( jsondict['ConfigurationBPDUs']) self.assertEqual(str(self.msg), str(msg)) class Test_TopologyChangeNotificationBPDUs(unittest.TestCase): """ Test case for TopologyChangeNotificationBPDUs """ def setUp(self): self.protocol_id = bpdu.PROTOCOL_IDENTIFIER self.version_id = bpdu.TopologyChangeNotificationBPDUs.VERSION_ID self.bpdu_type = bpdu.TopologyChangeNotificationBPDUs.BPDU_TYPE self.msg = bpdu.TopologyChangeNotificationBPDUs() self.fmt = bpdu.bpdu._PACK_STR self.buf = struct.pack(self.fmt, self.protocol_id, self.version_id, self.bpdu_type) def test_init(self): self.assertEqual(self.protocol_id, self.msg._protocol_id) self.assertEqual(self.version_id, self.msg._version_id) self.assertEqual(self.bpdu_type, self.msg._bpdu_type) def test_parser(self): r1, r2, _ = bpdu.bpdu.parser(self.buf) self.assertEqual(type(r1), type(self.msg)) self.assertEqual(r1._protocol_id, self.protocol_id) self.assertEqual(r1._version_id, self.version_id) self.assertEqual(r1._bpdu_type, self.bpdu_type) self.assertEqual(r2, None) def test_serialize(self): data = bytearray() prev = None buf = self.msg.serialize(data, prev) res = struct.unpack(self.fmt, buf) self.assertEqual(res[0], self.protocol_id) self.assertEqual(res[1], self.version_id) self.assertEqual(res[2], self.bpdu_type) def test_json(self): jsondict = self.msg.to_jsondict() msg = bpdu.TopologyChangeNotificationBPDUs.from_jsondict( jsondict['TopologyChangeNotificationBPDUs']) self.assertEqual(str(self.msg), str(msg)) class Test_RstBPDUs(unittest.TestCase): """ Test case for RstBPDUs """ def setUp(self): self.protocol_id = bpdu.PROTOCOL_IDENTIFIER self.version_id = bpdu.RstBPDUs.VERSION_ID self.bpdu_type = bpdu.RstBPDUs.BPDU_TYPE self.flags = 0b01111110 self.root_priority = 4096 self.root_system_id_extension = 1 self.root_mac_address = '12:34:56:78:9a:bc' self.root_path_cost = 2 self.bridge_priority = 8192 self.bridge_system_id_extension = 3 self.bridge_mac_address = 'aa:aa:aa:aa:aa:aa' self.port_priority = 16 self.port_number = 4 self.message_age = 5 self.max_age = 6 self.hello_time = 7 self.forward_delay = 8 self.version_1_length = bpdu.VERSION_1_LENGTH self.msg = bpdu.RstBPDUs( flags=self.flags, root_priority=self.root_priority, root_system_id_extension=self.root_system_id_extension, root_mac_address=self.root_mac_address, root_path_cost=self.root_path_cost, bridge_priority=self.bridge_priority, bridge_system_id_extension=self.bridge_system_id_extension, bridge_mac_address=self.bridge_mac_address, port_priority=self.port_priority, port_number=self.port_number, message_age=self.message_age, max_age=self.max_age, hello_time=self.hello_time, forward_delay=self.forward_delay) self.fmt = (bpdu.bpdu._PACK_STR + bpdu.ConfigurationBPDUs._PACK_STR[1:] + bpdu.RstBPDUs._PACK_STR[1:]) self.buf = struct.pack(self.fmt, self.protocol_id, self.version_id, self.bpdu_type, self.flags, bpdu.RstBPDUs.encode_bridge_id( self.root_priority, self.root_system_id_extension, self.root_mac_address), self.root_path_cost, bpdu.RstBPDUs.encode_bridge_id( self.bridge_priority, self.bridge_system_id_extension, self.bridge_mac_address), bpdu.RstBPDUs.encode_port_id( self.port_priority, self.port_number), bpdu.RstBPDUs._encode_timer(self.message_age), bpdu.RstBPDUs._encode_timer(self.max_age), bpdu.RstBPDUs._encode_timer(self.hello_time), bpdu.RstBPDUs._encode_timer(self.forward_delay), self.version_1_length) def test_init(self): self.assertEqual(self.protocol_id, self.msg._protocol_id) self.assertEqual(self.version_id, self.msg._version_id) self.assertEqual(self.bpdu_type, self.msg._bpdu_type) self.assertEqual(self.flags, self.msg.flags) self.assertEqual(self.root_priority, self.msg.root_priority) self.assertEqual(self.root_system_id_extension, self.msg.root_system_id_extension) self.assertEqual(self.root_mac_address, self.msg.root_mac_address) self.assertEqual(self.root_path_cost, self.msg.root_path_cost) self.assertEqual(self.bridge_priority, self.msg.bridge_priority) self.assertEqual(self.bridge_system_id_extension, self.msg.bridge_system_id_extension) self.assertEqual(self.bridge_mac_address, self.msg.bridge_mac_address) self.assertEqual(self.port_priority, self.msg.port_priority) self.assertEqual(self.port_number, self.msg.port_number) self.assertEqual(self.message_age, self.msg.message_age) self.assertEqual(self.max_age, self.msg.max_age) self.assertEqual(self.hello_time, self.msg.hello_time) self.assertEqual(self.forward_delay, self.msg.forward_delay) self.assertEqual(self.version_1_length, self.msg._version_1_length) def test_parser(self): r1, r2, _ = bpdu.bpdu.parser(self.buf) self.assertEqual(type(r1), type(self.msg)) self.assertEqual(r1._protocol_id, self.protocol_id) self.assertEqual(r1._version_id, self.version_id) self.assertEqual(r1._bpdu_type, self.bpdu_type) self.assertEqual(r1.flags, self.flags) self.assertEqual(r1.root_priority, self.root_priority) self.assertEqual(r1.root_system_id_extension, self.root_system_id_extension) self.assertEqual(r1.root_mac_address, self.root_mac_address) self.assertEqual(r1.root_path_cost, self.root_path_cost) self.assertEqual(r1.bridge_priority, self.bridge_priority) self.assertEqual(r1.bridge_system_id_extension, self.bridge_system_id_extension) self.assertEqual(r1.bridge_mac_address, self.bridge_mac_address) self.assertEqual(r1.port_priority, self.port_priority) self.assertEqual(r1.port_number, self.port_number) self.assertEqual(r1.message_age, self.message_age) self.assertEqual(r1.max_age, self.max_age) self.assertEqual(r1.hello_time, self.hello_time) self.assertEqual(r1.forward_delay, self.forward_delay) self.assertEqual(r1._version_1_length, self.version_1_length) self.assertEqual(r2, None) def test_serialize(self): data = bytearray() prev = None buf = self.msg.serialize(data, prev) res = struct.unpack(self.fmt, buf) self.assertEqual(res[0], self.protocol_id) self.assertEqual(res[1], self.version_id) self.assertEqual(res[2], self.bpdu_type) self.assertEqual(res[3], self.flags) self.assertEqual(bpdu.RstBPDUs._decode_bridge_id(res[4]), (self.root_priority, self.root_system_id_extension, self.root_mac_address)) self.assertEqual(res[5], self.root_path_cost) self.assertEqual(bpdu.RstBPDUs._decode_bridge_id(res[6]), (self.bridge_priority, self.bridge_system_id_extension, self.bridge_mac_address)) self.assertEqual(bpdu.RstBPDUs._decode_port_id(res[7]), (self.port_priority, self.port_number)) self.assertEqual(bpdu.RstBPDUs._decode_timer(res[8]), self.message_age) self.assertEqual(bpdu.RstBPDUs._decode_timer(res[9]), self.max_age) self.assertEqual(bpdu.RstBPDUs._decode_timer(res[10]), self.hello_time) self.assertEqual(bpdu.RstBPDUs._decode_timer(res[11]), self.forward_delay) self.assertEqual(res[12], self.version_1_length) def test_json(self): jsondict = self.msg.to_jsondict() msg = bpdu.RstBPDUs.from_jsondict(jsondict['RstBPDUs']) self.assertEqual(str(self.msg), str(msg)) class Test_UnknownVersion(unittest.TestCase): """ Test case for unknown BPDU version """ def setUp(self): self.protocol_id = bpdu.PROTOCOL_IDENTIFIER self.version_id = 111 # Unknown version self.bpdu_type = bpdu.RstBPDUs.BPDU_TYPE self.flags = 0b01111110 self.root_priority = 4096 self.root_system_id_extension = 1 self.root_mac_address = '12:34:56:78:9a:bc' self.root_path_cost = 2 self.bridge_priority = 8192 self.bridge_system_id_extension = 3 self.bridge_mac_address = 'aa:aa:aa:aa:aa:aa' self.port_priority = 16 self.port_number = 4 self.message_age = 5 self.max_age = 6 self.hello_time = 7 self.forward_delay = 8 self.version_1_length = bpdu.VERSION_1_LENGTH self.fmt = (bpdu.bpdu._PACK_STR + bpdu.ConfigurationBPDUs._PACK_STR[1:] + bpdu.RstBPDUs._PACK_STR[1:]) self.buf = struct.pack(self.fmt, self.protocol_id, self.version_id, self.bpdu_type, self.flags, bpdu.RstBPDUs.encode_bridge_id( self.root_priority, self.root_system_id_extension, self.root_mac_address), self.root_path_cost, bpdu.RstBPDUs.encode_bridge_id( self.bridge_priority, self.bridge_system_id_extension, self.bridge_mac_address), bpdu.RstBPDUs.encode_port_id( self.port_priority, self.port_number), bpdu.RstBPDUs._encode_timer(self.message_age), bpdu.RstBPDUs._encode_timer(self.max_age), bpdu.RstBPDUs._encode_timer(self.hello_time), bpdu.RstBPDUs._encode_timer(self.forward_delay), self.version_1_length) def test_parser(self): r1, r2, _ = bpdu.bpdu.parser(self.buf) self.assertEqual(r1, self.buf) self.assertEqual(r2, None) class Test_UnknownType(unittest.TestCase): """ Test case for unknown BPDU type """ def setUp(self): self.protocol_id = bpdu.PROTOCOL_IDENTIFIER self.version_id = bpdu.RstBPDUs.VERSION_ID self.bpdu_type = 222 # Unknown type self.flags = 0b01111110 self.root_priority = 4096 self.root_system_id_extension = 1 self.root_mac_address = '12:34:56:78:9a:bc' self.root_path_cost = 2 self.bridge_priority = 8192 self.bridge_system_id_extension = 3 self.bridge_mac_address = 'aa:aa:aa:aa:aa:aa' self.port_priority = 16 self.port_number = 4 self.message_age = 5 self.max_age = 6 self.hello_time = 7 self.forward_delay = 8 self.version_1_length = bpdu.VERSION_1_LENGTH self.fmt = (bpdu.bpdu._PACK_STR + bpdu.ConfigurationBPDUs._PACK_STR[1:] + bpdu.RstBPDUs._PACK_STR[1:]) self.buf = struct.pack(self.fmt, self.protocol_id, self.version_id, self.bpdu_type, self.flags, bpdu.RstBPDUs.encode_bridge_id( self.root_priority, self.root_system_id_extension, self.root_mac_address), self.root_path_cost, bpdu.RstBPDUs.encode_bridge_id( self.bridge_priority, self.bridge_system_id_extension, self.bridge_mac_address), bpdu.RstBPDUs.encode_port_id( self.port_priority, self.port_number), bpdu.RstBPDUs._encode_timer(self.message_age), bpdu.RstBPDUs._encode_timer(self.max_age), bpdu.RstBPDUs._encode_timer(self.hello_time), bpdu.RstBPDUs._encode_timer(self.forward_delay), self.version_1_length) def test_parser(self): r1, r2, _ = bpdu.bpdu.parser(self.buf) self.assertEqual(r1, self.buf) self.assertEqual(r2, None) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/packet/test_cfm.py0000664000175000017500000017453700000000000022056 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone 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. import unittest import logging import inspect import struct from os_ken.lib import addrconv from os_ken.lib.packet import cfm LOG = logging.getLogger(__name__) class Test_cfm(unittest.TestCase): def setUp(self): self.message = cfm.cc_message() self.ins = cfm.cfm(self.message) data = bytearray() prev = None self.buf = self.ins.serialize(data, prev) def setUp_cc_message(self): self.cc_message_md_lv = 1 self.cc_message_version = 1 self.cc_message_rdi = 1 self.cc_message_interval = 1 self.cc_message_seq_num = 123 self.cc_message_mep_id = 4 self.cc_message_md_name_format = 4 self.cc_message_md_name_length = 0 self.cc_message_md_name = b"hoge" self.cc_message_short_ma_name_format = 2 self.cc_message_short_ma_name_length = 0 self.cc_message_short_ma_name = b"pakeratta" self.cc_message_md_name_txfcf = 11 self.cc_message_md_name_rxfcb = 22 self.cc_message_md_name_txfcb = 33 self.cc_message_tlvs = [ cfm.sender_id_tlv(), cfm.port_status_tlv(), cfm.data_tlv(), cfm.interface_status_tlv(), cfm.reply_ingress_tlv(), cfm.reply_egress_tlv(), cfm.ltm_egress_identifier_tlv(), cfm.ltr_egress_identifier_tlv(), cfm.organization_specific_tlv(), ] self.message = cfm.cc_message( self.cc_message_md_lv, self.cc_message_version, self.cc_message_rdi, self.cc_message_interval, self.cc_message_seq_num, self.cc_message_mep_id, self.cc_message_md_name_format, self.cc_message_md_name_length, self.cc_message_md_name, self.cc_message_short_ma_name_format, self.cc_message_short_ma_name_length, self.cc_message_short_ma_name, self.cc_message_tlvs ) self.ins = cfm.cfm(self.message) data = bytearray() prev = None self.buf = self.ins.serialize(data, prev) def setUp_loopback_message(self): self.loopback_message_md_lv = 1 self.loopback_message_version = 1 self.loopback_message_transaction_id = 12345 self.loopback_message_tlvs = [ cfm.sender_id_tlv(), cfm.port_status_tlv(), cfm.data_tlv(), cfm.interface_status_tlv(), cfm.reply_ingress_tlv(), cfm.reply_egress_tlv(), cfm.ltm_egress_identifier_tlv(), cfm.ltr_egress_identifier_tlv(), cfm.organization_specific_tlv(), ] self.message = cfm.loopback_message( self.loopback_message_md_lv, self.loopback_message_version, self.loopback_message_transaction_id, self.loopback_message_tlvs) self.ins = cfm.cfm(self.message) data = bytearray() prev = None self.buf = self.ins.serialize(data, prev) def setUp_loopback_reply(self): self.loopback_reply_md_lv = 1 self.loopback_reply_version = 1 self.loopback_reply_transaction_id = 12345 self.loopback_reply_tlvs = [ cfm.sender_id_tlv(), cfm.port_status_tlv(), cfm.data_tlv(), cfm.interface_status_tlv(), cfm.reply_ingress_tlv(), cfm.reply_egress_tlv(), cfm.ltm_egress_identifier_tlv(), cfm.ltr_egress_identifier_tlv(), cfm.organization_specific_tlv(), ] self.message = cfm.loopback_reply( self.loopback_reply_md_lv, self.loopback_reply_version, self.loopback_reply_transaction_id, self.loopback_reply_tlvs) self.ins = cfm.cfm(self.message) data = bytearray() prev = None self.buf = self.ins.serialize(data, prev) def setUp_link_trace_message(self): self.link_trace_message_md_lv = 1 self.link_trace_message_version = 1 self.link_trace_message_use_fdb_only = 1 self.link_trace_message_transaction_id = 12345 self.link_trace_message_ttl = 123 self.link_trace_message_ltm_orig_addr = '11:22:33:44:55:66' self.link_trace_message_ltm_targ_addr = '77:88:99:aa:cc:dd' self.link_trace_message_tlvs = [ cfm.sender_id_tlv(), cfm.port_status_tlv(), cfm.data_tlv(), cfm.interface_status_tlv(), cfm.reply_ingress_tlv(), cfm.reply_egress_tlv(), cfm.ltm_egress_identifier_tlv(), cfm.ltr_egress_identifier_tlv(), cfm.organization_specific_tlv(), ] self.message = cfm.link_trace_message( self.link_trace_message_md_lv, self.link_trace_message_version, self.link_trace_message_use_fdb_only, self.link_trace_message_transaction_id, self.link_trace_message_ttl, self.link_trace_message_ltm_orig_addr, self.link_trace_message_ltm_targ_addr, self.link_trace_message_tlvs) self.ins = cfm.cfm(self.message) data = bytearray() prev = None self.buf = self.ins.serialize(data, prev) def setUp_link_trace_reply(self): self.link_trace_reply_md_lv = 1 self.link_trace_reply_version = 1 self.link_trace_reply_use_fdb_only = 1 self.link_trace_reply_fwd_yes = 0 self.link_trace_reply_terminal_mep = 1 self.link_trace_reply_transaction_id = 5432 self.link_trace_reply_ttl = 123 self.link_trace_reply_relay_action = 3 self.link_trace_reply_tlvs = [ cfm.sender_id_tlv(), cfm.port_status_tlv(), cfm.data_tlv(), cfm.interface_status_tlv(), cfm.reply_ingress_tlv(), cfm.reply_egress_tlv(), cfm.ltm_egress_identifier_tlv(), cfm.ltr_egress_identifier_tlv(), cfm.organization_specific_tlv(), ] self.message = cfm.link_trace_reply( self.link_trace_reply_md_lv, self.link_trace_reply_version, self.link_trace_reply_use_fdb_only, self.link_trace_reply_fwd_yes, self.link_trace_reply_terminal_mep, self.link_trace_reply_transaction_id, self.link_trace_reply_ttl, self.link_trace_reply_relay_action, self.link_trace_reply_tlvs) self.ins = cfm.cfm(self.message) data = bytearray() prev = None self.buf = self.ins.serialize(data, prev) def tearDown(self): pass def test_init(self): self.assertEqual(str(self.message), str(self.ins.op)) def test_init_cc_message(self): self.setUp_cc_message() self.test_init() def test_init_loopback_message(self): self.setUp_loopback_message() self.test_init() def test_init_loopback_reply(self): self.setUp_loopback_reply() self.test_init() def test_init_link_trace_message(self): self.setUp_link_trace_message() self.test_init() def test_init_link_trace_reply(self): self.setUp_link_trace_reply() self.test_init() def test_parser(self): _res = self.ins.parser(bytes(self.buf)) if type(_res) is tuple: res = _res[0] else: res = _res self.assertEqual(str(self.message), str(res.op)) def test_parser_with_cc_message(self): self.setUp_cc_message() self.test_parser() def test_parser_with_loopback_message(self): self.setUp_loopback_message() self.test_parser() def test_parser_with_loopback_reply(self): self.setUp_loopback_reply() self.test_parser() def test_parser_with_link_trace_message(self): self.setUp_link_trace_message() self.test_parser() def test_parser_with_link_trace_reply(self): self.setUp_link_trace_reply() self.test_parser() def test_serialize(self): pass def test_serialize_with_cc_message(self): self.setUp_cc_message() self.test_serialize() data = bytearray() prev = None buf = self.ins.serialize(data, prev) cc_message = cfm.cc_message.parser(bytes(buf)) self.assertEqual(repr(self.message), repr(cc_message)) def test_serialize_with_loopback_message(self): self.setUp_loopback_message() self.test_serialize() data = bytearray() prev = None buf = self.ins.serialize(data, prev) loopback_message = cfm.loopback_message.parser(bytes(buf)) self.assertEqual(repr(self.message), repr(loopback_message)) def test_serialize_with_loopback_reply(self): self.setUp_loopback_reply() self.test_serialize() data = bytearray() prev = None buf = self.ins.serialize(data, prev) loopback_reply = cfm.loopback_reply.parser(bytes(buf)) self.assertEqual(repr(self.message), repr(loopback_reply)) def test_serialize_with_link_trace_message(self): self.setUp_link_trace_message() self.test_serialize() data = bytearray() prev = None buf = self.ins.serialize(data, prev) link_trace_message = cfm.link_trace_message.parser(bytes(buf)) self.assertEqual(repr(self.message), repr(link_trace_message)) def test_serialize_with_link_trace_reply(self): self.setUp_link_trace_reply() self.test_serialize() data = bytearray() prev = None buf = self.ins.serialize(data, prev) link_trace_reply = cfm.link_trace_reply.parser(bytes(buf)) self.assertEqual(repr(self.message), repr(link_trace_reply)) def test_to_string(self): cfm_values = {'op': self.message} _cfm_str = ','.join(['%s=%s' % (k, cfm_values[k]) for k, v in inspect.getmembers(self.ins) if k in cfm_values]) cfm_str = '%s(%s)' % (cfm.cfm.__name__, _cfm_str) self.assertEqual(str(self.ins), cfm_str) self.assertEqual(repr(self.ins), cfm_str) def test_to_string_cc_message(self): self.setUp_cc_message() self.test_to_string() def test_to_string_loopback_message(self): self.setUp_loopback_message() self.test_to_string() def test_to_string_loopback_reply(self): self.setUp_loopback_reply() self.test_to_string() def test_to_string_link_trace_message(self): self.setUp_link_trace_message() self.test_to_string() def test_to_string_link_trace_reply(self): self.setUp_link_trace_reply() self.test_to_string() def test_len(self): pass def test_len_cc_message(self): self.setUp_cc_message() self.assertEqual(len(self.ins), 0 + len(self.message)) def test_len_loopback_message(self): self.setUp_loopback_message() self.assertEqual(len(self.ins), 0 + len(self.message)) def test_len_loopback_reply(self): self.setUp_loopback_reply() self.assertEqual(len(self.ins), 0 + len(self.message)) def test_len_link_trace_message(self): self.setUp_link_trace_message() self.assertEqual(len(self.ins), 0 + len(self.message)) def test_len_link_trace_reply(self): self.setUp_link_trace_reply() self.assertEqual(len(self.ins), 0 + len(self.message)) def test_default_args(self): pass def test_json(self): jsondict = self.ins.to_jsondict() ins = cfm.cfm.from_jsondict(jsondict['cfm']) self.assertEqual(str(self.ins), str(ins)) def test_json_with_cc_message(self): self.setUp_cc_message() self.test_json() def test_json_with_loopback_message(self): self.setUp_loopback_message() self.test_json() def test_json_with_loopback_reply(self): self.setUp_loopback_reply() self.test_json() def test_json_with_link_trace_message(self): self.setUp_link_trace_message() self.test_json() def test_json_with_link_trace_reply(self): self.setUp_link_trace_reply() self.test_json() class Test_cc_message(unittest.TestCase): def setUp(self): self.md_lv = 1 self.version = 1 self.opcode = cfm.CFM_CC_MESSAGE self.rdi = 1 self.interval = 5 self.first_tlv_offset = cfm.cc_message._TLV_OFFSET self.seq_num = 2 self.mep_id = 2 self.md_name_format = cfm.cc_message._MD_FMT_CHARACTER_STRING self.md_name_length = 3 self.md_name = b"foo" self.short_ma_name_format = 2 self.short_ma_name_length = 8 self.short_ma_name = b"hogehoge" self.tlvs = [ ] self.end_tlv = 0 self.ins = cfm.cc_message( self.md_lv, self.version, self.rdi, self.interval, self.seq_num, self.mep_id, self.md_name_format, self.md_name_length, self.md_name, self.short_ma_name_format, self.short_ma_name_length, self.short_ma_name, self.tlvs ) self.form = '!4BIH2B3s2B8s33x12x4xB' self.buf = struct.pack( self.form, (self.md_lv << 5) | self.version, self.opcode, (self.rdi << 7) | self.interval, self.first_tlv_offset, self.seq_num, self.mep_id, self.md_name_format, self.md_name_length, self.md_name, self.short_ma_name_format, self.short_ma_name_length, self.short_ma_name, self.end_tlv ) def tearDown(self): pass def test_init(self): self.assertEqual(self.md_lv, self.ins.md_lv) self.assertEqual(self.version, self.ins.version) self.assertEqual(self.rdi, self.ins.rdi) self.assertEqual(self.interval, self.ins.interval) self.assertEqual(self.seq_num, self.ins.seq_num) self.assertEqual(self.mep_id, self.ins.mep_id) self.assertEqual(self.md_name_format, self.ins.md_name_format) self.assertEqual(self.md_name_length, self.ins.md_name_length) self.assertEqual(self.md_name, self.ins.md_name) self.assertEqual(self.short_ma_name_format, self.ins.short_ma_name_format) self.assertEqual(self.short_ma_name_length, self.ins.short_ma_name_length) self.assertEqual(self.short_ma_name, self.ins.short_ma_name) self.assertEqual(self.tlvs, self.ins.tlvs) def test_parser(self): _res = cfm.cc_message.parser(self.buf) if type(_res) is tuple: res = _res[0] else: res = _res self.assertEqual(self.md_lv, res.md_lv) self.assertEqual(self.version, res.version) self.assertEqual(self.rdi, res.rdi) self.assertEqual(self.interval, res.interval) self.assertEqual(self.seq_num, res.seq_num) self.assertEqual(self.mep_id, res.mep_id) self.assertEqual(self.md_name_format, res.md_name_format) self.assertEqual(self.md_name_length, res.md_name_length) self.assertEqual(self.md_name, res.md_name) self.assertEqual(self.short_ma_name_format, res.short_ma_name_format) self.assertEqual(self.short_ma_name_length, res.short_ma_name_length) self.assertEqual(self.short_ma_name, res.short_ma_name) self.assertEqual(self.tlvs, res.tlvs) def test_parser_with_no_maintenance_domain_name_present(self): form = '!4BIH3B8s37x12x4xB' buf = struct.pack( form, (self.md_lv << 5) | self.version, self.opcode, (self.rdi << 7) | self.interval, self.first_tlv_offset, self.seq_num, self.mep_id, cfm.cc_message._MD_FMT_NO_MD_NAME_PRESENT, self.short_ma_name_format, self.short_ma_name_length, self.short_ma_name, self.end_tlv ) _res = cfm.cc_message.parser(buf) if type(_res) is tuple: res = _res[0] else: res = _res self.assertEqual(self.md_lv, res.md_lv) self.assertEqual(self.version, res.version) self.assertEqual(self.rdi, res.rdi) self.assertEqual(self.interval, res.interval) self.assertEqual(self.seq_num, res.seq_num) self.assertEqual(self.mep_id, res.mep_id) self.assertEqual(cfm.cc_message._MD_FMT_NO_MD_NAME_PRESENT, res.md_name_format) self.assertEqual(self.short_ma_name_format, res.short_ma_name_format) self.assertEqual(self.short_ma_name_length, res.short_ma_name_length) self.assertEqual(self.short_ma_name, res.short_ma_name) self.assertEqual(self.tlvs, res.tlvs) def test_serialize(self): buf = self.ins.serialize() res = struct.unpack_from(self.form, bytes(buf)) self.assertEqual(self.md_lv, res[0] >> 5) self.assertEqual(self.version, res[0] & 0x1f) self.assertEqual(self.opcode, res[1]) self.assertEqual(self.rdi, res[2] >> 7) self.assertEqual(self.interval, res[2] & 0x07) self.assertEqual(self.first_tlv_offset, res[3]) self.assertEqual(self.seq_num, res[4]) self.assertEqual(self.mep_id, res[5]) self.assertEqual(self.md_name_format, res[6]) self.assertEqual(self.md_name_length, res[7]) self.assertEqual(self.md_name, res[8]) self.assertEqual(self.short_ma_name_format, res[9]) self.assertEqual(self.short_ma_name_length, res[10]) self.assertEqual(self.short_ma_name, res[11]) self.assertEqual(self.end_tlv, res[12]) def test_serialize_with_md_name_length_zero(self): ins = cfm.cc_message( self.md_lv, self.version, self.rdi, self.interval, self.seq_num, self.mep_id, self.md_name_format, 0, self.md_name, self.short_ma_name_format, 0, self.short_ma_name, self.tlvs ) buf = ins.serialize() res = struct.unpack_from(self.form, bytes(buf)) self.assertEqual(self.md_lv, res[0] >> 5) self.assertEqual(self.version, res[0] & 0x1f) self.assertEqual(self.opcode, res[1]) self.assertEqual(self.rdi, res[2] >> 7) self.assertEqual(self.interval, res[2] & 0x07) self.assertEqual(self.first_tlv_offset, res[3]) self.assertEqual(self.seq_num, res[4]) self.assertEqual(self.mep_id, res[5]) self.assertEqual(self.md_name_format, res[6]) self.assertEqual(self.md_name_length, res[7]) self.assertEqual(self.md_name, res[8]) self.assertEqual(self.short_ma_name_format, res[9]) self.assertEqual(self.short_ma_name_length, res[10]) self.assertEqual(self.short_ma_name, res[11]) self.assertEqual(self.end_tlv, res[12]) def test_serialize_with_no_maintenance_domain_name_present(self): form = '!4BIH3B8s37x12x4xB' ins = cfm.cc_message( self.md_lv, self.version, self.rdi, self.interval, self.seq_num, self.mep_id, cfm.cc_message._MD_FMT_NO_MD_NAME_PRESENT, 0, self.md_name, self.short_ma_name_format, 0, self.short_ma_name, self.tlvs ) buf = ins.serialize() res = struct.unpack_from(form, bytes(buf)) self.assertEqual(self.md_lv, res[0] >> 5) self.assertEqual(self.version, res[0] & 0x1f) self.assertEqual(self.opcode, res[1]) self.assertEqual(self.rdi, res[2] >> 7) self.assertEqual(self.interval, res[2] & 0x07) self.assertEqual(self.first_tlv_offset, res[3]) self.assertEqual(self.seq_num, res[4]) self.assertEqual(self.mep_id, res[5]) self.assertEqual(cfm.cc_message._MD_FMT_NO_MD_NAME_PRESENT, res[6]) self.assertEqual(self.short_ma_name_format, res[7]) self.assertEqual(self.short_ma_name_length, res[8]) self.assertEqual(self.short_ma_name, res[9]) self.assertEqual(self.end_tlv, res[10]) def test_len(self): # 75 octet (If tlv does not exist) self.assertEqual(75, len(self.ins)) def test_default_args(self): ins = cfm.cc_message() buf = ins.serialize() res = struct.unpack_from(cfm.cc_message._PACK_STR, bytes(buf)) self.assertEqual(res[0] >> 5, 0) self.assertEqual(res[0] & 0x1f, 0) self.assertEqual(res[1], 1) self.assertEqual(res[2] >> 7, 0) self.assertEqual(res[2] & 0x07, 4) self.assertEqual(res[3], 70) self.assertEqual(res[4], 0) self.assertEqual(res[5], 1) self.assertEqual(res[6], 4) class Test_loopback_message(unittest.TestCase): def setUp(self): self.md_lv = 1 self.version = 1 self.opcode = cfm.CFM_LOOPBACK_MESSAGE self.flags = 0 self.first_tlv_offset = cfm.loopback_message._TLV_OFFSET self.transaction_id = 12345 self.tlvs = [ ] self.end_tlv = 0 self.ins = cfm.loopback_message( self.md_lv, self.version, self.transaction_id, self.tlvs, ) self.form = '!4BIB' self.buf = struct.pack( self.form, (self.md_lv << 5) | self.version, self.opcode, self.flags, self.first_tlv_offset, self.transaction_id, self.end_tlv ) def tearDown(self): pass def test_init(self): self.assertEqual(self.md_lv, self.ins.md_lv) self.assertEqual(self.version, self.ins.version) self.assertEqual(self.transaction_id, self.ins.transaction_id) self.assertEqual(self.tlvs, self.ins.tlvs) def test_parser(self): _res = cfm.loopback_message.parser(self.buf) if type(_res) is tuple: res = _res[0] else: res = _res self.assertEqual(self.md_lv, res.md_lv) self.assertEqual(self.version, res.version) self.assertEqual(self.transaction_id, res.transaction_id) self.assertEqual(self.tlvs, res.tlvs) def test_serialize(self): buf = self.ins.serialize() res = struct.unpack_from(self.form, bytes(buf)) self.assertEqual(self.md_lv, res[0] >> 5) self.assertEqual(self.version, res[0] & 0x1f) self.assertEqual(self.opcode, res[1]) self.assertEqual(self.flags, res[2]) self.assertEqual(self.first_tlv_offset, res[3]) self.assertEqual(self.transaction_id, res[4]) self.assertEqual(self.end_tlv, res[5]) def test_len(self): # 9 octet (If tlv does not exist) self.assertEqual(9, len(self.ins)) def test_default_args(self): ins = cfm.loopback_message() buf = ins.serialize() res = struct.unpack_from(cfm.loopback_message._PACK_STR, bytes(buf)) self.assertEqual(res[0] >> 5, 0) self.assertEqual(res[0] & 0x1f, 0) self.assertEqual(res[1], 3) self.assertEqual(res[2], 0) self.assertEqual(res[3], 4) self.assertEqual(res[4], 0) class Test_loopback_reply(unittest.TestCase): def setUp(self): self.md_lv = 1 self.version = 1 self.opcode = cfm.CFM_LOOPBACK_REPLY self.flags = 0 self.first_tlv_offset = cfm.loopback_reply._TLV_OFFSET self.transaction_id = 12345 self.tlvs = [ ] self.end_tlv = 0 self.ins = cfm.loopback_reply( self.md_lv, self.version, self.transaction_id, self.tlvs, ) self.form = '!4BIB' self.buf = struct.pack( self.form, (self.md_lv << 5) | self.version, self.opcode, self.flags, self.first_tlv_offset, self.transaction_id, self.end_tlv ) def tearDown(self): pass def test_init(self): self.assertEqual(self.md_lv, self.ins.md_lv) self.assertEqual(self.version, self.ins.version) self.assertEqual(self.transaction_id, self.ins.transaction_id) self.assertEqual(self.tlvs, self.ins.tlvs) def test_parser(self): _res = cfm.loopback_reply.parser(self.buf) if type(_res) is tuple: res = _res[0] else: res = _res self.assertEqual(self.md_lv, res.md_lv) self.assertEqual(self.version, res.version) self.assertEqual(self.transaction_id, res.transaction_id) self.assertEqual(self.tlvs, res.tlvs) def test_serialize(self): buf = self.ins.serialize() res = struct.unpack_from(self.form, bytes(buf)) self.assertEqual(self.md_lv, res[0] >> 5) self.assertEqual(self.version, res[0] & 0x1f) self.assertEqual(self.opcode, res[1]) self.assertEqual(self.flags, res[2]) self.assertEqual(self.first_tlv_offset, res[3]) self.assertEqual(self.transaction_id, res[4]) self.assertEqual(self.end_tlv, res[5]) def test_len(self): # 9 octet (If tlv does not exist) self.assertEqual(9, len(self.ins)) def test_default_args(self): ins = cfm.loopback_reply() buf = ins.serialize() res = struct.unpack_from(cfm.loopback_reply._PACK_STR, bytes(buf)) self.assertEqual(res[0] >> 5, 0) self.assertEqual(res[0] & 0x1f, 0) self.assertEqual(res[1], 2) self.assertEqual(res[2], 0) self.assertEqual(res[3], 4) self.assertEqual(res[4], 0) class Test_link_trace_message(unittest.TestCase): def setUp(self): self.md_lv = 1 self.version = 1 self.opcode = cfm.CFM_LINK_TRACE_MESSAGE self.use_fdb_only = 1 self.first_tlv_offset = cfm.link_trace_message._TLV_OFFSET self.transaction_id = 12345 self.ttl = 55 self.ltm_orig_addr = "00:11:22:44:55:66" self.ltm_targ_addr = "ab:cd:ef:23:12:65" self.tlvs = [ ] self.end_tlv = 0 self.ins = cfm.link_trace_message( self.md_lv, self.version, self.use_fdb_only, self.transaction_id, self.ttl, self.ltm_orig_addr, self.ltm_targ_addr, self.tlvs ) self.form = '!4BIB6s6sB' self.buf = struct.pack( self.form, (self.md_lv << 5) | self.version, self.opcode, self.use_fdb_only << 7, self.first_tlv_offset, self.transaction_id, self.ttl, addrconv.mac.text_to_bin(self.ltm_orig_addr), addrconv.mac.text_to_bin(self.ltm_targ_addr), self.end_tlv ) def tearDown(self): pass def test_init(self): self.assertEqual(self.md_lv, self.ins.md_lv) self.assertEqual(self.version, self.ins.version) self.assertEqual(self.use_fdb_only, self.ins.use_fdb_only) self.assertEqual(self.transaction_id, self.ins.transaction_id) self.assertEqual(self.ttl, self.ins.ttl) self.assertEqual(self.ltm_orig_addr, self.ins.ltm_orig_addr) self.assertEqual(self.ltm_targ_addr, self.ins.ltm_targ_addr) self.assertEqual(self.tlvs, self.ins.tlvs) def test_parser(self): _res = cfm.link_trace_message.parser(self.buf) if type(_res) is tuple: res = _res[0] else: res = _res self.assertEqual(self.md_lv, res.md_lv) self.assertEqual(self.version, res.version) self.assertEqual(self.use_fdb_only, res.use_fdb_only) self.assertEqual(self.transaction_id, res.transaction_id) self.assertEqual(self.ttl, res.ttl) self.assertEqual(self.ltm_orig_addr, res.ltm_orig_addr) self.assertEqual(self.ltm_targ_addr, res.ltm_targ_addr) self.assertEqual(self.tlvs, res.tlvs) def test_serialize(self): buf = self.ins.serialize() res = struct.unpack_from(self.form, bytes(buf)) self.assertEqual(self.md_lv, res[0] >> 5) self.assertEqual(self.version, res[0] & 0x1f) self.assertEqual(self.opcode, res[1]) self.assertEqual(self.use_fdb_only, res[2] >> 7) self.assertEqual(self.first_tlv_offset, res[3]) self.assertEqual(self.transaction_id, res[4]) self.assertEqual(self.ttl, res[5]) self.assertEqual(addrconv.mac.text_to_bin(self.ltm_orig_addr), res[6]) self.assertEqual(addrconv.mac.text_to_bin(self.ltm_targ_addr), res[7]) self.assertEqual(self.end_tlv, res[8]) def test_len(self): # 22 octet (If tlv does not exist) self.assertEqual(22, len(self.ins)) def test_default_args(self): ins = cfm.link_trace_message() buf = ins.serialize() res = struct.unpack_from(cfm.link_trace_message._PACK_STR, bytes(buf)) self.assertEqual(res[0] >> 5, 0) self.assertEqual(res[0] & 0x1f, 0) self.assertEqual(res[1], 5) self.assertEqual(res[2] >> 7, 1) self.assertEqual(res[3], 17) self.assertEqual(res[4], 0) self.assertEqual(res[5], 64) self.assertEqual(res[6], addrconv.mac.text_to_bin('00:00:00:00:00:00')) self.assertEqual(res[7], addrconv.mac.text_to_bin('00:00:00:00:00:00')) class Test_link_trace_reply(unittest.TestCase): def setUp(self): self.md_lv = 1 self.version = 1 self.opcode = cfm.CFM_LINK_TRACE_REPLY self.use_fdb_only = 1 self.fwd_yes = 0 self.terminal_mep = 1 self.first_tlv_offset = cfm.link_trace_reply._TLV_OFFSET self.transaction_id = 12345 self.ttl = 55 self.relay_action = 2 self.ltm_orig_addr = "00:11:22:aa:bb:cc" self.ltm_targ_addr = "53:45:24:64:ac:ff" self.tlvs = [ ] self.end_tlv = 0 self.ins = cfm.link_trace_reply( self.md_lv, self.version, self.use_fdb_only, self.fwd_yes, self.terminal_mep, self.transaction_id, self.ttl, self.relay_action, self.tlvs, ) self.form = '!4BIBBB' self.buf = struct.pack( self.form, (self.md_lv << 5) | self.version, self.opcode, (self.use_fdb_only << 7) | (self.fwd_yes << 6) | (self.terminal_mep << 5), self.first_tlv_offset, self.transaction_id, self.ttl, self.relay_action, self.end_tlv ) def tearDown(self): pass def test_init(self): self.assertEqual(self.md_lv, self.ins.md_lv) self.assertEqual(self.version, self.ins.version) self.assertEqual(self.use_fdb_only, self.ins.use_fdb_only) self.assertEqual(self.fwd_yes, self.ins.fwd_yes) self.assertEqual(self.terminal_mep, self.ins.terminal_mep) self.assertEqual(self.transaction_id, self.ins.transaction_id) self.assertEqual(self.ttl, self.ins.ttl) self.assertEqual(self.relay_action, self.ins.relay_action) self.assertEqual(self.tlvs, self.ins.tlvs) def test_parser(self): _res = cfm.link_trace_reply.parser(self.buf) if type(_res) is tuple: res = _res[0] else: res = _res self.assertEqual(self.md_lv, res.md_lv) self.assertEqual(self.version, res.version) self.assertEqual(self.use_fdb_only, self.ins.use_fdb_only) self.assertEqual(self.fwd_yes, self.ins.fwd_yes) self.assertEqual(self.terminal_mep, self.ins.terminal_mep) self.assertEqual(self.transaction_id, res.transaction_id) self.assertEqual(self.ttl, res.ttl) self.assertEqual(self.relay_action, res.relay_action) self.assertEqual(self.tlvs, res.tlvs) def test_serialize(self): buf = self.ins.serialize() res = struct.unpack_from(self.form, bytes(buf)) self.assertEqual(self.md_lv, res[0] >> 5) self.assertEqual(self.version, res[0] & 0x1f) self.assertEqual(self.opcode, res[1]) self.assertEqual(self.use_fdb_only, res[2] >> 7 & 0x01) self.assertEqual(self.fwd_yes, res[2] >> 6 & 0x01) self.assertEqual(self.terminal_mep, res[2] >> 5 & 0x01) self.assertEqual(self.first_tlv_offset, res[3]) self.assertEqual(self.transaction_id, res[4]) self.assertEqual(self.ttl, res[5]) self.assertEqual(self.relay_action, res[6]) self.assertEqual(self.end_tlv, res[7]) def test_len(self): # 11 octet (If tlv does not exist) self.assertEqual(11, len(self.ins)) def test_default_args(self): ins = cfm.link_trace_reply() buf = ins.serialize() res = struct.unpack_from(cfm.link_trace_reply._PACK_STR, bytes(buf)) self.assertEqual(res[0] >> 5, 0) self.assertEqual(res[0] & 0x1f, 0) self.assertEqual(res[1], 4) self.assertEqual(res[2] >> 7, 1) self.assertEqual(res[2] >> 6 & 0x01, 0) self.assertEqual(res[2] >> 5 & 0x01, 1) self.assertEqual(res[3], 6) self.assertEqual(res[4], 0) self.assertEqual(res[5], 64) self.assertEqual(res[6], 1) class Test_sender_id_tlv(unittest.TestCase): def setUp(self): self._type = cfm.CFM_SENDER_ID_TLV self.length = 10 self.chassis_id_length = 1 self.chassis_id_subtype = 3 self.chassis_id = b"\x0a" self.ma_domain_length = 2 self.ma_domain = b"\x04\x05" self.ma_length = 3 self.ma = b"\x01\x02\x03" self.ins = cfm.sender_id_tlv( self.length, self.chassis_id_length, self.chassis_id_subtype, self.chassis_id, self.ma_domain_length, self.ma_domain, self.ma_length, self.ma, ) self.form = '!BHBB1sB2sB3s' self.buf = struct.pack( self.form, self._type, self.length, self.chassis_id_length, self.chassis_id_subtype, self.chassis_id, self.ma_domain_length, self.ma_domain, self.ma_length, self.ma ) def tearDown(self): pass def test_init(self): self.assertEqual(self.length, self.ins.length) self.assertEqual(self.chassis_id_length, self.ins.chassis_id_length) self.assertEqual(self.chassis_id_subtype, self.ins.chassis_id_subtype) self.assertEqual(self.chassis_id, self.ins.chassis_id) self.assertEqual(self.ma_domain_length, self.ins.ma_domain_length) self.assertEqual(self.ma_domain, self.ins.ma_domain) self.assertEqual(self.ma_length, self.ins.ma_length) self.assertEqual(self.ma, self.ins.ma) def test_parser(self): _res = cfm.sender_id_tlv.parser(self.buf) if type(_res) is tuple: res = _res[0] else: res = _res self.assertEqual(self.length, res.length) self.assertEqual(self.chassis_id_length, res.chassis_id_length) self.assertEqual(self.chassis_id_subtype, res.chassis_id_subtype) self.assertEqual(self.chassis_id, res.chassis_id) self.assertEqual(self.ma_domain_length, res.ma_domain_length) self.assertEqual(self.ma_domain, res.ma_domain) self.assertEqual(self.ma_length, res.ma_length) self.assertEqual(self.ma, res.ma) def test_serialize(self): buf = self.ins.serialize() res = struct.unpack_from(self.form, bytes(buf)) self.assertEqual(self._type, res[0]) self.assertEqual(self.length, res[1]) self.assertEqual(self.chassis_id_length, res[2]) self.assertEqual(self.chassis_id_subtype, res[3]) self.assertEqual(self.chassis_id, res[4]) self.assertEqual(self.ma_domain_length, res[5]) self.assertEqual(self.ma_domain, res[6]) self.assertEqual(self.ma_length, res[7]) self.assertEqual(self.ma, res[8]) def test_serialize_semi_normal_ptn1(self): ins = cfm.sender_id_tlv( chassis_id_subtype=self.chassis_id_subtype, chassis_id=self.chassis_id, ma_domain=self.ma_domain, ) buf = ins.serialize() form = '!BHBB1sB2sB' res = struct.unpack_from(form, bytes(buf)) self.assertEqual(self._type, res[0]) self.assertEqual(7, res[1]) self.assertEqual(self.chassis_id_length, res[2]) self.assertEqual(self.chassis_id_subtype, res[3]) self.assertEqual(self.chassis_id, res[4]) self.assertEqual(self.ma_domain_length, res[5]) self.assertEqual(self.ma_domain, res[6]) self.assertEqual(0, res[7]) def test_serialize_semi_normal_ptn2(self): ins = cfm.sender_id_tlv( ma_domain=self.ma_domain, ma=self.ma, ) buf = ins.serialize() form = '!BHBB2sB3s' res = struct.unpack_from(form, bytes(buf)) self.assertEqual(self._type, res[0]) self.assertEqual(8, res[1]) self.assertEqual(0, res[2]) self.assertEqual(self.ma_domain_length, res[3]) self.assertEqual(self.ma_domain, res[4]) self.assertEqual(self.ma_length, res[5]) self.assertEqual(self.ma, res[6]) def test_serialize_semi_normal_ptn3(self): ins = cfm.sender_id_tlv( chassis_id_subtype=self.chassis_id_subtype, chassis_id=self.chassis_id, ) buf = ins.serialize() form = '!BHBB1sB' res = struct.unpack_from(form, bytes(buf)) self.assertEqual(self._type, res[0]) self.assertEqual(4, res[1]) self.assertEqual(self.chassis_id_length, res[2]) self.assertEqual(self.chassis_id_subtype, res[3]) self.assertEqual(self.chassis_id, res[4]) self.assertEqual(0, res[5]) def test_serialize_semi_normal_ptn4(self): ins = cfm.sender_id_tlv( ma_domain=self.ma_domain, ) buf = ins.serialize() form = '!BHBB2sB' res = struct.unpack_from(form, bytes(buf)) self.assertEqual(self._type, res[0]) self.assertEqual(5, res[1]) self.assertEqual(0, res[2]) self.assertEqual(self.ma_domain_length, res[3]) self.assertEqual(self.ma_domain, res[4]) self.assertEqual(0, res[5]) def test_serialize_with_length_zero(self): ins = cfm.sender_id_tlv( 0, 0, self.chassis_id_subtype, self.chassis_id, 0, self.ma_domain, 0, self.ma, ) buf = ins.serialize() res = struct.unpack_from(self.form, bytes(buf)) self.assertEqual(self._type, res[0]) self.assertEqual(self.length, res[1]) self.assertEqual(self.chassis_id_length, res[2]) self.assertEqual(self.chassis_id_subtype, res[3]) self.assertEqual(self.chassis_id, res[4]) self.assertEqual(self.ma_domain_length, res[5]) self.assertEqual(self.ma_domain, res[6]) self.assertEqual(self.ma_length, res[7]) self.assertEqual(self.ma, res[8]) def test_len(self): # tlv_length = type_len + length_len + value_len self.assertEqual(1 + 2 + 10, len(self.ins)) def test_default_args(self): ins = cfm.sender_id_tlv() buf = ins.serialize() res = struct.unpack_from(cfm.sender_id_tlv._PACK_STR, bytes(buf)) self.assertEqual(res[0], cfm.CFM_SENDER_ID_TLV) self.assertEqual(res[1], 1) self.assertEqual(res[2], 0) class Test_port_status_tlv(unittest.TestCase): def setUp(self): self._type = cfm.CFM_PORT_STATUS_TLV self.length = 1 self.port_status = 1 self.ins = cfm.port_status_tlv( self.length, self.port_status ) self.form = '!BHB' self.buf = struct.pack( self.form, self._type, self.length, self.port_status ) def tearDown(self): pass def test_init(self): self.assertEqual(self.length, self.ins.length) self.assertEqual(self.port_status, self.ins.port_status) def test_parser(self): _res = cfm.port_status_tlv.parser(self.buf) if type(_res) is tuple: res = _res[0] else: res = _res self.assertEqual(self.length, res.length) self.assertEqual(self.port_status, res.port_status) def test_serialize(self): buf = self.ins.serialize() res = struct.unpack_from(self.form, bytes(buf)) self.assertEqual(self._type, res[0]) self.assertEqual(self.length, res[1]) self.assertEqual(self.port_status, res[2]) def test_len(self): # tlv_length = type_len + length_len + value_len self.assertEqual(1 + 2 + 1, len(self.ins)) def test_default_args(self): ins = cfm.port_status_tlv() buf = ins.serialize() res = struct.unpack_from(cfm.port_status_tlv._PACK_STR, bytes(buf)) self.assertEqual(res[0], cfm.CFM_PORT_STATUS_TLV) self.assertEqual(res[1], 1) self.assertEqual(res[2], 2) class Test_data_tlv(unittest.TestCase): def setUp(self): self._type = cfm.CFM_DATA_TLV self.length = 3 self.data_value = b"\x01\x02\x03" self.ins = cfm.data_tlv( self.length, self.data_value ) self.form = '!BH3s' self.buf = struct.pack( self.form, self._type, self.length, self.data_value, ) def tearDown(self): pass def test_init(self): self.assertEqual(self.length, self.ins.length) self.assertEqual(self.data_value, self.ins.data_value) def test_parser(self): _res = cfm.data_tlv.parser(self.buf) if type(_res) is tuple: res = _res[0] else: res = _res self.assertEqual(self.length, res.length) self.assertEqual(self.data_value, res.data_value) def test_serialize(self): buf = self.ins.serialize() res = struct.unpack_from(self.form, bytes(buf)) self.assertEqual(self._type, res[0]) self.assertEqual(self.length, res[1]) self.assertEqual(self.data_value, res[2]) def test_serialize_with_length_zero(self): ins = cfm.data_tlv( 0, self.data_value ) buf = ins.serialize() res = struct.unpack_from(self.form, bytes(buf)) self.assertEqual(self._type, res[0]) self.assertEqual(self.length, res[1]) self.assertEqual(self.data_value, res[2]) def test_len(self): # tlv_length = type_len + length_len + value_len self.assertEqual(1 + 2 + 3, len(self.ins)) def test_default_args(self): ins = cfm.data_tlv() buf = ins.serialize() res = struct.unpack_from(cfm.data_tlv._PACK_STR, bytes(buf)) self.assertEqual(res[0], cfm.CFM_DATA_TLV) self.assertEqual(res[1], 0) class Test_interface_status_tlv(unittest.TestCase): def setUp(self): self._type = cfm.CFM_INTERFACE_STATUS_TLV self.length = 1 self.interface_status = 4 self.ins = cfm.interface_status_tlv( self.length, self.interface_status ) self.form = '!BHB' self.buf = struct.pack( self.form, self._type, self.length, self.interface_status ) def tearDown(self): pass def test_init(self): self.assertEqual(self.length, self.ins.length) self.assertEqual(self.interface_status, self.ins.interface_status) def test_parser(self): _res = cfm.interface_status_tlv.parser(self.buf) if type(_res) is tuple: res = _res[0] else: res = _res self.assertEqual(self.length, res.length) self.assertEqual(self.interface_status, res.interface_status) def test_serialize(self): buf = self.ins.serialize() res = struct.unpack_from(self.form, bytes(buf)) self.assertEqual(self._type, res[0]) self.assertEqual(self.length, res[1]) self.assertEqual(self.interface_status, res[2]) def test_len(self): # tlv_length = type_len + length_len + value_len self.assertEqual(1 + 2 + 1, len(self.ins)) def test_default_args(self): ins = cfm.interface_status_tlv() buf = ins.serialize() res = struct.unpack_from(cfm.interface_status_tlv._PACK_STR, bytes(buf)) self.assertEqual(res[0], cfm.CFM_INTERFACE_STATUS_TLV) self.assertEqual(res[1], 1) self.assertEqual(res[2], 1) class Test_ltm_egress_identifier_tlv(unittest.TestCase): def setUp(self): self._type = cfm.CFM_LTM_EGRESS_IDENTIFIER_TLV self.length = 8 self.egress_id_ui = 7 self.egress_id_mac = "11:22:33:44:55:66" self.ins = cfm.ltm_egress_identifier_tlv( self.length, self.egress_id_ui, self.egress_id_mac ) self.form = '!BHH6s' self.buf = struct.pack( self.form, self._type, self.length, self.egress_id_ui, addrconv.mac.text_to_bin(self.egress_id_mac) ) def tearDown(self): pass def test_init(self): self.assertEqual(self.length, self.ins.length) self.assertEqual(self.egress_id_ui, self.ins.egress_id_ui) self.assertEqual(self.egress_id_mac, self.ins.egress_id_mac) def test_parser(self): _res = cfm.ltm_egress_identifier_tlv.parser(self.buf) if type(_res) is tuple: res = _res[0] else: res = _res self.assertEqual(self.length, res.length) self.assertEqual(self.egress_id_ui, res.egress_id_ui) self.assertEqual(self.egress_id_mac, res.egress_id_mac) def test_serialize(self): buf = self.ins.serialize() res = struct.unpack_from(self.form, bytes(buf)) self.assertEqual(self._type, res[0]) self.assertEqual(self.length, res[1]) self.assertEqual(self.egress_id_ui, res[2]) self.assertEqual(addrconv.mac.text_to_bin(self.egress_id_mac), res[3]) def test_serialize_with_length_zero(self): ins = cfm.ltm_egress_identifier_tlv( 0, self.egress_id_ui, self.egress_id_mac ) buf = ins.serialize() res = struct.unpack_from(self.form, bytes(buf)) self.assertEqual(self._type, res[0]) self.assertEqual(self.length, res[1]) self.assertEqual(self.egress_id_ui, res[2]) self.assertEqual(addrconv.mac.text_to_bin(self.egress_id_mac), res[3]) def test_len(self): # tlv_length = type_len + length_len + value_len self.assertEqual(1 + 2 + 8, len(self.ins)) def test_default_args(self): ins = cfm.ltm_egress_identifier_tlv() buf = ins.serialize() res = struct.unpack_from( cfm.ltm_egress_identifier_tlv._PACK_STR, bytes(buf)) self.assertEqual(res[0], cfm.CFM_LTM_EGRESS_IDENTIFIER_TLV) self.assertEqual(res[1], 8) self.assertEqual(res[2], 0) self.assertEqual(res[3], addrconv.mac.text_to_bin('00:00:00:00:00:00')) class Test_ltr_egress_identifier_tlv(unittest.TestCase): def setUp(self): self._type = cfm.CFM_LTR_EGRESS_IDENTIFIER_TLV self.length = 16 self.last_egress_id_ui = 7 self.last_egress_id_mac = "11:22:33:44:55:66" self.next_egress_id_ui = 5 self.next_egress_id_mac = "33:11:33:aa:bb:cc" self.ins = cfm.ltr_egress_identifier_tlv(self.length, self.last_egress_id_ui, self.last_egress_id_mac, self.next_egress_id_ui, self.next_egress_id_mac ) self.form = '!BHH6sH6s' self.buf = struct.pack( self.form, self._type, self.length, self.last_egress_id_ui, addrconv.mac.text_to_bin(self.last_egress_id_mac), self.next_egress_id_ui, addrconv.mac.text_to_bin(self.next_egress_id_mac)) def tearDown(self): pass def test_init(self): self.assertEqual(self.length, self.ins.length) self.assertEqual(self.last_egress_id_ui, self.ins.last_egress_id_ui) self.assertEqual(self.last_egress_id_mac, self.ins.last_egress_id_mac) self.assertEqual(self.next_egress_id_ui, self.ins.next_egress_id_ui) self.assertEqual(self.next_egress_id_mac, self.ins.next_egress_id_mac) def test_parser(self): _res = cfm.ltr_egress_identifier_tlv.parser(self.buf) if type(_res) is tuple: res = _res[0] else: res = _res self.assertEqual(self.length, res.length) self.assertEqual(self.last_egress_id_ui, res.last_egress_id_ui) self.assertEqual(self.last_egress_id_mac, res.last_egress_id_mac) self.assertEqual(self.next_egress_id_ui, res.next_egress_id_ui) self.assertEqual(self.next_egress_id_mac, res.next_egress_id_mac) def test_serialize(self): buf = self.ins.serialize() res = struct.unpack_from(self.form, bytes(buf)) self.assertEqual(self._type, res[0]) self.assertEqual(self.length, res[1]) self.assertEqual(self.last_egress_id_ui, res[2]) self.assertEqual(addrconv.mac.text_to_bin(self.last_egress_id_mac), res[3]) self.assertEqual(self.next_egress_id_ui, res[4]) self.assertEqual(addrconv.mac.text_to_bin(self.next_egress_id_mac), res[5]) def test_serialize_with_length_zero(self): ins = cfm.ltr_egress_identifier_tlv(0, self.last_egress_id_ui, self.last_egress_id_mac, self.next_egress_id_ui, self.next_egress_id_mac ) buf = ins.serialize() res = struct.unpack_from(self.form, bytes(buf)) self.assertEqual(self._type, res[0]) self.assertEqual(self.length, res[1]) self.assertEqual(self.last_egress_id_ui, res[2]) self.assertEqual(addrconv.mac.text_to_bin(self.last_egress_id_mac), res[3]) self.assertEqual(self.next_egress_id_ui, res[4]) self.assertEqual(addrconv.mac.text_to_bin(self.next_egress_id_mac), res[5]) def test_len(self): # tlv_length = type_len + length_len + value_len self.assertEqual(1 + 2 + 16, len(self.ins)) def test_default_args(self): ins = cfm.ltr_egress_identifier_tlv() buf = ins.serialize() res = struct.unpack_from(cfm.ltr_egress_identifier_tlv._PACK_STR, bytes(buf)) self.assertEqual(res[0], cfm.CFM_LTR_EGRESS_IDENTIFIER_TLV) self.assertEqual(res[1], 16) self.assertEqual(res[2], 0) self.assertEqual(res[3], addrconv.mac.text_to_bin('00:00:00:00:00:00')) self.assertEqual(res[4], 0) self.assertEqual(res[5], addrconv.mac.text_to_bin('00:00:00:00:00:00')) class Test_organization_specific_tlv(unittest.TestCase): def setUp(self): self._type = cfm.CFM_ORGANIZATION_SPECIFIC_TLV self.length = 10 self.oui = b"\xff\x12\x34" self.subtype = 3 self.value = b"\x01\x02\x0f\x0e\x0d\x0c" self.ins = cfm.organization_specific_tlv(self.length, self.oui, self.subtype, self.value ) self.form = '!BH3sB6s' self.buf = struct.pack(self.form, self._type, self.length, self.oui, self.subtype, self.value ) def tearDown(self): pass def test_init(self): self.assertEqual(self.length, self.ins.length) self.assertEqual(self.oui, self.ins.oui) self.assertEqual(self.subtype, self.ins.subtype) self.assertEqual(self.value, self.ins.value) def test_parser(self): _res = cfm.organization_specific_tlv.parser(self.buf) if type(_res) is tuple: res = _res[0] else: res = _res self.assertEqual(self.length, res.length) self.assertEqual(self.oui, res.oui) self.assertEqual(self.subtype, res.subtype) self.assertEqual(self.value, res.value) def test_serialize(self): buf = self.ins.serialize() res = struct.unpack_from(self.form, bytes(buf)) self.assertEqual(self._type, res[0]) self.assertEqual(self.length, res[1]) self.assertEqual(self.oui, res[2]) self.assertEqual(self.subtype, res[3]) self.assertEqual(self.value, res[4]) def test_serialize_with_zero(self): ins = cfm.organization_specific_tlv(0, self.oui, self.subtype, self.value ) buf = ins.serialize() res = struct.unpack_from(self.form, bytes(buf)) self.assertEqual(self._type, res[0]) self.assertEqual(self.length, res[1]) self.assertEqual(self.oui, res[2]) self.assertEqual(self.subtype, res[3]) self.assertEqual(self.value, res[4]) def test_len(self): # tlv_length = type_len + length_len + value_len self.assertEqual(1 + 2 + 10, len(self.ins)) def test_default_args(self): ins = cfm.organization_specific_tlv() buf = ins.serialize() res = struct.unpack_from(cfm.organization_specific_tlv._PACK_STR, bytes(buf)) self.assertEqual(res[0], cfm.CFM_ORGANIZATION_SPECIFIC_TLV) self.assertEqual(res[1], 4) self.assertEqual(res[2], b"\x00\x00\x00") self.assertEqual(res[3], 0) class Test_reply_ingress_tlv(unittest.TestCase): def setUp(self): self._type = cfm.CFM_REPLY_INGRESS_TLV self.length = 12 self.action = 2 self.mac_address = 'aa:bb:cc:56:34:12' self.port_id_length = 3 self.port_id_subtype = 2 self.port_id = b"\x01\x04\x09" self.ins = cfm.reply_ingress_tlv(self.length, self.action, self.mac_address, self.port_id_length, self.port_id_subtype, self.port_id ) self.form = '!BHB6sBB3s' self.buf = struct.pack(self.form, self._type, self.length, self.action, addrconv.mac.text_to_bin(self.mac_address), self.port_id_length, self.port_id_subtype, self.port_id ) def tearDown(self): pass def test_init(self): self.assertEqual(self.length, self.ins.length) self.assertEqual(self.action, self.ins.action) self.assertEqual(self.mac_address, self.ins.mac_address) self.assertEqual(self.port_id_length, self.ins.port_id_length) self.assertEqual(self.port_id_subtype, self.ins.port_id_subtype) self.assertEqual(self.port_id, self.ins.port_id) def test_parser(self): _res = cfm.reply_ingress_tlv.parser(self.buf) if type(_res) is tuple: res = _res[0] else: res = _res self.assertEqual(self.length, res.length) self.assertEqual(self.action, res.action) self.assertEqual(self.mac_address, res.mac_address) self.assertEqual(self.port_id_length, res.port_id_length) self.assertEqual(self.port_id_subtype, res.port_id_subtype) self.assertEqual(self.port_id, res.port_id) def test_serialize(self): buf = self.ins.serialize() res = struct.unpack_from(self.form, bytes(buf)) self.assertEqual(self._type, res[0]) self.assertEqual(self.length, res[1]) self.assertEqual(self.action, res[2]) self.assertEqual(addrconv.mac.text_to_bin(self.mac_address), res[3]) self.assertEqual(self.port_id_length, res[4]) self.assertEqual(self.port_id_subtype, res[5]) self.assertEqual(self.port_id, res[6]) def test_serialize_with_zero(self): ins = cfm.reply_ingress_tlv(0, self.action, self.mac_address, 0, self.port_id_subtype, self.port_id ) buf = ins.serialize() res = struct.unpack_from(self.form, bytes(buf)) self.assertEqual(self._type, res[0]) self.assertEqual(self.length, res[1]) self.assertEqual(self.action, res[2]) self.assertEqual(addrconv.mac.text_to_bin(self.mac_address), res[3]) self.assertEqual(self.port_id_length, res[4]) self.assertEqual(self.port_id_subtype, res[5]) self.assertEqual(self.port_id, res[6]) def test_len(self): # tlv_length = type_len + length_len + value_len self.assertEqual(1 + 2 + 12, len(self.ins)) def test_default_args(self): ins = cfm.reply_ingress_tlv() buf = ins.serialize() res = struct.unpack_from(cfm.reply_ingress_tlv._PACK_STR, bytes(buf)) self.assertEqual(res[0], cfm.CFM_REPLY_INGRESS_TLV) self.assertEqual(res[1], 7) self.assertEqual(res[2], 1) self.assertEqual(res[3], addrconv.mac.text_to_bin('00:00:00:00:00:00')) class Test_reply_egress_tlv(unittest.TestCase): def setUp(self): self._type = cfm.CFM_REPLY_EGRESS_TLV self.length = 12 self.action = 2 self.mac_address = 'aa:bb:cc:56:34:12' self.port_id_length = 3 self.port_id_subtype = 2 self.port_id = b"\x01\x04\x09" self.ins = cfm.reply_egress_tlv(self.length, self.action, self.mac_address, self.port_id_length, self.port_id_subtype, self.port_id ) self.form = '!BHB6sBB3s' self.buf = struct.pack(self.form, self._type, self.length, self.action, addrconv.mac.text_to_bin(self.mac_address), self.port_id_length, self.port_id_subtype, self.port_id ) def tearDown(self): pass def test_init(self): self.assertEqual(self.length, self.ins.length) self.assertEqual(self.action, self.ins.action) self.assertEqual(self.mac_address, self.ins.mac_address) self.assertEqual(self.port_id_length, self.ins.port_id_length) self.assertEqual(self.port_id_subtype, self.ins.port_id_subtype) self.assertEqual(self.port_id, self.ins.port_id) def test_parser(self): _res = cfm.reply_ingress_tlv.parser(self.buf) if type(_res) is tuple: res = _res[0] else: res = _res self.assertEqual(self.length, res.length) self.assertEqual(self.action, res.action) self.assertEqual(self.mac_address, res.mac_address) self.assertEqual(self.port_id_length, res.port_id_length) self.assertEqual(self.port_id_subtype, res.port_id_subtype) self.assertEqual(self.port_id, res.port_id) def test_serialize(self): buf = self.ins.serialize() res = struct.unpack_from(self.form, bytes(buf)) self.assertEqual(self._type, res[0]) self.assertEqual(self.length, res[1]) self.assertEqual(self.action, res[2]) self.assertEqual(addrconv.mac.text_to_bin(self.mac_address), res[3]) self.assertEqual(self.port_id_length, res[4]) self.assertEqual(self.port_id_subtype, res[5]) self.assertEqual(self.port_id, res[6]) def test_serialize_with_zero(self): ins = cfm.reply_egress_tlv(0, self.action, self.mac_address, 0, self.port_id_subtype, self.port_id ) buf = ins.serialize() res = struct.unpack_from(self.form, bytes(buf)) self.assertEqual(self._type, res[0]) self.assertEqual(self.length, res[1]) self.assertEqual(self.action, res[2]) self.assertEqual(addrconv.mac.text_to_bin(self.mac_address), res[3]) self.assertEqual(self.port_id_length, res[4]) self.assertEqual(self.port_id_subtype, res[5]) self.assertEqual(self.port_id, res[6]) def test_len(self): # tlv_length = type_len + length_len + value_len self.assertEqual(1 + 2 + 12, len(self.ins)) def test_default_args(self): ins = cfm.reply_egress_tlv() buf = ins.serialize() res = struct.unpack_from(cfm.reply_egress_tlv._PACK_STR, bytes(buf)) self.assertEqual(res[0], cfm.CFM_REPLY_EGRESS_TLV) self.assertEqual(res[1], 7) self.assertEqual(res[2], 1) self.assertEqual(res[3], addrconv.mac.text_to_bin('00:00:00:00:00:00')) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/packet/test_dhcp.py0000664000175000017500000002243200000000000022211 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone 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. import inspect import logging import struct import unittest from os_ken.lib import addrconv from os_ken.lib.packet import dhcp LOG = logging.getLogger(__name__) class Test_dhcp_offer(unittest.TestCase): op = dhcp.DHCP_BOOT_REPLY chaddr = 'aa:aa:aa:aa:aa:aa' htype = 1 hlen = 6 hops = 0 xid = 1 secs = 0 flags = 1 ciaddr = '192.168.10.10' yiaddr = '192.168.20.20' siaddr = '192.168.30.30' giaddr = '192.168.40.40' sname = 'abc' boot_file = '' option_list = [ dhcp.option(dhcp.DHCP_MESSAGE_TYPE_OPT, b'\x02', 1), dhcp.option(dhcp.DHCP_SUBNET_MASK_OPT, b'\xff\xff\xff\x00', 4), dhcp.option(dhcp.DHCP_GATEWAY_ADDR_OPT, b'\xc0\xa8\x0a\x09', 4), dhcp.option(dhcp.DHCP_DNS_SERVER_ADDR_OPT, b'\xc0\xa8\x0a\x09', 4), dhcp.option(dhcp.DHCP_IP_ADDR_LEASE_TIME_OPT, b'\x00\x03\xf4\x80', 4), dhcp.option(dhcp.DHCP_RENEWAL_TIME_OPT, b'\x00\x01\xfa\x40', 4), dhcp.option(dhcp.DHCP_REBINDING_TIME_OPT, b'\x00\x03\x75\xf0', 4), dhcp.option(dhcp.DHCP_SERVER_IDENTIFIER_OPT, b'\xc0\xa8\x0a\x09', 4)] magic_cookie = '99.130.83.99' options = dhcp.options(option_list=option_list, options_len=50, magic_cookie=magic_cookie) dh = dhcp.dhcp(op, chaddr, options, htype=htype, hlen=hlen, hops=hops, xid=xid, secs=secs, flags=flags, ciaddr=ciaddr, yiaddr=yiaddr, siaddr=siaddr, giaddr=giaddr, sname=sname, boot_file=boot_file) buf = ( b"\x02\x01\x06\x00\x00\x00\x00\x01\x00\x00\x00\x01\xc0\xa8\x0a\x0a" b"\xc0\xa8\x14\x14\xc0\xa8\x1e\x1e\xc0\xa8\x28\x28\xaa\xaa\xaa\xaa" b"\xaa\xaa\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x61\x62\x63\x00" b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x63\x82\x53\x63" b"\x35\x01\x02\x01\x04\xff\xff\xff\x00\x03\x04\xc0\xa8\x0a\x09\x06" b"\x04\xc0\xa8\x0a\x09\x33\x04\x00\x03\xf4\x80\x3a\x04\x00\x01\xfa" b"\x40\x3b\x04\x00\x03\x75\xf0\x36\x04\xc0\xa8\x0a\x09\xff") def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(self.op, self.dh.op) self.assertEqual(self.htype, self.dh.htype) self.assertEqual(self.hlen, self.dh.hlen) self.assertEqual(self.hops, self.dh.hops) self.assertEqual(self.xid, self.dh.xid) self.assertEqual(self.secs, self.dh.secs) self.assertEqual(self.flags, self.dh.flags) self.assertEqual(self.ciaddr, self.dh.ciaddr) self.assertEqual(self.yiaddr, self.dh.yiaddr) self.assertEqual(self.siaddr, self.dh.siaddr) self.assertEqual(self.giaddr, self.dh.giaddr) self.assertEqual(self.chaddr, self.dh.chaddr) self.assertEqual(self.sname, self.dh.sname) self.assertEqual(self.boot_file, self.dh.boot_file) self.assertEqual(str(self.options), str(self.dh.options)) def test_parser(self): res, _, rest = dhcp.dhcp.parser(self.buf) self.assertEqual(self.op, res.op) self.assertEqual(self.htype, res.htype) self.assertEqual(self.hlen, res.hlen) self.assertEqual(self.hops, res.hops) self.assertEqual(self.xid, res.xid) self.assertEqual(self.secs, res.secs) self.assertEqual(self.flags, res.flags) self.assertEqual(self.ciaddr, res.ciaddr) self.assertEqual(self.yiaddr, res.yiaddr) self.assertEqual(self.siaddr, res.siaddr) self.assertEqual(self.giaddr, res.giaddr) self.assertEqual(self.chaddr, res.chaddr) # sname is 64 byte length. rest of data is filled by '\x00'. self.assertEqual(self.sname.ljust(64, '\x00'), res.sname) # boof_file is 128 byte length. rest of data is filled by '\x00'. self.assertEqual(self.boot_file.ljust(128, '\x00'), res.boot_file) self.assertEqual(str(self.options), str(res.options)) self.assertEqual(b'', rest) def test_parser_corrupted(self): corrupt_buf = self.buf[:-4] pkt, _, rest = dhcp.dhcp.parser(corrupt_buf) self.assertTrue(isinstance(pkt, dhcp.dhcp)) self.assertTrue(isinstance(pkt.options, dhcp.options)) for opt in pkt.options.option_list[:-1]: self.assertTrue(isinstance(opt, dhcp.option)) self.assertTrue(isinstance(pkt.options.option_list[-1], bytes)) buf = pkt.serialize() self.assertEqual(str(buf), str(corrupt_buf)) self.assertEqual(b'', rest) def test_serialize(self): buf = self.dh.serialize() res = struct.unpack_from(dhcp.dhcp._DHCP_PACK_STR, bytes(buf)) self.assertEqual(self.op, res[0]) self.assertEqual(self.htype, res[1]) self.assertEqual(self.hlen, res[2]) self.assertEqual(self.hops, res[3]) self.assertEqual(self.xid, res[4]) self.assertEqual(self.secs, res[5]) self.assertEqual(self.flags, res[6]) self.assertEqual(self.ciaddr, addrconv.ipv4.bin_to_text(res[7])) self.assertEqual(self.yiaddr, addrconv.ipv4.bin_to_text(res[8])) self.assertEqual(self.siaddr, addrconv.ipv4.bin_to_text(res[9])) self.assertEqual(self.giaddr, addrconv.ipv4.bin_to_text(res[10])) self.assertEqual(self.chaddr, addrconv.mac.bin_to_text(res[11][:6])) # sname is 64 byte length. rest of data is filled by '\x00'. self.assertEqual(self.sname.ljust(64, '\x00'), res[12].decode('ascii')) # boof_file is 128 byte length. rest of data is filled by '\x00'. self.assertEqual(self.boot_file.ljust(128, '\x00'), res[13].decode('ascii')) options = dhcp.options.parser( buf[struct.calcsize(dhcp.dhcp._DHCP_PACK_STR):]) self.assertEqual(str(self.options), str(options)) def test_to_string(self): option_values = ['tag', 'length', 'value'] opt_str_list = [] for option in self.option_list: _opt_str = ','.join(['%s=%s' % (k, repr(getattr(option, k))) for k, v in inspect.getmembers(option) if k in option_values]) opt_str = '%s(%s)' % (dhcp.option.__name__, _opt_str) opt_str_list.append(opt_str) option_str = '[%s]' % ', '.join(opt_str_list) opts_vals = {'magic_cookie': repr(self.magic_cookie), 'option_list': option_str, 'options_len': repr(self.options.options_len)} _options_str = ','.join(['%s=%s' % (k, opts_vals[k]) for k, v in inspect.getmembers(self.options) if k in opts_vals]) options_str = '%s(%s)' % (dhcp.options.__name__, _options_str) dhcp_values = {'op': repr(self.op), 'htype': repr(self.htype), 'hlen': repr(self.hlen), 'hops': repr(self.hops), 'xid': repr(self.xid), 'secs': repr(self.secs), 'flags': repr(self.flags), 'ciaddr': repr(self.ciaddr), 'yiaddr': repr(self.yiaddr), 'siaddr': repr(self.siaddr), 'giaddr': repr(self.giaddr), 'chaddr': repr(self.chaddr), 'sname': repr(self.sname), 'boot_file': repr(self.boot_file), 'options': options_str} _dh_str = ','.join(['%s=%s' % (k, dhcp_values[k]) for k, v in inspect.getmembers(self.dh) if k in dhcp_values]) dh_str = '%s(%s)' % (dhcp.dhcp.__name__, _dh_str) self.assertEqual(str(self.dh), dh_str) self.assertEqual(repr(self.dh), dh_str) def test_json(self): jsondict = self.dh.to_jsondict() dh = dhcp.dhcp.from_jsondict(jsondict['dhcp']) self.assertEqual(str(self.dh), str(dh)) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/packet/test_ethernet.py0000664000175000017500000000565700000000000023123 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone 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. import unittest import logging import struct from struct import * from os_ken.ofproto import ether, inet from os_ken.lib.packet.ethernet import ethernet from os_ken.lib.packet.arp import arp from os_ken.lib import addrconv LOG = logging.getLogger('test_ethernet') class Test_ethernet(unittest.TestCase): """ Test case for ethernet """ dst = 'aa:aa:aa:aa:aa:aa' src = 'bb:bb:bb:bb:bb:bb' ethertype = ether.ETH_TYPE_ARP buf = pack(ethernet._PACK_STR, addrconv.mac.text_to_bin(dst), addrconv.mac.text_to_bin(src), ethertype) e = ethernet(dst, src, ethertype) def setUp(self): pass def tearDown(self): pass def find_protocol(self, pkt, name): for p in pkt.protocols: if p.protocol_name == name: return p def test_init(self): self.assertEqual(self.dst, self.e.dst) self.assertEqual(self.src, self.e.src) self.assertEqual(self.ethertype, self.e.ethertype) def test_parser(self): res, ptype, _ = self.e.parser(self.buf) LOG.debug((res, ptype)) self.assertEqual(res.dst, self.dst) self.assertEqual(res.src, self.src) self.assertEqual(res.ethertype, self.ethertype) self.assertEqual(ptype, arp) def test_serialize(self): data = bytearray() prev = None buf = self.e.serialize(data, prev) fmt = ethernet._PACK_STR res = struct.unpack(fmt, buf) self.assertEqual(res[0], addrconv.mac.text_to_bin(self.dst)) self.assertEqual(res[1], addrconv.mac.text_to_bin(self.src)) self.assertEqual(res[2], self.ethertype) def test_malformed_ethernet(self): m_short_buf = self.buf[1:ethernet._MIN_LEN] self.assertRaises(Exception, ethernet.parser, m_short_buf) def test_default_args(self): e = ethernet() buf = e.serialize(bytearray(), None) res = struct.unpack(e._PACK_STR, bytes(buf)) self.assertEqual(res[0], addrconv.mac.text_to_bin('ff:ff:ff:ff:ff:ff')) self.assertEqual(res[1], addrconv.mac.text_to_bin('00:00:00:00:00:00')) self.assertEqual(res[2], ether.ETH_TYPE_IP) def test_json(self): jsondict = self.e.to_jsondict() e = ethernet.from_jsondict(jsondict['ethernet']) self.assertEqual(str(self.e), str(e)) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/packet/test_geneve.py0000664000175000017500000000347400000000000022551 0ustar00zuulzuul00000000000000# Copyright (C) 2016 Nippon Telegraph and Telephone 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. import logging import os import sys import unittest from os_ken.lib import pcaplib from os_ken.lib.packet import geneve from os_ken.lib.packet import packet from os_ken.utils import binary_str LOG = logging.getLogger(__name__) GENEVE_DATA_DIR = os.path.join( os.path.dirname(sys.modules[__name__].__file__), '../../packet_data/pcap/') class Test_geneve(unittest.TestCase): """ Test case for os_ken.lib.packet.geneve. """ def test_parser(self): files = [ 'geneve_unknown', ] for f in files: # print('*** testing %s ...' % f) for _, buf in pcaplib.Reader( open(GENEVE_DATA_DIR + f + '.pcap', 'rb')): # Checks if message can be parsed as expected. pkt = packet.Packet(buf) geneve_pkt = pkt.get_protocol(geneve.geneve) self.assertTrue(isinstance(geneve_pkt, geneve.geneve), 'Failed to parse Geneve message: %s' % pkt) # Checks if message can be serialized as expected. pkt.serialize() self.assertEqual(buf, pkt.data, "b'%s' != b'%s'" % (binary_str(buf), binary_str(pkt.data))) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/packet/test_gre.py0000664000175000017500000000714300000000000022052 0ustar00zuulzuul00000000000000# Copyright (C) 2016 Nippon Telegraph and Telephone 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. import logging import os import sys import unittest from os_ken.lib import pcaplib from os_ken.lib.packet import gre from os_ken.lib.packet import packet from os_ken.utils import binary_str from os_ken.lib.packet.ether_types import ETH_TYPE_IP, ETH_TYPE_TEB LOG = logging.getLogger(__name__) GENEVE_DATA_DIR = os.path.join( os.path.dirname(sys.modules[__name__].__file__), '../../packet_data/pcap/') class Test_gre(unittest.TestCase): """ Test case gre for os_ken.lib.packet.gre. """ version = 0 gre_proto = ETH_TYPE_IP nvgre_proto = ETH_TYPE_TEB checksum = 0x440d seq_number = 10 key = 256100 vsid = 1000 flow_id = 100 gre = gre.gre(version=version, protocol=gre_proto, checksum=checksum, key=key, seq_number=seq_number) def test_key_setter(self): self.gre.key = self.key self.assertEqual(self.gre._key, self.key) self.assertEqual(self.gre._vsid, self.vsid) self.assertEqual(self.gre._flow_id, self.flow_id) def test_key_setter_none(self): self.gre.key = None self.assertEqual(self.gre._key, None) self.assertEqual(self.gre._vsid, None) self.assertEqual(self.gre._flow_id, None) self.gre.key = self.key def test_vsid_setter(self): self.gre.vsid = self.vsid self.assertEqual(self.gre._key, self.key) self.assertEqual(self.gre._vsid, self.vsid) self.assertEqual(self.gre._flow_id, self.flow_id) def test_flowid_setter(self): self.gre.flow_id = self.flow_id self.assertEqual(self.gre._key, self.key) self.assertEqual(self.gre._vsid, self.vsid) self.assertEqual(self.gre._flow_id, self.flow_id) def test_nvgre_init(self): nvgre = gre.nvgre(version=self.version, vsid=self.vsid, flow_id=self.flow_id) self.assertEqual(nvgre.version, self.version) self.assertEqual(nvgre.protocol, self.nvgre_proto) self.assertEqual(nvgre.checksum, None) self.assertEqual(nvgre.seq_number, None) self.assertEqual(nvgre._key, self.key) self.assertEqual(nvgre._vsid, self.vsid) self.assertEqual(nvgre._flow_id, self.flow_id) def test_parser(self): files = [ 'gre_full_options', 'gre_no_option', 'gre_nvgre_option', ] for f in files: # print('*** testing %s ...' % f) for _, buf in pcaplib.Reader( open(GENEVE_DATA_DIR + f + '.pcap', 'rb')): # Checks if message can be parsed as expected. pkt = packet.Packet(buf) gre_pkt = pkt.get_protocol(gre.gre) self.assertTrue(isinstance(gre_pkt, gre.gre), 'Failed to parse Gre message: %s' % pkt) # Checks if message can be serialized as expected. pkt.serialize() self.assertEqual(buf, pkt.data, "b'%s' != b'%s'" % (binary_str(buf), binary_str(pkt.data))) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/packet/test_icmp.py0000664000175000017500000003016700000000000022227 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone 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. import inspect import logging import struct import unittest from os_ken.lib.packet import icmp from os_ken.lib.packet import packet_utils LOG = logging.getLogger(__name__) class Test_icmp(unittest.TestCase): echo_id = None echo_seq = None echo_data = None unreach_mtu = None unreach_data = None unreach_data_len = None te_data = None te_data_len = None def setUp(self): self.type_ = icmp.ICMP_ECHO_REQUEST self.code = 0 self.csum = 0 self.data = b'' self.ic = icmp.icmp(self.type_, self.code, self.csum, self.data) self.buf = bytearray(struct.pack( icmp.icmp._PACK_STR, self.type_, self.code, self.csum)) self.csum_calc = packet_utils.checksum(self.buf) struct.pack_into('!H', self.buf, 2, self.csum_calc) def setUp_with_echo(self): self.echo_id = 13379 self.echo_seq = 1 self.echo_data = b'\x30\x0e\x09\x00\x00\x00\x00\x00' \ + b'\x10\x11\x12\x13\x14\x15\x16\x17' \ + b'\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f' \ + b'\x20\x21\x22\x23\x24\x25\x26\x27' \ + b'\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f' \ + b'\x30\x31\x32\x33\x34\x35\x36\x37' self.data = icmp.echo( id_=self.echo_id, seq=self.echo_seq, data=self.echo_data) self.type_ = icmp.ICMP_ECHO_REQUEST self.code = 0 self.ic = icmp.icmp(self.type_, self.code, self.csum, self.data) self.buf = bytearray(struct.pack( icmp.icmp._PACK_STR, self.type_, self.code, self.csum)) self.buf += self.data.serialize() self.csum_calc = packet_utils.checksum(self.buf) struct.pack_into('!H', self.buf, 2, self.csum_calc) def setUp_with_dest_unreach(self): self.unreach_mtu = 10 self.unreach_data = b'abc' self.unreach_data_len = len(self.unreach_data) self.data = icmp.dest_unreach( data_len=self.unreach_data_len, mtu=self.unreach_mtu, data=self.unreach_data) self.type_ = icmp.ICMP_DEST_UNREACH self.code = icmp.ICMP_HOST_UNREACH_CODE self.ic = icmp.icmp(self.type_, self.code, self.csum, self.data) self.buf = bytearray(struct.pack( icmp.icmp._PACK_STR, self.type_, self.code, self.csum)) self.buf += self.data.serialize() self.csum_calc = packet_utils.checksum(self.buf) struct.pack_into('!H', self.buf, 2, self.csum_calc) def setUp_with_TimeExceeded(self): self.te_data = b'abc' self.te_data_len = len(self.te_data) self.data = icmp.TimeExceeded( data_len=self.te_data_len, data=self.te_data) self.type_ = icmp.ICMP_TIME_EXCEEDED self.code = 0 self.ic = icmp.icmp(self.type_, self.code, self.csum, self.data) self.buf = bytearray(struct.pack( icmp.icmp._PACK_STR, self.type_, self.code, self.csum)) self.buf += self.data.serialize() self.csum_calc = packet_utils.checksum(self.buf) struct.pack_into('!H', self.buf, 2, self.csum_calc) def test_init(self): self.assertEqual(self.type_, self.ic.type) self.assertEqual(self.code, self.ic.code) self.assertEqual(self.csum, self.ic.csum) self.assertEqual(str(self.data), str(self.ic.data)) def test_init_with_echo(self): self.setUp_with_echo() self.test_init() def test_init_with_dest_unreach(self): self.setUp_with_dest_unreach() self.test_init() def test_init_with_TimeExceeded(self): self.setUp_with_TimeExceeded() self.test_init() def test_parser(self): _res = icmp.icmp.parser(bytes(self.buf)) if type(_res) is tuple: res = _res[0] else: res = _res self.assertEqual(self.type_, res.type) self.assertEqual(self.code, res.code) self.assertEqual(self.csum_calc, res.csum) self.assertEqual(str(self.data), str(res.data)) def test_parser_with_echo(self): self.setUp_with_echo() self.test_parser() def test_parser_with_dest_unreach(self): self.setUp_with_dest_unreach() self.test_parser() def test_parser_with_TimeExceeded(self): self.setUp_with_TimeExceeded() self.test_parser() def test_serialize(self): data = bytearray() prev = None buf = self.ic.serialize(data, prev) res = struct.unpack_from(icmp.icmp._PACK_STR, bytes(buf)) self.assertEqual(self.type_, res[0]) self.assertEqual(self.code, res[1]) self.assertEqual(self.csum_calc, res[2]) def test_serialize_with_echo(self): self.setUp_with_echo() self.test_serialize() data = bytearray() prev = None buf = self.ic.serialize(data, prev) echo = icmp.echo.parser(bytes(buf), icmp.icmp._MIN_LEN) self.assertEqual(repr(self.data), repr(echo)) def test_serialize_with_dest_unreach(self): self.setUp_with_dest_unreach() self.test_serialize() data = bytearray() prev = None buf = self.ic.serialize(data, prev) unreach = icmp.dest_unreach.parser(bytes(buf), icmp.icmp._MIN_LEN) self.assertEqual(repr(self.data), repr(unreach)) def test_serialize_with_TimeExceeded(self): self.setUp_with_TimeExceeded() self.test_serialize() data = bytearray() prev = None buf = self.ic.serialize(data, prev) te = icmp.TimeExceeded.parser(bytes(buf), icmp.icmp._MIN_LEN) self.assertEqual(repr(self.data), repr(te)) def test_to_string(self): icmp_values = {'type': repr(self.type_), 'code': repr(self.code), 'csum': repr(self.csum), 'data': repr(self.data)} _ic_str = ','.join(['%s=%s' % (k, icmp_values[k]) for k, v in inspect.getmembers(self.ic) if k in icmp_values]) ic_str = '%s(%s)' % (icmp.icmp.__name__, _ic_str) self.assertEqual(str(self.ic), ic_str) self.assertEqual(repr(self.ic), ic_str) def test_to_string_with_echo(self): self.setUp_with_echo() self.test_to_string() def test_to_string_with_dest_unreach(self): self.setUp_with_dest_unreach() self.test_to_string() def test_to_string_with_TimeExceeded(self): self.setUp_with_TimeExceeded() self.test_to_string() def test_default_args(self): ic = icmp.icmp() buf = ic.serialize(bytearray(), None) res = struct.unpack(icmp.icmp._PACK_STR, bytes(buf[:4])) self.assertEqual(res[0], 8) self.assertEqual(res[1], 0) self.assertEqual(buf[4:], b'\x00\x00\x00\x00') # with data ic = icmp.icmp(type_=icmp.ICMP_DEST_UNREACH, data=icmp.dest_unreach()) buf = ic.serialize(bytearray(), None) res = struct.unpack(icmp.icmp._PACK_STR, bytes(buf[:4])) self.assertEqual(res[0], 3) self.assertEqual(res[1], 0) self.assertEqual(buf[4:], b'\x00\x00\x00\x00') def test_json(self): jsondict = self.ic.to_jsondict() ic = icmp.icmp.from_jsondict(jsondict['icmp']) self.assertEqual(str(self.ic), str(ic)) def test_json_with_echo(self): self.setUp_with_echo() self.test_json() def test_json_with_dest_unreach(self): self.setUp_with_dest_unreach() self.test_json() def test_json_with_TimeExceeded(self): self.setUp_with_TimeExceeded() self.test_json() class Test_echo(unittest.TestCase): def setUp(self): self.id_ = 13379 self.seq = 1 self.data = b'\x30\x0e\x09\x00\x00\x00\x00\x00' \ + b'\x10\x11\x12\x13\x14\x15\x16\x17' \ + b'\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f' \ + b'\x20\x21\x22\x23\x24\x25\x26\x27' \ + b'\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f' \ + b'\x30\x31\x32\x33\x34\x35\x36\x37' self.echo = icmp.echo( self.id_, self.seq, self.data) self.buf = struct.pack('!HH', self.id_, self.seq) self.buf += self.data def test_init(self): self.assertEqual(self.id_, self.echo.id) self.assertEqual(self.seq, self.echo.seq) self.assertEqual(self.data, self.echo.data) def test_parser(self): _res = icmp.echo.parser(self.buf, 0) if type(_res) is tuple: res = _res[0] else: res = _res self.assertEqual(self.id_, res.id) self.assertEqual(self.seq, res.seq) self.assertEqual(self.data, res.data) def test_serialize(self): buf = self.echo.serialize() res = struct.unpack_from('!HH', bytes(buf)) self.assertEqual(self.id_, res[0]) self.assertEqual(self.seq, res[1]) self.assertEqual(self.data, buf[struct.calcsize('!HH'):]) def test_default_args(self): ec = icmp.echo() buf = ec.serialize() res = struct.unpack(icmp.echo._PACK_STR, bytes(buf)) self.assertEqual(res[0], 0) self.assertEqual(res[1], 0) class Test_dest_unreach(unittest.TestCase): def setUp(self): self.mtu = 10 self.data = b'abc' self.data_len = len(self.data) self.dest_unreach = icmp.dest_unreach( data_len=self.data_len, mtu=self.mtu, data=self.data) self.buf = struct.pack('!xBH', self.data_len, self.mtu) self.buf += self.data def test_init(self): self.assertEqual(self.data_len, self.dest_unreach.data_len) self.assertEqual(self.mtu, self.dest_unreach.mtu) self.assertEqual(self.data, self.dest_unreach.data) def test_parser(self): _res = icmp.dest_unreach.parser(self.buf, 0) if type(_res) is tuple: res = _res[0] else: res = _res self.assertEqual(self.data_len, res.data_len) self.assertEqual(self.mtu, res.mtu) self.assertEqual(self.data, res.data) def test_serialize(self): buf = self.dest_unreach.serialize() res = struct.unpack_from('!xBH', bytes(buf)) self.assertEqual(self.data_len, res[0]) self.assertEqual(self.mtu, res[1]) self.assertEqual(self.data, buf[struct.calcsize('!xBH'):]) def test_default_args(self): du = icmp.dest_unreach() buf = du.serialize() res = struct.unpack(icmp.dest_unreach._PACK_STR, bytes(buf)) self.assertEqual(res[0], 0) self.assertEqual(res[1], 0) class Test_TimeExceeded(unittest.TestCase): def setUp(self): self.data = b'abc' self.data_len = len(self.data) self.te = icmp.TimeExceeded( data_len=self.data_len, data=self.data) self.buf = struct.pack('!xBxx', self.data_len) self.buf += self.data def test_init(self): self.assertEqual(self.data_len, self.te.data_len) self.assertEqual(self.data, self.te.data) def test_parser(self): _res = icmp.TimeExceeded.parser(self.buf, 0) if type(_res) is tuple: res = _res[0] else: res = _res self.assertEqual(self.data_len, res.data_len) self.assertEqual(self.data, res.data) def test_serialize(self): buf = self.te.serialize() res = struct.unpack_from('!xBxx', bytes(buf)) self.assertEqual(self.data_len, res[0]) self.assertEqual(self.data, buf[struct.calcsize('!xBxx'):]) def test_default_args(self): te = icmp.TimeExceeded() buf = te.serialize() res = struct.unpack(icmp.TimeExceeded._PACK_STR, bytes(buf)) self.assertEqual(res[0], 0) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/packet/test_icmpv6.py0000664000175000017500000022515700000000000022510 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone 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. import unittest import logging import struct import inspect from os_ken.ofproto import ether, inet from os_ken.lib.packet.ethernet import ethernet from os_ken.lib.packet import icmpv6 from os_ken.lib.packet.ipv6 import ipv6 from os_ken.lib.packet import packet_utils from os_ken.lib import addrconv LOG = logging.getLogger(__name__) def icmpv6_csum(prev, buf): ph = struct.pack('!16s16sI3xB', addrconv.ipv6.text_to_bin(prev.src), addrconv.ipv6.text_to_bin(prev.dst), prev.payload_length, prev.nxt) h = bytearray(buf) struct.pack_into('!H', h, 2, 0) return packet_utils.checksum(ph + h) class Test_icmpv6_header(unittest.TestCase): type_ = 255 code = 0 csum = 207 buf = b'\xff\x00\x00\xcf' icmp = icmpv6.icmpv6(type_, code, 0) def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(self.type_, self.icmp.type_) self.assertEqual(self.code, self.icmp.code) self.assertEqual(0, self.icmp.csum) def test_parser(self): msg, n, _ = self.icmp.parser(self.buf) self.assertEqual(msg.type_, self.type_) self.assertEqual(msg.code, self.code) self.assertEqual(msg.csum, self.csum) self.assertEqual(msg.data, b'') self.assertEqual(n, None) def test_serialize(self): src_ipv6 = 'fe80::200:ff:fe00:ef' dst_ipv6 = 'fe80::200:ff:fe00:1' prev = ipv6(6, 0, 0, 4, 58, 255, src_ipv6, dst_ipv6) buf = self.icmp.serialize(bytearray(), prev) (type_, code, csum) = struct.unpack(self.icmp._PACK_STR, bytes(buf)) self.assertEqual(type_, self.type_) self.assertEqual(code, self.code) self.assertEqual(csum, self.csum) def test_malformed_icmpv6(self): m_short_buf = self.buf[1:self.icmp._MIN_LEN] self.assertRaises(struct.error, self.icmp.parser, m_short_buf) def test_default_args(self): prev = ipv6(nxt=inet.IPPROTO_ICMPV6) ic = icmpv6.icmpv6() prev.serialize(ic, None) buf = ic.serialize(bytearray(), prev) res = struct.unpack(icmpv6.icmpv6._PACK_STR, bytes(buf)) self.assertEqual(res[0], 0) self.assertEqual(res[1], 0) self.assertEqual(res[2], icmpv6_csum(prev, buf)) def test_json(self): jsondict = self.icmp.to_jsondict() icmp = icmpv6.icmpv6.from_jsondict(jsondict['icmpv6']) self.assertEqual(str(self.icmp), str(icmp)) class Test_icmpv6_echo_request(unittest.TestCase): type_ = 128 code = 0 csum = 0xa572 id_ = 0x7620 seq = 0 data = b'\x01\xc9\xe7\x36\xd3\x39\x06\x00' buf = b'\x80\x00\xa5\x72\x76\x20\x00\x00' def setUp(self): pass def tearDown(self): pass def test_init(self): echo = icmpv6.echo(0, 0) self.assertEqual(echo.id, 0) self.assertEqual(echo.seq, 0) self.assertEqual(echo.data, None) def _test_parser(self, data=None): buf = self.buf + (data or b'') msg, n, _ = icmpv6.icmpv6.parser(buf) self.assertEqual(msg.type_, self.type_) self.assertEqual(msg.code, self.code) self.assertEqual(msg.csum, self.csum) self.assertEqual(msg.data.id, self.id_) self.assertEqual(msg.data.seq, self.seq) self.assertEqual(msg.data.data, data) self.assertEqual(n, None) def test_parser_without_data(self): self._test_parser() def test_parser_with_data(self): self._test_parser(self.data) def _test_serialize(self, echo_data=None): buf = self.buf + (echo_data or b'') src_ipv6 = '3ffe:507:0:1:200:86ff:fe05:80da' dst_ipv6 = '3ffe:501:0:1001::2' prev = ipv6(6, 0, 0, len(buf), 64, 255, src_ipv6, dst_ipv6) echo_csum = icmpv6_csum(prev, buf) echo = icmpv6.echo(self.id_, self.seq, echo_data) icmp = icmpv6.icmpv6(self.type_, self.code, 0, echo) buf = bytes(icmp.serialize(bytearray(), prev)) (type_, code, csum) = struct.unpack_from(icmp._PACK_STR, buf, 0) (id_, seq) = struct.unpack_from(echo._PACK_STR, buf, icmp._MIN_LEN) data = buf[(icmp._MIN_LEN + echo._MIN_LEN):] data = data if len(data) != 0 else None self.assertEqual(type_, self.type_) self.assertEqual(code, self.code) self.assertEqual(csum, echo_csum) self.assertEqual(id_, self.id_) self.assertEqual(seq, self.seq) self.assertEqual(data, echo_data) def test_serialize_without_data(self): self._test_serialize() def test_serialize_with_data(self): self._test_serialize(self.data) def test_to_string(self): ec = icmpv6.echo(self.id_, self.seq, self.data) ic = icmpv6.icmpv6(self.type_, self.code, self.csum, ec) echo_values = {'id': self.id_, 'seq': self.seq, 'data': self.data} _echo_str = ','.join(['%s=%s' % (k, repr(echo_values[k])) for k, v in inspect.getmembers(ec) if k in echo_values]) echo_str = '%s(%s)' % (icmpv6.echo.__name__, _echo_str) icmp_values = {'type_': repr(self.type_), 'code': repr(self.code), 'csum': repr(self.csum), 'data': echo_str} _ic_str = ','.join(['%s=%s' % (k, icmp_values[k]) for k, v in inspect.getmembers(ic) if k in icmp_values]) ic_str = '%s(%s)' % (icmpv6.icmpv6.__name__, _ic_str) self.assertEqual(str(ic), ic_str) self.assertEqual(repr(ic), ic_str) def test_default_args(self): prev = ipv6(nxt=inet.IPPROTO_ICMPV6) ic = icmpv6.icmpv6( type_=icmpv6.ICMPV6_ECHO_REQUEST, data=icmpv6.echo()) prev.serialize(ic, None) buf = ic.serialize(bytearray(), prev) res = struct.unpack(icmpv6.icmpv6._PACK_STR, bytes(buf[:4])) self.assertEqual(res[0], icmpv6.ICMPV6_ECHO_REQUEST) self.assertEqual(res[1], 0) self.assertEqual(res[2], icmpv6_csum(prev, buf)) res = struct.unpack(icmpv6.echo._PACK_STR, bytes(buf[4:])) self.assertEqual(res[0], 0) self.assertEqual(res[1], 0) def test_json(self): ec = icmpv6.echo(self.id_, self.seq, self.data) ic1 = icmpv6.icmpv6(self.type_, self.code, self.csum, ec) jsondict = ic1.to_jsondict() ic2 = icmpv6.icmpv6.from_jsondict(jsondict['icmpv6']) self.assertEqual(str(ic1), str(ic2)) class Test_icmpv6_echo_reply(Test_icmpv6_echo_request): def setUp(self): self.type_ = 129 self.csum = 0xa472 self.buf = b'\x81\x00\xa4\x72\x76\x20\x00\x00' def test_default_args(self): prev = ipv6(nxt=inet.IPPROTO_ICMPV6) ic = icmpv6.icmpv6( type_=icmpv6.ICMPV6_ECHO_REPLY, data=icmpv6.echo()) prev.serialize(ic, None) buf = ic.serialize(bytearray(), prev) res = struct.unpack(icmpv6.icmpv6._PACK_STR, bytes(buf[:4])) self.assertEqual(res[0], icmpv6.ICMPV6_ECHO_REPLY) self.assertEqual(res[1], 0) self.assertEqual(res[2], icmpv6_csum(prev, buf)) res = struct.unpack(icmpv6.echo._PACK_STR, bytes(buf[4:])) self.assertEqual(res[0], 0) self.assertEqual(res[1], 0) class Test_icmpv6_neighbor_solicit(unittest.TestCase): type_ = 135 code = 0 csum = 0x952d res = 0 dst = '3ffe:507:0:1:200:86ff:fe05:80da' nd_type = 1 nd_length = 1 nd_hw_src = '00:60:97:07:69:ea' data = b'\x01\x01\x00\x60\x97\x07\x69\xea' buf = b'\x87\x00\x95\x2d\x00\x00\x00\x00' \ + b'\x3f\xfe\x05\x07\x00\x00\x00\x01' \ + b'\x02\x00\x86\xff\xfe\x05\x80\xda' src_ipv6 = '3ffe:507:0:1:200:86ff:fe05:80da' dst_ipv6 = '3ffe:501:0:1001::2' def setUp(self): pass def tearDown(self): pass def test_init(self): nd = icmpv6.nd_neighbor(self.res, self.dst) self.assertEqual(nd.res, self.res) self.assertEqual(nd.dst, self.dst) self.assertEqual(nd.option, None) def _test_parser(self, data=None): buf = self.buf + (data or b'') msg, n, _ = icmpv6.icmpv6.parser(buf) self.assertEqual(msg.type_, self.type_) self.assertEqual(msg.code, self.code) self.assertEqual(msg.csum, self.csum) self.assertEqual(msg.data.res, self.res) self.assertEqual(addrconv.ipv6.text_to_bin(msg.data.dst), addrconv.ipv6.text_to_bin(self.dst)) self.assertEqual(n, None) if data: nd = msg.data.option self.assertEqual(nd.length, self.nd_length) self.assertEqual(nd.hw_src, self.nd_hw_src) self.assertEqual(nd.data, None) def test_parser_without_data(self): self._test_parser() def test_parser_with_data(self): self._test_parser(self.data) def test_serialize_without_data(self): nd = icmpv6.nd_neighbor(self.res, self.dst) prev = ipv6(6, 0, 0, 24, 64, 255, self.src_ipv6, self.dst_ipv6) nd_csum = icmpv6_csum(prev, self.buf) icmp = icmpv6.icmpv6(self.type_, self.code, 0, nd) buf = bytes(icmp.serialize(bytearray(), prev)) (type_, code, csum) = struct.unpack_from(icmp._PACK_STR, buf, 0) (res, dst) = struct.unpack_from(nd._PACK_STR, buf, icmp._MIN_LEN) data = buf[(icmp._MIN_LEN + nd._MIN_LEN):] self.assertEqual(type_, self.type_) self.assertEqual(code, self.code) self.assertEqual(csum, nd_csum) self.assertEqual(res >> 29, self.res) self.assertEqual(dst, addrconv.ipv6.text_to_bin(self.dst)) self.assertEqual(data, b'') def test_serialize_with_data(self): nd_opt = icmpv6.nd_option_sla(self.nd_length, self.nd_hw_src) nd = icmpv6.nd_neighbor(self.res, self.dst, nd_opt) prev = ipv6(6, 0, 0, 32, 64, 255, self.src_ipv6, self.dst_ipv6) nd_csum = icmpv6_csum(prev, self.buf + self.data) icmp = icmpv6.icmpv6(self.type_, self.code, 0, nd) buf = bytes(icmp.serialize(bytearray(), prev)) (type_, code, csum) = struct.unpack_from(icmp._PACK_STR, buf, 0) (res, dst) = struct.unpack_from(nd._PACK_STR, buf, icmp._MIN_LEN) (nd_type, nd_length, nd_hw_src) = struct.unpack_from( nd_opt._PACK_STR, buf, icmp._MIN_LEN + nd._MIN_LEN) data = buf[(icmp._MIN_LEN + nd._MIN_LEN + 8):] self.assertEqual(type_, self.type_) self.assertEqual(code, self.code) self.assertEqual(csum, nd_csum) self.assertEqual(res >> 29, self.res) self.assertEqual(dst, addrconv.ipv6.text_to_bin(self.dst)) self.assertEqual(nd_type, self.nd_type) self.assertEqual(nd_length, self.nd_length) self.assertEqual(nd_hw_src, addrconv.mac.text_to_bin(self.nd_hw_src)) def test_to_string(self): nd_opt = icmpv6.nd_option_sla(self.nd_length, self.nd_hw_src) nd = icmpv6.nd_neighbor(self.res, self.dst, nd_opt) ic = icmpv6.icmpv6(self.type_, self.code, self.csum, nd) nd_opt_values = {'length': self.nd_length, 'hw_src': self.nd_hw_src, 'data': None} _nd_opt_str = ','.join(['%s=%s' % (k, repr(nd_opt_values[k])) for k, v in inspect.getmembers(nd_opt) if k in nd_opt_values]) nd_opt_str = '%s(%s)' % (icmpv6.nd_option_sla.__name__, _nd_opt_str) nd_values = {'res': repr(nd.res), 'dst': repr(self.dst), 'option': nd_opt_str} _nd_str = ','.join(['%s=%s' % (k, nd_values[k]) for k, v in inspect.getmembers(nd) if k in nd_values]) nd_str = '%s(%s)' % (icmpv6.nd_neighbor.__name__, _nd_str) icmp_values = {'type_': repr(self.type_), 'code': repr(self.code), 'csum': repr(self.csum), 'data': nd_str} _ic_str = ','.join(['%s=%s' % (k, icmp_values[k]) for k, v in inspect.getmembers(ic) if k in icmp_values]) ic_str = '%s(%s)' % (icmpv6.icmpv6.__name__, _ic_str) self.assertEqual(str(ic), ic_str) self.assertEqual(repr(ic), ic_str) def test_default_args(self): prev = ipv6(nxt=inet.IPPROTO_ICMPV6) ic = icmpv6.icmpv6( type_=icmpv6.ND_NEIGHBOR_SOLICIT, data=icmpv6.nd_neighbor()) prev.serialize(ic, None) buf = ic.serialize(bytearray(), prev) res = struct.unpack(icmpv6.icmpv6._PACK_STR, bytes(buf[:4])) self.assertEqual(res[0], icmpv6.ND_NEIGHBOR_SOLICIT) self.assertEqual(res[1], 0) self.assertEqual(res[2], icmpv6_csum(prev, buf)) res = struct.unpack(icmpv6.nd_neighbor._PACK_STR, bytes(buf[4:])) self.assertEqual(res[0], 0) self.assertEqual(res[1], addrconv.ipv6.text_to_bin('::')) # with nd_option_sla prev = ipv6(nxt=inet.IPPROTO_ICMPV6) ic = icmpv6.icmpv6( type_=icmpv6.ND_NEIGHBOR_SOLICIT, data=icmpv6.nd_neighbor( option=icmpv6.nd_option_sla())) prev.serialize(ic, None) buf = ic.serialize(bytearray(), prev) res = struct.unpack(icmpv6.icmpv6._PACK_STR, bytes(buf[:4])) self.assertEqual(res[0], icmpv6.ND_NEIGHBOR_SOLICIT) self.assertEqual(res[1], 0) self.assertEqual(res[2], icmpv6_csum(prev, buf)) res = struct.unpack(icmpv6.nd_neighbor._PACK_STR, bytes(buf[4:24])) self.assertEqual(res[0], 0) self.assertEqual(res[1], addrconv.ipv6.text_to_bin('::')) res = struct.unpack(icmpv6.nd_option_sla._PACK_STR, bytes(buf[24:])) self.assertEqual(res[0], icmpv6.ND_OPTION_SLA) self.assertEqual(res[1], len(icmpv6.nd_option_sla()) // 8) self.assertEqual(res[2], addrconv.mac.text_to_bin('00:00:00:00:00:00')) def test_json(self): nd_opt = icmpv6.nd_option_sla(self.nd_length, self.nd_hw_src) nd = icmpv6.nd_neighbor(self.res, self.dst, nd_opt) ic1 = icmpv6.icmpv6(self.type_, self.code, self.csum, nd) jsondict = ic1.to_jsondict() ic2 = icmpv6.icmpv6.from_jsondict(jsondict['icmpv6']) self.assertEqual(str(ic1), str(ic2)) class Test_icmpv6_neighbor_advert(Test_icmpv6_neighbor_solicit): def setUp(self): self.type_ = 136 self.csum = 0xb8ba self.res = 7 self.dst = '3ffe:507:0:1:260:97ff:fe07:69ea' self.nd_type = 2 self.nd_length = 1 self.nd_data = None self.nd_hw_src = '00:60:97:07:69:ea' self.data = b'\x02\x01\x00\x60\x97\x07\x69\xea' self.buf = b'\x88\x00\xb8\xba\xe0\x00\x00\x00' \ + b'\x3f\xfe\x05\x07\x00\x00\x00\x01' \ + b'\x02\x60\x97\xff\xfe\x07\x69\xea' def test_serialize_with_data(self): nd_opt = icmpv6.nd_option_tla(self.nd_length, self.nd_hw_src) nd = icmpv6.nd_neighbor(self.res, self.dst, nd_opt) prev = ipv6(6, 0, 0, 32, 64, 255, self.src_ipv6, self.dst_ipv6) nd_csum = icmpv6_csum(prev, self.buf + self.data) icmp = icmpv6.icmpv6(self.type_, self.code, 0, nd) buf = bytes(icmp.serialize(bytearray(), prev)) (type_, code, csum) = struct.unpack_from(icmp._PACK_STR, buf, 0) (res, dst) = struct.unpack_from(nd._PACK_STR, buf, icmp._MIN_LEN) (nd_type, nd_length, nd_hw_src) = struct.unpack_from( nd_opt._PACK_STR, buf, icmp._MIN_LEN + nd._MIN_LEN) data = buf[(icmp._MIN_LEN + nd._MIN_LEN + 8):] self.assertEqual(type_, self.type_) self.assertEqual(code, self.code) self.assertEqual(csum, nd_csum) self.assertEqual(res >> 29, self.res) self.assertEqual(dst, addrconv.ipv6.text_to_bin(self.dst)) self.assertEqual(nd_type, self.nd_type) self.assertEqual(nd_length, self.nd_length) self.assertEqual(nd_hw_src, addrconv.mac.text_to_bin(self.nd_hw_src)) def test_to_string(self): nd_opt = icmpv6.nd_option_tla(self.nd_length, self.nd_hw_src) nd = icmpv6.nd_neighbor(self.res, self.dst, nd_opt) ic = icmpv6.icmpv6(self.type_, self.code, self.csum, nd) nd_opt_values = {'length': self.nd_length, 'hw_src': self.nd_hw_src, 'data': None} _nd_opt_str = ','.join(['%s=%s' % (k, repr(nd_opt_values[k])) for k, v in inspect.getmembers(nd_opt) if k in nd_opt_values]) nd_opt_str = '%s(%s)' % (icmpv6.nd_option_tla.__name__, _nd_opt_str) nd_values = {'res': repr(nd.res), 'dst': repr(self.dst), 'option': nd_opt_str} _nd_str = ','.join(['%s=%s' % (k, nd_values[k]) for k, v in inspect.getmembers(nd) if k in nd_values]) nd_str = '%s(%s)' % (icmpv6.nd_neighbor.__name__, _nd_str) icmp_values = {'type_': repr(self.type_), 'code': repr(self.code), 'csum': repr(self.csum), 'data': nd_str} _ic_str = ','.join(['%s=%s' % (k, icmp_values[k]) for k, v in inspect.getmembers(ic) if k in icmp_values]) ic_str = '%s(%s)' % (icmpv6.icmpv6.__name__, _ic_str) self.assertEqual(str(ic), ic_str) self.assertEqual(repr(ic), ic_str) def test_default_args(self): prev = ipv6(nxt=inet.IPPROTO_ICMPV6) ic = icmpv6.icmpv6( type_=icmpv6.ND_NEIGHBOR_ADVERT, data=icmpv6.nd_neighbor()) prev.serialize(ic, None) buf = ic.serialize(bytearray(), prev) res = struct.unpack(icmpv6.icmpv6._PACK_STR, bytes(buf[:4])) self.assertEqual(res[0], icmpv6.ND_NEIGHBOR_ADVERT) self.assertEqual(res[1], 0) self.assertEqual(res[2], icmpv6_csum(prev, buf)) res = struct.unpack(icmpv6.nd_neighbor._PACK_STR, bytes(buf[4:])) self.assertEqual(res[0], 0) self.assertEqual(res[1], addrconv.ipv6.text_to_bin('::')) # with nd_option_tla prev = ipv6(nxt=inet.IPPROTO_ICMPV6) ic = icmpv6.icmpv6( type_=icmpv6.ND_NEIGHBOR_ADVERT, data=icmpv6.nd_neighbor( option=icmpv6.nd_option_tla())) prev.serialize(ic, None) buf = ic.serialize(bytearray(), prev) res = struct.unpack(icmpv6.icmpv6._PACK_STR, bytes(buf[:4])) self.assertEqual(res[0], icmpv6.ND_NEIGHBOR_ADVERT) self.assertEqual(res[1], 0) self.assertEqual(res[2], icmpv6_csum(prev, buf)) res = struct.unpack(icmpv6.nd_neighbor._PACK_STR, bytes(buf[4:24])) self.assertEqual(res[0], 0) self.assertEqual(res[1], addrconv.ipv6.text_to_bin('::')) res = struct.unpack(icmpv6.nd_option_tla._PACK_STR, bytes(buf[24:])) self.assertEqual(res[0], icmpv6.ND_OPTION_TLA) self.assertEqual(res[1], len(icmpv6.nd_option_tla()) // 8) self.assertEqual(res[2], addrconv.mac.text_to_bin('00:00:00:00:00:00')) class Test_icmpv6_router_solicit(unittest.TestCase): type_ = 133 code = 0 csum = 0x97d9 res = 0 nd_type = 1 nd_length = 1 nd_hw_src = '12:2d:a5:6d:bc:0f' data = b'\x00\x00\x00\x00\x01\x01\x12\x2d\xa5\x6d\xbc\x0f' buf = b'\x85\x00\x97\xd9' src_ipv6 = '3ffe:507:0:1:200:86ff:fe05:80da' dst_ipv6 = '3ffe:501:0:1001::2' def setUp(self): pass def tearDown(self): pass def test_init(self): rs = icmpv6.nd_router_solicit(self.res) self.assertEqual(rs.res, self.res) self.assertEqual(rs.option, None) def _test_parser(self, data=None): buf = self.buf + (data or b'') msg, n, _ = icmpv6.icmpv6.parser(buf) self.assertEqual(msg.type_, self.type_) self.assertEqual(msg.code, self.code) self.assertEqual(msg.csum, self.csum) if data is not None: self.assertEqual(msg.data.res, self.res) self.assertEqual(n, None) if data: rs = msg.data.option self.assertEqual(rs.length, self.nd_length) self.assertEqual(rs.hw_src, self.nd_hw_src) self.assertEqual(rs.data, None) def test_parser_without_data(self): self._test_parser() def test_parser_with_data(self): self._test_parser(self.data) def test_serialize_without_data(self): rs = icmpv6.nd_router_solicit(self.res) prev = ipv6(6, 0, 0, 8, 64, 255, self.src_ipv6, self.dst_ipv6) rs_csum = icmpv6_csum(prev, self.buf) icmp = icmpv6.icmpv6(self.type_, self.code, 0, rs) buf = bytes(icmp.serialize(bytearray(), prev)) (type_, code, csum) = struct.unpack_from(icmp._PACK_STR, buf, 0) res = struct.unpack_from(rs._PACK_STR, buf, icmp._MIN_LEN) data = buf[(icmp._MIN_LEN + rs._MIN_LEN):] self.assertEqual(type_, self.type_) self.assertEqual(code, self.code) self.assertEqual(csum, rs_csum) self.assertEqual(res[0], self.res) self.assertEqual(data, b'') def test_serialize_with_data(self): nd_opt = icmpv6.nd_option_sla(self.nd_length, self.nd_hw_src) rs = icmpv6.nd_router_solicit(self.res, nd_opt) prev = ipv6(6, 0, 0, 16, 64, 255, self.src_ipv6, self.dst_ipv6) rs_csum = icmpv6_csum(prev, self.buf + self.data) icmp = icmpv6.icmpv6(self.type_, self.code, 0, rs) buf = bytes(icmp.serialize(bytearray(), prev)) (type_, code, csum) = struct.unpack_from(icmp._PACK_STR, buf, 0) res = struct.unpack_from(rs._PACK_STR, buf, icmp._MIN_LEN) (nd_type, nd_length, nd_hw_src) = struct.unpack_from( nd_opt._PACK_STR, buf, icmp._MIN_LEN + rs._MIN_LEN) data = buf[(icmp._MIN_LEN + rs._MIN_LEN + 8):] self.assertEqual(type_, self.type_) self.assertEqual(code, self.code) self.assertEqual(csum, rs_csum) self.assertEqual(res[0], self.res) self.assertEqual(nd_type, self.nd_type) self.assertEqual(nd_length, self.nd_length) self.assertEqual(nd_hw_src, addrconv.mac.text_to_bin(self.nd_hw_src)) def test_to_string(self): nd_opt = icmpv6.nd_option_sla(self.nd_length, self.nd_hw_src) rs = icmpv6.nd_router_solicit(self.res, nd_opt) ic = icmpv6.icmpv6(self.type_, self.code, self.csum, rs) nd_opt_values = {'length': self.nd_length, 'hw_src': self.nd_hw_src, 'data': None} _nd_opt_str = ','.join(['%s=%s' % (k, repr(nd_opt_values[k])) for k, v in inspect.getmembers(nd_opt) if k in nd_opt_values]) nd_opt_str = '%s(%s)' % (icmpv6.nd_option_sla.__name__, _nd_opt_str) rs_values = {'res': repr(rs.res), 'option': nd_opt_str} _rs_str = ','.join(['%s=%s' % (k, rs_values[k]) for k, v in inspect.getmembers(rs) if k in rs_values]) rs_str = '%s(%s)' % (icmpv6.nd_router_solicit.__name__, _rs_str) icmp_values = {'type_': repr(self.type_), 'code': repr(self.code), 'csum': repr(self.csum), 'data': rs_str} _ic_str = ','.join(['%s=%s' % (k, icmp_values[k]) for k, v in inspect.getmembers(ic) if k in icmp_values]) ic_str = '%s(%s)' % (icmpv6.icmpv6.__name__, _ic_str) self.assertEqual(str(ic), ic_str) self.assertEqual(repr(ic), ic_str) def test_default_args(self): prev = ipv6(nxt=inet.IPPROTO_ICMPV6) ic = icmpv6.icmpv6( type_=icmpv6.ND_ROUTER_SOLICIT, data=icmpv6.nd_router_solicit()) prev.serialize(ic, None) buf = ic.serialize(bytearray(), prev) res = struct.unpack(icmpv6.icmpv6._PACK_STR, bytes(buf[:4])) self.assertEqual(res[0], icmpv6.ND_ROUTER_SOLICIT) self.assertEqual(res[1], 0) self.assertEqual(res[2], icmpv6_csum(prev, buf)) res = struct.unpack(icmpv6.nd_router_solicit._PACK_STR, bytes(buf[4:])) self.assertEqual(res[0], 0) # with nd_option_sla prev = ipv6(nxt=inet.IPPROTO_ICMPV6) ic = icmpv6.icmpv6( type_=icmpv6.ND_ROUTER_SOLICIT, data=icmpv6.nd_router_solicit( option=icmpv6.nd_option_sla())) prev.serialize(ic, None) buf = ic.serialize(bytearray(), prev) res = struct.unpack(icmpv6.icmpv6._PACK_STR, bytes(buf[:4])) self.assertEqual(res[0], icmpv6.ND_ROUTER_SOLICIT) self.assertEqual(res[1], 0) self.assertEqual(res[2], icmpv6_csum(prev, buf)) res = struct.unpack(icmpv6.nd_router_solicit._PACK_STR, bytes(buf[4:8])) self.assertEqual(res[0], 0) res = struct.unpack(icmpv6.nd_option_sla._PACK_STR, bytes(buf[8:])) self.assertEqual(res[0], icmpv6.ND_OPTION_SLA) self.assertEqual(res[1], len(icmpv6.nd_option_sla()) // 8) self.assertEqual(res[2], addrconv.mac.text_to_bin('00:00:00:00:00:00')) def test_json(self): nd_opt = icmpv6.nd_option_sla(self.nd_length, self.nd_hw_src) rs = icmpv6.nd_router_solicit(self.res, nd_opt) ic1 = icmpv6.icmpv6(self.type_, self.code, self.csum, rs) jsondict = ic1.to_jsondict() ic2 = icmpv6.icmpv6.from_jsondict(jsondict['icmpv6']) self.assertEqual(str(ic1), str(ic2)) class Test_icmpv6_router_advert(unittest.TestCase): def setUp(self): pass def tearDown(self): pass def test_default_args(self): prev = ipv6(nxt=inet.IPPROTO_ICMPV6) ic = icmpv6.icmpv6( type_=icmpv6.ND_ROUTER_ADVERT, data=icmpv6.nd_router_advert()) prev.serialize(ic, None) buf = ic.serialize(bytearray(), prev) res = struct.unpack(icmpv6.icmpv6._PACK_STR, bytes(buf[:4])) self.assertEqual(res[0], icmpv6.ND_ROUTER_ADVERT) self.assertEqual(res[1], 0) self.assertEqual(res[2], icmpv6_csum(prev, buf)) res = struct.unpack(icmpv6.nd_router_advert._PACK_STR, bytes(buf[4:])) self.assertEqual(res[0], 0) self.assertEqual(res[1], 0) self.assertEqual(res[2], 0) self.assertEqual(res[3], 0) self.assertEqual(res[4], 0) # with nd_option_sla prev = ipv6(nxt=inet.IPPROTO_ICMPV6) ic = icmpv6.icmpv6( type_=icmpv6.ND_ROUTER_ADVERT, data=icmpv6.nd_router_advert( options=[icmpv6.nd_option_sla()])) prev.serialize(ic, None) buf = ic.serialize(bytearray(), prev) res = struct.unpack(icmpv6.icmpv6._PACK_STR, bytes(buf[:4])) self.assertEqual(res[0], icmpv6.ND_ROUTER_ADVERT) self.assertEqual(res[1], 0) self.assertEqual(res[2], icmpv6_csum(prev, buf)) res = struct.unpack(icmpv6.nd_router_advert._PACK_STR, bytes(buf[4:16])) self.assertEqual(res[0], 0) self.assertEqual(res[1], 0) self.assertEqual(res[2], 0) self.assertEqual(res[3], 0) self.assertEqual(res[4], 0) res = struct.unpack(icmpv6.nd_option_sla._PACK_STR, bytes(buf[16:])) self.assertEqual(res[0], icmpv6.ND_OPTION_SLA) self.assertEqual(res[1], len(icmpv6.nd_option_sla()) // 8) self.assertEqual(res[2], addrconv.mac.text_to_bin('00:00:00:00:00:00')) # with nd_option_pi prev = ipv6(nxt=inet.IPPROTO_ICMPV6) ic = icmpv6.icmpv6( type_=icmpv6.ND_ROUTER_ADVERT, data=icmpv6.nd_router_advert( options=[icmpv6.nd_option_pi()])) prev.serialize(ic, None) buf = ic.serialize(bytearray(), prev) res = struct.unpack(icmpv6.icmpv6._PACK_STR, bytes(buf[:4])) self.assertEqual(res[0], icmpv6.ND_ROUTER_ADVERT) self.assertEqual(res[1], 0) self.assertEqual(res[2], icmpv6_csum(prev, buf)) res = struct.unpack(icmpv6.nd_router_advert._PACK_STR, bytes(buf[4:16])) self.assertEqual(res[0], 0) self.assertEqual(res[1], 0) self.assertEqual(res[2], 0) self.assertEqual(res[3], 0) self.assertEqual(res[4], 0) res = struct.unpack(icmpv6.nd_option_pi._PACK_STR, bytes(buf[16:])) self.assertEqual(res[0], icmpv6.ND_OPTION_PI) self.assertEqual(res[1], 4) self.assertEqual(res[2], 0) self.assertEqual(res[3], 0) self.assertEqual(res[4], 0) self.assertEqual(res[5], 0) self.assertEqual(res[6], 0) self.assertEqual(res[7], addrconv.ipv6.text_to_bin('::')) # with nd_option_sla and nd_option_pi prev = ipv6(nxt=inet.IPPROTO_ICMPV6) ic = icmpv6.icmpv6( type_=icmpv6.ND_ROUTER_ADVERT, data=icmpv6.nd_router_advert( options=[icmpv6.nd_option_sla(), icmpv6.nd_option_pi()])) prev.serialize(ic, None) buf = ic.serialize(bytearray(), prev) res = struct.unpack(icmpv6.icmpv6._PACK_STR, bytes(buf[:4])) self.assertEqual(res[0], icmpv6.ND_ROUTER_ADVERT) self.assertEqual(res[1], 0) self.assertEqual(res[2], icmpv6_csum(prev, buf)) res = struct.unpack(icmpv6.nd_router_advert._PACK_STR, bytes(buf[4:16])) self.assertEqual(res[0], 0) self.assertEqual(res[1], 0) self.assertEqual(res[2], 0) self.assertEqual(res[3], 0) self.assertEqual(res[4], 0) res = struct.unpack(icmpv6.nd_option_sla._PACK_STR, bytes(buf[16:24])) self.assertEqual(res[0], icmpv6.ND_OPTION_SLA) self.assertEqual(res[1], len(icmpv6.nd_option_sla()) // 8) self.assertEqual(res[2], addrconv.mac.text_to_bin('00:00:00:00:00:00')) res = struct.unpack(icmpv6.nd_option_pi._PACK_STR, bytes(buf[24:])) self.assertEqual(res[0], icmpv6.ND_OPTION_PI) self.assertEqual(res[1], len(icmpv6.nd_option_pi()) // 8) self.assertEqual(res[2], 0) self.assertEqual(res[3], 0) self.assertEqual(res[4], 0) self.assertEqual(res[5], 0) self.assertEqual(res[6], 0) self.assertEqual(res[7], addrconv.ipv6.text_to_bin('::')) def test_json(self): ic1 = icmpv6.icmpv6( type_=icmpv6.ND_ROUTER_ADVERT, data=icmpv6.nd_router_advert( options=[icmpv6.nd_option_sla(), icmpv6.nd_option_pi()])) jsondict = ic1.to_jsondict() ic2 = icmpv6.icmpv6.from_jsondict(jsondict['icmpv6']) self.assertEqual(str(ic1), str(ic2)) class Test_icmpv6_nd_option_la(unittest.TestCase): def setUp(self): pass def tearDown(self): pass def test_default_args(self): la = icmpv6.nd_option_sla() buf = la.serialize() res = struct.unpack(icmpv6.nd_option_sla._PACK_STR, bytes(buf)) self.assertEqual(res[0], icmpv6.ND_OPTION_SLA) self.assertEqual(res[1], len(icmpv6.nd_option_sla()) // 8) self.assertEqual(res[2], addrconv.mac.text_to_bin('00:00:00:00:00:00')) # with nd_neighbor prev = ipv6(nxt=inet.IPPROTO_ICMPV6) ic = icmpv6.icmpv6( type_=icmpv6.ND_NEIGHBOR_ADVERT, data=icmpv6.nd_neighbor( option=icmpv6.nd_option_tla())) prev.serialize(ic, None) buf = ic.serialize(bytearray(), prev) res = struct.unpack(icmpv6.icmpv6._PACK_STR, bytes(buf[:4])) self.assertEqual(res[0], icmpv6.ND_NEIGHBOR_ADVERT) self.assertEqual(res[1], 0) self.assertEqual(res[2], icmpv6_csum(prev, buf)) res = struct.unpack(icmpv6.nd_neighbor._PACK_STR, bytes(buf[4:24])) self.assertEqual(res[0], 0) self.assertEqual(res[1], addrconv.ipv6.text_to_bin('::')) res = struct.unpack(icmpv6.nd_option_tla._PACK_STR, bytes(buf[24:])) self.assertEqual(res[0], icmpv6.ND_OPTION_TLA) self.assertEqual(res[1], len(icmpv6.nd_option_tla()) // 8) self.assertEqual(res[2], addrconv.mac.text_to_bin('00:00:00:00:00:00')) # with nd_router_solicit prev = ipv6(nxt=inet.IPPROTO_ICMPV6) ic = icmpv6.icmpv6( type_=icmpv6.ND_ROUTER_SOLICIT, data=icmpv6.nd_router_solicit( option=icmpv6.nd_option_sla())) prev.serialize(ic, None) buf = ic.serialize(bytearray(), prev) res = struct.unpack(icmpv6.icmpv6._PACK_STR, bytes(buf[:4])) self.assertEqual(res[0], icmpv6.ND_ROUTER_SOLICIT) self.assertEqual(res[1], 0) self.assertEqual(res[2], icmpv6_csum(prev, buf)) res = struct.unpack(icmpv6.nd_router_solicit._PACK_STR, bytes(buf[4:8])) self.assertEqual(res[0], 0) res = struct.unpack(icmpv6.nd_option_sla._PACK_STR, bytes(buf[8:])) self.assertEqual(res[0], icmpv6.ND_OPTION_SLA) self.assertEqual(res[1], len(icmpv6.nd_option_sla()) // 8) self.assertEqual(res[2], addrconv.mac.text_to_bin('00:00:00:00:00:00')) class Test_icmpv6_nd_option_pi(unittest.TestCase): def setUp(self): pass def tearDown(self): pass def test_default_args(self): pi = icmpv6.nd_option_pi() buf = pi.serialize() res = struct.unpack(icmpv6.nd_option_pi._PACK_STR, bytes(buf)) self.assertEqual(res[0], icmpv6.ND_OPTION_PI) self.assertEqual(res[1], len(icmpv6.nd_option_pi()) // 8) self.assertEqual(res[2], 0) self.assertEqual(res[3], 0) self.assertEqual(res[4], 0) self.assertEqual(res[5], 0) self.assertEqual(res[6], 0) self.assertEqual(res[7], addrconv.ipv6.text_to_bin('::')) # with nd_router_advert prev = ipv6(nxt=inet.IPPROTO_ICMPV6) ic = icmpv6.icmpv6( type_=icmpv6.ND_ROUTER_ADVERT, data=icmpv6.nd_router_advert( options=[icmpv6.nd_option_pi()])) prev.serialize(ic, None) buf = ic.serialize(bytearray(), prev) res = struct.unpack(icmpv6.icmpv6._PACK_STR, bytes(buf[:4])) self.assertEqual(res[0], icmpv6.ND_ROUTER_ADVERT) self.assertEqual(res[1], 0) self.assertEqual(res[2], icmpv6_csum(prev, buf)) res = struct.unpack(icmpv6.nd_router_advert._PACK_STR, bytes(buf[4:16])) self.assertEqual(res[0], 0) self.assertEqual(res[1], 0) self.assertEqual(res[2], 0) self.assertEqual(res[3], 0) self.assertEqual(res[4], 0) res = struct.unpack(icmpv6.nd_option_pi._PACK_STR, bytes(buf[16:])) self.assertEqual(res[0], icmpv6.ND_OPTION_PI) self.assertEqual(res[1], 4) self.assertEqual(res[2], 0) self.assertEqual(res[3], 0) self.assertEqual(res[4], 0) self.assertEqual(res[5], 0) self.assertEqual(res[6], 0) self.assertEqual(res[7], addrconv.ipv6.text_to_bin('::')) class Test_icmpv6_membership_query(unittest.TestCase): type_ = 130 code = 0 csum = 0xb5a4 maxresp = 10000 address = 'ff08::1' buf = b'\x82\x00\xb5\xa4\x27\x10\x00\x00' \ + b'\xff\x08\x00\x00\x00\x00\x00\x00' \ + b'\x00\x00\x00\x00\x00\x00\x00\x01' def setUp(self): pass def tearDown(self): pass def test_init(self): mld = icmpv6.mld(self.maxresp, self.address) self.assertEqual(mld.maxresp, self.maxresp) self.assertEqual(mld.address, self.address) def test_parser(self): msg, n, _ = icmpv6.icmpv6.parser(self.buf) self.assertEqual(msg.type_, self.type_) self.assertEqual(msg.code, self.code) self.assertEqual(msg.csum, self.csum) self.assertEqual(msg.data.maxresp, self.maxresp) self.assertEqual(msg.data.address, self.address) self.assertEqual(n, None) def test_serialize(self): src_ipv6 = '3ffe:507:0:1:200:86ff:fe05:80da' dst_ipv6 = '3ffe:501:0:1001::2' prev = ipv6(6, 0, 0, len(self.buf), 64, 255, src_ipv6, dst_ipv6) mld_csum = icmpv6_csum(prev, self.buf) mld = icmpv6.mld(self.maxresp, self.address) icmp = icmpv6.icmpv6(self.type_, self.code, 0, mld) buf = bytes(icmp.serialize(bytearray(), prev)) (type_, code, csum) = struct.unpack_from(icmp._PACK_STR, buf, 0) (maxresp, address) = struct.unpack_from( mld._PACK_STR, buf, icmp._MIN_LEN) self.assertEqual(type_, self.type_) self.assertEqual(code, self.code) self.assertEqual(csum, mld_csum) self.assertEqual(maxresp, self.maxresp) self.assertEqual(address, addrconv.ipv6.text_to_bin(self.address)) def test_to_string(self): ml = icmpv6.mld(self.maxresp, self.address) ic = icmpv6.icmpv6(self.type_, self.code, self.csum, ml) mld_values = {'maxresp': self.maxresp, 'address': self.address} _mld_str = ','.join(['%s=%s' % (k, repr(mld_values[k])) for k, v in inspect.getmembers(ml) if k in mld_values]) mld_str = '%s(%s)' % (icmpv6.mld.__name__, _mld_str) icmp_values = {'type_': repr(self.type_), 'code': repr(self.code), 'csum': repr(self.csum), 'data': mld_str} _ic_str = ','.join(['%s=%s' % (k, icmp_values[k]) for k, v in inspect.getmembers(ic) if k in icmp_values]) ic_str = '%s(%s)' % (icmpv6.icmpv6.__name__, _ic_str) self.assertEqual(str(ic), ic_str) self.assertEqual(repr(ic), ic_str) def test_default_args(self): prev = ipv6(nxt=inet.IPPROTO_ICMPV6) ic = icmpv6.icmpv6( type_=icmpv6.MLD_LISTENER_QUERY, data=icmpv6.mld()) prev.serialize(ic, None) buf = ic.serialize(bytearray(), prev) res = struct.unpack(icmpv6.icmpv6._PACK_STR, bytes(buf[:4])) self.assertEqual(res[0], icmpv6.MLD_LISTENER_QUERY) self.assertEqual(res[1], 0) self.assertEqual(res[2], icmpv6_csum(prev, buf)) res = struct.unpack(icmpv6.mld._PACK_STR, bytes(buf[4:])) self.assertEqual(res[0], 0) self.assertEqual(res[1], addrconv.ipv6.text_to_bin('::')) def test_json(self): ic1 = icmpv6.icmpv6( type_=icmpv6.MLD_LISTENER_QUERY, data=icmpv6.mld()) jsondict = ic1.to_jsondict() ic2 = icmpv6.icmpv6.from_jsondict(jsondict['icmpv6']) self.assertEqual(str(ic1), str(ic2)) class Test_icmpv6_membership_report(Test_icmpv6_membership_query): type_ = 131 code = 0 csum = 0xb4a4 maxresp = 10000 address = 'ff08::1' buf = b'\x83\x00\xb4\xa4\x27\x10\x00\x00' \ + b'\xff\x08\x00\x00\x00\x00\x00\x00' \ + b'\x00\x00\x00\x00\x00\x00\x00\x01' def test_json(self): ic1 = icmpv6.icmpv6( type_=icmpv6.MLD_LISTENER_REPOR, data=icmpv6.mld()) jsondict = ic1.to_jsondict() ic2 = icmpv6.icmpv6.from_jsondict(jsondict['icmpv6']) self.assertEqual(str(ic1), str(ic2)) class Test_icmpv6_membership_done(Test_icmpv6_membership_query): type_ = 132 code = 0 csum = 0xb3a4 maxresp = 10000 address = 'ff08::1' buf = b'\x84\x00\xb3\xa4\x27\x10\x00\x00' \ + b'\xff\x08\x00\x00\x00\x00\x00\x00' \ + b'\x00\x00\x00\x00\x00\x00\x00\x01' def test_json(self): ic1 = icmpv6.icmpv6( type_=icmpv6.MLD_LISTENER_DONE, data=icmpv6.mld()) jsondict = ic1.to_jsondict() ic2 = icmpv6.icmpv6.from_jsondict(jsondict['icmpv6']) self.assertEqual(str(ic1), str(ic2)) class Test_mldv2_query(unittest.TestCase): type_ = 130 code = 0 csum = 0xb5a4 maxresp = 10000 address = 'ff08::1' s_flg = 0 qrv = 2 s_qrv = s_flg << 3 | qrv qqic = 10 num = 0 srcs = [] mld = icmpv6.mldv2_query( maxresp, address, s_flg, qrv, qqic, num, srcs) buf = b'\x82\x00\xb5\xa4\x27\x10\x00\x00' \ + b'\xff\x08\x00\x00\x00\x00\x00\x00' \ + b'\x00\x00\x00\x00\x00\x00\x00\x01' \ + b'\x02\x0a\x00\x00' def setUp(self): pass def setUp_with_srcs(self): self.num = 2 self.srcs = ['ff80::1', 'ff80::2'] self.mld = icmpv6.mldv2_query( self.maxresp, self.address, self.s_flg, self.qrv, self.qqic, self.num, self.srcs) self.buf = b'\x82\x00\xb5\xa4\x27\x10\x00\x00' \ + b'\xff\x08\x00\x00\x00\x00\x00\x00' \ + b'\x00\x00\x00\x00\x00\x00\x00\x01' \ + b'\x02\x0a\x00\x02' \ + b'\xff\x80\x00\x00\x00\x00\x00\x00' \ + b'\x00\x00\x00\x00\x00\x00\x00\x01' \ + b'\xff\x80\x00\x00\x00\x00\x00\x00' \ + b'\x00\x00\x00\x00\x00\x00\x00\x02' def tearDown(self): pass def find_protocol(self, pkt, name): for p in pkt.protocols: if p.protocol_name == name: return p def test_init(self): self.assertEqual(self.mld.maxresp, self.maxresp) self.assertEqual(self.mld.address, self.address) self.assertEqual(self.mld.s_flg, self.s_flg) self.assertEqual(self.mld.qrv, self.qrv) self.assertEqual(self.mld.qqic, self.qqic) self.assertEqual(self.mld.num, self.num) self.assertEqual(self.mld.srcs, self.srcs) def test_init_with_srcs(self): self.setUp_with_srcs() self.test_init() def test_parser(self): msg, n, _ = icmpv6.icmpv6.parser(self.buf) self.assertEqual(msg.type_, self.type_) self.assertEqual(msg.code, self.code) self.assertEqual(msg.csum, self.csum) self.assertEqual(msg.data.maxresp, self.maxresp) self.assertEqual(msg.data.address, self.address) self.assertEqual(msg.data.s_flg, self.s_flg) self.assertEqual(msg.data.qrv, self.qrv) self.assertEqual(msg.data.qqic, self.qqic) self.assertEqual(msg.data.num, self.num) self.assertEqual(msg.data.srcs, self.srcs) self.assertEqual(n, None) def test_parser_with_srcs(self): self.setUp_with_srcs() self.test_parser() def test_serialize(self): src_ipv6 = '3ffe:507:0:1:200:86ff:fe05:80da' dst_ipv6 = '3ffe:501:0:1001::2' prev = ipv6(6, 0, 0, len(self.buf), 64, 255, src_ipv6, dst_ipv6) mld_csum = icmpv6_csum(prev, self.buf) icmp = icmpv6.icmpv6(self.type_, self.code, 0, self.mld) buf = icmp.serialize(bytearray(), prev) (type_, code, csum) = struct.unpack_from(icmp._PACK_STR, bytes(buf)) (maxresp, address, s_qrv, qqic, num) = struct.unpack_from( self.mld._PACK_STR, bytes(buf), icmp._MIN_LEN) self.assertEqual(type_, self.type_) self.assertEqual(code, self.code) self.assertEqual(csum, mld_csum) self.assertEqual(maxresp, self.maxresp) self.assertEqual(address, addrconv.ipv6.text_to_bin(self.address)) s_flg = (s_qrv >> 3) & 0b1 qrv = s_qrv & 0b111 self.assertEqual(s_flg, self.s_flg) self.assertEqual(qrv, self.qrv) self.assertEqual(qqic, self.qqic) self.assertEqual(num, self.num) def test_serialize_with_srcs(self): self.setUp_with_srcs() src_ipv6 = '3ffe:507:0:1:200:86ff:fe05:80da' dst_ipv6 = '3ffe:501:0:1001::2' prev = ipv6(6, 0, 0, len(self.buf), 64, 255, src_ipv6, dst_ipv6) mld_csum = icmpv6_csum(prev, self.buf) icmp = icmpv6.icmpv6(self.type_, self.code, 0, self.mld) buf = icmp.serialize(bytearray(), prev) (type_, code, csum) = struct.unpack_from(icmp._PACK_STR, bytes(buf)) (maxresp, address, s_qrv, qqic, num) = struct.unpack_from( self.mld._PACK_STR, bytes(buf), icmp._MIN_LEN) (addr1, addr2) = struct.unpack_from( '!16s16s', bytes(buf), icmp._MIN_LEN + self.mld._MIN_LEN) self.assertEqual(type_, self.type_) self.assertEqual(code, self.code) self.assertEqual(csum, mld_csum) self.assertEqual(maxresp, self.maxresp) self.assertEqual(address, addrconv.ipv6.text_to_bin(self.address)) s_flg = (s_qrv >> 3) & 0b1 qrv = s_qrv & 0b111 self.assertEqual(s_flg, self.s_flg) self.assertEqual(qrv, self.qrv) self.assertEqual(qqic, self.qqic) self.assertEqual(num, self.num) self.assertEqual(addr1, addrconv.ipv6.text_to_bin(self.srcs[0])) self.assertEqual(addr2, addrconv.ipv6.text_to_bin(self.srcs[1])) def _build_mldv2_query(self): e = ethernet(ethertype=ether.ETH_TYPE_IPV6) i = ipv6(nxt=inet.IPPROTO_ICMPV6) ic = icmpv6.icmpv6(type_=icmpv6.MLD_LISTENER_QUERY, data=self.mld) p = e / i / ic return p def test_build_mldv2_query(self): p = self._build_mldv2_query() e = self.find_protocol(p, "ethernet") self.assertTrue(e) self.assertEqual(e.ethertype, ether.ETH_TYPE_IPV6) i = self.find_protocol(p, "ipv6") self.assertTrue(i) self.assertEqual(i.nxt, inet.IPPROTO_ICMPV6) ic = self.find_protocol(p, "icmpv6") self.assertTrue(ic) self.assertEqual(ic.type_, icmpv6.MLD_LISTENER_QUERY) self.assertEqual(ic.data.maxresp, self.maxresp) self.assertEqual(ic.data.address, self.address) self.assertEqual(ic.data.s_flg, self.s_flg) self.assertEqual(ic.data.qrv, self.qrv) self.assertEqual(ic.data.num, self.num) self.assertEqual(ic.data.srcs, self.srcs) def test_build_mldv2_query_with_srcs(self): self.setUp_with_srcs() self.test_build_mldv2_query() def test_to_string(self): ic = icmpv6.icmpv6(self.type_, self.code, self.csum, self.mld) mld_values = {'maxresp': self.maxresp, 'address': self.address, 's_flg': self.s_flg, 'qrv': self.qrv, 'qqic': self.qqic, 'num': self.num, 'srcs': self.srcs} _mld_str = ','.join(['%s=%s' % (k, repr(mld_values[k])) for k, v in inspect.getmembers(self.mld) if k in mld_values]) mld_str = '%s(%s)' % (icmpv6.mldv2_query.__name__, _mld_str) icmp_values = {'type_': repr(self.type_), 'code': repr(self.code), 'csum': repr(self.csum), 'data': mld_str} _ic_str = ','.join(['%s=%s' % (k, icmp_values[k]) for k, v in inspect.getmembers(ic) if k in icmp_values]) ic_str = '%s(%s)' % (icmpv6.icmpv6.__name__, _ic_str) self.assertEqual(str(ic), ic_str) self.assertEqual(repr(ic), ic_str) def test_to_string_with_srcs(self): self.setUp_with_srcs() self.test_to_string() def test_num_larger_than_srcs(self): self.srcs = ['ff80::1', 'ff80::2', 'ff80::3'] self.num = len(self.srcs) + 1 self.buf = struct.pack( icmpv6.mldv2_query._PACK_STR, self.maxresp, addrconv.ipv6.text_to_bin(self.address), self.s_qrv, self.qqic, self.num) for src in self.srcs: self.buf += struct.pack('16s', addrconv.ipv6.text_to_bin(src)) self.mld = icmpv6.mldv2_query( self.maxresp, self.address, self.s_flg, self.qrv, self.qqic, self.num, self.srcs) self.assertRaises(AssertionError, self.test_parser) def test_num_smaller_than_srcs(self): self.srcs = ['ff80::1', 'ff80::2', 'ff80::3'] self.num = len(self.srcs) - 1 self.buf = struct.pack( icmpv6.mldv2_query._PACK_STR, self.maxresp, addrconv.ipv6.text_to_bin(self.address), self.s_qrv, self.qqic, self.num) for src in self.srcs: self.buf += struct.pack('16s', addrconv.ipv6.text_to_bin(src)) self.mld = icmpv6.mldv2_query( self.maxresp, self.address, self.s_flg, self.qrv, self.qqic, self.num, self.srcs) self.assertRaises(AssertionError, self.test_parser) def test_default_args(self): prev = ipv6(nxt=inet.IPPROTO_ICMPV6) ic = icmpv6.icmpv6( type_=icmpv6.MLD_LISTENER_QUERY, data=icmpv6.mldv2_query()) prev.serialize(ic, None) buf = ic.serialize(bytearray(), prev) res = struct.unpack(icmpv6.icmpv6._PACK_STR, bytes(buf[:4])) self.assertEqual(res[0], icmpv6.MLD_LISTENER_QUERY) self.assertEqual(res[1], 0) self.assertEqual(res[2], icmpv6_csum(prev, buf)) res = struct.unpack(icmpv6.mldv2_query._PACK_STR, bytes(buf[4:])) self.assertEqual(res[0], 0) self.assertEqual(res[1], addrconv.ipv6.text_to_bin('::')) self.assertEqual(res[2], 2) self.assertEqual(res[3], 0) self.assertEqual(res[4], 0) # srcs without num srcs = ['ff80::1', 'ff80::2', 'ff80::3'] que = icmpv6.mldv2_query(srcs=srcs) buf = que.serialize() res = struct.unpack_from( icmpv6.mldv2_query._PACK_STR, bytes(buf)) self.assertEqual(res[0], 0) self.assertEqual(res[1], addrconv.ipv6.text_to_bin('::')) self.assertEqual(res[2], 2) self.assertEqual(res[3], 0) self.assertEqual(res[4], len(srcs)) (src1, src2, src3) = struct.unpack_from( '16s16s16s', bytes(buf), icmpv6.mldv2_query._MIN_LEN) self.assertEqual(src1, addrconv.ipv6.text_to_bin(srcs[0])) self.assertEqual(src2, addrconv.ipv6.text_to_bin(srcs[1])) self.assertEqual(src3, addrconv.ipv6.text_to_bin(srcs[2])) def test_json(self): jsondict = self.mld.to_jsondict() mld = icmpv6.mldv2_query.from_jsondict(jsondict['mldv2_query']) self.assertEqual(str(self.mld), str(mld)) def test_json_with_srcs(self): self.setUp_with_srcs() self.test_json() class Test_mldv2_report(unittest.TestCase): type_ = 143 code = 0 csum = 0xb5a4 record_num = 0 records = [] mld = icmpv6.mldv2_report(record_num, records) buf = b'\x8f\x00\xb5\xa4\x00\x00\x00\x00' def setUp(self): pass def setUp_with_records(self): self.record1 = icmpv6.mldv2_report_group( icmpv6.MODE_IS_INCLUDE, 0, 0, 'ff00::1') self.record2 = icmpv6.mldv2_report_group( icmpv6.MODE_IS_INCLUDE, 0, 2, 'ff00::2', ['fe80::1', 'fe80::2']) self.record3 = icmpv6.mldv2_report_group( icmpv6.MODE_IS_INCLUDE, 1, 0, 'ff00::3', [], b'abc\x00') self.record4 = icmpv6.mldv2_report_group( icmpv6.MODE_IS_INCLUDE, 2, 2, 'ff00::4', ['fe80::1', 'fe80::2'], b'abcde\x00\x00\x00') self.records = [self.record1, self.record2, self.record3, self.record4] self.record_num = len(self.records) self.mld = icmpv6.mldv2_report(self.record_num, self.records) self.buf = b'\x8f\x00\xb5\xa4\x00\x00\x00\x04' \ + b'\x01\x00\x00\x00' \ + b'\xff\x00\x00\x00\x00\x00\x00\x00' \ + b'\x00\x00\x00\x00\x00\x00\x00\x01' \ + b'\x01\x00\x00\x02' \ + b'\xff\x00\x00\x00\x00\x00\x00\x00' \ + b'\x00\x00\x00\x00\x00\x00\x00\x02' \ + b'\xfe\x80\x00\x00\x00\x00\x00\x00' \ + b'\x00\x00\x00\x00\x00\x00\x00\x01' \ + b'\xfe\x80\x00\x00\x00\x00\x00\x00' \ + b'\x00\x00\x00\x00\x00\x00\x00\x02' \ + b'\x01\x01\x00\x00' \ + b'\xff\x00\x00\x00\x00\x00\x00\x00' \ + b'\x00\x00\x00\x00\x00\x00\x00\x03' \ + b'\x61\x62\x63\x00' \ + b'\x01\x02\x00\x02' \ + b'\xff\x00\x00\x00\x00\x00\x00\x00' \ + b'\x00\x00\x00\x00\x00\x00\x00\x04' \ + b'\xfe\x80\x00\x00\x00\x00\x00\x00' \ + b'\x00\x00\x00\x00\x00\x00\x00\x01' \ + b'\xfe\x80\x00\x00\x00\x00\x00\x00' \ + b'\x00\x00\x00\x00\x00\x00\x00\x02' \ + b'\x61\x62\x63\x64\x65\x00\x00\x00' def tearDown(self): pass def find_protocol(self, pkt, name): for p in pkt.protocols: if p.protocol_name == name: return p def test_init(self): self.assertEqual(self.mld.record_num, self.record_num) self.assertEqual(self.mld.records, self.records) def test_init_with_records(self): self.setUp_with_records() self.test_init() def test_parser(self): msg, n, _ = icmpv6.icmpv6.parser(self.buf) self.assertEqual(msg.type_, self.type_) self.assertEqual(msg.code, self.code) self.assertEqual(msg.csum, self.csum) self.assertEqual(msg.data.record_num, self.record_num) self.assertEqual(repr(msg.data.records), repr(self.records)) def test_parser_with_records(self): self.setUp_with_records() self.test_parser() def test_serialize(self): src_ipv6 = '3ffe:507:0:1:200:86ff:fe05:80da' dst_ipv6 = '3ffe:501:0:1001::2' prev = ipv6(6, 0, 0, len(self.buf), 64, 255, src_ipv6, dst_ipv6) mld_csum = icmpv6_csum(prev, self.buf) icmp = icmpv6.icmpv6(self.type_, self.code, 0, self.mld) buf = icmp.serialize(bytearray(), prev) (type_, code, csum) = struct.unpack_from(icmp._PACK_STR, bytes(buf)) (record_num, ) = struct.unpack_from( self.mld._PACK_STR, bytes(buf), icmp._MIN_LEN) self.assertEqual(type_, self.type_) self.assertEqual(code, self.code) self.assertEqual(csum, mld_csum) self.assertEqual(record_num, self.record_num) def test_serialize_with_records(self): self.setUp_with_records() src_ipv6 = '3ffe:507:0:1:200:86ff:fe05:80da' dst_ipv6 = '3ffe:501:0:1001::2' prev = ipv6(6, 0, 0, len(self.buf), 64, 255, src_ipv6, dst_ipv6) mld_csum = icmpv6_csum(prev, self.buf) icmp = icmpv6.icmpv6(self.type_, self.code, 0, self.mld) buf = bytes(icmp.serialize(bytearray(), prev)) (type_, code, csum) = struct.unpack_from(icmp._PACK_STR, bytes(buf)) (record_num, ) = struct.unpack_from( self.mld._PACK_STR, bytes(buf), icmp._MIN_LEN) offset = icmp._MIN_LEN + self.mld._MIN_LEN rec1 = icmpv6.mldv2_report_group.parser(buf[offset:]) offset += len(rec1) rec2 = icmpv6.mldv2_report_group.parser(buf[offset:]) offset += len(rec2) rec3 = icmpv6.mldv2_report_group.parser(buf[offset:]) offset += len(rec3) rec4 = icmpv6.mldv2_report_group.parser(buf[offset:]) self.assertEqual(type_, self.type_) self.assertEqual(code, self.code) self.assertEqual(csum, mld_csum) self.assertEqual(record_num, self.record_num) self.assertEqual(repr(rec1), repr(self.record1)) self.assertEqual(repr(rec2), repr(self.record2)) self.assertEqual(repr(rec3), repr(self.record3)) self.assertEqual(repr(rec4), repr(self.record4)) def _build_mldv2_report(self): e = ethernet(ethertype=ether.ETH_TYPE_IPV6) i = ipv6(nxt=inet.IPPROTO_ICMPV6) ic = icmpv6.icmpv6(type_=icmpv6.MLDV2_LISTENER_REPORT, data=self.mld) p = e / i / ic return p def test_build_mldv2_report(self): p = self._build_mldv2_report() e = self.find_protocol(p, "ethernet") self.assertTrue(e) self.assertEqual(e.ethertype, ether.ETH_TYPE_IPV6) i = self.find_protocol(p, "ipv6") self.assertTrue(i) self.assertEqual(i.nxt, inet.IPPROTO_ICMPV6) ic = self.find_protocol(p, "icmpv6") self.assertTrue(ic) self.assertEqual(ic.type_, icmpv6.MLDV2_LISTENER_REPORT) self.assertEqual(ic.data.record_num, self.record_num) self.assertEqual(ic.data.records, self.records) def test_build_mldv2_report_with_records(self): self.setUp_with_records() self.test_build_mldv2_report() def test_to_string(self): ic = icmpv6.icmpv6(self.type_, self.code, self.csum, self.mld) mld_values = {'record_num': self.record_num, 'records': self.records} _mld_str = ','.join(['%s=%s' % (k, repr(mld_values[k])) for k, v in inspect.getmembers(self.mld) if k in mld_values]) mld_str = '%s(%s)' % (icmpv6.mldv2_report.__name__, _mld_str) icmp_values = {'type_': repr(self.type_), 'code': repr(self.code), 'csum': repr(self.csum), 'data': mld_str} _ic_str = ','.join(['%s=%s' % (k, icmp_values[k]) for k, v in inspect.getmembers(ic) if k in icmp_values]) ic_str = '%s(%s)' % (icmpv6.icmpv6.__name__, _ic_str) self.assertEqual(str(ic), ic_str) self.assertEqual(repr(ic), ic_str) def test_to_string_with_records(self): self.setUp_with_records() self.test_to_string() def test_record_num_larger_than_records(self): self.record1 = icmpv6.mldv2_report_group( icmpv6.MODE_IS_INCLUDE, 0, 0, 'ff00::1') self.record2 = icmpv6.mldv2_report_group( icmpv6.MODE_IS_INCLUDE, 0, 2, 'ff00::2', ['fe80::1', 'fe80::2']) self.record3 = icmpv6.mldv2_report_group( icmpv6.MODE_IS_INCLUDE, 1, 0, 'ff00::3', [], b'abc\x00') self.record4 = icmpv6.mldv2_report_group( icmpv6.MODE_IS_INCLUDE, 2, 2, 'ff00::4', ['fe80::1', 'fe80::2'], b'abcde\x00\x00\x00') self.records = [self.record1, self.record2, self.record3, self.record4] self.record_num = len(self.records) + 1 self.buf = struct.pack( icmpv6.mldv2_report._PACK_STR, self.record_num) self.buf += self.record1.serialize() self.buf += self.record2.serialize() self.buf += self.record3.serialize() self.buf += self.record4.serialize() self.mld = icmpv6.mldv2_report(self.record_num, self.records) self.assertRaises(AssertionError, self.test_parser) def test_record_num_smaller_than_records(self): self.record1 = icmpv6.mldv2_report_group( icmpv6.MODE_IS_INCLUDE, 0, 0, 'ff00::1') self.record2 = icmpv6.mldv2_report_group( icmpv6.MODE_IS_INCLUDE, 0, 2, 'ff00::2', ['fe80::1', 'fe80::2']) self.record3 = icmpv6.mldv2_report_group( icmpv6.MODE_IS_INCLUDE, 1, 0, 'ff00::3', [], b'abc\x00') self.record4 = icmpv6.mldv2_report_group( icmpv6.MODE_IS_INCLUDE, 2, 2, 'ff00::4', ['fe80::1', 'fe80::2'], b'abcde\x00\x00\x00') self.records = [self.record1, self.record2, self.record3, self.record4] self.record_num = len(self.records) - 1 self.buf = struct.pack( icmpv6.mldv2_report._PACK_STR, self.record_num) self.buf += self.record1.serialize() self.buf += self.record2.serialize() self.buf += self.record3.serialize() self.buf += self.record4.serialize() self.mld = icmpv6.mldv2_report(self.record_num, self.records) self.assertRaises(AssertionError, self.test_parser) def test_default_args(self): prev = ipv6(nxt=inet.IPPROTO_ICMPV6) ic = icmpv6.icmpv6( type_=icmpv6.MLDV2_LISTENER_REPORT, data=icmpv6.mldv2_report()) prev.serialize(ic, None) buf = ic.serialize(bytearray(), prev) res = struct.unpack(icmpv6.icmpv6._PACK_STR, bytes(buf[:4])) self.assertEqual(res[0], icmpv6.MLDV2_LISTENER_REPORT) self.assertEqual(res[1], 0) self.assertEqual(res[2], icmpv6_csum(prev, buf)) res = struct.unpack(icmpv6.mldv2_report._PACK_STR, bytes(buf[4:])) self.assertEqual(res[0], 0) # records without record_num record1 = icmpv6.mldv2_report_group( icmpv6.MODE_IS_INCLUDE, 0, 0, 'ff00::1') record2 = icmpv6.mldv2_report_group( icmpv6.MODE_IS_INCLUDE, 0, 2, 'ff00::2', ['fe80::1', 'fe80::2']) records = [record1, record2] rep = icmpv6.mldv2_report(records=records) buf = rep.serialize() res = struct.unpack_from( icmpv6.mldv2_report._PACK_STR, bytes(buf)) self.assertEqual(res[0], len(records)) res = struct.unpack_from( icmpv6.mldv2_report_group._PACK_STR, bytes(buf), icmpv6.mldv2_report._MIN_LEN) self.assertEqual(res[0], icmpv6.MODE_IS_INCLUDE) self.assertEqual(res[1], 0) self.assertEqual(res[2], 0) self.assertEqual(res[3], addrconv.ipv6.text_to_bin('ff00::1')) res = struct.unpack_from( icmpv6.mldv2_report_group._PACK_STR, bytes(buf), icmpv6.mldv2_report._MIN_LEN + icmpv6.mldv2_report_group._MIN_LEN) self.assertEqual(res[0], icmpv6.MODE_IS_INCLUDE) self.assertEqual(res[1], 0) self.assertEqual(res[2], 2) self.assertEqual(res[3], addrconv.ipv6.text_to_bin('ff00::2')) res = struct.unpack_from( '16s16s', bytes(buf), icmpv6.mldv2_report._MIN_LEN + icmpv6.mldv2_report_group._MIN_LEN + icmpv6.mldv2_report_group._MIN_LEN) self.assertEqual(res[0], addrconv.ipv6.text_to_bin('fe80::1')) self.assertEqual(res[1], addrconv.ipv6.text_to_bin('fe80::2')) def test_json(self): jsondict = self.mld.to_jsondict() mld = icmpv6.mldv2_report.from_jsondict(jsondict['mldv2_report']) self.assertEqual(str(self.mld), str(mld)) def test_json_with_records(self): self.setUp_with_records() self.test_json() class Test_mldv2_report_group(unittest.TestCase): type_ = icmpv6.MODE_IS_INCLUDE aux_len = 0 num = 0 address = 'ff00::1' srcs = [] aux = None mld = icmpv6.mldv2_report_group( type_, aux_len, num, address, srcs, aux) buf = b'\x01\x00\x00\x00' \ + b'\xff\x00\x00\x00\x00\x00\x00\x00' \ + b'\x00\x00\x00\x00\x00\x00\x00\x01' def setUp(self): pass def setUp_with_srcs(self): self.srcs = ['fe80::1', 'fe80::2', 'fe80::3'] self.num = len(self.srcs) self.mld = icmpv6.mldv2_report_group( self.type_, self.aux_len, self.num, self.address, self.srcs, self.aux) self.buf = b'\x01\x00\x00\x03' \ + b'\xff\x00\x00\x00\x00\x00\x00\x00' \ + b'\x00\x00\x00\x00\x00\x00\x00\x01' \ + b'\xfe\x80\x00\x00\x00\x00\x00\x00' \ + b'\x00\x00\x00\x00\x00\x00\x00\x01' \ + b'\xfe\x80\x00\x00\x00\x00\x00\x00' \ + b'\x00\x00\x00\x00\x00\x00\x00\x02' \ + b'\xfe\x80\x00\x00\x00\x00\x00\x00' \ + b'\x00\x00\x00\x00\x00\x00\x00\x03' def setUp_with_aux(self): self.aux = b'\x01\x02\x03\x04\x05\x06\x07\x08' self.aux_len = len(self.aux) // 4 self.mld = icmpv6.mldv2_report_group( self.type_, self.aux_len, self.num, self.address, self.srcs, self.aux) self.buf = b'\x01\x02\x00\x00' \ + b'\xff\x00\x00\x00\x00\x00\x00\x00' \ + b'\x00\x00\x00\x00\x00\x00\x00\x01' \ + b'\x01\x02\x03\x04\x05\x06\x07\x08' def setUp_with_srcs_and_aux(self): self.srcs = ['fe80::1', 'fe80::2', 'fe80::3'] self.num = len(self.srcs) self.aux = b'\x01\x02\x03\x04\x05\x06\x07\x08' self.aux_len = len(self.aux) // 4 self.mld = icmpv6.mldv2_report_group( self.type_, self.aux_len, self.num, self.address, self.srcs, self.aux) self.buf = b'\x01\x02\x00\x03' \ + b'\xff\x00\x00\x00\x00\x00\x00\x00' \ + b'\x00\x00\x00\x00\x00\x00\x00\x01' \ + b'\xfe\x80\x00\x00\x00\x00\x00\x00' \ + b'\x00\x00\x00\x00\x00\x00\x00\x01' \ + b'\xfe\x80\x00\x00\x00\x00\x00\x00' \ + b'\x00\x00\x00\x00\x00\x00\x00\x02' \ + b'\xfe\x80\x00\x00\x00\x00\x00\x00' \ + b'\x00\x00\x00\x00\x00\x00\x00\x03' \ + b'\x01\x02\x03\x04\x05\x06\x07\x08' def tearDown(self): pass def test_init(self): self.assertEqual(self.mld.type_, self.type_) self.assertEqual(self.mld.aux_len, self.aux_len) self.assertEqual(self.mld.num, self.num) self.assertEqual(self.mld.address, self.address) self.assertEqual(self.mld.srcs, self.srcs) self.assertEqual(self.mld.aux, self.aux) def test_init_with_srcs(self): self.setUp_with_srcs() self.test_init() def test_init_with_aux(self): self.setUp_with_aux() self.test_init() def test_init_with_srcs_and_aux(self): self.setUp_with_srcs_and_aux() self.test_init() def test_parser(self): _res = icmpv6.mldv2_report_group.parser(self.buf) if type(_res) is tuple: res = _res[0] else: res = _res self.assertEqual(res.type_, self.type_) self.assertEqual(res.aux_len, self.aux_len) self.assertEqual(res.num, self.num) self.assertEqual(res.address, self.address) self.assertEqual(res.srcs, self.srcs) self.assertEqual(res.aux, self.aux) def test_parser_with_srcs(self): self.setUp_with_srcs() self.test_parser() def test_parser_with_aux(self): self.setUp_with_aux() self.test_parser() def test_parser_with_srcs_and_aux(self): self.setUp_with_srcs_and_aux() self.test_parser() def test_serialize(self): buf = self.mld.serialize() res = struct.unpack_from( icmpv6.mldv2_report_group._PACK_STR, bytes(buf)) self.assertEqual(res[0], self.type_) self.assertEqual(res[1], self.aux_len) self.assertEqual(res[2], self.num) self.assertEqual(res[3], addrconv.ipv6.text_to_bin(self.address)) def test_serialize_with_srcs(self): self.setUp_with_srcs() buf = self.mld.serialize() res = struct.unpack_from( icmpv6.mldv2_report_group._PACK_STR, bytes(buf)) (src1, src2, src3) = struct.unpack_from( '16s16s16s', bytes(buf), icmpv6.mldv2_report_group._MIN_LEN) self.assertEqual(res[0], self.type_) self.assertEqual(res[1], self.aux_len) self.assertEqual(res[2], self.num) self.assertEqual(res[3], addrconv.ipv6.text_to_bin(self.address)) self.assertEqual(src1, addrconv.ipv6.text_to_bin(self.srcs[0])) self.assertEqual(src2, addrconv.ipv6.text_to_bin(self.srcs[1])) self.assertEqual(src3, addrconv.ipv6.text_to_bin(self.srcs[2])) def test_serialize_with_aux(self): self.setUp_with_aux() buf = self.mld.serialize() res = struct.unpack_from( icmpv6.mldv2_report_group._PACK_STR, bytes(buf)) (aux, ) = struct.unpack_from( '%ds' % (self.aux_len * 4), bytes(buf), icmpv6.mldv2_report_group._MIN_LEN) self.assertEqual(res[0], self.type_) self.assertEqual(res[1], self.aux_len) self.assertEqual(res[2], self.num) self.assertEqual(res[3], addrconv.ipv6.text_to_bin(self.address)) self.assertEqual(aux, self.aux) def test_serialize_with_srcs_and_aux(self): self.setUp_with_srcs_and_aux() buf = self.mld.serialize() res = struct.unpack_from( icmpv6.mldv2_report_group._PACK_STR, bytes(buf)) (src1, src2, src3) = struct.unpack_from( '16s16s16s', bytes(buf), icmpv6.mldv2_report_group._MIN_LEN) (aux, ) = struct.unpack_from( '%ds' % (self.aux_len * 4), bytes(buf), icmpv6.mldv2_report_group._MIN_LEN + 16 * 3) self.assertEqual(res[0], self.type_) self.assertEqual(res[1], self.aux_len) self.assertEqual(res[2], self.num) self.assertEqual(res[3], addrconv.ipv6.text_to_bin(self.address)) self.assertEqual(src1, addrconv.ipv6.text_to_bin(self.srcs[0])) self.assertEqual(src2, addrconv.ipv6.text_to_bin(self.srcs[1])) self.assertEqual(src3, addrconv.ipv6.text_to_bin(self.srcs[2])) self.assertEqual(aux, self.aux) def test_to_string(self): igmp_values = {'type_': repr(self.type_), 'aux_len': repr(self.aux_len), 'num': repr(self.num), 'address': repr(self.address), 'srcs': repr(self.srcs), 'aux': repr(self.aux)} _g_str = ','.join(['%s=%s' % (k, igmp_values[k]) for k, v in inspect.getmembers(self.mld) if k in igmp_values]) g_str = '%s(%s)' % (icmpv6.mldv2_report_group.__name__, _g_str) self.assertEqual(str(self.mld), g_str) self.assertEqual(repr(self.mld), g_str) def test_to_string_with_srcs(self): self.setUp_with_srcs() self.test_to_string() def test_to_string_with_aux(self): self.setUp_with_aux() self.test_to_string() def test_to_string_with_srcs_and_aux(self): self.setUp_with_srcs_and_aux() self.test_to_string() def test_len(self): self.assertEqual(len(self.mld), 20) def test_len_with_srcs(self): self.setUp_with_srcs() self.assertEqual(len(self.mld), 68) def test_len_with_aux(self): self.setUp_with_aux() self.assertEqual(len(self.mld), 28) def test_len_with_srcs_and_aux(self): self.setUp_with_srcs_and_aux() self.assertEqual(len(self.mld), 76) def test_num_larger_than_srcs(self): self.srcs = ['fe80::1', 'fe80::2', 'fe80::3'] self.num = len(self.srcs) + 1 self.buf = struct.pack( icmpv6.mldv2_report_group._PACK_STR, self.type_, self.aux_len, self.num, addrconv.ipv6.text_to_bin(self.address)) for src in self.srcs: self.buf += struct.pack('16s', addrconv.ipv6.text_to_bin(src)) self.mld = icmpv6.mldv2_report_group( self.type_, self.aux_len, self.num, self.address, self.srcs, self.aux) self.assertRaises(AssertionError, self.test_parser) def test_num_smaller_than_srcs(self): self.srcs = ['fe80::1', 'fe80::2', 'fe80::3'] self.num = len(self.srcs) - 1 self.buf = struct.pack( icmpv6.mldv2_report_group._PACK_STR, self.type_, self.aux_len, self.num, addrconv.ipv6.text_to_bin(self.address)) for src in self.srcs: self.buf += struct.pack('16s', addrconv.ipv6.text_to_bin(src)) self.mld = icmpv6.mldv2_report_group( self.type_, self.aux_len, self.num, self.address, self.srcs, self.aux) self.assertRaises(AssertionError, self.test_parser) def test_aux_len_larger_than_aux(self): self.aux = b'\x01\x02\x03\x04\x05\x06\x07\x08' self.aux_len = len(self.aux) // 4 + 1 self.buf = struct.pack( icmpv6.mldv2_report_group._PACK_STR, self.type_, self.aux_len, self.num, addrconv.ipv6.text_to_bin(self.address)) self.buf += self.aux self.mld = icmpv6.mldv2_report_group( self.type_, self.aux_len, self.num, self.address, self.srcs, self.aux) self.assertRaises(struct.error, self.test_parser) def test_aux_len_smaller_than_aux(self): self.aux = b'\x01\x02\x03\x04\x05\x06\x07\x08' self.aux_len = len(self.aux) // 4 - 1 self.buf = struct.pack( icmpv6.mldv2_report_group._PACK_STR, self.type_, self.aux_len, self.num, addrconv.ipv6.text_to_bin(self.address)) self.buf += self.aux self.mld = icmpv6.mldv2_report_group( self.type_, self.aux_len, self.num, self.address, self.srcs, self.aux) self.assertRaises(AssertionError, self.test_parser) def test_default_args(self): rep = icmpv6.mldv2_report_group() buf = rep.serialize() res = struct.unpack_from( icmpv6.mldv2_report_group._PACK_STR, bytes(buf)) self.assertEqual(res[0], 0) self.assertEqual(res[1], 0) self.assertEqual(res[2], 0) self.assertEqual(res[3], addrconv.ipv6.text_to_bin('::')) # srcs without num srcs = ['fe80::1', 'fe80::2', 'fe80::3'] rep = icmpv6.mldv2_report_group(srcs=srcs) buf = rep.serialize() LOG.info(repr(buf)) res = struct.unpack_from( icmpv6.mldv2_report_group._PACK_STR, bytes(buf)) self.assertEqual(res[0], 0) self.assertEqual(res[1], 0) self.assertEqual(res[2], len(srcs)) self.assertEqual(res[3], addrconv.ipv6.text_to_bin('::')) (src1, src2, src3) = struct.unpack_from( '16s16s16s', bytes(buf), icmpv6.mldv2_report_group._MIN_LEN) self.assertEqual(src1, addrconv.ipv6.text_to_bin(srcs[0])) self.assertEqual(src2, addrconv.ipv6.text_to_bin(srcs[1])) self.assertEqual(src3, addrconv.ipv6.text_to_bin(srcs[2])) # aux without aux_len rep = icmpv6.mldv2_report_group(aux=b'\x01\x02\x03') buf = rep.serialize() res = struct.unpack_from( icmpv6.mldv2_report_group._PACK_STR, bytes(buf)) self.assertEqual(res[0], 0) self.assertEqual(res[1], 1) self.assertEqual(res[2], 0) self.assertEqual(res[3], addrconv.ipv6.text_to_bin('::')) self.assertEqual(buf[icmpv6.mldv2_report_group._MIN_LEN:], b'\x01\x02\x03\x00') def test_json(self): jsondict = self.mld.to_jsondict() mld = icmpv6.mldv2_report_group.from_jsondict( jsondict['mldv2_report_group']) self.assertEqual(str(self.mld), str(mld)) def test_json_with_srcs(self): self.setUp_with_srcs() self.test_json() def test_json_with_aux(self): self.setUp_with_aux() self.test_json() def test_json_with_srcs_and_aux(self): self.setUp_with_srcs_and_aux() self.test_json() ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/packet/test_igmp.py0000664000175000017500000011001000000000000022215 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone 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. import unittest import inspect import logging from struct import pack, unpack_from, pack_into from os_ken.ofproto import ether from os_ken.ofproto import inet from os_ken.lib.packet.ethernet import ethernet from os_ken.lib.packet.ipv4 import ipv4 from os_ken.lib.packet.packet import Packet from os_ken.lib.packet.packet_utils import checksum from os_ken.lib import addrconv from os_ken.lib.packet.igmp import igmp from os_ken.lib.packet.igmp import igmpv3_query from os_ken.lib.packet.igmp import igmpv3_report from os_ken.lib.packet.igmp import igmpv3_report_group from os_ken.lib.packet.igmp import IGMP_TYPE_QUERY from os_ken.lib.packet.igmp import IGMP_TYPE_REPORT_V3 from os_ken.lib.packet.igmp import MODE_IS_INCLUDE LOG = logging.getLogger(__name__) class Test_igmp(unittest.TestCase): """ Test case for Internet Group Management Protocol """ def setUp(self): self.msgtype = IGMP_TYPE_QUERY self.maxresp = 100 self.csum = 0 self.address = '225.0.0.1' self.buf = pack(igmp._PACK_STR, self.msgtype, self.maxresp, self.csum, addrconv.ipv4.text_to_bin(self.address)) self.g = igmp(self.msgtype, self.maxresp, self.csum, self.address) def tearDown(self): pass def find_protocol(self, pkt, name): for p in pkt.protocols: if p.protocol_name == name: return p def test_init(self): self.assertEqual(self.msgtype, self.g.msgtype) self.assertEqual(self.maxresp, self.g.maxresp) self.assertEqual(self.csum, self.g.csum) self.assertEqual(self.address, self.g.address) def test_parser(self): _res = self.g.parser(self.buf) if type(_res) is tuple: res = _res[0] else: res = _res self.assertEqual(res.msgtype, self.msgtype) self.assertEqual(res.maxresp, self.maxresp) self.assertEqual(res.csum, self.csum) self.assertEqual(res.address, self.address) def test_serialize(self): data = bytearray() prev = None buf = self.g.serialize(data, prev) res = unpack_from(igmp._PACK_STR, bytes(buf)) self.assertEqual(res[0], self.msgtype) self.assertEqual(res[1], self.maxresp) self.assertEqual(res[2], checksum(self.buf)) self.assertEqual(res[3], addrconv.ipv4.text_to_bin(self.address)) def _build_igmp(self): dl_dst = '11:22:33:44:55:66' dl_src = 'aa:bb:cc:dd:ee:ff' dl_type = ether.ETH_TYPE_IP e = ethernet(dl_dst, dl_src, dl_type) total_length = 20 + igmp._MIN_LEN nw_proto = inet.IPPROTO_IGMP nw_dst = '11.22.33.44' nw_src = '55.66.77.88' i = ipv4(total_length=total_length, src=nw_src, dst=nw_dst, proto=nw_proto) p = Packet() p.add_protocol(e) p.add_protocol(i) p.add_protocol(self.g) p.serialize() return p def test_build_igmp(self): p = self._build_igmp() e = self.find_protocol(p, "ethernet") self.assertIsNotNone(e) self.assertEqual(e.ethertype, ether.ETH_TYPE_IP) i = self.find_protocol(p, "ipv4") self.assertTrue(i) self.assertEqual(i.proto, inet.IPPROTO_IGMP) g = self.find_protocol(p, "igmp") self.assertTrue(g) self.assertEqual(g.msgtype, self.msgtype) self.assertEqual(g.maxresp, self.maxresp) self.assertEqual(g.csum, checksum(self.buf)) self.assertEqual(g.address, self.address) def test_to_string(self): igmp_values = {'msgtype': repr(self.msgtype), 'maxresp': repr(self.maxresp), 'csum': repr(self.csum), 'address': repr(self.address)} _g_str = ','.join(['%s=%s' % (k, igmp_values[k]) for k, v in inspect.getmembers(self.g) if k in igmp_values]) g_str = '%s(%s)' % (igmp.__name__, _g_str) self.assertEqual(str(self.g), g_str) self.assertEqual(repr(self.g), g_str) def test_malformed_igmp(self): m_short_buf = self.buf[1:igmp._MIN_LEN] self.assertRaises(Exception, igmp.parser, m_short_buf) def test_default_args(self): ig = igmp() buf = ig.serialize(bytearray(), None) res = unpack_from(igmp._PACK_STR, bytes(buf)) self.assertEqual(res[0], 0x11) self.assertEqual(res[1], 0) self.assertEqual(res[3], addrconv.ipv4.text_to_bin('0.0.0.0')) def test_json(self): jsondict = self.g.to_jsondict() g = igmp.from_jsondict(jsondict['igmp']) self.assertEqual(str(self.g), str(g)) class Test_igmpv3_query(unittest.TestCase): """ Test case for Internet Group Management Protocol v3 Membership Query Message""" def setUp(self): self.msgtype = IGMP_TYPE_QUERY self.maxresp = 100 self.csum = 0 self.address = '225.0.0.1' self.s_flg = 0 self.qrv = 2 self.qqic = 10 self.num = 0 self.srcs = [] self.s_qrv = self.s_flg << 3 | self.qrv self.buf = pack(igmpv3_query._PACK_STR, self.msgtype, self.maxresp, self.csum, addrconv.ipv4.text_to_bin(self.address), self.s_qrv, self.qqic, self.num) self.g = igmpv3_query( self.msgtype, self.maxresp, self.csum, self.address, self.s_flg, self.qrv, self.qqic, self.num, self.srcs) def setUp_with_srcs(self): self.srcs = ['192.168.1.1', '192.168.1.2', '192.168.1.3'] self.num = len(self.srcs) self.buf = pack(igmpv3_query._PACK_STR, self.msgtype, self.maxresp, self.csum, addrconv.ipv4.text_to_bin(self.address), self.s_qrv, self.qqic, self.num) for src in self.srcs: self.buf += pack('4s', addrconv.ipv4.text_to_bin(src)) self.g = igmpv3_query( self.msgtype, self.maxresp, self.csum, self.address, self.s_flg, self.qrv, self.qqic, self.num, self.srcs) def tearDown(self): pass def find_protocol(self, pkt, name): for p in pkt.protocols: if p.protocol_name == name: return p def test_init(self): self.assertEqual(self.msgtype, self.g.msgtype) self.assertEqual(self.maxresp, self.g.maxresp) self.assertEqual(self.csum, self.g.csum) self.assertEqual(self.address, self.g.address) self.assertEqual(self.s_flg, self.g.s_flg) self.assertEqual(self.qrv, self.g.qrv) self.assertEqual(self.qqic, self.g.qqic) self.assertEqual(self.num, self.g.num) self.assertEqual(self.srcs, self.g.srcs) def test_init_with_srcs(self): self.setUp_with_srcs() self.test_init() def test_parser(self): _res = self.g.parser(self.buf) if type(_res) is tuple: res = _res[0] else: res = _res self.assertEqual(res.msgtype, self.msgtype) self.assertEqual(res.maxresp, self.maxresp) self.assertEqual(res.csum, self.csum) self.assertEqual(res.address, self.address) self.assertEqual(res.s_flg, self.s_flg) self.assertEqual(res.qrv, self.qrv) self.assertEqual(res.qqic, self.qqic) self.assertEqual(res.num, self.num) self.assertEqual(res.srcs, self.srcs) def test_parser_with_srcs(self): self.setUp_with_srcs() self.test_parser() def test_serialize(self): data = bytearray() prev = None buf = self.g.serialize(data, prev) res = unpack_from(igmpv3_query._PACK_STR, bytes(buf)) self.assertEqual(res[0], self.msgtype) self.assertEqual(res[1], self.maxresp) self.assertEqual(res[2], checksum(self.buf)) self.assertEqual(res[3], addrconv.ipv4.text_to_bin(self.address)) self.assertEqual(res[4], self.s_qrv) self.assertEqual(res[5], self.qqic) self.assertEqual(res[6], self.num) def test_serialize_with_srcs(self): self.setUp_with_srcs() data = bytearray() prev = None buf = self.g.serialize(data, prev) res = unpack_from(igmpv3_query._PACK_STR, bytes(buf)) (src1, src2, src3) = unpack_from('4s4s4s', bytes(buf), igmpv3_query._MIN_LEN) self.assertEqual(res[0], self.msgtype) self.assertEqual(res[1], self.maxresp) self.assertEqual(res[2], checksum(self.buf)) self.assertEqual(res[3], addrconv.ipv4.text_to_bin(self.address)) self.assertEqual(res[4], self.s_qrv) self.assertEqual(res[5], self.qqic) self.assertEqual(res[6], self.num) self.assertEqual(src1, addrconv.ipv4.text_to_bin(self.srcs[0])) self.assertEqual(src2, addrconv.ipv4.text_to_bin(self.srcs[1])) self.assertEqual(src3, addrconv.ipv4.text_to_bin(self.srcs[2])) def _build_igmp(self): dl_dst = '11:22:33:44:55:66' dl_src = 'aa:bb:cc:dd:ee:ff' dl_type = ether.ETH_TYPE_IP e = ethernet(dl_dst, dl_src, dl_type) total_length = len(ipv4()) + len(self.g) nw_proto = inet.IPPROTO_IGMP nw_dst = '11.22.33.44' nw_src = '55.66.77.88' i = ipv4(total_length=total_length, src=nw_src, dst=nw_dst, proto=nw_proto, ttl=1) p = Packet() p.add_protocol(e) p.add_protocol(i) p.add_protocol(self.g) p.serialize() return p def test_build_igmp(self): p = self._build_igmp() e = self.find_protocol(p, "ethernet") self.assertTrue(e) self.assertEqual(e.ethertype, ether.ETH_TYPE_IP) i = self.find_protocol(p, "ipv4") self.assertTrue(i) self.assertEqual(i.proto, inet.IPPROTO_IGMP) g = self.find_protocol(p, "igmpv3_query") self.assertTrue(g) self.assertEqual(g.msgtype, self.msgtype) self.assertEqual(g.maxresp, self.maxresp) self.assertEqual(g.csum, checksum(self.buf)) self.assertEqual(g.address, self.address) self.assertEqual(g.s_flg, self.s_flg) self.assertEqual(g.qrv, self.qrv) self.assertEqual(g.qqic, self.qqic) self.assertEqual(g.num, self.num) self.assertEqual(g.srcs, self.srcs) def test_build_igmp_with_srcs(self): self.setUp_with_srcs() self.test_build_igmp() def test_to_string(self): igmp_values = {'msgtype': repr(self.msgtype), 'maxresp': repr(self.maxresp), 'csum': repr(self.csum), 'address': repr(self.address), 's_flg': repr(self.s_flg), 'qrv': repr(self.qrv), 'qqic': repr(self.qqic), 'num': repr(self.num), 'srcs': repr(self.srcs)} _g_str = ','.join(['%s=%s' % (k, igmp_values[k]) for k, v in inspect.getmembers(self.g) if k in igmp_values]) g_str = '%s(%s)' % (igmpv3_query.__name__, _g_str) self.assertEqual(str(self.g), g_str) self.assertEqual(repr(self.g), g_str) def test_to_string_with_srcs(self): self.setUp_with_srcs() self.test_to_string() def test_num_larger_than_srcs(self): self.srcs = ['192.168.1.1', '192.168.1.2', '192.168.1.3'] self.num = len(self.srcs) + 1 self.buf = pack(igmpv3_query._PACK_STR, self.msgtype, self.maxresp, self.csum, addrconv.ipv4.text_to_bin(self.address), self.s_qrv, self.qqic, self.num) for src in self.srcs: self.buf += pack('4s', addrconv.ipv4.text_to_bin(src)) self.g = igmpv3_query( self.msgtype, self.maxresp, self.csum, self.address, self.s_flg, self.qrv, self.qqic, self.num, self.srcs) self.assertRaises(Exception, self.test_parser) def test_num_smaller_than_srcs(self): self.srcs = ['192.168.1.1', '192.168.1.2', '192.168.1.3'] self.num = len(self.srcs) - 1 self.buf = pack(igmpv3_query._PACK_STR, self.msgtype, self.maxresp, self.csum, addrconv.ipv4.text_to_bin(self.address), self.s_qrv, self.qqic, self.num) for src in self.srcs: self.buf += pack('4s', addrconv.ipv4.text_to_bin(src)) self.g = igmpv3_query( self.msgtype, self.maxresp, self.csum, self.address, self.s_flg, self.qrv, self.qqic, self.num, self.srcs) self.assertRaises(Exception, self.test_parser) def test_default_args(self): prev = ipv4(proto=inet.IPPROTO_IGMP) g = igmpv3_query() prev.serialize(g, None) buf = g.serialize(bytearray(), prev) res = unpack_from(igmpv3_query._PACK_STR, bytes(buf)) buf = bytearray(buf) pack_into('!H', buf, 2, 0) self.assertEqual(res[0], IGMP_TYPE_QUERY) self.assertEqual(res[1], 100) self.assertEqual(res[2], checksum(buf)) self.assertEqual(res[3], addrconv.ipv4.text_to_bin('0.0.0.0')) self.assertEqual(res[4], 2) self.assertEqual(res[5], 0) self.assertEqual(res[6], 0) # srcs without num prev = ipv4(proto=inet.IPPROTO_IGMP) srcs = ['192.168.1.1', '192.168.1.2', '192.168.1.3'] g = igmpv3_query(srcs=srcs) prev.serialize(g, None) buf = g.serialize(bytearray(), prev) res = unpack_from(igmpv3_query._PACK_STR, bytes(buf)) buf = bytearray(buf) pack_into('!H', buf, 2, 0) self.assertEqual(res[0], IGMP_TYPE_QUERY) self.assertEqual(res[1], 100) self.assertEqual(res[2], checksum(buf)) self.assertEqual(res[3], addrconv.ipv4.text_to_bin('0.0.0.0')) self.assertEqual(res[4], 2) self.assertEqual(res[5], 0) self.assertEqual(res[6], len(srcs)) res = unpack_from('4s4s4s', bytes(buf), igmpv3_query._MIN_LEN) self.assertEqual(res[0], addrconv.ipv4.text_to_bin(srcs[0])) self.assertEqual(res[1], addrconv.ipv4.text_to_bin(srcs[1])) self.assertEqual(res[2], addrconv.ipv4.text_to_bin(srcs[2])) def test_json(self): jsondict = self.g.to_jsondict() g = igmpv3_query.from_jsondict(jsondict['igmpv3_query']) self.assertEqual(str(self.g), str(g)) def test_json_with_srcs(self): self.setUp_with_srcs() self.test_json() class Test_igmpv3_report(unittest.TestCase): """ Test case for Internet Group Management Protocol v3 Membership Report Message""" def setUp(self): self.msgtype = IGMP_TYPE_REPORT_V3 self.csum = 0 self.record_num = 0 self.records = [] self.buf = pack(igmpv3_report._PACK_STR, self.msgtype, self.csum, self.record_num) self.g = igmpv3_report( self.msgtype, self.csum, self.record_num, self.records) def setUp_with_records(self): self.record1 = igmpv3_report_group( MODE_IS_INCLUDE, 0, 0, '225.0.0.1') self.record2 = igmpv3_report_group( MODE_IS_INCLUDE, 0, 2, '225.0.0.2', ['172.16.10.10', '172.16.10.27']) self.record3 = igmpv3_report_group( MODE_IS_INCLUDE, 1, 0, '225.0.0.3', [], b'abc\x00') self.record4 = igmpv3_report_group( MODE_IS_INCLUDE, 2, 2, '225.0.0.4', ['172.16.10.10', '172.16.10.27'], b'abcde\x00\x00\x00') self.records = [self.record1, self.record2, self.record3, self.record4] self.record_num = len(self.records) self.buf = pack(igmpv3_report._PACK_STR, self.msgtype, self.csum, self.record_num) self.buf += self.record1.serialize() self.buf += self.record2.serialize() self.buf += self.record3.serialize() self.buf += self.record4.serialize() self.g = igmpv3_report( self.msgtype, self.csum, self.record_num, self.records) def tearDown(self): pass def find_protocol(self, pkt, name): for p in pkt.protocols: if p.protocol_name == name: return p def test_init(self): self.assertEqual(self.msgtype, self.g.msgtype) self.assertEqual(self.csum, self.g.csum) self.assertEqual(self.record_num, self.g.record_num) self.assertEqual(self.records, self.g.records) def test_init_with_records(self): self.setUp_with_records() self.test_init() def test_parser(self): _res = self.g.parser(bytes(self.buf)) if type(_res) is tuple: res = _res[0] else: res = _res self.assertEqual(res.msgtype, self.msgtype) self.assertEqual(res.csum, self.csum) self.assertEqual(res.record_num, self.record_num) self.assertEqual(repr(res.records), repr(self.records)) def test_parser_with_records(self): self.setUp_with_records() self.test_parser() def test_serialize(self): data = bytearray() prev = None buf = self.g.serialize(data, prev) res = unpack_from(igmpv3_report._PACK_STR, bytes(buf)) self.assertEqual(res[0], self.msgtype) self.assertEqual(res[1], checksum(self.buf)) self.assertEqual(res[2], self.record_num) def test_serialize_with_records(self): self.setUp_with_records() data = bytearray() prev = None buf = bytes(self.g.serialize(data, prev)) res = unpack_from(igmpv3_report._PACK_STR, buf) offset = igmpv3_report._MIN_LEN rec1 = igmpv3_report_group.parser(buf[offset:]) offset += len(rec1) rec2 = igmpv3_report_group.parser(buf[offset:]) offset += len(rec2) rec3 = igmpv3_report_group.parser(buf[offset:]) offset += len(rec3) rec4 = igmpv3_report_group.parser(buf[offset:]) self.assertEqual(res[0], self.msgtype) self.assertEqual(res[1], checksum(self.buf)) self.assertEqual(res[2], self.record_num) self.assertEqual(repr(rec1), repr(self.record1)) self.assertEqual(repr(rec2), repr(self.record2)) self.assertEqual(repr(rec3), repr(self.record3)) self.assertEqual(repr(rec4), repr(self.record4)) def _build_igmp(self): dl_dst = '11:22:33:44:55:66' dl_src = 'aa:bb:cc:dd:ee:ff' dl_type = ether.ETH_TYPE_IP e = ethernet(dl_dst, dl_src, dl_type) total_length = len(ipv4()) + len(self.g) nw_proto = inet.IPPROTO_IGMP nw_dst = '11.22.33.44' nw_src = '55.66.77.88' i = ipv4(total_length=total_length, src=nw_src, dst=nw_dst, proto=nw_proto, ttl=1) p = Packet() p.add_protocol(e) p.add_protocol(i) p.add_protocol(self.g) p.serialize() return p def test_build_igmp(self): p = self._build_igmp() e = self.find_protocol(p, "ethernet") self.assertTrue(e) self.assertEqual(e.ethertype, ether.ETH_TYPE_IP) i = self.find_protocol(p, "ipv4") self.assertTrue(i) self.assertEqual(i.proto, inet.IPPROTO_IGMP) g = self.find_protocol(p, "igmpv3_report") self.assertTrue(g) self.assertEqual(g.msgtype, self.msgtype) self.assertEqual(g.csum, checksum(self.buf)) self.assertEqual(g.record_num, self.record_num) self.assertEqual(g.records, self.records) def test_build_igmp_with_records(self): self.setUp_with_records() self.test_build_igmp() def test_to_string(self): igmp_values = {'msgtype': repr(self.msgtype), 'csum': repr(self.csum), 'record_num': repr(self.record_num), 'records': repr(self.records)} _g_str = ','.join(['%s=%s' % (k, igmp_values[k]) for k, v in inspect.getmembers(self.g) if k in igmp_values]) g_str = '%s(%s)' % (igmpv3_report.__name__, _g_str) self.assertEqual(str(self.g), g_str) self.assertEqual(repr(self.g), g_str) def test_to_string_with_records(self): self.setUp_with_records() self.test_to_string() def test_record_num_larger_than_records(self): self.record1 = igmpv3_report_group( MODE_IS_INCLUDE, 0, 0, '225.0.0.1') self.record2 = igmpv3_report_group( MODE_IS_INCLUDE, 0, 2, '225.0.0.2', ['172.16.10.10', '172.16.10.27']) self.record3 = igmpv3_report_group( MODE_IS_INCLUDE, 1, 0, '225.0.0.3', [], b'abc\x00') self.record4 = igmpv3_report_group( MODE_IS_INCLUDE, 1, 2, '225.0.0.4', ['172.16.10.10', '172.16.10.27'], b'abc\x00') self.records = [self.record1, self.record2, self.record3, self.record4] self.record_num = len(self.records) + 1 self.buf = pack(igmpv3_report._PACK_STR, self.msgtype, self.csum, self.record_num) self.buf += self.record1.serialize() self.buf += self.record2.serialize() self.buf += self.record3.serialize() self.buf += self.record4.serialize() self.g = igmpv3_report( self.msgtype, self.csum, self.record_num, self.records) self.assertRaises(Exception, self.test_parser) def test_record_num_smaller_than_records(self): self.record1 = igmpv3_report_group( MODE_IS_INCLUDE, 0, 0, '225.0.0.1') self.record2 = igmpv3_report_group( MODE_IS_INCLUDE, 0, 2, '225.0.0.2', ['172.16.10.10', '172.16.10.27']) self.record3 = igmpv3_report_group( MODE_IS_INCLUDE, 1, 0, '225.0.0.3', [], b'abc\x00') self.record4 = igmpv3_report_group( MODE_IS_INCLUDE, 1, 2, '225.0.0.4', ['172.16.10.10', '172.16.10.27'], b'abc\x00') self.records = [self.record1, self.record2, self.record3, self.record4] self.record_num = len(self.records) - 1 self.buf = pack(igmpv3_report._PACK_STR, self.msgtype, self.csum, self.record_num) self.buf += self.record1.serialize() self.buf += self.record2.serialize() self.buf += self.record3.serialize() self.buf += self.record4.serialize() self.g = igmpv3_report( self.msgtype, self.csum, self.record_num, self.records) self.assertRaises(Exception, self.test_parser) def test_default_args(self): prev = ipv4(proto=inet.IPPROTO_IGMP) g = igmpv3_report() prev.serialize(g, None) buf = g.serialize(bytearray(), prev) res = unpack_from(igmpv3_report._PACK_STR, bytes(buf)) buf = bytearray(buf) pack_into('!H', buf, 2, 0) self.assertEqual(res[0], IGMP_TYPE_REPORT_V3) self.assertEqual(res[1], checksum(buf)) self.assertEqual(res[2], 0) # records without record_num prev = ipv4(proto=inet.IPPROTO_IGMP) record1 = igmpv3_report_group( MODE_IS_INCLUDE, 0, 0, '225.0.0.1') record2 = igmpv3_report_group( MODE_IS_INCLUDE, 0, 2, '225.0.0.2', ['172.16.10.10', '172.16.10.27']) record3 = igmpv3_report_group( MODE_IS_INCLUDE, 1, 0, '225.0.0.3', [], b'abc\x00') record4 = igmpv3_report_group( MODE_IS_INCLUDE, 1, 2, '225.0.0.4', ['172.16.10.10', '172.16.10.27'], b'abc\x00') records = [record1, record2, record3, record4] g = igmpv3_report(records=records) prev.serialize(g, None) buf = g.serialize(bytearray(), prev) res = unpack_from(igmpv3_report._PACK_STR, bytes(buf)) buf = bytearray(buf) pack_into('!H', buf, 2, 0) self.assertEqual(res[0], IGMP_TYPE_REPORT_V3) self.assertEqual(res[1], checksum(buf)) self.assertEqual(res[2], len(records)) def test_json(self): jsondict = self.g.to_jsondict() g = igmpv3_report.from_jsondict(jsondict['igmpv3_report']) self.assertEqual(str(self.g), str(g)) def test_json_with_records(self): self.setUp_with_records() self.test_json() class Test_igmpv3_report_group(unittest.TestCase): """Test case for Group Records of Internet Group Management Protocol v3 Membership Report Message""" def setUp(self): self.type_ = MODE_IS_INCLUDE self.aux_len = 0 self.num = 0 self.address = '225.0.0.1' self.srcs = [] self.aux = None self.buf = pack(igmpv3_report_group._PACK_STR, self.type_, self.aux_len, self.num, addrconv.ipv4.text_to_bin(self.address)) self.g = igmpv3_report_group( self.type_, self.aux_len, self.num, self.address, self.srcs, self.aux) def setUp_with_srcs(self): self.srcs = ['192.168.1.1', '192.168.1.2', '192.168.1.3'] self.num = len(self.srcs) self.buf = pack(igmpv3_report_group._PACK_STR, self.type_, self.aux_len, self.num, addrconv.ipv4.text_to_bin(self.address)) for src in self.srcs: self.buf += pack('4s', addrconv.ipv4.text_to_bin(src)) self.g = igmpv3_report_group( self.type_, self.aux_len, self.num, self.address, self.srcs, self.aux) def setUp_with_aux(self): self.aux = b'\x01\x02\x03\x04\x05\x00\x00\x00' self.aux_len = len(self.aux) // 4 self.buf = pack(igmpv3_report_group._PACK_STR, self.type_, self.aux_len, self.num, addrconv.ipv4.text_to_bin(self.address)) self.buf += self.aux self.g = igmpv3_report_group( self.type_, self.aux_len, self.num, self.address, self.srcs, self.aux) def setUp_with_srcs_and_aux(self): self.srcs = ['192.168.1.1', '192.168.1.2', '192.168.1.3'] self.num = len(self.srcs) self.aux = b'\x01\x02\x03\x04\x05\x00\x00\x00' self.aux_len = len(self.aux) // 4 self.buf = pack(igmpv3_report_group._PACK_STR, self.type_, self.aux_len, self.num, addrconv.ipv4.text_to_bin(self.address)) for src in self.srcs: self.buf += pack('4s', addrconv.ipv4.text_to_bin(src)) self.buf += self.aux self.g = igmpv3_report_group( self.type_, self.aux_len, self.num, self.address, self.srcs, self.aux) def tearDown(self): pass def test_init(self): self.assertEqual(self.type_, self.g.type_) self.assertEqual(self.aux_len, self.g.aux_len) self.assertEqual(self.num, self.g.num) self.assertEqual(self.address, self.g.address) self.assertEqual(self.srcs, self.g.srcs) self.assertEqual(self.aux, self.g.aux) def test_init_with_srcs(self): self.setUp_with_srcs() self.test_init() def test_init_with_aux(self): self.setUp_with_aux() self.test_init() def test_init_with_srcs_and_aux(self): self.setUp_with_srcs_and_aux() self.test_init() def test_parser(self): _res = self.g.parser(self.buf) if type(_res) is tuple: res = _res[0] else: res = _res self.assertEqual(res.type_, self.type_) self.assertEqual(res.aux_len, self.aux_len) self.assertEqual(res.num, self.num) self.assertEqual(res.address, self.address) self.assertEqual(res.srcs, self.srcs) self.assertEqual(res.aux, self.aux) def test_parser_with_srcs(self): self.setUp_with_srcs() self.test_parser() def test_parser_with_aux(self): self.setUp_with_aux() self.test_parser() def test_parser_with_srcs_and_aux(self): self.setUp_with_srcs_and_aux() self.test_parser() def test_serialize(self): buf = self.g.serialize() res = unpack_from(igmpv3_report_group._PACK_STR, bytes(buf)) self.assertEqual(res[0], self.type_) self.assertEqual(res[1], self.aux_len) self.assertEqual(res[2], self.num) self.assertEqual(res[3], addrconv.ipv4.text_to_bin(self.address)) def test_serialize_with_srcs(self): self.setUp_with_srcs() buf = self.g.serialize() res = unpack_from(igmpv3_report_group._PACK_STR, bytes(buf)) (src1, src2, src3) = unpack_from('4s4s4s', bytes(buf), igmpv3_report_group._MIN_LEN) self.assertEqual(res[0], self.type_) self.assertEqual(res[1], self.aux_len) self.assertEqual(res[2], self.num) self.assertEqual(res[3], addrconv.ipv4.text_to_bin(self.address)) self.assertEqual(src1, addrconv.ipv4.text_to_bin(self.srcs[0])) self.assertEqual(src2, addrconv.ipv4.text_to_bin(self.srcs[1])) self.assertEqual(src3, addrconv.ipv4.text_to_bin(self.srcs[2])) def test_serialize_with_aux(self): self.setUp_with_aux() buf = self.g.serialize() res = unpack_from(igmpv3_report_group._PACK_STR, bytes(buf)) (aux, ) = unpack_from('%ds' % (self.aux_len * 4), bytes(buf), igmpv3_report_group._MIN_LEN) self.assertEqual(res[0], self.type_) self.assertEqual(res[1], self.aux_len) self.assertEqual(res[2], self.num) self.assertEqual(res[3], addrconv.ipv4.text_to_bin(self.address)) self.assertEqual(aux, self.aux) def test_serialize_with_srcs_and_aux(self): self.setUp_with_srcs_and_aux() buf = self.g.serialize() res = unpack_from(igmpv3_report_group._PACK_STR, bytes(buf)) (src1, src2, src3) = unpack_from('4s4s4s', bytes(buf), igmpv3_report_group._MIN_LEN) (aux, ) = unpack_from('%ds' % (self.aux_len * 4), bytes(buf), igmpv3_report_group._MIN_LEN + 12) self.assertEqual(res[0], self.type_) self.assertEqual(res[1], self.aux_len) self.assertEqual(res[2], self.num) self.assertEqual(res[3], addrconv.ipv4.text_to_bin(self.address)) self.assertEqual(src1, addrconv.ipv4.text_to_bin(self.srcs[0])) self.assertEqual(src2, addrconv.ipv4.text_to_bin(self.srcs[1])) self.assertEqual(src3, addrconv.ipv4.text_to_bin(self.srcs[2])) self.assertEqual(aux, self.aux) def test_to_string(self): igmp_values = {'type_': repr(self.type_), 'aux_len': repr(self.aux_len), 'num': repr(self.num), 'address': repr(self.address), 'srcs': repr(self.srcs), 'aux': repr(self.aux)} _g_str = ','.join(['%s=%s' % (k, igmp_values[k]) for k, v in inspect.getmembers(self.g) if k in igmp_values]) g_str = '%s(%s)' % (igmpv3_report_group.__name__, _g_str) self.assertEqual(str(self.g), g_str) self.assertEqual(repr(self.g), g_str) def test_to_string_with_srcs(self): self.setUp_with_srcs() self.test_to_string() def test_to_string_with_aux(self): self.setUp_with_aux() self.test_to_string() def test_to_string_with_srcs_and_aux(self): self.setUp_with_srcs_and_aux() self.test_to_string() def test_len(self): self.assertEqual(len(self.g), 8) def test_len_with_srcs(self): self.setUp_with_srcs() self.assertEqual(len(self.g), 20) def test_len_with_aux(self): self.setUp_with_aux() self.assertEqual(len(self.g), 16) def test_len_with_srcs_and_aux(self): self.setUp_with_srcs_and_aux() self.assertEqual(len(self.g), 28) def test_num_larger_than_srcs(self): self.srcs = ['192.168.1.1', '192.168.1.2', '192.168.1.3'] self.num = len(self.srcs) + 1 self.buf = pack(igmpv3_report_group._PACK_STR, self.type_, self.aux_len, self.num, addrconv.ipv4.text_to_bin(self.address)) for src in self.srcs: self.buf += pack('4s', addrconv.ipv4.text_to_bin(src)) self.g = igmpv3_report_group( self.type_, self.aux_len, self.num, self.address, self.srcs, self.aux) self.assertRaises(AssertionError, self.test_parser) def test_num_smaller_than_srcs(self): self.srcs = ['192.168.1.1', '192.168.1.2', '192.168.1.3'] self.num = len(self.srcs) - 1 self.buf = pack(igmpv3_report_group._PACK_STR, self.type_, self.aux_len, self.num, addrconv.ipv4.text_to_bin(self.address)) for src in self.srcs: self.buf += pack('4s', addrconv.ipv4.text_to_bin(src)) self.g = igmpv3_report_group( self.type_, self.aux_len, self.num, self.address, self.srcs, self.aux) self.assertRaises(AssertionError, self.test_parser) def test_aux_len_larger_than_aux(self): self.aux = b'\x01\x02\x03\x04\x05\x00\x00\x00' self.aux_len = len(self.aux) // 4 + 1 self.buf = pack(igmpv3_report_group._PACK_STR, self.type_, self.aux_len, self.num, addrconv.ipv4.text_to_bin(self.address)) self.buf += self.aux self.g = igmpv3_report_group( self.type_, self.aux_len, self.num, self.address, self.srcs, self.aux) self.assertRaises(Exception, self.test_parser) def test_aux_len_smaller_than_aux(self): self.aux = b'\x01\x02\x03\x04\x05\x00\x00\x00' self.aux_len = len(self.aux) // 4 - 1 self.buf = pack(igmpv3_report_group._PACK_STR, self.type_, self.aux_len, self.num, addrconv.ipv4.text_to_bin(self.address)) self.buf += self.aux self.g = igmpv3_report_group( self.type_, self.aux_len, self.num, self.address, self.srcs, self.aux) self.assertRaises(AssertionError, self.test_parser) def test_default_args(self): rep = igmpv3_report_group() buf = rep.serialize() res = unpack_from(igmpv3_report_group._PACK_STR, bytes(buf)) self.assertEqual(res[0], 0) self.assertEqual(res[1], 0) self.assertEqual(res[2], 0) self.assertEqual(res[3], addrconv.ipv4.text_to_bin('0.0.0.0')) # srcs without num srcs = ['192.168.1.1', '192.168.1.2', '192.168.1.3'] rep = igmpv3_report_group(srcs=srcs) buf = rep.serialize() res = unpack_from(igmpv3_report_group._PACK_STR, bytes(buf)) self.assertEqual(res[0], 0) self.assertEqual(res[1], 0) self.assertEqual(res[2], len(srcs)) self.assertEqual(res[3], addrconv.ipv4.text_to_bin('0.0.0.0')) res = unpack_from('4s4s4s', bytes(buf), igmpv3_report_group._MIN_LEN) self.assertEqual(res[0], addrconv.ipv4.text_to_bin(srcs[0])) self.assertEqual(res[1], addrconv.ipv4.text_to_bin(srcs[1])) self.assertEqual(res[2], addrconv.ipv4.text_to_bin(srcs[2])) # aux without aux_len aux = b'abcde' rep = igmpv3_report_group(aux=aux) buf = rep.serialize() res = unpack_from(igmpv3_report_group._PACK_STR, bytes(buf)) self.assertEqual(res[0], 0) self.assertEqual(res[1], 2) self.assertEqual(res[2], 0) self.assertEqual(res[3], addrconv.ipv4.text_to_bin('0.0.0.0')) self.assertEqual(buf[igmpv3_report_group._MIN_LEN:], b'abcde\x00\x00\x00') ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/packet/test_ipv4.py0000664000175000017500000001113000000000000022146 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone 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. import unittest import logging import struct from struct import * from os_ken.ofproto import inet from os_ken.lib.packet import packet_utils from os_ken.lib.packet.ipv4 import ipv4 from os_ken.lib.packet.tcp import tcp from os_ken.lib import addrconv LOG = logging.getLogger('test_ipv4') class Test_ipv4(unittest.TestCase): """ Test case for ipv4 """ version = 4 header_length = 5 + 10 ver_hlen = version << 4 | header_length tos = 0 total_length = header_length + 64 identification = 30774 flags = 4 offset = 1480 flg_off = flags << 13 | offset ttl = 64 proto = inet.IPPROTO_TCP csum = 0xadc6 src = '131.151.32.21' dst = '131.151.32.129' length = header_length * 4 option = b'\x86\x28\x00\x00\x00\x01\x01\x22' \ + b'\x00\x01\xae\x00\x00\x00\x00\x00' \ + b'\x00\x00\x00\x00\x00\x00\x00\x00' \ + b'\x00\x00\x00\x00\x00\x00\x00\x00' \ + b'\x00\x00\x00\x00\x00\x00\x00\x01' buf = pack(ipv4._PACK_STR, ver_hlen, tos, total_length, identification, flg_off, ttl, proto, csum, addrconv.ipv4.text_to_bin(src), addrconv.ipv4.text_to_bin(dst)) \ + option ip = ipv4(version, header_length, tos, total_length, identification, flags, offset, ttl, proto, csum, src, dst, option) def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(self.version, self.ip.version) self.assertEqual(self.header_length, self.ip.header_length) self.assertEqual(self.tos, self.ip.tos) self.assertEqual(self.total_length, self.ip.total_length) self.assertEqual(self.identification, self.ip.identification) self.assertEqual(self.flags, self.ip.flags) self.assertEqual(self.offset, self.ip.offset) self.assertEqual(self.ttl, self.ip.ttl) self.assertEqual(self.proto, self.ip.proto) self.assertEqual(self.csum, self.ip.csum) self.assertEqual(self.src, self.ip.src) self.assertEqual(self.dst, self.ip.dst) self.assertEqual(self.length, len(self.ip)) self.assertEqual(self.option, self.ip.option) def test_parser(self): res, ptype, _ = self.ip.parser(self.buf) self.assertEqual(res.version, self.version) self.assertEqual(res.header_length, self.header_length) self.assertEqual(res.tos, self.tos) self.assertEqual(res.total_length, self.total_length) self.assertEqual(res.identification, self.identification) self.assertEqual(res.flags, self.flags) self.assertEqual(res.offset, self.offset) self.assertEqual(res.ttl, self.ttl) self.assertEqual(res.proto, self.proto) self.assertEqual(res.csum, self.csum) self.assertEqual(res.src, self.src) self.assertEqual(res.dst, self.dst) self.assertEqual(ptype, tcp) def test_serialize(self): buf = self.ip.serialize(bytearray(), None) res = struct.unpack_from(ipv4._PACK_STR, bytes(buf)) option = buf[ipv4._MIN_LEN:ipv4._MIN_LEN + len(self.option)] self.assertEqual(res[0], self.ver_hlen) self.assertEqual(res[1], self.tos) self.assertEqual(res[2], self.total_length) self.assertEqual(res[3], self.identification) self.assertEqual(res[4], self.flg_off) self.assertEqual(res[5], self.ttl) self.assertEqual(res[6], self.proto) self.assertEqual(res[8], addrconv.ipv4.text_to_bin(self.src)) self.assertEqual(res[9], addrconv.ipv4.text_to_bin(self.dst)) self.assertEqual(option, self.option) # checksum csum = packet_utils.checksum(buf) self.assertEqual(csum, 0) def test_malformed_ipv4(self): m_short_buf = self.buf[1:ipv4._MIN_LEN] self.assertRaises(Exception, ipv4.parser, m_short_buf) def test_json(self): jsondict = self.ip.to_jsondict() ip = ipv4.from_jsondict(jsondict['ipv4']) self.assertEqual(str(self.ip), str(ip)) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/packet/test_ipv6.py0000664000175000017500000011520000000000000022153 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone 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. import unittest import logging import inspect import struct from os_ken.lib import addrconv from os_ken.lib import ip from os_ken.lib.packet import ipv6 LOG = logging.getLogger(__name__) class Test_ipv6(unittest.TestCase): def setUp(self): self.version = 6 self.traffic_class = 0 self.flow_label = 0 self.payload_length = 817 self.nxt = 6 self.hop_limit = 128 self.src = '2002:4637:d5d3::4637:d5d3' self.dst = '2001:4860:0:2001::68' self.ext_hdrs = [] self.ip = ipv6.ipv6( self.version, self.traffic_class, self.flow_label, self.payload_length, self.nxt, self.hop_limit, self.src, self.dst, self.ext_hdrs) self.v_tc_flow = ( self.version << 28 | self.traffic_class << 20 | self.flow_label << 12) self.buf = struct.pack( ipv6.ipv6._PACK_STR, self.v_tc_flow, self.payload_length, self.nxt, self.hop_limit, addrconv.ipv6.text_to_bin(self.src), addrconv.ipv6.text_to_bin(self.dst)) def setUp_with_hop_opts(self): self.opt1_type = 5 self.opt1_len = 2 self.opt1_data = b'\x00\x00' self.opt2_type = 1 self.opt2_len = 0 self.opt2_data = None self.options = [ ipv6.option(self.opt1_type, self.opt1_len, self.opt1_data), ipv6.option(self.opt2_type, self.opt2_len, self.opt2_data), ] self.hop_opts_nxt = 6 self.hop_opts_size = 0 self.hop_opts = ipv6.hop_opts( self.hop_opts_nxt, self.hop_opts_size, self.options) self.ext_hdrs = [self.hop_opts] self.payload_length += len(self.hop_opts) self.nxt = ipv6.hop_opts.TYPE self.ip = ipv6.ipv6( self.version, self.traffic_class, self.flow_label, self.payload_length, self.nxt, self.hop_limit, self.src, self.dst, self.ext_hdrs) self.buf = struct.pack( ipv6.ipv6._PACK_STR, self.v_tc_flow, self.payload_length, self.nxt, self.hop_limit, addrconv.ipv6.text_to_bin(self.src), addrconv.ipv6.text_to_bin(self.dst)) self.buf += self.hop_opts.serialize() def setUp_with_dst_opts(self): self.opt1_type = 5 self.opt1_len = 2 self.opt1_data = b'\x00\x00' self.opt2_type = 1 self.opt2_len = 0 self.opt2_data = None self.options = [ ipv6.option(self.opt1_type, self.opt1_len, self.opt1_data), ipv6.option(self.opt2_type, self.opt2_len, self.opt2_data), ] self.dst_opts_nxt = 6 self.dst_opts_size = 0 self.dst_opts = ipv6.dst_opts( self.dst_opts_nxt, self.dst_opts_size, self.options) self.ext_hdrs = [self.dst_opts] self.payload_length += len(self.dst_opts) self.nxt = ipv6.dst_opts.TYPE self.ip = ipv6.ipv6( self.version, self.traffic_class, self.flow_label, self.payload_length, self.nxt, self.hop_limit, self.src, self.dst, self.ext_hdrs) self.buf = struct.pack( ipv6.ipv6._PACK_STR, self.v_tc_flow, self.payload_length, self.nxt, self.hop_limit, addrconv.ipv6.text_to_bin(self.src), addrconv.ipv6.text_to_bin(self.dst)) self.buf += self.dst_opts.serialize() def setUp_with_routing_type3(self): self.routing_nxt = 6 self.routing_size = 6 self.routing_type = 3 self.routing_seg = 2 self.routing_cmpi = 0 self.routing_cmpe = 0 self.routing_adrs = ["2001:db8:dead::1", "2001:db8:dead::2", "2001:db8:dead::3"] self.routing = ipv6.routing_type3( self.routing_nxt, self.routing_size, self.routing_type, self.routing_seg, self.routing_cmpi, self.routing_cmpe, self.routing_adrs) self.ext_hdrs = [self.routing] self.payload_length += len(self.routing) self.nxt = ipv6.routing.TYPE self.ip = ipv6.ipv6( self.version, self.traffic_class, self.flow_label, self.payload_length, self.nxt, self.hop_limit, self.src, self.dst, self.ext_hdrs) self.buf = struct.pack( ipv6.ipv6._PACK_STR, self.v_tc_flow, self.payload_length, self.nxt, self.hop_limit, addrconv.ipv6.text_to_bin(self.src), addrconv.ipv6.text_to_bin(self.dst)) self.buf += self.routing.serialize() def setUp_with_fragment(self): self.fragment_nxt = 6 self.fragment_offset = 50 self.fragment_more = 1 self.fragment_id = 123 self.fragment = ipv6.fragment( self.fragment_nxt, self.fragment_offset, self.fragment_more, self.fragment_id) self.ext_hdrs = [self.fragment] self.payload_length += len(self.fragment) self.nxt = ipv6.fragment.TYPE self.ip = ipv6.ipv6( self.version, self.traffic_class, self.flow_label, self.payload_length, self.nxt, self.hop_limit, self.src, self.dst, self.ext_hdrs) self.buf = struct.pack( ipv6.ipv6._PACK_STR, self.v_tc_flow, self.payload_length, self.nxt, self.hop_limit, addrconv.ipv6.text_to_bin(self.src), addrconv.ipv6.text_to_bin(self.dst)) self.buf += self.fragment.serialize() def setUp_with_auth(self): self.auth_nxt = 6 self.auth_size = 4 self.auth_spi = 256 self.auth_seq = 1 self.auth_data = b'\xa0\xe7\xf8\xab\xf9\x69\x1a\x8b\xf3\x9f\x7c\xae' self.auth = ipv6.auth( self.auth_nxt, self.auth_size, self.auth_spi, self.auth_seq, self.auth_data) self.ext_hdrs = [self.auth] self.payload_length += len(self.auth) self.nxt = ipv6.auth.TYPE self.ip = ipv6.ipv6( self.version, self.traffic_class, self.flow_label, self.payload_length, self.nxt, self.hop_limit, self.src, self.dst, self.ext_hdrs) self.buf = struct.pack( ipv6.ipv6._PACK_STR, self.v_tc_flow, self.payload_length, self.nxt, self.hop_limit, addrconv.ipv6.text_to_bin(self.src), addrconv.ipv6.text_to_bin(self.dst)) self.buf += self.auth.serialize() def setUp_with_multi_headers(self): self.opt1_type = 5 self.opt1_len = 2 self.opt1_data = b'\x00\x00' self.opt2_type = 1 self.opt2_len = 0 self.opt2_data = None self.options = [ ipv6.option(self.opt1_type, self.opt1_len, self.opt1_data), ipv6.option(self.opt2_type, self.opt2_len, self.opt2_data), ] self.hop_opts_nxt = ipv6.auth.TYPE self.hop_opts_size = 0 self.hop_opts = ipv6.hop_opts( self.hop_opts_nxt, self.hop_opts_size, self.options) self.auth_nxt = 6 self.auth_size = 4 self.auth_spi = 256 self.auth_seq = 1 self.auth_data = b'\xa0\xe7\xf8\xab\xf9\x69\x1a\x8b\xf3\x9f\x7c\xae' self.auth = ipv6.auth( self.auth_nxt, self.auth_size, self.auth_spi, self.auth_seq, self.auth_data) self.ext_hdrs = [self.hop_opts, self.auth] self.payload_length += len(self.hop_opts) + len(self.auth) self.nxt = ipv6.hop_opts.TYPE self.ip = ipv6.ipv6( self.version, self.traffic_class, self.flow_label, self.payload_length, self.nxt, self.hop_limit, self.src, self.dst, self.ext_hdrs) self.buf = struct.pack( ipv6.ipv6._PACK_STR, self.v_tc_flow, self.payload_length, self.nxt, self.hop_limit, addrconv.ipv6.text_to_bin(self.src), addrconv.ipv6.text_to_bin(self.dst)) self.buf += self.hop_opts.serialize() self.buf += self.auth.serialize() def tearDown(self): pass def test_init(self): self.assertEqual(self.version, self.ip.version) self.assertEqual(self.traffic_class, self.ip.traffic_class) self.assertEqual(self.flow_label, self.ip.flow_label) self.assertEqual(self.payload_length, self.ip.payload_length) self.assertEqual(self.nxt, self.ip.nxt) self.assertEqual(self.hop_limit, self.ip.hop_limit) self.assertEqual(self.src, self.ip.src) self.assertEqual(self.dst, self.ip.dst) self.assertEqual(str(self.ext_hdrs), str(self.ip.ext_hdrs)) def test_init_with_hop_opts(self): self.setUp_with_hop_opts() self.test_init() def test_init_with_dst_opts(self): self.setUp_with_dst_opts() self.test_init() def test_init_with_routing_type3(self): self.setUp_with_routing_type3() self.test_init() def test_init_with_fragment(self): self.setUp_with_fragment() self.test_init() def test_init_with_auth(self): self.setUp_with_auth() self.test_init() def test_init_with_multi_headers(self): self.setUp_with_multi_headers() self.test_init() def test_parser(self): _res = self.ip.parser(bytes(self.buf)) if type(_res) is tuple: res = _res[0] else: res = _res self.assertEqual(self.version, res.version) self.assertEqual(self.traffic_class, res.traffic_class) self.assertEqual(self.flow_label, res.flow_label) self.assertEqual(self.payload_length, res.payload_length) self.assertEqual(self.nxt, res.nxt) self.assertEqual(self.hop_limit, res.hop_limit) self.assertEqual(self.src, res.src) self.assertEqual(self.dst, res.dst) self.assertEqual(str(self.ext_hdrs), str(res.ext_hdrs)) def test_parser_with_hop_opts(self): self.setUp_with_hop_opts() self.test_parser() def test_parser_with_dst_opts(self): self.setUp_with_dst_opts() self.test_parser() def test_parser_with_routing_type3(self): self.setUp_with_routing_type3() self.test_parser() def test_parser_with_fragment(self): self.setUp_with_fragment() self.test_parser() def test_parser_with_auth(self): self.setUp_with_auth() self.test_parser() def test_parser_with_multi_headers(self): self.setUp_with_multi_headers() self.test_parser() def test_serialize(self): data = bytearray() prev = None buf = self.ip.serialize(data, prev) res = struct.unpack_from(ipv6.ipv6._PACK_STR, bytes(buf)) self.assertEqual(self.v_tc_flow, res[0]) self.assertEqual(self.payload_length, res[1]) self.assertEqual(self.nxt, res[2]) self.assertEqual(self.hop_limit, res[3]) self.assertEqual(self.src, addrconv.ipv6.bin_to_text(res[4])) self.assertEqual(self.dst, addrconv.ipv6.bin_to_text(res[5])) def test_serialize_with_hop_opts(self): self.setUp_with_hop_opts() self.test_serialize() data = bytearray() prev = None buf = self.ip.serialize(data, prev) hop_opts = ipv6.hop_opts.parser(bytes(buf[ipv6.ipv6._MIN_LEN:])) self.assertEqual(repr(self.hop_opts), repr(hop_opts)) def test_serialize_with_dst_opts(self): self.setUp_with_dst_opts() self.test_serialize() data = bytearray() prev = None buf = self.ip.serialize(data, prev) dst_opts = ipv6.dst_opts.parser(bytes(buf[ipv6.ipv6._MIN_LEN:])) self.assertEqual(repr(self.dst_opts), repr(dst_opts)) def test_serialize_with_routing_type3(self): self.setUp_with_routing_type3() self.test_serialize() data = bytearray() prev = None buf = self.ip.serialize(data, prev) routing = ipv6.routing.parser(bytes(buf[ipv6.ipv6._MIN_LEN:])) self.assertEqual(repr(self.routing), repr(routing)) def test_serialize_with_fragment(self): self.setUp_with_fragment() self.test_serialize() data = bytearray() prev = None buf = self.ip.serialize(data, prev) fragment = ipv6.fragment.parser(bytes(buf[ipv6.ipv6._MIN_LEN:])) self.assertEqual(repr(self.fragment), repr(fragment)) def test_serialize_with_auth(self): self.setUp_with_auth() self.test_serialize() data = bytearray() prev = None buf = self.ip.serialize(data, prev) auth = ipv6.auth.parser(bytes(buf[ipv6.ipv6._MIN_LEN:])) self.assertEqual(repr(self.auth), repr(auth)) def test_serialize_with_multi_headers(self): self.setUp_with_multi_headers() self.test_serialize() data = bytearray() prev = None buf = self.ip.serialize(data, prev) offset = ipv6.ipv6._MIN_LEN hop_opts = ipv6.hop_opts.parser(bytes(buf[offset:])) offset += len(hop_opts) auth = ipv6.auth.parser(bytes(buf[offset:])) self.assertEqual(repr(self.hop_opts), repr(hop_opts)) self.assertEqual(repr(self.auth), repr(auth)) def test_to_string(self): ipv6_values = {'version': self.version, 'traffic_class': self.traffic_class, 'flow_label': self.flow_label, 'payload_length': self.payload_length, 'nxt': self.nxt, 'hop_limit': self.hop_limit, 'src': repr(self.src), 'dst': repr(self.dst), 'ext_hdrs': self.ext_hdrs} _ipv6_str = ','.join(['%s=%s' % (k, ipv6_values[k]) for k, v in inspect.getmembers(self.ip) if k in ipv6_values]) ipv6_str = '%s(%s)' % (ipv6.ipv6.__name__, _ipv6_str) self.assertEqual(str(self.ip), ipv6_str) self.assertEqual(repr(self.ip), ipv6_str) def test_to_string_with_hop_opts(self): self.setUp_with_hop_opts() self.test_to_string() def test_to_string_with_dst_opts(self): self.setUp_with_dst_opts() self.test_to_string() def test_to_string_with_fragment(self): self.setUp_with_fragment() self.test_to_string() def test_to_string_with_auth(self): self.setUp_with_auth() self.test_to_string() def test_to_string_with_multi_headers(self): self.setUp_with_multi_headers() self.test_to_string() def test_len(self): self.assertEqual(len(self.ip), 40) def test_len_with_hop_opts(self): self.setUp_with_hop_opts() self.assertEqual(len(self.ip), 40 + len(self.hop_opts)) def test_len_with_dst_opts(self): self.setUp_with_dst_opts() self.assertEqual(len(self.ip), 40 + len(self.dst_opts)) def test_len_with_routing_type3(self): self.setUp_with_routing_type3() self.assertEqual(len(self.ip), 40 + len(self.routing)) def test_len_with_fragment(self): self.setUp_with_fragment() self.assertEqual(len(self.ip), 40 + len(self.fragment)) def test_len_with_auth(self): self.setUp_with_auth() self.assertEqual(len(self.ip), 40 + len(self.auth)) def test_len_with_multi_headers(self): self.setUp_with_multi_headers() self.assertEqual(len(self.ip), 40 + len(self.hop_opts) + len(self.auth)) def test_default_args(self): ip = ipv6.ipv6() buf = ip.serialize(bytearray(), None) res = struct.unpack(ipv6.ipv6._PACK_STR, bytes(buf)) self.assertEqual(res[0], 6 << 28) self.assertEqual(res[1], 0) self.assertEqual(res[2], 6) self.assertEqual(res[3], 255) self.assertEqual(res[4], addrconv.ipv6.text_to_bin('10::10')) self.assertEqual(res[5], addrconv.ipv6.text_to_bin('20::20')) # with extension header ip = ipv6.ipv6( nxt=0, ext_hdrs=[ ipv6.hop_opts(58, 0, [ ipv6.option(5, 2, b'\x00\x00'), ipv6.option(1, 0, None)])]) buf = ip.serialize(bytearray(), None) res = struct.unpack(ipv6.ipv6._PACK_STR + '8s', bytes(buf)) self.assertEqual(res[0], 6 << 28) self.assertEqual(res[1], 8) self.assertEqual(res[2], 0) self.assertEqual(res[3], 255) self.assertEqual(res[4], addrconv.ipv6.text_to_bin('10::10')) self.assertEqual(res[5], addrconv.ipv6.text_to_bin('20::20')) self.assertEqual(res[6], b'\x3a\x00\x05\x02\x00\x00\x01\x00') def test_json(self): jsondict = self.ip.to_jsondict() ip = ipv6.ipv6.from_jsondict(jsondict['ipv6']) self.assertEqual(str(self.ip), str(ip)) def test_json_with_hop_opts(self): self.setUp_with_hop_opts() self.test_json() def test_json_with_dst_opts(self): self.setUp_with_dst_opts() self.test_json() def test_json_with_routing_type3(self): self.setUp_with_routing_type3() self.test_json() def test_json_with_fragment(self): self.setUp_with_fragment() self.test_json() def test_json_with_auth(self): self.setUp_with_auth() self.test_json() def test_json_with_multi_headers(self): self.setUp_with_multi_headers() self.test_json() class Test_hop_opts(unittest.TestCase): def setUp(self): self.nxt = 0 self.size = 8 self.data = [ ipv6.option(5, 2, b'\x00\x00'), ipv6.option(1, 0, None), ipv6.option(0xc2, 4, b'\x00\x01\x00\x00'), ipv6.option(1, 0, None), ] self.hop = ipv6.hop_opts(self.nxt, self.size, self.data) self.form = '!BB' self.buf = struct.pack(self.form, self.nxt, self.size) \ + self.data[0].serialize() \ + self.data[1].serialize() \ + self.data[2].serialize() \ + self.data[3].serialize() def tearDown(self): pass def test_init(self): self.assertEqual(self.nxt, self.hop.nxt) self.assertEqual(self.size, self.hop.size) self.assertEqual(self.data, self.hop.data) def test_invalid_size(self): self.assertRaises(Exception, ipv6.hop_opts, self.nxt, 1, self.data) def test_parser(self): _res = ipv6.hop_opts.parser(self.buf) if type(_res) is tuple: res = _res[0] else: res = _res self.assertEqual(self.nxt, res.nxt) self.assertEqual(self.size, res.size) self.assertEqual(str(self.data), str(res.data)) def test_serialize(self): buf = self.hop.serialize() res = struct.unpack_from(self.form, bytes(buf)) self.assertEqual(self.nxt, res[0]) self.assertEqual(self.size, res[1]) offset = struct.calcsize(self.form) opt1 = ipv6.option.parser(bytes(buf[offset:])) offset += len(opt1) opt2 = ipv6.option.parser(bytes(buf[offset:])) offset += len(opt2) opt3 = ipv6.option.parser(bytes(buf[offset:])) offset += len(opt3) opt4 = ipv6.option.parser(bytes(buf[offset:])) self.assertEqual(5, opt1.type_) self.assertEqual(2, opt1.len_) self.assertEqual(b'\x00\x00', opt1.data) self.assertEqual(1, opt2.type_) self.assertEqual(0, opt2.len_) self.assertEqual(None, opt2.data) self.assertEqual(0xc2, opt3.type_) self.assertEqual(4, opt3.len_) self.assertEqual(b'\x00\x01\x00\x00', opt3.data) self.assertEqual(1, opt4.type_) self.assertEqual(0, opt4.len_) self.assertEqual(None, opt4.data) def test_len(self): self.assertEqual(16, len(self.hop)) def test_default_args(self): hdr = ipv6.hop_opts() buf = hdr.serialize() res = struct.unpack('!BB', bytes(buf[:2])) self.assertEqual(res[0], 6) self.assertEqual(res[1], 0) opt = ipv6.option(type_=1, len_=4, data=b'\x00\x00\x00\x00') self.assertEqual(bytes(buf[2:]), opt.serialize()) class Test_dst_opts(unittest.TestCase): def setUp(self): self.nxt = 60 self.size = 8 self.data = [ ipv6.option(5, 2, b'\x00\x00'), ipv6.option(1, 0, None), ipv6.option(0xc2, 4, b'\x00\x01\x00\x00'), ipv6.option(1, 0, None), ] self.dst = ipv6.dst_opts(self.nxt, self.size, self.data) self.form = '!BB' self.buf = struct.pack(self.form, self.nxt, self.size) \ + self.data[0].serialize() \ + self.data[1].serialize() \ + self.data[2].serialize() \ + self.data[3].serialize() def tearDown(self): pass def test_init(self): self.assertEqual(self.nxt, self.dst.nxt) self.assertEqual(self.size, self.dst.size) self.assertEqual(self.data, self.dst.data) def test_invalid_size(self): self.assertRaises(Exception, ipv6.dst_opts, self.nxt, 1, self.data) def test_parser(self): _res = ipv6.dst_opts.parser(self.buf) if type(_res) is tuple: res = _res[0] else: res = _res self.assertEqual(self.nxt, res.nxt) self.assertEqual(self.size, res.size) self.assertEqual(str(self.data), str(res.data)) def test_serialize(self): buf = self.dst.serialize() res = struct.unpack_from(self.form, bytes(buf)) self.assertEqual(self.nxt, res[0]) self.assertEqual(self.size, res[1]) offset = struct.calcsize(self.form) opt1 = ipv6.option.parser(bytes(buf[offset:])) offset += len(opt1) opt2 = ipv6.option.parser(bytes(buf[offset:])) offset += len(opt2) opt3 = ipv6.option.parser(bytes(buf[offset:])) offset += len(opt3) opt4 = ipv6.option.parser(bytes(buf[offset:])) self.assertEqual(5, opt1.type_) self.assertEqual(2, opt1.len_) self.assertEqual(b'\x00\x00', opt1.data) self.assertEqual(1, opt2.type_) self.assertEqual(0, opt2.len_) self.assertEqual(None, opt2.data) self.assertEqual(0xc2, opt3.type_) self.assertEqual(4, opt3.len_) self.assertEqual(b'\x00\x01\x00\x00', opt3.data) self.assertEqual(1, opt4.type_) self.assertEqual(0, opt4.len_) self.assertEqual(None, opt4.data) def test_len(self): self.assertEqual(16, len(self.dst)) def test_default_args(self): hdr = ipv6.dst_opts() buf = hdr.serialize() res = struct.unpack('!BB', bytes(buf[:2])) self.assertEqual(res[0], 6) self.assertEqual(res[1], 0) opt = ipv6.option(type_=1, len_=4, data=b'\x00\x00\x00\x00') self.assertEqual(bytes(buf[2:]), opt.serialize()) class Test_option(unittest.TestCase): def setUp(self): self.type_ = 5 self.data = b'\x00\x00' self.len_ = len(self.data) self.opt = ipv6.option(self.type_, self.len_, self.data) self.form = '!BB%ds' % self.len_ self.buf = struct.pack(self.form, self.type_, self.len_, self.data) def tearDown(self): pass def test_init(self): self.assertEqual(self.type_, self.opt.type_) self.assertEqual(self.len_, self.opt.len_) self.assertEqual(self.data, self.opt.data) def test_parser(self): _res = ipv6.option.parser(self.buf) if type(_res) is tuple: res = _res[0] else: res = _res self.assertEqual(self.type_, res.type_) self.assertEqual(self.len_, res.len_) self.assertEqual(self.data, res.data) def test_serialize(self): buf = self.opt.serialize() res = struct.unpack_from(self.form, buf) self.assertEqual(self.type_, res[0]) self.assertEqual(self.len_, res[1]) self.assertEqual(self.data, res[2]) def test_len(self): self.assertEqual(len(self.opt), 2 + self.len_) class Test_option_pad1(Test_option): def setUp(self): self.type_ = 0 self.len_ = -1 self.data = None self.opt = ipv6.option(self.type_, self.len_, self.data) self.form = '!B' self.buf = struct.pack(self.form, self.type_) def test_serialize(self): buf = self.opt.serialize() res = struct.unpack_from(self.form, buf) self.assertEqual(self.type_, res[0]) def test_default_args(self): opt = ipv6.option() buf = opt.serialize() res = struct.unpack('!B', buf) self.assertEqual(res[0], 0) class Test_option_padN(Test_option): def setUp(self): self.type_ = 1 self.len_ = 0 self.data = None self.opt = ipv6.option(self.type_, self.len_, self.data) self.form = '!BB' self.buf = struct.pack(self.form, self.type_, self.len_) def test_serialize(self): buf = self.opt.serialize() res = struct.unpack_from(self.form, buf) self.assertEqual(self.type_, res[0]) self.assertEqual(self.len_, res[1]) class Test_routing(unittest.TestCase): def setUp(self): self.nxt = 0 self.size = 6 self.type_ = ipv6.routing.ROUTING_TYPE_3 self.seg = 0 self.cmpi = 0 self.cmpe = 0 self.adrs = ["2001:db8:dead::1", "2001:db8:dead::2", "2001:db8:dead::3"] # calculate pad self.pad = (8 - ((len(self.adrs) - 1) * (16 - self.cmpi) + (16 - self.cmpe) % 8)) % 8 # create buf self.form = '!BBBBBB2x16s16s16s' self.buf = struct.pack(self.form, self.nxt, self.size, self.type_, self.seg, (self.cmpi << 4) | self.cmpe, self.pad << 4, addrconv.ipv6.text_to_bin(self.adrs[0]), addrconv.ipv6.text_to_bin(self.adrs[1]), addrconv.ipv6.text_to_bin(self.adrs[2])) def tearDown(self): pass def test_parser(self): _res = ipv6.routing.parser(self.buf) if type(_res) is tuple: res = _res[0] else: res = _res self.assertEqual(self.nxt, res.nxt) self.assertEqual(self.size, res.size) self.assertEqual(self.type_, res.type_) self.assertEqual(self.seg, res.seg) self.assertEqual(self.cmpi, res.cmpi) self.assertEqual(self.cmpe, res.cmpe) self.assertEqual(self.pad, res._pad) self.assertEqual(self.adrs[0], res.adrs[0]) self.assertEqual(self.adrs[1], res.adrs[1]) self.assertEqual(self.adrs[2], res.adrs[2]) def test_not_implemented_type(self): not_implemented_buf = struct.pack( '!BBBBBB2x', 0, 6, ipv6.routing.ROUTING_TYPE_2, 0, 0, 0) instance = ipv6.routing.parser(not_implemented_buf) assert None is instance def test_invalid_type(self): invalid_type = 99 invalid_buf = struct.pack('!BBBBBB2x', 0, 6, invalid_type, 0, 0, 0) instance = ipv6.routing.parser(invalid_buf) assert None is instance class Test_routing_type3(unittest.TestCase): def setUp(self): self.nxt = 0 self.size = 6 self.type_ = 3 self.seg = 0 self.cmpi = 0 self.cmpe = 0 self.adrs = ["2001:db8:dead::1", "2001:db8:dead::2", "2001:db8:dead::3"] # calculate pad self.pad = (8 - ((len(self.adrs) - 1) * (16 - self.cmpi) + (16 - self.cmpe) % 8)) % 8 self.routing = ipv6.routing_type3( self.nxt, self.size, self.type_, self.seg, self.cmpi, self.cmpe, self.adrs) self.form = '!BBBBBB2x16s16s16s' self.buf = struct.pack(self.form, self.nxt, self.size, self.type_, self.seg, (self.cmpi << 4) | self.cmpe, self.pad << 4, addrconv.ipv6.text_to_bin(self.adrs[0]), addrconv.ipv6.text_to_bin(self.adrs[1]), addrconv.ipv6.text_to_bin(self.adrs[2])) def test_init(self): self.assertEqual(self.nxt, self.routing.nxt) self.assertEqual(self.size, self.routing.size) self.assertEqual(self.type_, self.routing.type_) self.assertEqual(self.seg, self.routing.seg) self.assertEqual(self.cmpi, self.routing.cmpi) self.assertEqual(self.cmpe, self.routing.cmpe) self.assertEqual(self.pad, self.routing._pad) self.assertEqual(self.adrs[0], self.routing.adrs[0]) self.assertEqual(self.adrs[1], self.routing.adrs[1]) self.assertEqual(self.adrs[2], self.routing.adrs[2]) def test_parser(self): _res = ipv6.routing.parser(self.buf) if type(_res) is tuple: res = _res[0] else: res = _res self.assertEqual(self.nxt, res.nxt) self.assertEqual(self.size, res.size) self.assertEqual(self.type_, res.type_) self.assertEqual(self.seg, res.seg) self.assertEqual(self.cmpi, res.cmpi) self.assertEqual(self.cmpe, res.cmpe) self.assertEqual(self.pad, res._pad) self.assertEqual(self.adrs[0], res.adrs[0]) self.assertEqual(self.adrs[1], res.adrs[1]) self.assertEqual(self.adrs[2], res.adrs[2]) def test_serialize(self): buf = self.routing.serialize() res = struct.unpack_from(self.form, bytes(buf)) self.assertEqual(self.nxt, res[0]) self.assertEqual(self.size, res[1]) self.assertEqual(self.type_, res[2]) self.assertEqual(self.seg, res[3]) self.assertEqual(self.cmpi, res[4] >> 4) self.assertEqual(self.cmpe, res[4] & 0xf) self.assertEqual(self.pad, res[5]) self.assertEqual(addrconv.ipv6.text_to_bin(self.adrs[0]), res[6]) self.assertEqual(addrconv.ipv6.text_to_bin(self.adrs[1]), res[7]) self.assertEqual(addrconv.ipv6.text_to_bin(self.adrs[2]), res[8]) def test_parser_with_adrs_zero(self): nxt = 0 size = 0 type_ = 3 seg = 0 cmpi = 0 cmpe = 0 adrs = [] # calculate pad pad = (8 - ((len(adrs) - 1) * (16 - cmpi) + (16 - cmpe) % 8)) % 8 form = '!BBBBBB2x' buf = struct.pack(form, nxt, size, type_, seg, (cmpi << 4) | cmpe, pad << 4) _res = ipv6.routing.parser(buf) if type(_res) is tuple: res = _res[0] else: res = _res self.assertEqual(nxt, res.nxt) self.assertEqual(size, res.size) self.assertEqual(type_, res.type_) self.assertEqual(seg, res.seg) self.assertEqual(cmpi, res.cmpi) self.assertEqual(cmpe, res.cmpe) self.assertEqual(pad, res._pad) def test_serialize_with_adrs_zero(self): nxt = 0 size = 0 type_ = 3 seg = 0 cmpi = 0 cmpe = 0 adrs = [] # calculate pad pad = (8 - ((len(adrs) - 1) * (16 - cmpi) + (16 - cmpe) % 8)) % 8 routing = ipv6.routing_type3( nxt, size, type_, seg, cmpi, cmpe, pad) buf = routing.serialize() form = '!BBBBBB2x' res = struct.unpack_from(form, bytes(buf)) self.assertEqual(nxt, res[0]) self.assertEqual(size, res[1]) self.assertEqual(type_, res[2]) self.assertEqual(seg, res[3]) self.assertEqual(cmpi, res[4] >> 4) self.assertEqual(cmpe, res[4] & 0xf) self.assertEqual(pad, res[5]) def test_parser_with_compression(self): pass nxt = 0 size = 3 type_ = 3 seg = 0 cmpi = 8 cmpe = 12 adrs = ["2001:0db8:dead:0123:4567:89ab:cdef:0001", "2001:0db8:dead:0123:4567:89ab:cdef:0002", "2001:0db8:dead:0123:4567:89ab:cdef:0003"] # calculate pad pad = (8 - ((len(adrs) - 1) * (16 - cmpi) + (16 - cmpe) % 8)) % 8 form = '!BBBBBB2x%ds%ds%ds' % (16 - cmpi, 16 - cmpi, 16 - cmpe) slice_i = slice(cmpi, 16) slice_e = slice(cmpe, 16) buf = struct.pack(form, nxt, size, type_, seg, (cmpi << 4) | cmpe, pad << 4, addrconv.ipv6.text_to_bin(adrs[0])[slice_i], addrconv.ipv6.text_to_bin(adrs[1])[slice_i], addrconv.ipv6.text_to_bin(adrs[2])[slice_e]) _res = ipv6.routing.parser(buf) if type(_res) is tuple: res = _res[0] else: res = _res self.assertEqual(nxt, res.nxt) self.assertEqual(size, res.size) self.assertEqual(type_, res.type_) self.assertEqual(seg, res.seg) self.assertEqual(cmpi, res.cmpi) self.assertEqual(cmpe, res.cmpe) self.assertEqual(pad, res._pad) self.assertEqual("::4567:89ab:cdef:1", res.adrs[0]) self.assertEqual("::4567:89ab:cdef:2", res.adrs[1]) self.assertEqual("::205.239.0.3", res.adrs[2]) def test_serialize_with_compression(self): nxt = 0 size = 3 type_ = 3 seg = 0 cmpi = 8 cmpe = 8 adrs = ["2001:db8:dead::1", "2001:db8:dead::2", "2001:db8:dead::3"] # calculate pad pad = (8 - ((len(adrs) - 1) * (16 - cmpi) + (16 - cmpe) % 8)) % 8 slice_i = slice(cmpi, 16) slice_e = slice(cmpe, 16) routing = ipv6.routing_type3( nxt, size, type_, seg, cmpi, cmpe, adrs) buf = routing.serialize() form = '!BBBBBB2x8s8s8s' res = struct.unpack_from(form, bytes(buf)) self.assertEqual(nxt, res[0]) self.assertEqual(size, res[1]) self.assertEqual(type_, res[2]) self.assertEqual(seg, res[3]) self.assertEqual(cmpi, res[4] >> 4) self.assertEqual(cmpe, res[4] & 0xf) self.assertEqual(pad, res[5]) self.assertEqual(addrconv.ipv6.text_to_bin(adrs[0])[slice_i], res[6]) self.assertEqual(addrconv.ipv6.text_to_bin(adrs[1])[slice_i], res[7]) self.assertEqual(addrconv.ipv6.text_to_bin(adrs[2])[slice_e], res[8]) def test_len(self): self.assertEqual((6 + 1) * 8, len(self.routing)) def test_default_args(self): hdr = ipv6.routing_type3() buf = hdr.serialize() LOG.info(repr(buf)) res = struct.unpack_from(ipv6.routing_type3._PACK_STR, bytes(buf)) LOG.info(res) self.assertEqual(res[0], 6) self.assertEqual(res[1], 0) self.assertEqual(res[2], 3) self.assertEqual(res[3], 0) self.assertEqual(res[4], (0 << 4) | 0) self.assertEqual(res[5], 0) class Test_fragment(unittest.TestCase): def setUp(self): self.nxt = 44 self.offset = 50 self.more = 1 self.id_ = 123 self.fragment = ipv6.fragment( self.nxt, self.offset, self.more, self.id_) self.off_m = (self.offset << 3 | self.more) self.form = '!BxHI' self.buf = struct.pack(self.form, self.nxt, self.off_m, self.id_) def test_init(self): self.assertEqual(self.nxt, self.fragment.nxt) self.assertEqual(self.offset, self.fragment.offset) self.assertEqual(self.more, self.fragment.more) self.assertEqual(self.id_, self.fragment.id_) def test_parser(self): _res = ipv6.fragment.parser(self.buf) if type(_res) is tuple: res = _res[0] else: res = _res self.assertEqual(self.nxt, res.nxt) self.assertEqual(self.offset, res.offset) self.assertEqual(self.more, res.more) self.assertEqual(self.id_, res.id_) def test_serialize(self): buf = self.fragment.serialize() res = struct.unpack_from(self.form, bytes(buf)) self.assertEqual(self.nxt, res[0]) self.assertEqual(self.off_m, res[1]) self.assertEqual(self.id_, res[2]) def test_len(self): self.assertEqual(8, len(self.fragment)) def test_default_args(self): hdr = ipv6.fragment() buf = hdr.serialize() res = struct.unpack_from(ipv6.fragment._PACK_STR, buf) self.assertEqual(res[0], 6) self.assertEqual(res[1], 0) self.assertEqual(res[2], 0) class Test_auth(unittest.TestCase): def setUp(self): self.nxt = 0 self.size = 4 self.spi = 256 self.seq = 1 self.data = b'\x21\xd3\xa9\x5c\x5f\xfd\x4d\x18\x46\x22\xb9\xf8' self.auth = ipv6.auth( self.nxt, self.size, self.spi, self.seq, self.data) self.form = '!BB2xII12s' self.buf = struct.pack(self.form, self.nxt, self.size, self.spi, self.seq, self.data) def test_init(self): self.assertEqual(self.nxt, self.auth.nxt) self.assertEqual(self.size, self.auth.size) self.assertEqual(self.spi, self.auth.spi) self.assertEqual(self.seq, self.auth.seq) self.assertEqual(self.data, self.auth.data) def test_parser(self): _res = ipv6.auth.parser(self.buf) if type(_res) is tuple: res = _res[0] else: res = _res self.assertEqual(self.nxt, res.nxt) self.assertEqual(self.size, res.size) self.assertEqual(self.spi, res.spi) self.assertEqual(self.seq, res.seq) self.assertEqual(self.data, res.data) def test_serialize(self): buf = self.auth.serialize() res = struct.unpack_from(self.form, bytes(buf)) self.assertEqual(self.nxt, res[0]) self.assertEqual(self.size, res[1]) self.assertEqual(self.spi, res[2]) self.assertEqual(self.seq, res[3]) self.assertEqual(self.data, res[4]) def test_len(self): self.assertEqual((4 + 2) * 4, len(self.auth)) def test_len_re(self): size = 5 auth = ipv6.auth( 0, size, 256, 1, b'\x21\xd3\xa9\x5c\x5f\xfd\x4d\x18\x46\x22\xb9\xf8\xf8\xf8\xf8\xf8') self.assertEqual((size + 2) * 4, len(auth)) def test_default_args(self): hdr = ipv6.auth() buf = hdr.serialize() LOG.info(repr(buf)) res = struct.unpack_from(ipv6.auth._PACK_STR, bytes(buf)) LOG.info(res) self.assertEqual(res[0], 6) self.assertEqual(res[1], 2) self.assertEqual(res[2], 0) self.assertEqual(res[3], 0) self.assertEqual(buf[ipv6.auth._MIN_LEN:], b'\x00\x00\x00\x00') ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/packet/test_llc.py0000664000175000017500000000240300000000000022041 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone 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. # vim: tabstop=4 shiftwidth=4 softtabstop=4 import unittest import logging from os_ken.lib.packet import llc LOG = logging.getLogger(__name__) class Test_ControlFormatI(unittest.TestCase): msg = llc.llc(llc.SAP_BPDU, llc.SAP_BPDU, llc.ControlFormatI()) def test_json(self): jsondict = self.msg.to_jsondict() msg = llc.llc.from_jsondict(jsondict['llc']) self.assertEqual(str(self.msg), str(msg)) class Test_ControlFormatS(Test_ControlFormatI): msg = llc.llc(llc.SAP_BPDU, llc.SAP_BPDU, llc.ControlFormatS()) class Test_ControlFormatU(Test_ControlFormatI): msg = llc.llc(llc.SAP_BPDU, llc.SAP_BPDU, llc.ControlFormatU()) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/packet/test_lldp.py0000664000175000017500000005603600000000000022235 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone 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. import unittest import logging import struct import inspect from os_ken.ofproto import ether from os_ken.lib.packet import packet from os_ken.lib.packet import ethernet from os_ken.lib.packet import lldp from os_ken.lib import addrconv LOG = logging.getLogger(__name__) class TestLLDPMandatoryTLV(unittest.TestCase): def setUp(self): # sample data is based on: # http://wiki.wireshark.org/LinkLayerDiscoveryProtocol # # mandatory TLV only self.data = b'\x01\x80\xc2\x00\x00\x0e\x00\x04' \ + b'\x96\x1f\xa7\x26\x88\xcc\x02\x07' \ + b'\x04\x00\x04\x96\x1f\xa7\x26\x04' \ + b'\x04\x05\x31\x2f\x33\x06\x02\x00' \ + b'\x78\x00\x00' def tearDown(self): pass def test_get_tlv_type(self): buf = b'\x02\x07\x04\x00\x04\x96\x1f\xa7\x26' self.assertEqual(lldp.LLDPBasicTLV.get_type(buf), lldp.LLDP_TLV_CHASSIS_ID) def test_parse_without_ethernet(self): buf = self.data[ethernet.ethernet._MIN_LEN:] (lldp_pkt, cls, rest_buf) = lldp.lldp.parser(buf) self.assertEqual(len(rest_buf), 0) tlvs = lldp_pkt.tlvs self.assertEqual(tlvs[0].tlv_type, lldp.LLDP_TLV_CHASSIS_ID) self.assertEqual(tlvs[0].len, 7) self.assertEqual(tlvs[0].subtype, lldp.ChassisID.SUB_MAC_ADDRESS) self.assertEqual(tlvs[0].chassis_id, b'\x00\x04\x96\x1f\xa7\x26') self.assertEqual(tlvs[1].tlv_type, lldp.LLDP_TLV_PORT_ID) self.assertEqual(tlvs[1].len, 4) self.assertEqual(tlvs[1].subtype, lldp.PortID.SUB_INTERFACE_NAME) self.assertEqual(tlvs[1].port_id, b'1/3') self.assertEqual(tlvs[2].tlv_type, lldp.LLDP_TLV_TTL) self.assertEqual(tlvs[2].len, 2) self.assertEqual(tlvs[2].ttl, 120) self.assertEqual(tlvs[3].tlv_type, lldp.LLDP_TLV_END) def test_parse(self): buf = self.data pkt = packet.Packet(buf) i = iter(pkt) self.assertEqual(type(next(i)), ethernet.ethernet) self.assertEqual(type(next(i)), lldp.lldp) def test_tlv(self): tlv = lldp.ChassisID(subtype=lldp.ChassisID.SUB_MAC_ADDRESS, chassis_id=b'\x00\x04\x96\x1f\xa7\x26') self.assertEqual(tlv.tlv_type, lldp.LLDP_TLV_CHASSIS_ID) self.assertEqual(tlv.len, 7) (typelen, ) = struct.unpack('!H', b'\x02\x07') self.assertEqual(tlv.typelen, typelen) def test_serialize_without_ethernet(self): tlv_chassis_id = lldp.ChassisID(subtype=lldp.ChassisID.SUB_MAC_ADDRESS, chassis_id=b'\x00\x04\x96\x1f\xa7\x26') tlv_port_id = lldp.PortID(subtype=lldp.PortID.SUB_INTERFACE_NAME, port_id=b'1/3') tlv_ttl = lldp.TTL(ttl=120) tlv_end = lldp.End() tlvs = (tlv_chassis_id, tlv_port_id, tlv_ttl, tlv_end) lldp_pkt = lldp.lldp(tlvs) self.assertEqual(lldp_pkt.serialize(None, None), self.data[ethernet.ethernet._MIN_LEN:]) def test_serialize(self): pkt = packet.Packet() dst = lldp.LLDP_MAC_NEAREST_BRIDGE src = '00:04:96:1f:a7:26' ethertype = ether.ETH_TYPE_LLDP eth_pkt = ethernet.ethernet(dst, src, ethertype) pkt.add_protocol(eth_pkt) tlv_chassis_id = lldp.ChassisID(subtype=lldp.ChassisID.SUB_MAC_ADDRESS, chassis_id=addrconv.mac. text_to_bin(src)) tlv_port_id = lldp.PortID(subtype=lldp.PortID.SUB_INTERFACE_NAME, port_id=b'1/3') tlv_ttl = lldp.TTL(ttl=120) tlv_end = lldp.End() tlvs = (tlv_chassis_id, tlv_port_id, tlv_ttl, tlv_end) lldp_pkt = lldp.lldp(tlvs) pkt.add_protocol(lldp_pkt) self.assertEqual(len(pkt.protocols), 2) pkt.serialize() # Note: If ethernet frame is less than 60 bytes length, # ethernet.ethernet() appends padding to the payload. # So, we splits the serialized data to compare. data_len = len(self.data) pkt_data_lldp = pkt.data[:data_len] pkt_data_pad = pkt.data[data_len:] self.assertEqual(b'\x00' * (60 - data_len), pkt_data_pad) self.assertEqual(self.data, pkt_data_lldp) def test_to_string(self): chassis_id = lldp.ChassisID(subtype=lldp.ChassisID.SUB_MAC_ADDRESS, chassis_id=b'\x00\x04\x96\x1f\xa7\x26') port_id = lldp.PortID(subtype=lldp.PortID.SUB_INTERFACE_NAME, port_id=b'1/3') ttl = lldp.TTL(ttl=120) end = lldp.End() tlvs = (chassis_id, port_id, ttl, end) lldp_pkt = lldp.lldp(tlvs) chassis_id_values = {'subtype': lldp.ChassisID.SUB_MAC_ADDRESS, 'chassis_id': b'\x00\x04\x96\x1f\xa7\x26', 'len': chassis_id.len, 'typelen': chassis_id.typelen} _ch_id_str = ','.join(['%s=%s' % (k, repr(chassis_id_values[k])) for k, v in inspect.getmembers(chassis_id) if k in chassis_id_values]) tlv_chassis_id_str = '%s(%s)' % (lldp.ChassisID.__name__, _ch_id_str) port_id_values = {'subtype': port_id.subtype, 'port_id': port_id.port_id, 'len': port_id.len, 'typelen': port_id.typelen} _port_id_str = ','.join(['%s=%s' % (k, repr(port_id_values[k])) for k, v in inspect.getmembers(port_id) if k in port_id_values]) tlv_port_id_str = '%s(%s)' % (lldp.PortID.__name__, _port_id_str) ttl_values = {'ttl': ttl.ttl, 'len': ttl.len, 'typelen': ttl.typelen} _ttl_str = ','.join(['%s=%s' % (k, repr(ttl_values[k])) for k, v in inspect.getmembers(ttl) if k in ttl_values]) tlv_ttl_str = '%s(%s)' % (lldp.TTL.__name__, _ttl_str) end_values = {'len': end.len, 'typelen': end.typelen} _end_str = ','.join(['%s=%s' % (k, repr(end_values[k])) for k, v in inspect.getmembers(end) if k in end_values]) tlv_end_str = '%s(%s)' % (lldp.End.__name__, _end_str) _tlvs_str = '(%s, %s, %s, %s)' tlvs_str = _tlvs_str % (tlv_chassis_id_str, tlv_port_id_str, tlv_ttl_str, tlv_end_str) _lldp_str = '%s(tlvs=%s)' lldp_str = _lldp_str % (lldp.lldp.__name__, tlvs_str) self.assertEqual(str(lldp_pkt), lldp_str) self.assertEqual(repr(lldp_pkt), lldp_str) def test_json(self): chassis_id = lldp.ChassisID(subtype=lldp.ChassisID.SUB_MAC_ADDRESS, chassis_id=b'\x00\x04\x96\x1f\xa7\x26') port_id = lldp.PortID(subtype=lldp.PortID.SUB_INTERFACE_NAME, port_id=b'1/3') ttl = lldp.TTL(ttl=120) end = lldp.End() tlvs = (chassis_id, port_id, ttl, end) lldp1 = lldp.lldp(tlvs) jsondict = lldp1.to_jsondict() lldp2 = lldp.lldp.from_jsondict(jsondict['lldp']) self.assertEqual(str(lldp1), str(lldp2)) class TestLLDPOptionalTLV(unittest.TestCase): def setUp(self): # sample data is based on: # http://wiki.wireshark.org/LinkLayerDiscoveryProtocol # # include optional TLV self.data = b'\x01\x80\xc2\x00\x00\x0e\x00\x01' \ + b'\x30\xf9\xad\xa0\x88\xcc\x02\x07' \ + b'\x04\x00\x01\x30\xf9\xad\xa0\x04' \ + b'\x04\x05\x31\x2f\x31\x06\x02\x00' \ + b'\x78\x08\x17\x53\x75\x6d\x6d\x69' \ + b'\x74\x33\x30\x30\x2d\x34\x38\x2d' \ + b'\x50\x6f\x72\x74\x20\x31\x30\x30' \ + b'\x31\x00\x0a\x0d\x53\x75\x6d\x6d' \ + b'\x69\x74\x33\x30\x30\x2d\x34\x38' \ + b'\x00\x0c\x4c\x53\x75\x6d\x6d\x69' \ + b'\x74\x33\x30\x30\x2d\x34\x38\x20' \ + b'\x2d\x20\x56\x65\x72\x73\x69\x6f' \ + b'\x6e\x20\x37\x2e\x34\x65\x2e\x31' \ + b'\x20\x28\x42\x75\x69\x6c\x64\x20' \ + b'\x35\x29\x20\x62\x79\x20\x52\x65' \ + b'\x6c\x65\x61\x73\x65\x5f\x4d\x61' \ + b'\x73\x74\x65\x72\x20\x30\x35\x2f' \ + b'\x32\x37\x2f\x30\x35\x20\x30\x34' \ + b'\x3a\x35\x33\x3a\x31\x31\x00\x0e' \ + b'\x04\x00\x14\x00\x14\x10\x0e\x07' \ + b'\x06\x00\x01\x30\xf9\xad\xa0\x02' \ + b'\x00\x00\x03\xe9\x00\xfe\x07\x00' \ + b'\x12\x0f\x02\x07\x01\x00\xfe\x09' \ + b'\x00\x12\x0f\x01\x03\x6c\x00\x00' \ + b'\x10\xfe\x09\x00\x12\x0f\x03\x01' \ + b'\x00\x00\x00\x00\xfe\x06\x00\x12' \ + b'\x0f\x04\x05\xf2\xfe\x06\x00\x80' \ + b'\xc2\x01\x01\xe8\xfe\x07\x00\x80' \ + b'\xc2\x02\x01\x00\x00\xfe\x17\x00' \ + b'\x80\xc2\x03\x01\xe8\x10\x76\x32' \ + b'\x2d\x30\x34\x38\x38\x2d\x30\x33' \ + b'\x2d\x30\x35\x30\x35\x00\xfe\x05' \ + b'\x00\x80\xc2\x04\x00\x00\x00' def tearDown(self): pass def test_parse(self): buf = self.data pkt = packet.Packet(buf) i = iter(pkt) self.assertEqual(type(next(i)), ethernet.ethernet) lldp_pkt = next(i) self.assertEqual(type(lldp_pkt), lldp.lldp) tlvs = lldp_pkt.tlvs # Port Description self.assertEqual(tlvs[3].tlv_type, lldp.LLDP_TLV_PORT_DESCRIPTION) self.assertEqual(tlvs[3].port_description, b'Summit300-48-Port 1001\x00') # System Name self.assertEqual(tlvs[4].tlv_type, lldp.LLDP_TLV_SYSTEM_NAME) self.assertEqual(tlvs[4].system_name, b'Summit300-48\x00') # System Description self.assertEqual(tlvs[5].tlv_type, lldp.LLDP_TLV_SYSTEM_DESCRIPTION) self.assertEqual(tlvs[5].system_description, b'Summit300-48 - Version 7.4e.1 (Build 5) ' + b'by Release_Master 05/27/05 04:53:11\x00') # SystemCapabilities self.assertEqual(tlvs[6].tlv_type, lldp.LLDP_TLV_SYSTEM_CAPABILITIES) self.assertEqual(tlvs[6].system_cap & lldp.SystemCapabilities.CAP_MAC_BRIDGE, lldp.SystemCapabilities.CAP_MAC_BRIDGE) self.assertEqual(tlvs[6].enabled_cap & lldp.SystemCapabilities.CAP_MAC_BRIDGE, lldp.SystemCapabilities.CAP_MAC_BRIDGE) self.assertEqual(tlvs[6].system_cap & lldp.SystemCapabilities.CAP_TELEPHONE, 0) self.assertEqual(tlvs[6].enabled_cap & lldp.SystemCapabilities.CAP_TELEPHONE, 0) # Management Address self.assertEqual(tlvs[7].tlv_type, lldp.LLDP_TLV_MANAGEMENT_ADDRESS) self.assertEqual(tlvs[7].addr_len, 7) self.assertEqual(tlvs[7].addr, b'\x00\x01\x30\xf9\xad\xa0') self.assertEqual(tlvs[7].intf_num, 1001) # Organizationally Specific self.assertEqual(tlvs[8].tlv_type, lldp.LLDP_TLV_ORGANIZATIONALLY_SPECIFIC) self.assertEqual(tlvs[8].oui, b'\x00\x12\x0f') # IEEE 802.3 self.assertEqual(tlvs[8].subtype, 0x02) # Power Via MDI # End self.assertEqual(tlvs[16].tlv_type, lldp.LLDP_TLV_END) def test_parse_corrupted(self): buf = self.data pkt = packet.Packet(buf[:128]) def test_serialize(self): pkt = packet.Packet() dst = lldp.LLDP_MAC_NEAREST_BRIDGE src = '00:01:30:f9:ad:a0' ethertype = ether.ETH_TYPE_LLDP eth_pkt = ethernet.ethernet(dst, src, ethertype) pkt.add_protocol(eth_pkt) tlv_chassis_id = lldp.ChassisID(subtype=lldp.ChassisID.SUB_MAC_ADDRESS, chassis_id=addrconv.mac. text_to_bin(src)) tlv_port_id = lldp.PortID(subtype=lldp.PortID.SUB_INTERFACE_NAME, port_id=b'1/1') tlv_ttl = lldp.TTL(ttl=120) tlv_port_description = lldp.PortDescription( port_description=b'Summit300-48-Port 1001\x00') tlv_system_name = lldp.SystemName(system_name=b'Summit300-48\x00') tlv_system_description = lldp.SystemDescription( system_description=b'Summit300-48 - Version 7.4e.1 (Build 5) ' + b'by Release_Master 05/27/05 04:53:11\x00') tlv_system_capabilities = lldp.SystemCapabilities( system_cap=0x14, enabled_cap=0x14) tlv_management_address = lldp.ManagementAddress( addr_subtype=0x06, addr=b'\x00\x01\x30\xf9\xad\xa0', intf_subtype=0x02, intf_num=1001, oid=b'') tlv_organizationally_specific = lldp.OrganizationallySpecific( oui=b'\x00\x12\x0f', subtype=0x02, info=b'\x07\x01\x00') tlv_end = lldp.End() tlvs = (tlv_chassis_id, tlv_port_id, tlv_ttl, tlv_port_description, tlv_system_name, tlv_system_description, tlv_system_capabilities, tlv_management_address, tlv_organizationally_specific, tlv_end) lldp_pkt = lldp.lldp(tlvs) pkt.add_protocol(lldp_pkt) self.assertEqual(len(pkt.protocols), 2) pkt.serialize() # self.data has many organizationally specific TLVs data = bytes(pkt.data[:-2]) self.assertEqual(data, self.data[:len(data)]) def test_to_string(self): chassis_id = lldp.ChassisID(subtype=lldp.ChassisID.SUB_MAC_ADDRESS, chassis_id=b'\x00\x01\x30\xf9\xad\xa0') port_id = lldp.PortID(subtype=lldp.PortID.SUB_INTERFACE_NAME, port_id=b'1/1') ttl = lldp.TTL(ttl=120) port_desc = lldp.PortDescription( port_description=b'Summit300-48-Port 1001\x00') sys_name = lldp.SystemName(system_name=b'Summit300-48\x00') sys_desc = lldp.SystemDescription( system_description=b'Summit300-48 - Version 7.4e.1 (Build 5) ' + b'by Release_Master 05/27/05 04:53:11\x00') sys_cap = lldp.SystemCapabilities( system_cap=0x14, enabled_cap=0x14) man_addr = lldp.ManagementAddress( addr_subtype=0x06, addr=b'\x00\x01\x30\xf9\xad\xa0', intf_subtype=0x02, intf_num=1001, oid='') org_spec = lldp.OrganizationallySpecific( oui=b'\x00\x12\x0f', subtype=0x02, info=b'\x07\x01\x00') end = lldp.End() tlvs = (chassis_id, port_id, ttl, port_desc, sys_name, sys_desc, sys_cap, man_addr, org_spec, end) lldp_pkt = lldp.lldp(tlvs) # ChassisID string chassis_id_values = {'subtype': lldp.ChassisID.SUB_MAC_ADDRESS, 'chassis_id': b'\x00\x01\x30\xf9\xad\xa0', 'len': chassis_id.len, 'typelen': chassis_id.typelen} _ch_id_str = ','.join(['%s=%s' % (k, repr(chassis_id_values[k])) for k, v in inspect.getmembers(chassis_id) if k in chassis_id_values]) tlv_chassis_id_str = '%s(%s)' % (lldp.ChassisID.__name__, _ch_id_str) # PortID string port_id_values = {'subtype': port_id.subtype, 'port_id': port_id.port_id, 'len': port_id.len, 'typelen': port_id.typelen} _port_id_str = ','.join(['%s=%s' % (k, repr(port_id_values[k])) for k, v in inspect.getmembers(port_id) if k in port_id_values]) tlv_port_id_str = '%s(%s)' % (lldp.PortID.__name__, _port_id_str) # TTL string ttl_values = {'ttl': ttl.ttl, 'len': ttl.len, 'typelen': ttl.typelen} _ttl_str = ','.join(['%s=%s' % (k, repr(ttl_values[k])) for k, v in inspect.getmembers(ttl) if k in ttl_values]) tlv_ttl_str = '%s(%s)' % (lldp.TTL.__name__, _ttl_str) # PortDescription string port_desc_values = {'tlv_info': port_desc.tlv_info, 'len': port_desc.len, 'typelen': port_desc.typelen} _port_desc_str = ','.join(['%s=%s' % (k, repr(port_desc_values[k])) for k, v in inspect.getmembers(port_desc) if k in port_desc_values]) tlv_port_desc_str = '%s(%s)' % (lldp.PortDescription.__name__, _port_desc_str) # SystemName string sys_name_values = {'tlv_info': sys_name.tlv_info, 'len': sys_name.len, 'typelen': sys_name.typelen} _system_name_str = ','.join(['%s=%s' % (k, repr(sys_name_values[k])) for k, v in inspect.getmembers(sys_name) if k in sys_name_values]) tlv_system_name_str = '%s(%s)' % (lldp.SystemName.__name__, _system_name_str) # SystemDescription string sys_desc_values = {'tlv_info': sys_desc.tlv_info, 'len': sys_desc.len, 'typelen': sys_desc.typelen} _sys_desc_str = ','.join(['%s=%s' % (k, repr(sys_desc_values[k])) for k, v in inspect.getmembers(sys_desc) if k in sys_desc_values]) tlv_sys_desc_str = '%s(%s)' % (lldp.SystemDescription.__name__, _sys_desc_str) # SystemCapabilities string sys_cap_values = {'system_cap': 0x14, 'enabled_cap': 0x14, 'len': sys_cap.len, 'typelen': sys_cap.typelen} _sys_cap_str = ','.join(['%s=%s' % (k, repr(sys_cap_values[k])) for k, v in inspect.getmembers(sys_cap) if k in sys_cap_values]) tlv_sys_cap_str = '%s(%s)' % (lldp.SystemCapabilities.__name__, _sys_cap_str) # ManagementAddress string man_addr_values = {'addr_subtype': 0x06, 'addr': b'\x00\x01\x30\xf9\xad\xa0', 'addr_len': man_addr.addr_len, 'intf_subtype': 0x02, 'intf_num': 1001, 'oid': '', 'oid_len': man_addr.oid_len, 'len': man_addr.len, 'typelen': man_addr.typelen} _man_addr_str = ','.join(['%s=%s' % (k, repr(man_addr_values[k])) for k, v in inspect.getmembers(man_addr) if k in man_addr_values]) tlv_man_addr_str = '%s(%s)' % (lldp.ManagementAddress.__name__, _man_addr_str) # OrganizationallySpecific string org_spec_values = {'oui': b'\x00\x12\x0f', 'subtype': 0x02, 'info': b'\x07\x01\x00', 'len': org_spec.len, 'typelen': org_spec.typelen} _org_spec_str = ','.join(['%s=%s' % (k, repr(org_spec_values[k])) for k, v in inspect.getmembers(org_spec) if k in org_spec_values]) tlv_org_spec_str = '%s(%s)' % (lldp.OrganizationallySpecific.__name__, _org_spec_str) # End string end_values = {'len': end.len, 'typelen': end.typelen} _end_str = ','.join(['%s=%s' % (k, repr(end_values[k])) for k, v in inspect.getmembers(end) if k in end_values]) tlv_end_str = '%s(%s)' % (lldp.End.__name__, _end_str) # tlvs string _tlvs_str = '(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)' tlvs_str = _tlvs_str % (tlv_chassis_id_str, tlv_port_id_str, tlv_ttl_str, tlv_port_desc_str, tlv_system_name_str, tlv_sys_desc_str, tlv_sys_cap_str, tlv_man_addr_str, tlv_org_spec_str, tlv_end_str) # lldp string _lldp_str = '%s(tlvs=%s)' lldp_str = _lldp_str % (lldp.lldp.__name__, tlvs_str) self.assertEqual(str(lldp_pkt), lldp_str) self.assertEqual(repr(lldp_pkt), lldp_str) def test_json(self): chassis_id = lldp.ChassisID(subtype=lldp.ChassisID.SUB_MAC_ADDRESS, chassis_id=b'\x00\x01\x30\xf9\xad\xa0') port_id = lldp.PortID(subtype=lldp.PortID.SUB_INTERFACE_NAME, port_id=b'1/1') ttl = lldp.TTL(ttl=120) port_desc = lldp.PortDescription( port_description=b'Summit300-48-Port 1001\x00') sys_name = lldp.SystemName(system_name=b'Summit300-48\x00') sys_desc = lldp.SystemDescription( system_description=b'Summit300-48 - Version 7.4e.1 (Build 5) ' + b'by Release_Master 05/27/05 04:53:11\x00') sys_cap = lldp.SystemCapabilities( system_cap=0x14, enabled_cap=0x14) man_addr = lldp.ManagementAddress( addr_subtype=0x06, addr=b'\x00\x01\x30\xf9\xad\xa0', intf_subtype=0x02, intf_num=1001, oid='') org_spec = lldp.OrganizationallySpecific( oui=b'\x00\x12\x0f', subtype=0x02, info=b'\x07\x01\x00') end = lldp.End() tlvs = (chassis_id, port_id, ttl, port_desc, sys_name, sys_desc, sys_cap, man_addr, org_spec, end) lldp1 = lldp.lldp(tlvs) jsondict = lldp1.to_jsondict() lldp2 = lldp.lldp.from_jsondict(jsondict['lldp']) self.assertEqual(str(lldp1), str(lldp2)) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/packet/test_mpls.py0000664000175000017500000000515300000000000022247 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone 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. import unittest import logging import inspect from os_ken.lib.packet import mpls LOG = logging.getLogger(__name__) class Test_mpls(unittest.TestCase): label = 29 exp = 6 bsb = 1 ttl = 64 mp = mpls.mpls(label, exp, bsb, ttl) def setUp(self): pass def tearDown(self): pass def test_to_string(self): mpls_values = {'label': self.label, 'exp': self.exp, 'bsb': self.bsb, 'ttl': self.ttl} _mpls_str = ','.join(['%s=%s' % (k, repr(mpls_values[k])) for k, v in inspect.getmembers(self.mp) if k in mpls_values]) mpls_str = '%s(%s)' % (mpls.mpls.__name__, _mpls_str) self.assertEqual(str(self.mp), mpls_str) self.assertEqual(repr(self.mp), mpls_str) def test_json(self): jsondict = self.mp.to_jsondict() mp = mpls.mpls.from_jsondict(jsondict['mpls']) self.assertEqual(str(self.mp), str(mp)) def test_label_from_bin_true(self): mpls_label = 0xfffff is_bos = True buf = b'\xff\xff\xf1' mpls_label_out, is_bos_out = mpls.label_from_bin(buf) self.assertEqual(mpls_label, mpls_label_out) self.assertEqual(is_bos, is_bos_out) def test_label_from_bin_false(self): mpls_label = 0xfffff is_bos = False buf = b'\xff\xff\xf0' mpls_label_out, is_bos_out = mpls.label_from_bin(buf) self.assertEqual(mpls_label, mpls_label_out) self.assertEqual(is_bos, is_bos_out) def test_label_to_bin_true(self): mpls_label = 0xfffff is_bos = True label = b'\xff\xff\xf1' label_out = mpls.label_to_bin(mpls_label, is_bos) self.assertEqual(label, label_out) def test_label_to_bin_false(self): mpls_label = 0xfffff is_bos = False label = b'\xff\xff\xf0' label_out = mpls.label_to_bin(mpls_label, is_bos) self.assertEqual(label, label_out) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/packet/test_openflow.py0000664000175000017500000000364200000000000023126 0ustar00zuulzuul00000000000000# Copyright (C) 2017 Nippon Telegraph and Telephone 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. import logging import os import sys import unittest from os_ken.lib import pcaplib from os_ken.lib.packet import openflow from os_ken.lib.packet import packet from os_ken.utils import binary_str LOG = logging.getLogger(__name__) OPENFLOW_DATA_DIR = os.path.join( os.path.dirname(sys.modules[__name__].__file__), '../../packet_data/pcap/') class Test_openflow(unittest.TestCase): """ Test case for os_ken.lib.packet.openflow. """ def test_pcap(self): files = [ 'openflow_flowmod', 'openflow_flowstats_req', 'openflow_invalid_version', ] for f in files: # print('*** testing %s ...' % f) for _, buf in pcaplib.Reader( open(OPENFLOW_DATA_DIR + f + '.pcap', 'rb')): # Checks if message can be parsed as expected. pkt = packet.Packet(buf) openflow_pkt = pkt.get_protocol(openflow.openflow) self.assertTrue(isinstance(openflow_pkt, openflow.openflow), 'Failed to parse OpenFlow message: %s' % pkt) # Checks if message can be serialized as expected. pkt.serialize() self.assertEqual(buf, pkt.data, "b'%s' != b'%s'" % (binary_str(buf), binary_str(pkt.data))) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/packet/test_ospf.py0000664000175000017500000001201600000000000022237 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone 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. import unittest from os_ken.lib.packet import ospf class Test_ospf(unittest.TestCase): """ Test case for os_ken.lib.packet.ospf """ def setUp(self): pass def tearDown(self): pass def test_router_lsa(self): link1 = ospf.RouterLSA.Link(id_='10.0.0.1', data='255.255.255.0', type_=ospf.LSA_LINK_TYPE_STUB, metric=10) msg = ospf.RouterLSA(id_='192.168.0.1', adv_router='192.168.0.2', links=[link1]) binmsg = msg.serialize() msg2, cls, rest = ospf.LSA.parser(binmsg) self.assertEqual(msg.header.checksum, msg2.header.checksum) self.assertEqual(str(msg), str(msg2)) self.assertEqual(rest, b'') def test_network_lsa(self): msg = ospf.NetworkLSA(id_='192.168.0.1', adv_router='192.168.0.2', mask='255.255.255.0', routers=['192.168.0.2']) binmsg = msg.serialize() msg2, cls, rest = ospf.LSA.parser(binmsg) self.assertEqual(msg.header.checksum, msg2.header.checksum) self.assertEqual(str(msg), str(msg2)) self.assertEqual(rest, b'') def test_as_external_lsa(self): extnw1 = ospf.ASExternalLSA.ExternalNetwork(mask='255.255.255.0', metric=20, fwd_addr='10.0.0.1') msg = ospf.ASExternalLSA(id_='192.168.0.1', adv_router='192.168.0.2', extnws=[extnw1]) binmsg = msg.serialize() msg2, cls, rest = ospf.LSA.parser(binmsg) self.assertEqual(msg.header.checksum, msg2.header.checksum) self.assertEqual(str(msg), str(msg2)) self.assertEqual(rest, b'') def test_hello(self): msg = ospf.OSPFHello(router_id='192.168.0.1', neighbors=['192.168.0.2']) binmsg = msg.serialize() msg2, cls, rest = ospf.OSPFMessage.parser(binmsg) self.assertEqual(msg.checksum, msg2.checksum) self.assertEqual(str(msg), str(msg2)) self.assertEqual(rest, b'') def test_dbdesc(self): link1 = ospf.RouterLSA.Link(id_='10.0.0.1', data='255.255.255.0', type_=ospf.LSA_LINK_TYPE_STUB, metric=10) lsa1 = ospf.RouterLSA(id_='192.168.0.1', adv_router='192.168.0.2', links=[link1]) msg = ospf.OSPFDBDesc(router_id='192.168.0.1', lsa_headers=[lsa1.header]) binmsg = msg.serialize() msg2, cls, rest = ospf.OSPFMessage.parser(binmsg) self.assertEqual(msg.checksum, msg2.checksum) self.assertEqual(str(msg), str(msg2)) self.assertEqual(rest, b'') def test_lsreq(self): req = ospf.OSPFLSReq.Request(type_=ospf.OSPF_ROUTER_LSA, id_='192.168.0.1', adv_router='192.168.0.2') msg = ospf.OSPFLSReq(router_id='192.168.0.1', lsa_requests=[req]) binmsg = msg.serialize() msg2, cls, rest = ospf.OSPFMessage.parser(binmsg) self.assertEqual(msg.checksum, msg2.checksum) self.assertEqual(str(msg), str(msg2)) self.assertEqual(rest, b'') def test_lsupd(self): link1 = ospf.RouterLSA.Link(id_='10.0.0.1', data='255.255.255.0', type_=ospf.LSA_LINK_TYPE_STUB, metric=10) lsa1 = ospf.RouterLSA(id_='192.168.0.1', adv_router='192.168.0.2', links=[link1]) msg = ospf.OSPFLSUpd(router_id='192.168.0.1', lsas=[lsa1]) binmsg = msg.serialize() msg2, cls, rest = ospf.OSPFMessage.parser(binmsg) self.assertEqual(msg.checksum, msg2.checksum) self.assertEqual(str(msg), str(msg2)) self.assertEqual(rest, b'') def test_lsack(self): link1 = ospf.RouterLSA.Link(id_='10.0.0.1', data='255.255.255.0', type_=ospf.LSA_LINK_TYPE_STUB, metric=10) lsa1 = ospf.RouterLSA(id_='192.168.0.1', adv_router='192.168.0.2', links=[link1]) msg = ospf.OSPFLSAck(router_id='192.168.0.1', lsa_headers=[lsa1.header]) binmsg = msg.serialize() msg2, cls, rest = ospf.OSPFMessage.parser(binmsg) self.assertEqual(msg.checksum, msg2.checksum) self.assertEqual(str(msg), str(msg2)) self.assertEqual(rest, b'') ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/packet/test_packet.py0000664000175000017500000015663600000000000022560 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone 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. # vim: tabstop=4 shiftwidth=4 softtabstop=4 import unittest import logging import struct import inspect from os_ken.ofproto import ether, inet from os_ken.lib.packet import arp from os_ken.lib.packet import bpdu from os_ken.lib.packet import ethernet from os_ken.lib.packet import icmp, icmpv6 from os_ken.lib.packet import ipv4, ipv6 from os_ken.lib.packet import llc from os_ken.lib.packet import packet, packet_utils from os_ken.lib.packet import sctp from os_ken.lib.packet import tcp, udp from os_ken.lib.packet import vlan from os_ken.lib import addrconv LOG = logging.getLogger('test_packet') class TestPacket(unittest.TestCase): """ Test case for packet """ dst_mac = 'aa:aa:aa:aa:aa:aa' src_mac = 'bb:bb:bb:bb:bb:bb' dst_mac_bin = addrconv.mac.text_to_bin(dst_mac) src_mac_bin = addrconv.mac.text_to_bin(src_mac) dst_ip = '192.168.128.10' src_ip = '192.168.122.20' dst_ip_bin = addrconv.ipv4.text_to_bin(dst_ip) src_port = 50001 dst_port = 50002 src_ip_bin = addrconv.ipv4.text_to_bin(src_ip) payload = b'\x06\x06\x47\x50\x00\x00\x00\x00' \ + b'\xcd\xc5\x00\x00\x00\x00\x00\x00' \ + b'\x10\x11\x12\x13\x14\x15\x16\x17' \ + b'\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f' def get_protocols(self, pkt): protocols = {} for p in pkt: if hasattr(p, 'protocol_name'): protocols[p.protocol_name] = p else: protocols['payload'] = p return protocols def setUp(self): pass def tearDown(self): pass def test_arp(self): # buid packet e = ethernet.ethernet(self.dst_mac, self.src_mac, ether.ETH_TYPE_ARP) a = arp.arp(1, ether.ETH_TYPE_IP, 6, 4, 2, self.src_mac, self.src_ip, self.dst_mac, self.dst_ip) p = packet.Packet() p.add_protocol(e) p.add_protocol(a) p.serialize() # ethernet !6s6sH e_buf = self.dst_mac_bin \ + self.src_mac_bin \ + b'\x08\x06' # arp !HHBBH6sI6sI a_buf = b'\x00\x01' \ + b'\x08\x00' \ + b'\x06' \ + b'\x04' \ + b'\x00\x02' \ + self.src_mac_bin \ + self.src_ip_bin \ + self.dst_mac_bin \ + self.dst_ip_bin buf = e_buf + a_buf # Append padding if ethernet frame is less than 60 bytes length pad_len = 60 - len(buf) if pad_len > 0: buf += b'\x00' * pad_len self.assertEqual(buf, p.data) # parse pkt = packet.Packet(p.data) protocols = self.get_protocols(pkt) p_eth = protocols['ethernet'] p_arp = protocols['arp'] # ethernet self.assertTrue(p_eth) self.assertEqual(self.dst_mac, p_eth.dst) self.assertEqual(self.src_mac, p_eth.src) self.assertEqual(ether.ETH_TYPE_ARP, p_eth.ethertype) # arp self.assertTrue(p_arp) self.assertEqual(1, p_arp.hwtype) self.assertEqual(ether.ETH_TYPE_IP, p_arp.proto) self.assertEqual(6, p_arp.hlen) self.assertEqual(4, p_arp.plen) self.assertEqual(2, p_arp.opcode) self.assertEqual(self.src_mac, p_arp.src_mac) self.assertEqual(self.src_ip, p_arp.src_ip) self.assertEqual(self.dst_mac, p_arp.dst_mac) self.assertEqual(self.dst_ip, p_arp.dst_ip) # to string eth_values = {'dst': self.dst_mac, 'src': self.src_mac, 'ethertype': ether.ETH_TYPE_ARP} _eth_str = ','.join(['%s=%s' % (k, repr(eth_values[k])) for k, v in inspect.getmembers(p_eth) if k in eth_values]) eth_str = '%s(%s)' % (ethernet.ethernet.__name__, _eth_str) arp_values = {'hwtype': 1, 'proto': ether.ETH_TYPE_IP, 'hlen': 6, 'plen': 4, 'opcode': 2, 'src_mac': self.src_mac, 'dst_mac': self.dst_mac, 'src_ip': self.src_ip, 'dst_ip': self.dst_ip} _arp_str = ','.join(['%s=%s' % (k, repr(arp_values[k])) for k, v in inspect.getmembers(p_arp) if k in arp_values]) arp_str = '%s(%s)' % (arp.arp.__name__, _arp_str) pkt_str = '%s, %s' % (eth_str, arp_str) self.assertEqual(eth_str, str(p_eth)) self.assertEqual(eth_str, repr(p_eth)) self.assertEqual(arp_str, str(p_arp)) self.assertEqual(arp_str, repr(p_arp)) self.assertEqual(pkt_str, str(pkt)) self.assertEqual(pkt_str, repr(pkt)) def test_vlan_arp(self): # buid packet e = ethernet.ethernet(self.dst_mac, self.src_mac, ether.ETH_TYPE_8021Q) v = vlan.vlan(0b111, 0b1, 3, ether.ETH_TYPE_ARP) a = arp.arp(1, ether.ETH_TYPE_IP, 6, 4, 2, self.src_mac, self.src_ip, self.dst_mac, self.dst_ip) p = packet.Packet() p.add_protocol(e) p.add_protocol(v) p.add_protocol(a) p.serialize() # ethernet !6s6sH e_buf = self.dst_mac_bin \ + self.src_mac_bin \ + b'\x81\x00' # vlan !HH v_buf = b'\xF0\x03' \ + b'\x08\x06' # arp !HHBBH6sI6sI a_buf = b'\x00\x01' \ + b'\x08\x00' \ + b'\x06' \ + b'\x04' \ + b'\x00\x02' \ + self.src_mac_bin \ + self.src_ip_bin \ + self.dst_mac_bin \ + self.dst_ip_bin buf = e_buf + v_buf + a_buf # Append padding if ethernet frame is less than 60 bytes length pad_len = 60 - len(buf) if pad_len > 0: buf += b'\x00' * pad_len self.assertEqual(buf, p.data) # parse pkt = packet.Packet(p.data) protocols = self.get_protocols(pkt) p_eth = protocols['ethernet'] p_vlan = protocols['vlan'] p_arp = protocols['arp'] # ethernet self.assertTrue(p_eth) self.assertEqual(self.dst_mac, p_eth.dst) self.assertEqual(self.src_mac, p_eth.src) self.assertEqual(ether.ETH_TYPE_8021Q, p_eth.ethertype) # vlan self.assertTrue(p_vlan) self.assertEqual(0b111, p_vlan.pcp) self.assertEqual(0b1, p_vlan.cfi) self.assertEqual(3, p_vlan.vid) self.assertEqual(ether.ETH_TYPE_ARP, p_vlan.ethertype) # arp self.assertTrue(p_arp) self.assertEqual(1, p_arp.hwtype) self.assertEqual(ether.ETH_TYPE_IP, p_arp.proto) self.assertEqual(6, p_arp.hlen) self.assertEqual(4, p_arp.plen) self.assertEqual(2, p_arp.opcode) self.assertEqual(self.src_mac, p_arp.src_mac) self.assertEqual(self.src_ip, p_arp.src_ip) self.assertEqual(self.dst_mac, p_arp.dst_mac) self.assertEqual(self.dst_ip, p_arp.dst_ip) # to string eth_values = {'dst': self.dst_mac, 'src': self.src_mac, 'ethertype': ether.ETH_TYPE_8021Q} _eth_str = ','.join(['%s=%s' % (k, repr(eth_values[k])) for k, v in inspect.getmembers(p_eth) if k in eth_values]) eth_str = '%s(%s)' % (ethernet.ethernet.__name__, _eth_str) vlan_values = {'pcp': 0b111, 'cfi': 0b1, 'vid': 3, 'ethertype': ether.ETH_TYPE_ARP} _vlan_str = ','.join(['%s=%s' % (k, repr(vlan_values[k])) for k, v in inspect.getmembers(p_vlan) if k in vlan_values]) vlan_str = '%s(%s)' % (vlan.vlan.__name__, _vlan_str) arp_values = {'hwtype': 1, 'proto': ether.ETH_TYPE_IP, 'hlen': 6, 'plen': 4, 'opcode': 2, 'src_mac': self.src_mac, 'dst_mac': self.dst_mac, 'src_ip': self.src_ip, 'dst_ip': self.dst_ip} _arp_str = ','.join(['%s=%s' % (k, repr(arp_values[k])) for k, v in inspect.getmembers(p_arp) if k in arp_values]) arp_str = '%s(%s)' % (arp.arp.__name__, _arp_str) pkt_str = '%s, %s, %s' % (eth_str, vlan_str, arp_str) self.assertEqual(eth_str, str(p_eth)) self.assertEqual(eth_str, repr(p_eth)) self.assertEqual(vlan_str, str(p_vlan)) self.assertEqual(vlan_str, repr(p_vlan)) self.assertEqual(arp_str, str(p_arp)) self.assertEqual(arp_str, repr(p_arp)) self.assertEqual(pkt_str, str(pkt)) self.assertEqual(pkt_str, repr(pkt)) def test_ipv4_udp(self): # buid packet e = ethernet.ethernet(self.dst_mac, self.src_mac, ether.ETH_TYPE_IP) ip = ipv4.ipv4(4, 5, 1, 0, 3, 1, 4, 64, inet.IPPROTO_UDP, 0, self.src_ip, self.dst_ip) u = udp.udp(0x190F, 0x1F90, 0, 0) p = packet.Packet() p.add_protocol(e) p.add_protocol(ip) p.add_protocol(u) p.add_protocol(self.payload) p.serialize() # ethernet !6s6sH e_buf = self.dst_mac_bin \ + self.src_mac_bin \ + b'\x08\x00' # ipv4 !BBHHHBBHII ip_buf = b'\x45' \ + b'\x01' \ + b'\x00\x3C' \ + b'\x00\x03' \ + b'\x20\x04' \ + b'\x40' \ + b'\x11' \ + b'\x00\x00' \ + self.src_ip_bin \ + self.dst_ip_bin # udp !HHHH u_buf = b'\x19\x0F' \ + b'\x1F\x90' \ + b'\x00\x28' \ + b'\x00\x00' buf = e_buf + ip_buf + u_buf + self.payload # parse pkt = packet.Packet(p.data) protocols = self.get_protocols(pkt) p_eth = protocols['ethernet'] p_ipv4 = protocols['ipv4'] p_udp = protocols['udp'] # ethernet self.assertTrue(p_eth) self.assertEqual(self.dst_mac, p_eth.dst) self.assertEqual(self.src_mac, p_eth.src) self.assertEqual(ether.ETH_TYPE_IP, p_eth.ethertype) # ipv4 self.assertTrue(p_ipv4) self.assertEqual(4, p_ipv4.version) self.assertEqual(5, p_ipv4.header_length) self.assertEqual(1, p_ipv4.tos) l = len(ip_buf) + len(u_buf) + len(self.payload) self.assertEqual(l, p_ipv4.total_length) self.assertEqual(3, p_ipv4.identification) self.assertEqual(1, p_ipv4.flags) self.assertEqual(64, p_ipv4.ttl) self.assertEqual(inet.IPPROTO_UDP, p_ipv4.proto) self.assertEqual(self.src_ip, p_ipv4.src) self.assertEqual(self.dst_ip, p_ipv4.dst) t = bytearray(ip_buf) struct.pack_into('!H', t, 10, p_ipv4.csum) self.assertEqual(packet_utils.checksum(t), 0) # udp self.assertTrue(p_udp) self.assertEqual(0x190f, p_udp.src_port) self.assertEqual(0x1F90, p_udp.dst_port) self.assertEqual(len(u_buf) + len(self.payload), p_udp.total_length) self.assertEqual(0x77b2, p_udp.csum) t = bytearray(u_buf) struct.pack_into('!H', t, 6, p_udp.csum) ph = struct.pack('!4s4sBBH', self.src_ip_bin, self.dst_ip_bin, 0, 17, len(u_buf) + len(self.payload)) t = ph + t + self.payload self.assertEqual(packet_utils.checksum(t), 0) # payload self.assertTrue('payload' in protocols) self.assertEqual(self.payload, protocols['payload']) # to string eth_values = {'dst': self.dst_mac, 'src': self.src_mac, 'ethertype': ether.ETH_TYPE_IP} _eth_str = ','.join(['%s=%s' % (k, repr(eth_values[k])) for k, v in inspect.getmembers(p_eth) if k in eth_values]) eth_str = '%s(%s)' % (ethernet.ethernet.__name__, _eth_str) ipv4_values = {'version': 4, 'header_length': 5, 'tos': 1, 'total_length': l, 'identification': 3, 'flags': 1, 'offset': p_ipv4.offset, 'ttl': 64, 'proto': inet.IPPROTO_UDP, 'csum': p_ipv4.csum, 'src': self.src_ip, 'dst': self.dst_ip, 'option': None} _ipv4_str = ','.join(['%s=%s' % (k, repr(ipv4_values[k])) for k, v in inspect.getmembers(p_ipv4) if k in ipv4_values]) ipv4_str = '%s(%s)' % (ipv4.ipv4.__name__, _ipv4_str) udp_values = {'src_port': 0x190f, 'dst_port': 0x1F90, 'total_length': len(u_buf) + len(self.payload), 'csum': 0x77b2} _udp_str = ','.join(['%s=%s' % (k, repr(udp_values[k])) for k, v in inspect.getmembers(p_udp) if k in udp_values]) udp_str = '%s(%s)' % (udp.udp.__name__, _udp_str) pkt_str = '%s, %s, %s, %s' % (eth_str, ipv4_str, udp_str, repr(protocols['payload'])) self.assertEqual(eth_str, str(p_eth)) self.assertEqual(eth_str, repr(p_eth)) self.assertEqual(ipv4_str, str(p_ipv4)) self.assertEqual(ipv4_str, repr(p_ipv4)) self.assertEqual(udp_str, str(p_udp)) self.assertEqual(udp_str, repr(p_udp)) self.assertEqual(pkt_str, str(pkt)) self.assertEqual(pkt_str, repr(pkt)) def test_ipv4_tcp(self): # buid packet e = ethernet.ethernet(self.dst_mac, self.src_mac, ether.ETH_TYPE_IP) ip = ipv4.ipv4(4, 5, 0, 0, 0, 0, 0, 64, inet.IPPROTO_TCP, 0, self.src_ip, self.dst_ip) t = tcp.tcp(0x190F, 0x1F90, 0x123, 1, 6, 0b101010, 2048, 0, 0x6f, b'\x01\x02') p = packet.Packet() p.add_protocol(e) p.add_protocol(ip) p.add_protocol(t) p.add_protocol(self.payload) p.serialize() # ethernet !6s6sH e_buf = self.dst_mac_bin \ + self.src_mac_bin \ + b'\x08\x00' # ipv4 !BBHHHBBHII ip_buf = b'\x45' \ + b'\x00' \ + b'\x00\x4C' \ + b'\x00\x00' \ + b'\x00\x00' \ + b'\x40' \ + b'\x06' \ + b'\x00\x00' \ + self.src_ip_bin \ + self.dst_ip_bin # tcp !HHIIBBHHH + option t_buf = b'\x19\x0F' \ + b'\x1F\x90' \ + b'\x00\x00\x01\x23' \ + b'\x00\x00\x00\x01' \ + b'\x60' \ + b'\x2A' \ + b'\x08\x00' \ + b'\x00\x00' \ + b'\x00\x6F' \ + b'\x01\x02\x00\x00' buf = e_buf + ip_buf + t_buf + self.payload # parse pkt = packet.Packet(p.data) protocols = self.get_protocols(pkt) p_eth = protocols['ethernet'] p_ipv4 = protocols['ipv4'] p_tcp = protocols['tcp'] # ethernet self.assertTrue(p_eth) self.assertEqual(self.dst_mac, p_eth.dst) self.assertEqual(self.src_mac, p_eth.src) self.assertEqual(ether.ETH_TYPE_IP, p_eth.ethertype) # ipv4 self.assertTrue(p_ipv4) self.assertEqual(4, p_ipv4.version) self.assertEqual(5, p_ipv4.header_length) self.assertEqual(0, p_ipv4.tos) l = len(ip_buf) + len(t_buf) + len(self.payload) self.assertEqual(l, p_ipv4.total_length) self.assertEqual(0, p_ipv4.identification) self.assertEqual(0, p_ipv4.flags) self.assertEqual(64, p_ipv4.ttl) self.assertEqual(inet.IPPROTO_TCP, p_ipv4.proto) self.assertEqual(self.src_ip, p_ipv4.src) self.assertEqual(self.dst_ip, p_ipv4.dst) t = bytearray(ip_buf) struct.pack_into('!H', t, 10, p_ipv4.csum) self.assertEqual(packet_utils.checksum(t), 0) # tcp self.assertTrue(p_tcp) self.assertEqual(0x190f, p_tcp.src_port) self.assertEqual(0x1F90, p_tcp.dst_port) self.assertEqual(0x123, p_tcp.seq) self.assertEqual(1, p_tcp.ack) self.assertEqual(6, p_tcp.offset) self.assertEqual(0b101010, p_tcp.bits) self.assertEqual(2048, p_tcp.window_size) self.assertEqual(0x6f, p_tcp.urgent) self.assertEqual(len(t_buf), len(p_tcp)) t = bytearray(t_buf) struct.pack_into('!H', t, 16, p_tcp.csum) ph = struct.pack('!4s4sBBH', self.src_ip_bin, self.dst_ip_bin, 0, 6, len(t_buf) + len(self.payload)) t = ph + t + self.payload self.assertEqual(packet_utils.checksum(t), 0) # payload self.assertTrue('payload' in protocols) self.assertEqual(self.payload, protocols['payload']) # to string eth_values = {'dst': self.dst_mac, 'src': self.src_mac, 'ethertype': ether.ETH_TYPE_IP} _eth_str = ','.join(['%s=%s' % (k, repr(eth_values[k])) for k, v in inspect.getmembers(p_eth) if k in eth_values]) eth_str = '%s(%s)' % (ethernet.ethernet.__name__, _eth_str) ipv4_values = {'version': 4, 'header_length': 5, 'tos': 0, 'total_length': l, 'identification': 0, 'flags': 0, 'offset': p_ipv4.offset, 'ttl': 64, 'proto': inet.IPPROTO_TCP, 'csum': p_ipv4.csum, 'src': self.src_ip, 'dst': self.dst_ip, 'option': None} _ipv4_str = ','.join(['%s=%s' % (k, repr(ipv4_values[k])) for k, v in inspect.getmembers(p_ipv4) if k in ipv4_values]) ipv4_str = '%s(%s)' % (ipv4.ipv4.__name__, _ipv4_str) tcp_values = {'src_port': 0x190f, 'dst_port': 0x1F90, 'seq': 0x123, 'ack': 1, 'offset': 6, 'bits': 0b101010, 'window_size': 2048, 'csum': p_tcp.csum, 'urgent': 0x6f, 'option': p_tcp.option} _tcp_str = ','.join(['%s=%s' % (k, repr(tcp_values[k])) for k, v in inspect.getmembers(p_tcp) if k in tcp_values]) tcp_str = '%s(%s)' % (tcp.tcp.__name__, _tcp_str) pkt_str = '%s, %s, %s, %s' % (eth_str, ipv4_str, tcp_str, repr(protocols['payload'])) self.assertEqual(eth_str, str(p_eth)) self.assertEqual(eth_str, repr(p_eth)) self.assertEqual(ipv4_str, str(p_ipv4)) self.assertEqual(ipv4_str, repr(p_ipv4)) self.assertEqual(tcp_str, str(p_tcp)) self.assertEqual(tcp_str, repr(p_tcp)) self.assertEqual(pkt_str, str(pkt)) self.assertEqual(pkt_str, repr(pkt)) def test_ipv4_sctp(self): # build packet e = ethernet.ethernet() ip = ipv4.ipv4(proto=inet.IPPROTO_SCTP) s = sctp.sctp(chunks=[sctp.chunk_data(payload_data=self.payload)]) p = e / ip / s p.serialize() ipaddr = addrconv.ipv4.text_to_bin('0.0.0.0') # ethernet !6s6sH e_buf = b'\xff\xff\xff\xff\xff\xff' \ + b'\x00\x00\x00\x00\x00\x00' \ + b'\x08\x00' # ipv4 !BBHHHBBHII ip_buf = b'\x45' \ + b'\x00' \ + b'\x00\x50' \ + b'\x00\x00' \ + b'\x00\x00' \ + b'\xff' \ + b'\x84' \ + b'\x00\x00' \ + ipaddr \ + ipaddr # sctp !HHII + chunk_data !BBHIHHI + payload s_buf = b'\x00\x00' \ + b'\x00\x00' \ + b'\x00\x00\x00\x00' \ + b'\x00\x00\x00\x00' \ + b'\x00' \ + b'\x00' \ + b'\x00\x00' \ + b'\x00\x00\x00\x00' \ + b'\x00\x00' \ + b'\x00\x00' \ + b'\x00\x00\x00\x00' \ + self.payload buf = e_buf + ip_buf + s_buf # parse pkt = packet.Packet(p.data) protocols = self.get_protocols(pkt) p_eth = protocols['ethernet'] p_ipv4 = protocols['ipv4'] p_sctp = protocols['sctp'] # ethernet self.assertTrue(p_eth) self.assertEqual('ff:ff:ff:ff:ff:ff', p_eth.dst) self.assertEqual('00:00:00:00:00:00', p_eth.src) self.assertEqual(ether.ETH_TYPE_IP, p_eth.ethertype) # ipv4 self.assertTrue(p_ipv4) self.assertEqual(4, p_ipv4.version) self.assertEqual(5, p_ipv4.header_length) self.assertEqual(0, p_ipv4.tos) l = len(ip_buf) + len(s_buf) self.assertEqual(l, p_ipv4.total_length) self.assertEqual(0, p_ipv4.identification) self.assertEqual(0, p_ipv4.flags) self.assertEqual(255, p_ipv4.ttl) self.assertEqual(inet.IPPROTO_SCTP, p_ipv4.proto) self.assertEqual('10.0.0.1', p_ipv4.src) self.assertEqual('10.0.0.2', p_ipv4.dst) t = bytearray(ip_buf) struct.pack_into('!H', t, 10, p_ipv4.csum) self.assertEqual(packet_utils.checksum(t), 0x1403) # sctp self.assertTrue(p_sctp) self.assertEqual(1, p_sctp.src_port) self.assertEqual(1, p_sctp.dst_port) self.assertEqual(0, p_sctp.vtag) assert isinstance(p_sctp.chunks[0], sctp.chunk_data) self.assertEqual(0, p_sctp.chunks[0]._type) self.assertEqual(0, p_sctp.chunks[0].unordered) self.assertEqual(0, p_sctp.chunks[0].begin) self.assertEqual(0, p_sctp.chunks[0].end) self.assertEqual(16 + len(self.payload), p_sctp.chunks[0].length) self.assertEqual(0, p_sctp.chunks[0].tsn) self.assertEqual(0, p_sctp.chunks[0].sid) self.assertEqual(0, p_sctp.chunks[0].seq) self.assertEqual(0, p_sctp.chunks[0].payload_id) self.assertEqual(self.payload, p_sctp.chunks[0].payload_data) self.assertEqual(len(s_buf), len(p_sctp)) # to string eth_values = {'dst': 'ff:ff:ff:ff:ff:ff', 'src': '00:00:00:00:00:00', 'ethertype': ether.ETH_TYPE_IP} _eth_str = ','.join(['%s=%s' % (k, repr(eth_values[k])) for k, v in inspect.getmembers(p_eth) if k in eth_values]) eth_str = '%s(%s)' % (ethernet.ethernet.__name__, _eth_str) ipv4_values = {'version': 4, 'header_length': 5, 'tos': 0, 'total_length': l, 'identification': 0, 'flags': 0, 'offset': 0, 'ttl': 255, 'proto': inet.IPPROTO_SCTP, 'csum': p_ipv4.csum, 'src': '10.0.0.1', 'dst': '10.0.0.2', 'option': None} _ipv4_str = ','.join(['%s=%s' % (k, repr(ipv4_values[k])) for k, v in inspect.getmembers(p_ipv4) if k in ipv4_values]) ipv4_str = '%s(%s)' % (ipv4.ipv4.__name__, _ipv4_str) data_values = {'unordered': 0, 'begin': 0, 'end': 0, 'length': 16 + len(self.payload), 'tsn': 0, 'sid': 0, 'seq': 0, 'payload_id': 0, 'payload_data': self.payload} _data_str = ','.join(['%s=%s' % (k, repr(data_values[k])) for k in sorted(data_values.keys())]) data_str = '[%s(%s)]' % (sctp.chunk_data.__name__, _data_str) sctp_values = {'src_port': 1, 'dst_port': 1, 'vtag': 0, 'csum': repr(p_sctp.csum), 'chunks': data_str} _sctp_str = ','.join(['%s=%s' % (k, sctp_values[k]) for k, _ in inspect.getmembers(p_sctp) if k in sctp_values]) sctp_str = '%s(%s)' % (sctp.sctp.__name__, _sctp_str) pkt_str = '%s, %s, %s' % (eth_str, ipv4_str, sctp_str) self.assertEqual(eth_str, str(p_eth)) self.assertEqual(eth_str, repr(p_eth)) self.assertEqual(ipv4_str, str(p_ipv4)) self.assertEqual(ipv4_str, repr(p_ipv4)) self.assertEqual(sctp_str, str(p_sctp)) self.assertEqual(sctp_str, repr(p_sctp)) self.assertEqual(pkt_str, str(pkt)) self.assertEqual(pkt_str, repr(pkt)) def test_ipv4_icmp(self): # buid packet e = ethernet.ethernet() ip = ipv4.ipv4(proto=inet.IPPROTO_ICMP) ic = icmp.icmp() p = e / ip / ic p.serialize() ipaddr = addrconv.ipv4.text_to_bin('0.0.0.0') # ethernet !6s6sH e_buf = b'\xff\xff\xff\xff\xff\xff' \ + b'\x00\x00\x00\x00\x00\x00' \ + b'\x08\x00' # ipv4 !BBHHHBBHII ip_buf = b'\x45' \ + b'\x00' \ + b'\x00\x1c' \ + b'\x00\x00' \ + b'\x00\x00' \ + b'\xff' \ + b'\x01' \ + b'\x00\x00' \ + ipaddr \ + ipaddr # icmp !BBH + echo !HH ic_buf = b'\x08' \ + b'\x00' \ + b'\x00\x00' \ + b'\x00\x00' \ + b'\x00\x00' buf = e_buf + ip_buf + ic_buf # parse pkt = packet.Packet(p.data) protocols = self.get_protocols(pkt) p_eth = protocols['ethernet'] p_ipv4 = protocols['ipv4'] p_icmp = protocols['icmp'] # ethernet self.assertTrue(p_eth) self.assertEqual('ff:ff:ff:ff:ff:ff', p_eth.dst) self.assertEqual('00:00:00:00:00:00', p_eth.src) self.assertEqual(ether.ETH_TYPE_IP, p_eth.ethertype) # ipv4 self.assertTrue(p_ipv4) self.assertEqual(4, p_ipv4.version) self.assertEqual(5, p_ipv4.header_length) self.assertEqual(0, p_ipv4.tos) l = len(ip_buf) + len(ic_buf) self.assertEqual(l, p_ipv4.total_length) self.assertEqual(0, p_ipv4.identification) self.assertEqual(0, p_ipv4.flags) self.assertEqual(255, p_ipv4.ttl) self.assertEqual(inet.IPPROTO_ICMP, p_ipv4.proto) self.assertEqual('10.0.0.1', p_ipv4.src) self.assertEqual('10.0.0.2', p_ipv4.dst) t = bytearray(ip_buf) struct.pack_into('!H', t, 10, p_ipv4.csum) self.assertEqual(packet_utils.checksum(t), 0x1403) # icmp self.assertTrue(p_icmp) self.assertEqual(8, p_icmp.type) self.assertEqual(0, p_icmp.code) self.assertEqual(0, p_icmp.data.id) self.assertEqual(0, p_icmp.data.seq) self.assertEqual(len(ic_buf), len(p_icmp)) t = bytearray(ic_buf) struct.pack_into('!H', t, 2, p_icmp.csum) self.assertEqual(packet_utils.checksum(t), 0) # to string eth_values = {'dst': 'ff:ff:ff:ff:ff:ff', 'src': '00:00:00:00:00:00', 'ethertype': ether.ETH_TYPE_IP} _eth_str = ','.join(['%s=%s' % (k, repr(eth_values[k])) for k, _ in inspect.getmembers(p_eth) if k in eth_values]) eth_str = '%s(%s)' % (ethernet.ethernet.__name__, _eth_str) ipv4_values = {'version': 4, 'header_length': 5, 'tos': 0, 'total_length': l, 'identification': 0, 'flags': 0, 'offset': p_ipv4.offset, 'ttl': 255, 'proto': inet.IPPROTO_ICMP, 'csum': p_ipv4.csum, 'src': '10.0.0.1', 'dst': '10.0.0.2', 'option': None} _ipv4_str = ','.join(['%s=%s' % (k, repr(ipv4_values[k])) for k, _ in inspect.getmembers(p_ipv4) if k in ipv4_values]) ipv4_str = '%s(%s)' % (ipv4.ipv4.__name__, _ipv4_str) echo_values = {'id': 0, 'seq': 0, 'data': None} _echo_str = ','.join(['%s=%s' % (k, repr(echo_values[k])) for k in sorted(echo_values.keys())]) echo_str = '%s(%s)' % (icmp.echo.__name__, _echo_str) icmp_values = {'type': 8, 'code': 0, 'csum': p_icmp.csum, 'data': echo_str} _icmp_str = ','.join(['%s=%s' % (k, icmp_values[k]) for k, _ in inspect.getmembers(p_icmp) if k in icmp_values]) icmp_str = '%s(%s)' % (icmp.icmp.__name__, _icmp_str) pkt_str = '%s, %s, %s' % (eth_str, ipv4_str, icmp_str) self.assertEqual(eth_str, str(p_eth)) self.assertEqual(eth_str, repr(p_eth)) self.assertEqual(ipv4_str, str(p_ipv4)) self.assertEqual(ipv4_str, repr(p_ipv4)) self.assertEqual(icmp_str, str(p_icmp)) self.assertEqual(icmp_str, repr(p_icmp)) self.assertEqual(pkt_str, str(pkt)) self.assertEqual(pkt_str, repr(pkt)) def test_ipv6_udp(self): # build packet e = ethernet.ethernet(ethertype=ether.ETH_TYPE_IPV6) ip = ipv6.ipv6(nxt=inet.IPPROTO_UDP) u = udp.udp() p = e / ip / u / self.payload p.serialize() ipaddr = addrconv.ipv6.text_to_bin('::') # ethernet !6s6sH e_buf = b'\xff\xff\xff\xff\xff\xff' \ + b'\x00\x00\x00\x00\x00\x00' \ + b'\x86\xdd' # ipv6 !IHBB16s16s' ip_buf = b'\x60\x00\x00\x00' \ + b'\x00\x00' \ + b'\x11' \ + b'\xff' \ + b'\x00\x00' \ + ipaddr \ + ipaddr # udp !HHHH u_buf = b'\x00\x00' \ + b'\x00\x00' \ + b'\x00\x28' \ + b'\x00\x00' buf = e_buf + ip_buf + u_buf + self.payload # parse pkt = packet.Packet(p.data) protocols = self.get_protocols(pkt) p_eth = protocols['ethernet'] p_ipv6 = protocols['ipv6'] p_udp = protocols['udp'] # ethernet self.assertTrue(p_eth) self.assertEqual('ff:ff:ff:ff:ff:ff', p_eth.dst) self.assertEqual('00:00:00:00:00:00', p_eth.src) self.assertEqual(ether.ETH_TYPE_IPV6, p_eth.ethertype) # ipv6 self.assertTrue(p_ipv6) self.assertEqual(6, p_ipv6.version) self.assertEqual(0, p_ipv6.traffic_class) self.assertEqual(0, p_ipv6.flow_label) self.assertEqual(len(u_buf) + len(self.payload), p_ipv6.payload_length) self.assertEqual(inet.IPPROTO_UDP, p_ipv6.nxt) self.assertEqual(255, p_ipv6.hop_limit) self.assertEqual('10::10', p_ipv6.src) self.assertEqual('20::20', p_ipv6.dst) # udp self.assertTrue(p_udp) self.assertEqual(1, p_udp.src_port) self.assertEqual(1, p_udp.dst_port) self.assertEqual(len(u_buf) + len(self.payload), p_udp.total_length) self.assertEqual(0x2B60, p_udp.csum) t = bytearray(u_buf) struct.pack_into('!H', t, 6, p_udp.csum) ph = struct.pack('!16s16sI3xB', ipaddr, ipaddr, len(u_buf) + len(self.payload), 17) t = ph + t + self.payload self.assertEqual(packet_utils.checksum(t), 0x62) # payload self.assertTrue('payload' in protocols) self.assertEqual(self.payload, protocols['payload']) # to string eth_values = {'dst': 'ff:ff:ff:ff:ff:ff', 'src': '00:00:00:00:00:00', 'ethertype': ether.ETH_TYPE_IPV6} _eth_str = ','.join(['%s=%s' % (k, repr(eth_values[k])) for k, v in inspect.getmembers(p_eth) if k in eth_values]) eth_str = '%s(%s)' % (ethernet.ethernet.__name__, _eth_str) ipv6_values = {'version': 6, 'traffic_class': 0, 'flow_label': 0, 'payload_length': len(u_buf) + len(self.payload), 'nxt': inet.IPPROTO_UDP, 'hop_limit': 255, 'src': '10::10', 'dst': '20::20', 'ext_hdrs': []} _ipv6_str = ','.join(['%s=%s' % (k, repr(ipv6_values[k])) for k, v in inspect.getmembers(p_ipv6) if k in ipv6_values]) ipv6_str = '%s(%s)' % (ipv6.ipv6.__name__, _ipv6_str) udp_values = {'src_port': 1, 'dst_port': 1, 'total_length': len(u_buf) + len(self.payload), 'csum': 0x2B60} _udp_str = ','.join(['%s=%s' % (k, repr(udp_values[k])) for k, v in inspect.getmembers(p_udp) if k in udp_values]) udp_str = '%s(%s)' % (udp.udp.__name__, _udp_str) pkt_str = '%s, %s, %s, %s' % (eth_str, ipv6_str, udp_str, repr(protocols['payload'])) self.assertEqual(eth_str, str(p_eth)) self.assertEqual(eth_str, repr(p_eth)) self.assertEqual(ipv6_str, str(p_ipv6)) self.assertEqual(ipv6_str, repr(p_ipv6)) self.assertEqual(udp_str, str(p_udp)) self.assertEqual(udp_str, repr(p_udp)) self.assertEqual(pkt_str, str(pkt)) self.assertEqual(pkt_str, repr(pkt)) def test_ipv6_tcp(self): # build packet e = ethernet.ethernet(ethertype=ether.ETH_TYPE_IPV6) ip = ipv6.ipv6() t = tcp.tcp(option=b'\x01\x02') p = e / ip / t / self.payload p.serialize() ipaddr = addrconv.ipv6.text_to_bin('::') # ethernet !6s6sH e_buf = b'\xff\xff\xff\xff\xff\xff' \ + b'\x00\x00\x00\x00\x00\x00' \ + b'\x86\xdd' # ipv6 !IHBB16s16s' ip_buf = b'\x60\x00\x00\x00' \ + b'\x00\x00' \ + b'\x06' \ + b'\xff' \ + b'\x00\x00' \ + ipaddr \ + ipaddr # tcp !HHIIBBHHH + option t_buf = b'\x00\x00' \ + b'\x00\x00' \ + b'\x00\x00\x00\x00' \ + b'\x00\x00\x00\x00' \ + b'\x60' \ + b'\x00' \ + b'\x00\x00' \ + b'\x00\x00' \ + b'\x00\x00' \ + b'\x01\x02\x00\x00' buf = e_buf + ip_buf + t_buf + self.payload # parse pkt = packet.Packet(p.data) protocols = self.get_protocols(pkt) p_eth = protocols['ethernet'] p_ipv6 = protocols['ipv6'] p_tcp = protocols['tcp'] # ethernet self.assertTrue(p_eth) self.assertEqual('ff:ff:ff:ff:ff:ff', p_eth.dst) self.assertEqual('00:00:00:00:00:00', p_eth.src) self.assertEqual(ether.ETH_TYPE_IPV6, p_eth.ethertype) # ipv6 self.assertTrue(p_ipv6) self.assertEqual(6, p_ipv6.version) self.assertEqual(0, p_ipv6.traffic_class) self.assertEqual(0, p_ipv6.flow_label) self.assertEqual(len(t_buf) + len(self.payload), p_ipv6.payload_length) self.assertEqual(inet.IPPROTO_TCP, p_ipv6.nxt) self.assertEqual(255, p_ipv6.hop_limit) self.assertEqual('10::10', p_ipv6.src) self.assertEqual('20::20', p_ipv6.dst) # tcp self.assertTrue(p_tcp) self.assertEqual(1, p_tcp.src_port) self.assertEqual(1, p_tcp.dst_port) self.assertEqual(0, p_tcp.seq) self.assertEqual(0, p_tcp.ack) self.assertEqual(6, p_tcp.offset) self.assertEqual(0, p_tcp.bits) self.assertEqual(0, p_tcp.window_size) self.assertEqual(0, p_tcp.urgent) self.assertEqual(len(t_buf), len(p_tcp)) t = bytearray(t_buf) struct.pack_into('!H', t, 16, p_tcp.csum) ph = struct.pack('!16s16sI3xB', ipaddr, ipaddr, len(t_buf) + len(self.payload), 6) t = ph + t + self.payload self.assertEqual(packet_utils.checksum(t), 0x62) # payload self.assertTrue('payload' in protocols) self.assertEqual(self.payload, protocols['payload']) # to string eth_values = {'dst': 'ff:ff:ff:ff:ff:ff', 'src': '00:00:00:00:00:00', 'ethertype': ether.ETH_TYPE_IPV6} _eth_str = ','.join(['%s=%s' % (k, repr(eth_values[k])) for k, v in inspect.getmembers(p_eth) if k in eth_values]) eth_str = '%s(%s)' % (ethernet.ethernet.__name__, _eth_str) ipv6_values = {'version': 6, 'traffic_class': 0, 'flow_label': 0, 'payload_length': len(t_buf) + len(self.payload), 'nxt': inet.IPPROTO_TCP, 'hop_limit': 255, 'src': '10::10', 'dst': '20::20', 'ext_hdrs': []} _ipv6_str = ','.join(['%s=%s' % (k, repr(ipv6_values[k])) for k, v in inspect.getmembers(p_ipv6) if k in ipv6_values]) ipv6_str = '%s(%s)' % (ipv6.ipv6.__name__, _ipv6_str) tcp_values = {'src_port': 1, 'dst_port': 1, 'seq': 0, 'ack': 0, 'offset': 6, 'bits': 0, 'window_size': 0, 'csum': p_tcp.csum, 'urgent': 0, 'option': p_tcp.option} _tcp_str = ','.join(['%s=%s' % (k, repr(tcp_values[k])) for k, v in inspect.getmembers(p_tcp) if k in tcp_values]) tcp_str = '%s(%s)' % (tcp.tcp.__name__, _tcp_str) pkt_str = '%s, %s, %s, %s' % (eth_str, ipv6_str, tcp_str, repr(protocols['payload'])) self.assertEqual(eth_str, str(p_eth)) self.assertEqual(eth_str, repr(p_eth)) self.assertEqual(ipv6_str, str(p_ipv6)) self.assertEqual(ipv6_str, repr(p_ipv6)) self.assertEqual(tcp_str, str(p_tcp)) self.assertEqual(tcp_str, repr(p_tcp)) self.assertEqual(pkt_str, str(pkt)) self.assertEqual(pkt_str, repr(pkt)) def test_ipv6_sctp(self): # build packet e = ethernet.ethernet(ethertype=ether.ETH_TYPE_IPV6) ip = ipv6.ipv6(nxt=inet.IPPROTO_SCTP) s = sctp.sctp(chunks=[sctp.chunk_data(payload_data=self.payload)]) p = e / ip / s p.serialize() ipaddr = addrconv.ipv6.text_to_bin('::') # ethernet !6s6sH e_buf = b'\xff\xff\xff\xff\xff\xff' \ + b'\x00\x00\x00\x00\x00\x00' \ + b'\x86\xdd' # ipv6 !IHBB16s16s' ip_buf = b'\x60\x00\x00\x00' \ + b'\x00\x00' \ + b'\x84' \ + b'\xff' \ + b'\x00\x00' \ + ipaddr \ + ipaddr # sctp !HHII + chunk_data !BBHIHHI + payload s_buf = b'\x00\x00' \ + b'\x00\x00' \ + b'\x00\x00\x00\x00' \ + b'\x00\x00\x00\x00' \ + b'\x00' \ + b'\x00' \ + b'\x00\x00' \ + b'\x00\x00\x00\x00' \ + b'\x00\x00' \ + b'\x00\x00' \ + b'\x00\x00\x00\x00' \ + self.payload buf = e_buf + ip_buf + s_buf # parse pkt = packet.Packet(p.data) protocols = self.get_protocols(pkt) p_eth = protocols['ethernet'] p_ipv6 = protocols['ipv6'] p_sctp = protocols['sctp'] # ethernet self.assertTrue(p_eth) self.assertEqual('ff:ff:ff:ff:ff:ff', p_eth.dst) self.assertEqual('00:00:00:00:00:00', p_eth.src) self.assertEqual(ether.ETH_TYPE_IPV6, p_eth.ethertype) # ipv6 self.assertTrue(p_ipv6) self.assertEqual(6, p_ipv6.version) self.assertEqual(0, p_ipv6.traffic_class) self.assertEqual(0, p_ipv6.flow_label) self.assertEqual(len(s_buf), p_ipv6.payload_length) self.assertEqual(inet.IPPROTO_SCTP, p_ipv6.nxt) self.assertEqual(255, p_ipv6.hop_limit) self.assertEqual('10::10', p_ipv6.src) self.assertEqual('20::20', p_ipv6.dst) # sctp self.assertTrue(p_sctp) self.assertEqual(1, p_sctp.src_port) self.assertEqual(1, p_sctp.dst_port) self.assertEqual(0, p_sctp.vtag) assert isinstance(p_sctp.chunks[0], sctp.chunk_data) self.assertEqual(0, p_sctp.chunks[0]._type) self.assertEqual(0, p_sctp.chunks[0].unordered) self.assertEqual(0, p_sctp.chunks[0].begin) self.assertEqual(0, p_sctp.chunks[0].end) self.assertEqual(16 + len(self.payload), p_sctp.chunks[0].length) self.assertEqual(0, p_sctp.chunks[0].tsn) self.assertEqual(0, p_sctp.chunks[0].sid) self.assertEqual(0, p_sctp.chunks[0].seq) self.assertEqual(0, p_sctp.chunks[0].payload_id) self.assertEqual(self.payload, p_sctp.chunks[0].payload_data) self.assertEqual(len(s_buf), len(p_sctp)) # to string eth_values = {'dst': 'ff:ff:ff:ff:ff:ff', 'src': '00:00:00:00:00:00', 'ethertype': ether.ETH_TYPE_IPV6} _eth_str = ','.join(['%s=%s' % (k, repr(eth_values[k])) for k, v in inspect.getmembers(p_eth) if k in eth_values]) eth_str = '%s(%s)' % (ethernet.ethernet.__name__, _eth_str) ipv6_values = {'version': 6, 'traffic_class': 0, 'flow_label': 0, 'payload_length': len(s_buf), 'nxt': inet.IPPROTO_SCTP, 'hop_limit': 255, 'src': '10::10', 'dst': '20::20', 'ext_hdrs': []} _ipv6_str = ','.join(['%s=%s' % (k, repr(ipv6_values[k])) for k, v in inspect.getmembers(p_ipv6) if k in ipv6_values]) ipv6_str = '%s(%s)' % (ipv6.ipv6.__name__, _ipv6_str) data_values = {'unordered': 0, 'begin': 0, 'end': 0, 'length': 16 + len(self.payload), 'tsn': 0, 'sid': 0, 'seq': 0, 'payload_id': 0, 'payload_data': self.payload} _data_str = ','.join(['%s=%s' % (k, repr(data_values[k])) for k in sorted(data_values.keys())]) data_str = '[%s(%s)]' % (sctp.chunk_data.__name__, _data_str) sctp_values = {'src_port': 1, 'dst_port': 1, 'vtag': 0, 'csum': repr(p_sctp.csum), 'chunks': data_str} _sctp_str = ','.join(['%s=%s' % (k, sctp_values[k]) for k, _ in inspect.getmembers(p_sctp) if k in sctp_values]) sctp_str = '%s(%s)' % (sctp.sctp.__name__, _sctp_str) pkt_str = '%s, %s, %s' % (eth_str, ipv6_str, sctp_str) self.assertEqual(eth_str, str(p_eth)) self.assertEqual(eth_str, repr(p_eth)) self.assertEqual(ipv6_str, str(p_ipv6)) self.assertEqual(ipv6_str, repr(p_ipv6)) self.assertEqual(sctp_str, str(p_sctp)) self.assertEqual(sctp_str, repr(p_sctp)) self.assertEqual(pkt_str, str(pkt)) self.assertEqual(pkt_str, repr(pkt)) def test_ipv6_icmpv6(self): # build packet e = ethernet.ethernet(ethertype=ether.ETH_TYPE_IPV6) ip = ipv6.ipv6(nxt=inet.IPPROTO_ICMPV6) ic = icmpv6.icmpv6() p = e / ip / ic p.serialize() ipaddr = addrconv.ipv6.text_to_bin('::') # ethernet !6s6sH e_buf = b'\xff\xff\xff\xff\xff\xff' \ + b'\x00\x00\x00\x00\x00\x00' \ + b'\x86\xdd' # ipv6 !IHBB16s16s' ip_buf = b'\x60\x00\x00\x00' \ + b'\x00\x00' \ + b'\x3a' \ + b'\xff' \ + b'\x00\x00' \ + ipaddr \ + ipaddr # icmpv6 !BBH ic_buf = b'\x00' \ + b'\x00' \ + b'\x00\x00' buf = e_buf + ip_buf + ic_buf # parse pkt = packet.Packet(p.data) protocols = self.get_protocols(pkt) p_eth = protocols['ethernet'] p_ipv6 = protocols['ipv6'] p_icmpv6 = protocols['icmpv6'] # ethernet self.assertTrue(p_eth) self.assertEqual('ff:ff:ff:ff:ff:ff', p_eth.dst) self.assertEqual('00:00:00:00:00:00', p_eth.src) self.assertEqual(ether.ETH_TYPE_IPV6, p_eth.ethertype) # ipv6 self.assertTrue(p_ipv6) self.assertEqual(6, p_ipv6.version) self.assertEqual(0, p_ipv6.traffic_class) self.assertEqual(0, p_ipv6.flow_label) self.assertEqual(len(ic_buf), p_ipv6.payload_length) self.assertEqual(inet.IPPROTO_ICMPV6, p_ipv6.nxt) self.assertEqual(255, p_ipv6.hop_limit) self.assertEqual('10::10', p_ipv6.src) self.assertEqual('20::20', p_ipv6.dst) # icmpv6 self.assertTrue(p_icmpv6) self.assertEqual(0, p_icmpv6.type_) self.assertEqual(0, p_icmpv6.code) self.assertEqual(len(ic_buf), len(p_icmpv6)) t = bytearray(ic_buf) struct.pack_into('!H', t, 2, p_icmpv6.csum) ph = struct.pack('!16s16sI3xB', ipaddr, ipaddr, len(ic_buf), 58) t = ph + t self.assertEqual(packet_utils.checksum(t), 0x60) # to string eth_values = {'dst': 'ff:ff:ff:ff:ff:ff', 'src': '00:00:00:00:00:00', 'ethertype': ether.ETH_TYPE_IPV6} _eth_str = ','.join(['%s=%s' % (k, repr(eth_values[k])) for k, _ in inspect.getmembers(p_eth) if k in eth_values]) eth_str = '%s(%s)' % (ethernet.ethernet.__name__, _eth_str) ipv6_values = {'version': 6, 'traffic_class': 0, 'flow_label': 0, 'payload_length': len(ic_buf), 'nxt': inet.IPPROTO_ICMPV6, 'hop_limit': 255, 'src': '10::10', 'dst': '20::20', 'ext_hdrs': []} _ipv6_str = ','.join(['%s=%s' % (k, repr(ipv6_values[k])) for k, _ in inspect.getmembers(p_ipv6) if k in ipv6_values]) ipv6_str = '%s(%s)' % (ipv6.ipv6.__name__, _ipv6_str) icmpv6_values = {'type_': 0, 'code': 0, 'csum': p_icmpv6.csum, 'data': b''} _icmpv6_str = ','.join(['%s=%s' % (k, repr(icmpv6_values[k])) for k, _ in inspect.getmembers(p_icmpv6) if k in icmpv6_values]) icmpv6_str = '%s(%s)' % (icmpv6.icmpv6.__name__, _icmpv6_str) pkt_str = '%s, %s, %s' % (eth_str, ipv6_str, icmpv6_str) self.assertEqual(eth_str, str(p_eth)) self.assertEqual(eth_str, repr(p_eth)) self.assertEqual(ipv6_str, str(p_ipv6)) self.assertEqual(ipv6_str, repr(p_ipv6)) self.assertEqual(icmpv6_str, str(p_icmpv6)) self.assertEqual(icmpv6_str, repr(p_icmpv6)) self.assertEqual(pkt_str, str(pkt)) self.assertEqual(pkt_str, repr(pkt)) def test_llc_bpdu(self): # buid packet e = ethernet.ethernet(self.dst_mac, self.src_mac, ether.ETH_TYPE_IEEE802_3) llc_control = llc.ControlFormatU(0, 0, 0) l = llc.llc(llc.SAP_BPDU, llc.SAP_BPDU, llc_control) b = bpdu.ConfigurationBPDUs(flags=0, root_priority=32768, root_system_id_extension=0, root_mac_address=self.src_mac, root_path_cost=0, bridge_priority=32768, bridge_system_id_extension=0, bridge_mac_address=self.dst_mac, port_priority=128, port_number=4, message_age=1, max_age=20, hello_time=2, forward_delay=15) p = packet.Packet() p.add_protocol(e) p.add_protocol(l) p.add_protocol(b) p.serialize() # ethernet !6s6sH e_buf = self.dst_mac_bin + self.src_mac_bin + b'\x05\xdc' # llc !BBB l_buf = (b'\x42' b'\x42' b'\x03') # bpdu !HBBBQIQHHHHH b_buf = (b'\x00\x00' b'\x00' b'\x00' b'\x00' b'\x80\x00\xbb\xbb\xbb\xbb\xbb\xbb' b'\x00\x00\x00\x00' b'\x80\x00\xaa\xaa\xaa\xaa\xaa\xaa' b'\x80\x04' b'\x01\x00' b'\x14\x00' b'\x02\x00' b'\x0f\x00') buf = e_buf + l_buf + b_buf # Append padding if ethernet frame is less than 60 bytes length pad_len = 60 - len(buf) if pad_len > 0: buf += b'\x00' * pad_len self.assertEqual(buf, p.data) # parse pkt = packet.Packet(p.data) protocols = self.get_protocols(pkt) p_eth = protocols['ethernet'] p_llc = protocols['llc'] p_bpdu = protocols['ConfigurationBPDUs'] # ethernet self.assertTrue(p_eth) self.assertEqual(self.dst_mac, p_eth.dst) self.assertEqual(self.src_mac, p_eth.src) self.assertEqual(ether.ETH_TYPE_IEEE802_3, p_eth.ethertype) # llc self.assertTrue(p_llc) self.assertEqual(llc.SAP_BPDU, p_llc.dsap_addr) self.assertEqual(llc.SAP_BPDU, p_llc.ssap_addr) self.assertEqual(0, p_llc.control.modifier_function1) self.assertEqual(0, p_llc.control.pf_bit) self.assertEqual(0, p_llc.control.modifier_function2) # bpdu self.assertTrue(p_bpdu) self.assertEqual(bpdu.PROTOCOL_IDENTIFIER, p_bpdu._protocol_id) self.assertEqual(bpdu.PROTOCOLVERSION_ID_BPDU, p_bpdu._version_id) self.assertEqual(bpdu.TYPE_CONFIG_BPDU, p_bpdu._bpdu_type) self.assertEqual(0, p_bpdu.flags) self.assertEqual(32768, p_bpdu.root_priority) self.assertEqual(0, p_bpdu.root_system_id_extension) self.assertEqual(self.src_mac, p_bpdu.root_mac_address) self.assertEqual(0, p_bpdu.root_path_cost) self.assertEqual(32768, p_bpdu.bridge_priority) self.assertEqual(0, p_bpdu.bridge_system_id_extension) self.assertEqual(self.dst_mac, p_bpdu.bridge_mac_address) self.assertEqual(128, p_bpdu.port_priority) self.assertEqual(4, p_bpdu.port_number) self.assertEqual(1, p_bpdu.message_age) self.assertEqual(20, p_bpdu.max_age) self.assertEqual(2, p_bpdu.hello_time) self.assertEqual(15, p_bpdu.forward_delay) # to string eth_values = {'dst': self.dst_mac, 'src': self.src_mac, 'ethertype': ether.ETH_TYPE_IEEE802_3} _eth_str = ','.join(['%s=%s' % (k, repr(eth_values[k])) for k, v in inspect.getmembers(p_eth) if k in eth_values]) eth_str = '%s(%s)' % (ethernet.ethernet.__name__, _eth_str) ctrl_values = {'modifier_function1': 0, 'pf_bit': 0, 'modifier_function2': 0} _ctrl_str = ','.join(['%s=%s' % (k, repr(ctrl_values[k])) for k, v in inspect.getmembers(p_llc.control) if k in ctrl_values]) ctrl_str = '%s(%s)' % (llc.ControlFormatU.__name__, _ctrl_str) llc_values = {'dsap_addr': repr(llc.SAP_BPDU), 'ssap_addr': repr(llc.SAP_BPDU), 'control': ctrl_str} _llc_str = ','.join(['%s=%s' % (k, llc_values[k]) for k, v in inspect.getmembers(p_llc) if k in llc_values]) llc_str = '%s(%s)' % (llc.llc.__name__, _llc_str) bpdu_values = {'flags': 0, 'root_priority': int(32768), 'root_system_id_extension': int(0), 'root_mac_address': self.src_mac, 'root_path_cost': 0, 'bridge_priority': int(32768), 'bridge_system_id_extension': int(0), 'bridge_mac_address': self.dst_mac, 'port_priority': 128, 'port_number': 4, 'message_age': float(1), 'max_age': float(20), 'hello_time': float(2), 'forward_delay': float(15)} _bpdu_str = ','.join(['%s=%s' % (k, repr(bpdu_values[k])) for k, v in inspect.getmembers(p_bpdu) if k in bpdu_values]) bpdu_str = '%s(%s)' % (bpdu.ConfigurationBPDUs.__name__, _bpdu_str) pkt_str = '%s, %s, %s' % (eth_str, llc_str, bpdu_str) self.assertEqual(eth_str, str(p_eth)) self.assertEqual(eth_str, repr(p_eth)) self.assertEqual(llc_str, str(p_llc)) self.assertEqual(llc_str, repr(p_llc)) self.assertEqual(bpdu_str, str(p_bpdu)) self.assertEqual(bpdu_str, repr(p_bpdu)) self.assertEqual(pkt_str, str(pkt)) self.assertEqual(pkt_str, repr(pkt)) def test_div_api(self): e = ethernet.ethernet(self.dst_mac, self.src_mac, ether.ETH_TYPE_IP) i = ipv4.ipv4() u = udp.udp(self.src_port, self.dst_port) pkt = e / i / u self.assertTrue(isinstance(pkt, packet.Packet)) self.assertTrue(isinstance(pkt.protocols[0], ethernet.ethernet)) self.assertTrue(isinstance(pkt.protocols[1], ipv4.ipv4)) self.assertTrue(isinstance(pkt.protocols[2], udp.udp)) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/packet/test_pbb.py0000664000175000017500000001155300000000000022040 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone 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. import logging import struct import unittest from os_ken.ofproto import ether from os_ken.ofproto import inet from os_ken.lib.packet import ethernet from os_ken.lib.packet import packet from os_ken.lib.packet import ipv4 from os_ken.lib.packet import vlan from os_ken.lib.packet import pbb LOG = logging.getLogger(__name__) class Test_itag(unittest.TestCase): pcp = 3 dei = 0 uca = 1 sid = 16770000 data = pcp << 29 | dei << 28 | uca << 27 | sid buf = struct.pack(pbb.itag._PACK_STR, data) it = pbb.itag(pcp, dei, uca, sid) def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(self.pcp, self.it.pcp) self.assertEqual(self.dei, self.it.dei) self.assertEqual(self.uca, self.it.uca) self.assertEqual(self.sid, self.it.sid) def test_parser(self): _res = pbb.itag.parser(self.buf) if type(_res) is tuple: res = _res[0] else: res = _res self.assertEqual(res.pcp, self.pcp) self.assertEqual(res.dei, self.dei) self.assertEqual(res.uca, self.uca) self.assertEqual(res.sid, self.sid) def test_serialize(self): data = bytearray() prev = None buf = self.it.serialize(data, prev) res = struct.unpack(pbb.itag._PACK_STR, buf) self.assertEqual(res[0], self.data) def _build_itag(self): b_src_mac = '00:07:0d:af:f4:54' b_dst_mac = '00:00:00:00:00:00' b_ethertype = ether.ETH_TYPE_8021AD e1 = ethernet.ethernet(b_dst_mac, b_src_mac, b_ethertype) b_pcp = 0 b_cfi = 0 b_vid = 32 b_ethertype = ether.ETH_TYPE_8021Q bt = vlan.svlan(b_pcp, b_cfi, b_vid, b_ethertype) c_src_mac = '11:11:11:11:11:11' c_dst_mac = 'aa:aa:aa:aa:aa:aa' c_ethertype = ether.ETH_TYPE_8021AD e2 = ethernet.ethernet(c_dst_mac, c_src_mac, c_ethertype) s_pcp = 0 s_cfi = 0 s_vid = 32 s_ethertype = ether.ETH_TYPE_8021Q st = vlan.svlan(s_pcp, s_cfi, s_vid, s_ethertype) c_pcp = 0 c_cfi = 0 c_vid = 32 c_ethertype = ether.ETH_TYPE_IP ct = vlan.vlan(c_pcp, c_cfi, c_vid, c_ethertype) version = 4 header_length = 20 tos = 0 total_length = 24 identification = 0x8a5d flags = 0 offset = 1480 ttl = 64 proto = inet.IPPROTO_ICMP csum = 0xa7f2 src = '131.151.32.21' dst = '131.151.32.129' option = b'TEST' ip = ipv4.ipv4(version, header_length, tos, total_length, identification, flags, offset, ttl, proto, csum, src, dst, option) p = packet.Packet() p.add_protocol(e1) p.add_protocol(bt) p.add_protocol(self.it) p.add_protocol(e2) p.add_protocol(st) p.add_protocol(ct) p.add_protocol(ip) p.serialize() return p def test_build_itag(self): p = self._build_itag() e = p.get_protocols(ethernet.ethernet) self.assertTrue(e) self.assertTrue(isinstance(e, list)) self.assertEqual(e[0].ethertype, ether.ETH_TYPE_8021AD) self.assertEqual(e[1].ethertype, ether.ETH_TYPE_8021AD) sv = p.get_protocols(vlan.svlan) self.assertTrue(sv) self.assertTrue(isinstance(sv, list)) self.assertEqual(sv[0].ethertype, ether.ETH_TYPE_8021Q) self.assertEqual(sv[1].ethertype, ether.ETH_TYPE_8021Q) it = p.get_protocol(pbb.itag) self.assertTrue(it) v = p.get_protocol(vlan.vlan) self.assertTrue(v) self.assertEqual(v.ethertype, ether.ETH_TYPE_IP) ip = p.get_protocol(ipv4.ipv4) self.assertTrue(ip) self.assertEqual(it.pcp, self.pcp) self.assertEqual(it.dei, self.dei) self.assertEqual(it.uca, self.uca) self.assertEqual(it.sid, self.sid) def test_malformed_itag(self): m_short_buf = self.buf[1:pbb.itag._MIN_LEN] self.assertRaises(Exception, pbb.itag.parser, m_short_buf) def test_json(self): jsondict = self.it.to_jsondict() it = pbb.itag.from_jsondict(jsondict['itag']) self.assertEqual(str(self.it), str(it)) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/packet/test_sctp.py0000664000175000017500000015000200000000000022237 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone 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. import inspect import logging import struct import unittest from os_ken.lib import addrconv from os_ken.lib.packet import packet from os_ken.lib.packet import ethernet from os_ken.lib.packet import ipv4 from os_ken.lib.packet import sctp from os_ken.ofproto import ether from os_ken.ofproto import inet LOG = logging.getLogger(__name__) class Test_sctp(unittest.TestCase): def setUp(self): self.chunks = [] self.csum = 0 self.dst_port = 1234 self.src_port = 5678 self.vtag = 98765432 self.sc = sctp.sctp( self.src_port, self.dst_port, self.vtag, self.csum, self.chunks) self.buf = b'\x16\x2e\x04\xd2\x05\xe3\x0a\x78\x00\x00\x00\x00' def setUp_with_data(self): self.unordered = 1 self.begin = 1 self.end = 1 self.length = 16 + 10 self.tsn = 12345 self.sid = 1 self.seq = 0 self.payload_id = 0 self.payload_data = b'\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a' self.data = sctp.chunk_data( unordered=self.unordered, begin=self.begin, end=self.end, tsn=self.tsn, sid=self.sid, payload_data=self.payload_data) self.chunks = [self.data] self.sc = sctp.sctp( self.src_port, self.dst_port, self.vtag, self.csum, self.chunks) self.buf += b'\x00\x07\x00\x1a\x00\x00\x30\x39\x00\x01\x00\x00' + \ b'\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a' def setUp_with_init(self): self.flags = 0 self.length = 20 + 8 + 20 + 8 + 4 + 16 + 16 self.init_tag = 123456 self.a_rwnd = 9876 self.os = 3 self.mis = 3 self.i_tsn = 123456 self.p_ipv4 = sctp.param_ipv4('192.168.1.1') self.p_ipv6 = sctp.param_ipv6('fe80::647e:1aff:fec4:8284') self.p_cookie_preserve = sctp.param_cookie_preserve(5000) self.p_ecn = sctp.param_ecn() self.p_host_addr = sctp.param_host_addr(b'test host\x00') self.p_support_type = sctp.param_supported_addr( [sctp.PTYPE_IPV4, sctp.PTYPE_IPV6, sctp.PTYPE_COOKIE_PRESERVE, sctp.PTYPE_ECN, sctp.PTYPE_HOST_ADDR]) self.params = [ self.p_ipv4, self.p_ipv6, self.p_cookie_preserve, self.p_ecn, self.p_host_addr, self.p_support_type] self.init = sctp.chunk_init( init_tag=self.init_tag, a_rwnd=self.a_rwnd, os=self.os, mis=self.mis, i_tsn=self.i_tsn, params=self.params) self.chunks = [self.init] self.sc = sctp.sctp( self.src_port, self.dst_port, self.vtag, self.csum, self.chunks) self.buf += b'\x01\x00\x00\x5c\x00\x01\xe2\x40\x00\x00\x26\x94' + \ b'\x00\x03\x00\x03\x00\x01\xe2\x40' + \ b'\x00\x05\x00\x08\xc0\xa8\x01\x01' + \ b'\x00\x06\x00\x14' + \ b'\xfe\x80\x00\x00\x00\x00\x00\x00' + \ b'\x64\x7e\x1a\xff\xfe\xc4\x82\x84' + \ b'\x00\x09\x00\x08\x00\x00\x13\x88' + \ b'\x80\x00\x00\x04' + \ b'\x00\x0b\x00\x0e' + \ b'\x74\x65\x73\x74\x20\x68\x6f\x73\x74\x00\x00\x00' + \ b'\x00\x0c\x00\x0e\x00\x05\x00\x06\x00\x09\x80\x00' + \ b'\x00\x0b\x00\x00' def setUp_with_init_ack(self): self.flags = 0 self.length = 20 + 8 + 8 + 20 + 8 + 4 + 16 self.init_tag = 123456 self.a_rwnd = 9876 self.os = 3 self.mis = 3 self.i_tsn = 123456 self.p_state_cookie = sctp.param_state_cookie(b'\x01\x02\x03') self.p_ipv4 = sctp.param_ipv4('192.168.1.1') self.p_ipv6 = sctp.param_ipv6('fe80::647e:1aff:fec4:8284') self.p_unrecognized_param = sctp.param_unrecognized_param( b'\xff\xff\x00\x04') self.p_ecn = sctp.param_ecn() self.p_host_addr = sctp.param_host_addr(b'test host\x00') self.params = [ self.p_state_cookie, self.p_ipv4, self.p_ipv6, self.p_unrecognized_param, self.p_ecn, self.p_host_addr] self.init_ack = sctp.chunk_init_ack( init_tag=self.init_tag, a_rwnd=self.a_rwnd, os=self.os, mis=self.mis, i_tsn=self.i_tsn, params=self.params) self.chunks = [self.init_ack] self.sc = sctp.sctp( self.src_port, self.dst_port, self.vtag, self.csum, self.chunks) self.buf += b'\x02\x00\x00\x54\x00\x01\xe2\x40\x00\x00\x26\x94' + \ b'\x00\x03\x00\x03\x00\x01\xe2\x40' + \ b'\x00\x07\x00\x07\x01\x02\x03\x00' + \ b'\x00\x05\x00\x08\xc0\xa8\x01\x01' + \ b'\x00\x06\x00\x14' + \ b'\xfe\x80\x00\x00\x00\x00\x00\x00' + \ b'\x64\x7e\x1a\xff\xfe\xc4\x82\x84' + \ b'\x00\x08\x00\x08\xff\xff\x00\x04' + \ b'\x80\x00\x00\x04' + \ b'\x00\x0b\x00\x0e' + \ b'\x74\x65\x73\x74\x20\x68\x6f\x73\x74\x00\x00\x00' def setUp_with_sack(self): self.flags = 0 self.length = 16 + 2 * 2 * 5 + 4 * 5 self.tsn_ack = 123456 self.a_rwnd = 9876 self.gapack_num = 5 self.duptsn_num = 5 self.gapacks = [[2, 3], [10, 12], [20, 24], [51, 52], [62, 63]] self.duptsns = [123458, 123466, 123476, 123507, 123518] self.sack = sctp.chunk_sack( tsn_ack=self.tsn_ack, a_rwnd=self.a_rwnd, gapack_num=self.gapack_num, duptsn_num=self.duptsn_num, gapacks=self.gapacks, duptsns=self.duptsns) self.chunks = [self.sack] self.sc = sctp.sctp( self.src_port, self.dst_port, self.vtag, self.csum, self.chunks) self.buf += b'\x03\x00\x00\x38\x00\x01\xe2\x40' + \ b'\x00\x00\x26\x94\x00\x05\x00\x05' + \ b'\x00\x02\x00\x03\x00\x0a\x00\x0c\x00\x14\x00\x18' + \ b'\x00\x33\x00\x34\x00\x3e\x00\x3f' + \ b'\x00\x01\xe2\x42\x00\x01\xe2\x4a\x00\x01\xe2\x54' + \ b'\x00\x01\xe2\x73\x00\x01\xe2\x7e' def setUp_with_heartbeat(self): self.flags = 0 self.length = 4 + 8 self.p_heartbeat = sctp.param_heartbeat(b'\x01\x02\x03\x04') self.heartbeat = sctp.chunk_heartbeat(info=self.p_heartbeat) self.chunks = [self.heartbeat] self.sc = sctp.sctp( self.src_port, self.dst_port, self.vtag, self.csum, self.chunks) self.buf += b'\x04\x00\x00\x0c' + \ b'\x00\x01\x00\x08' + \ b'\x01\x02\x03\x04' def setUp_with_heartbeat_ack(self): self.flags = 0 self.length = 4 + 12 self.p_heartbeat = sctp.param_heartbeat( b'\xff\xee\xdd\xcc\xbb\xaa\x99\x88') self.heartbeat_ack = sctp.chunk_heartbeat_ack(info=self.p_heartbeat) self.chunks = [self.heartbeat_ack] self.sc = sctp.sctp( self.src_port, self.dst_port, self.vtag, self.csum, self.chunks) self.buf += b'\x05\x00\x00\x10' + \ b'\x00\x01\x00\x0c' + \ b'\xff\xee\xdd\xcc\xbb\xaa\x99\x88' def setUp_with_abort(self): self.tflag = 0 self.length = 4 + 8 + 16 + 8 + 4 + 20 + 8 + 4 + 8 + 8 + 4 + 12 \ + 20 + 20 self.c_invalid_stream_id = sctp.cause_invalid_stream_id(4096) self.c_missing_param = sctp.cause_missing_param( [sctp.PTYPE_IPV4, sctp.PTYPE_IPV6, sctp.PTYPE_COOKIE_PRESERVE, sctp.PTYPE_HOST_ADDR]) self.c_stale_cookie = sctp.cause_stale_cookie(b'\x00\x00\x13\x88') self.c_out_of_resource = sctp.cause_out_of_resource() self.c_unresolvable_addr = sctp.cause_unresolvable_addr( sctp.param_host_addr(b'test host\x00')) self.c_unrecognized_chunk = sctp.cause_unrecognized_chunk( b'\xff\x00\x00\x04') self.c_invalid_param = sctp.cause_invalid_param() self.c_unrecognized_param = sctp.cause_unrecognized_param( b'\xff\xff\x00\x04') self.c_no_userdata = sctp.cause_no_userdata(b'\x00\x01\xe2\x40') self.c_cookie_while_shutdown = sctp.cause_cookie_while_shutdown() self.c_restart_with_new_addr = sctp.cause_restart_with_new_addr( sctp.param_ipv4('192.168.1.1')) self.c_user_initiated_abort = sctp.cause_user_initiated_abort( b'Key Interrupt.\x00') self.c_protocol_violation = sctp.cause_protocol_violation( b'Unknown reason.\x00') self.causes = [ self.c_invalid_stream_id, self.c_missing_param, self.c_stale_cookie, self.c_out_of_resource, self.c_unresolvable_addr, self.c_unrecognized_chunk, self.c_invalid_param, self.c_unrecognized_param, self.c_no_userdata, self.c_cookie_while_shutdown, self.c_restart_with_new_addr, self.c_user_initiated_abort, self.c_protocol_violation] self.abort = sctp.chunk_abort(causes=self.causes) self.chunks = [self.abort] self.sc = sctp.sctp( self.src_port, self.dst_port, self.vtag, self.csum, self.chunks) self.buf += b'\x06\x00\x00\x90' + \ b'\x00\x01\x00\x08\x10\x00\x00\x00' + \ b'\x00\x02\x00\x10\x00\x00\x00\x04' + \ b'\x00\x05\x00\x06\x00\x09\x00\x0b' + \ b'\x00\x03\x00\x08\x00\x00\x13\x88' + \ b'\x00\x04\x00\x04' + \ b'\x00\x05\x00\x14' + \ b'\x00\x0b\x00\x0e' + \ b'\x74\x65\x73\x74\x20\x68\x6f\x73\x74\x00\x00\x00' + \ b'\x00\x06\x00\x08\xff\x00\x00\x04' + \ b'\x00\x07\x00\x04' + \ b'\x00\x08\x00\x08\xff\xff\x00\x04' + \ b'\x00\x09\x00\x08\x00\x01\xe2\x40' + \ b'\x00\x0a\x00\x04' + \ b'\x00\x0b\x00\x0c' + \ b'\x00\x05\x00\x08\xc0\xa8\x01\x01' + \ b'\x00\x0c\x00\x13' + \ b'\x4b\x65\x79\x20\x49\x6e\x74\x65' + \ b'\x72\x72\x75\x70\x74\x2e\x00\x00' + \ b'\x00\x0d\x00\x14' + \ b'\x55\x6e\x6b\x6e\x6f\x77\x6e\x20' + \ b'\x72\x65\x61\x73\x6f\x6e\x2e\x00' def setUp_with_shutdown(self): self.flags = 0 self.length = 8 self.tsn_ack = 123456 self.shutdown = sctp.chunk_shutdown(tsn_ack=self.tsn_ack) self.chunks = [self.shutdown] self.sc = sctp.sctp( self.src_port, self.dst_port, self.vtag, self.csum, self.chunks) self.buf += b'\x07\x00\x00\x08\x00\x01\xe2\x40' def setUp_with_shutdown_ack(self): self.flags = 0 self.length = 4 self.shutdown_ack = sctp.chunk_shutdown_ack() self.chunks = [self.shutdown_ack] self.sc = sctp.sctp( self.src_port, self.dst_port, self.vtag, self.csum, self.chunks) self.buf += b'\x08\x00\x00\x04' def setUp_with_error(self): self.flags = 0 self.length = 4 + 8 + 16 + 8 + 4 + 20 + 8 + 4 + 8 + 8 + 4 + 12 \ + 20 + 20 self.c_invalid_stream_id = sctp.cause_invalid_stream_id(4096) self.c_missing_param = sctp.cause_missing_param( [sctp.PTYPE_IPV4, sctp.PTYPE_IPV6, sctp.PTYPE_COOKIE_PRESERVE, sctp.PTYPE_HOST_ADDR]) self.c_stale_cookie = sctp.cause_stale_cookie(b'\x00\x00\x13\x88') self.c_out_of_resource = sctp.cause_out_of_resource() self.c_unresolvable_addr = sctp.cause_unresolvable_addr( sctp.param_host_addr(b'test host\x00')) self.c_unrecognized_chunk = sctp.cause_unrecognized_chunk( b'\xff\x00\x00\x04') self.c_invalid_param = sctp.cause_invalid_param() self.c_unrecognized_param = sctp.cause_unrecognized_param( b'\xff\xff\x00\x04') self.c_no_userdata = sctp.cause_no_userdata(b'\x00\x01\xe2\x40') self.c_cookie_while_shutdown = sctp.cause_cookie_while_shutdown() self.c_restart_with_new_addr = sctp.cause_restart_with_new_addr( sctp.param_ipv4('192.168.1.1')) self.c_user_initiated_abort = sctp.cause_user_initiated_abort( b'Key Interrupt.\x00') self.c_protocol_violation = sctp.cause_protocol_violation( b'Unknown reason.\x00') self.causes = [ self.c_invalid_stream_id, self.c_missing_param, self.c_stale_cookie, self.c_out_of_resource, self.c_unresolvable_addr, self.c_unrecognized_chunk, self.c_invalid_param, self.c_unrecognized_param, self.c_no_userdata, self.c_cookie_while_shutdown, self.c_restart_with_new_addr, self.c_user_initiated_abort, self.c_protocol_violation] self.error = sctp.chunk_error(causes=self.causes) self.chunks = [self.error] self.sc = sctp.sctp( self.src_port, self.dst_port, self.vtag, self.csum, self.chunks) self.buf += b'\x09\x00\x00\x90' + \ b'\x00\x01\x00\x08\x10\x00\x00\x00' + \ b'\x00\x02\x00\x10\x00\x00\x00\x04' + \ b'\x00\x05\x00\x06\x00\x09\x00\x0b' + \ b'\x00\x03\x00\x08\x00\x00\x13\x88' + \ b'\x00\x04\x00\x04' + \ b'\x00\x05\x00\x14' + \ b'\x00\x0b\x00\x0e' + \ b'\x74\x65\x73\x74\x20\x68\x6f\x73\x74\x00\x00\x00' + \ b'\x00\x06\x00\x08\xff\x00\x00\x04' + \ b'\x00\x07\x00\x04' + \ b'\x00\x08\x00\x08\xff\xff\x00\x04' + \ b'\x00\x09\x00\x08\x00\x01\xe2\x40' + \ b'\x00\x0a\x00\x04' + \ b'\x00\x0b\x00\x0c' + \ b'\x00\x05\x00\x08\xc0\xa8\x01\x01' + \ b'\x00\x0c\x00\x13' + \ b'\x4b\x65\x79\x20\x49\x6e\x74\x65' + \ b'\x72\x72\x75\x70\x74\x2e\x00\x00' + \ b'\x00\x0d\x00\x14' + \ b'\x55\x6e\x6b\x6e\x6f\x77\x6e\x20' + \ b'\x72\x65\x61\x73\x6f\x6e\x2e\x00' def setUp_with_cookie_echo(self): self.flags = 0 self.length = 8 self.cookie = b'\x12\x34\x56\x78' self.cookie_echo = sctp.chunk_cookie_echo(cookie=self.cookie) self.chunks = [self.cookie_echo] self.sc = sctp.sctp( self.src_port, self.dst_port, self.vtag, self.csum, self.chunks) self.buf += b'\x0a\x00\x00\x08\x12\x34\x56\x78' def setUp_with_cookie_ack(self): self.flags = 0 self.length = 4 self.cookie_ack = sctp.chunk_cookie_ack() self.chunks = [self.cookie_ack] self.sc = sctp.sctp( self.src_port, self.dst_port, self.vtag, self.csum, self.chunks) self.buf += b'\x0b\x00\x00\x04' def setUp_with_ecn_echo(self): self.flags = 0 self.length = 8 self.low_tsn = 123456 self.ecn_echo = sctp.chunk_ecn_echo(low_tsn=self.low_tsn) self.chunks = [self.ecn_echo] self.sc = sctp.sctp( self.src_port, self.dst_port, self.vtag, self.csum, self.chunks) self.buf += b'\x0c\x00\x00\x08\x00\x01\xe2\x40' def setUp_with_cwr(self): self.flags = 0 self.length = 8 self.low_tsn = 123456 self.cwr = sctp.chunk_cwr(low_tsn=self.low_tsn) self.chunks = [self.cwr] self.sc = sctp.sctp( self.src_port, self.dst_port, self.vtag, self.csum, self.chunks) self.buf += b'\x0d\x00\x00\x08\x00\x01\xe2\x40' def setUp_with_shutdown_complete(self): self.tflag = 0 self.length = 4 self.shutdown_complete = sctp.chunk_shutdown_complete() self.chunks = [self.shutdown_complete] self.sc = sctp.sctp( self.src_port, self.dst_port, self.vtag, self.csum, self.chunks) self.buf += b'\x0e\x00\x00\x04' def setUp_with_multi_chunks(self): self.s_flags = 0 self.s_length = 16 self.s_tsn_ack = 123456 self.s_a_rwnd = 9876 self.s_gapack_num = 0 self.s_duptsn_num = 0 self.s_gapacks = None self.s_duptsns = None self.sack = sctp.chunk_sack( tsn_ack=self.s_tsn_ack, a_rwnd=self.s_a_rwnd) self.d1_unordered = 0 self.d1_begin = 1 self.d1_end = 0 self.d1_length = 16 + 10 self.d1_tsn = 12345 self.d1_sid = 1 self.d1_seq = 0 self.d1_payload_id = 0 self.d1_payload_data = b'\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a' self.data1 = sctp.chunk_data( begin=self.d1_begin, tsn=self.d1_tsn, sid=self.d1_sid, payload_data=self.d1_payload_data) self.d2_unordered = 0 self.d2_begin = 0 self.d2_end = 1 self.d2_length = 16 + 10 self.d2_tsn = 12346 self.d2_sid = 1 self.d2_seq = 1 self.d2_payload_id = 0 self.d2_payload_data = b'\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a' self.data2 = sctp.chunk_data( end=self.d2_end, tsn=self.d2_tsn, sid=self.d2_sid, seq=self.d2_seq, payload_data=self.d2_payload_data) self.chunks = [self.sack, self.data1, self.data2] self.sc = sctp.sctp( self.src_port, self.dst_port, self.vtag, self.csum, self.chunks) self.buf += b'\x03\x00\x00\x10\x00\x01\xe2\x40' + \ b'\x00\x00\x26\x94\x00\x00\x00\x00' + \ b'\x00\x02\x00\x1a\x00\x00\x30\x39\x00\x01\x00\x00' + \ b'\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a' + \ b'\x00\x01\x00\x1a\x00\x00\x30\x3a\x00\x01\x00\x01' + \ b'\x00\x00\x00\x00\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a' def tearDown(self): pass def test_init(self): self.assertEqual(self.src_port, self.sc.src_port) self.assertEqual(self.dst_port, self.sc.dst_port) self.assertEqual(self.vtag, self.sc.vtag) self.assertEqual(self.csum, self.sc.csum) self.assertEqual(self.chunks, self.sc.chunks) def test_init_with_data(self): self.setUp_with_data() self.test_init() def test_init_with_init(self): self.setUp_with_init() self.test_init() def test_init_with_init_ack(self): self.setUp_with_init_ack() self.test_init() def test_init_with_sack(self): self.setUp_with_sack() self.test_init() def test_init_with_heartbeat(self): self.setUp_with_heartbeat() self.test_init() def test_init_with_heartbeat_ack(self): self.setUp_with_heartbeat_ack() self.test_init() def test_init_with_abort(self): self.setUp_with_abort() self.test_init() def test_init_with_shutdown(self): self.setUp_with_shutdown() self.test_init() def test_init_with_shutdown_ack(self): self.setUp_with_shutdown_ack() self.test_init() def test_init_with_error(self): self.setUp_with_error() self.test_init() def test_init_with_cookie_echo(self): self.setUp_with_cookie_echo() self.test_init() def test_init_with_cookie_ack(self): self.setUp_with_cookie_ack() self.test_init() def test_init_with_ecn_echo(self): self.setUp_with_ecn_echo() self.test_init() def test_init_with_cwr(self): self.setUp_with_cwr() self.test_init() def test_init_with_shutdown_complete(self): self.setUp_with_shutdown_complete() self.test_init() def test_init_with_multi_chunks(self): self.setUp_with_multi_chunks() self.test_init() def test_parser(self): _res = self.sc.parser(bytes(self.buf)) if type(_res) is tuple: res = _res[0] else: res = _res # to calculate the lengths of parameters. self.sc.serialize(None, None) self.assertEqual(self.src_port, res.src_port) self.assertEqual(self.dst_port, res.dst_port) self.assertEqual(self.vtag, res.vtag) self.assertEqual(self.csum, res.csum) self.assertEqual(str(self.chunks), str(res.chunks)) def test_parser_with_data(self): self.setUp_with_data() self.test_parser() def test_parser_with_init(self): self.setUp_with_init() self.test_parser() def test_parser_with_init_ack(self): self.setUp_with_init_ack() self.test_parser() def test_parser_with_sack(self): self.setUp_with_sack() self.test_parser() def test_parser_with_heartbeat(self): self.setUp_with_heartbeat() self.test_parser() def test_parser_with_heartbeat_ack(self): self.setUp_with_heartbeat_ack() self.test_parser() def test_parser_with_abort(self): self.setUp_with_abort() self.test_parser() def test_parser_with_shutdown(self): self.setUp_with_shutdown() self.test_parser() def test_parser_with_shutdown_ack(self): self.setUp_with_shutdown_ack() self.test_parser() def test_parser_with_error(self): self.setUp_with_error() self.test_parser() def test_parser_with_cookie_echo(self): self.setUp_with_cookie_echo() self.test_parser() def test_parser_with_cookie_ack(self): self.setUp_with_cookie_ack() self.test_parser() def test_parser_with_ecn_echo(self): self.setUp_with_ecn_echo() self.test_parser() def test_parser_with_cwr(self): self.setUp_with_cwr() self.test_parser() def test_parser_with_shutdown_complete(self): self.setUp_with_shutdown_complete() self.test_parser() def test_parser_with_multi_chunks(self): self.setUp_with_multi_chunks() self.test_parser() def _test_serialize(self): buf = self.sc.serialize(bytearray(), None) res = struct.unpack_from(sctp.sctp._PACK_STR, buf) self.assertEqual(self.src_port, res[0]) self.assertEqual(self.dst_port, res[1]) self.assertEqual(self.vtag, res[2]) # skip compare checksum # self.assertEqual(self.csum, res[3]) return buf[sctp.sctp._MIN_LEN:] def test_serialize(self): self._test_serialize() def test_serialize_with_data(self): self.setUp_with_data() buf = self._test_serialize() res = struct.unpack_from(sctp.chunk_data._PACK_STR, buf) self.assertEqual(sctp.chunk_data.chunk_type(), res[0]) flags = ( (self.unordered << 2) | (self.begin << 1) | (self.end << 0)) self.assertEqual(flags, res[1]) self.assertEqual(self.length, res[2]) self.assertEqual(self.tsn, res[3]) self.assertEqual(self.sid, res[4]) self.assertEqual(self.seq, res[5]) self.assertEqual(self.payload_id, res[6]) self.assertEqual(self.payload_data, buf[sctp.chunk_data._MIN_LEN:]) def test_serialize_with_init(self): self.setUp_with_init() buf = self._test_serialize() res = struct.unpack_from(sctp.chunk_init._PACK_STR, buf) self.assertEqual(sctp.chunk_init.chunk_type(), res[0]) self.assertEqual(self.flags, res[1]) self.assertEqual(self.length, res[2]) self.assertEqual(self.init_tag, res[3]) self.assertEqual(self.a_rwnd, res[4]) self.assertEqual(self.os, res[5]) self.assertEqual(self.mis, res[6]) self.assertEqual(self.i_tsn, res[7]) buf = buf[sctp.chunk_init._MIN_LEN:] res1 = struct.unpack_from(sctp.param_ipv4._PACK_STR, buf) self.assertEqual(sctp.param_ipv4.param_type(), res1[0]) self.assertEqual(8, res1[1]) self.assertEqual('192.168.1.1', addrconv.ipv4.bin_to_text( buf[sctp.param_ipv4._MIN_LEN:sctp.param_ipv4._MIN_LEN + 4])) buf = buf[8:] res2 = struct.unpack_from(sctp.param_ipv6._PACK_STR, buf) self.assertEqual(sctp.param_ipv6.param_type(), res2[0]) self.assertEqual(20, res2[1]) self.assertEqual('fe80::647e:1aff:fec4:8284', addrconv.ipv6.bin_to_text( buf[sctp.param_ipv6._MIN_LEN:sctp.param_ipv6._MIN_LEN + 16])) buf = buf[20:] res3 = struct.unpack_from(sctp.param_cookie_preserve._PACK_STR, buf) self.assertEqual(sctp.param_cookie_preserve.param_type(), res3[0]) self.assertEqual(8, res3[1]) self.assertEqual(5000, res3[2]) buf = buf[8:] res4 = struct.unpack_from(sctp.param_ecn._PACK_STR, buf) self.assertEqual(sctp.param_ecn.param_type(), res4[0]) self.assertEqual(4, res4[1]) buf = buf[4:] res5 = struct.unpack_from(sctp.param_host_addr._PACK_STR, buf) self.assertEqual(sctp.param_host_addr.param_type(), res5[0]) self.assertEqual(14, res5[1]) self.assertEqual(b'test host\x00', buf[sctp.param_host_addr._MIN_LEN: sctp.param_host_addr._MIN_LEN + 10]) buf = buf[16:] res6 = struct.unpack_from(sctp.param_supported_addr._PACK_STR, buf) res6 = list(res6) self.assertEqual(sctp.param_supported_addr.param_type(), res6[0]) self.assertEqual(14, res6[1]) buf = buf[sctp.param_supported_addr._MIN_LEN:] offset = 0 tmplist = [] while offset < len(buf): (tmp, ) = struct.unpack_from('!H', buf, offset) tmplist.append(tmp) offset += struct.calcsize('!H') res6.extend(tmplist) self.assertEqual(sctp.PTYPE_IPV4, res6[2]) self.assertEqual(sctp.PTYPE_IPV6, res6[3]) self.assertEqual(sctp.PTYPE_COOKIE_PRESERVE, res6[4]) self.assertEqual(sctp.PTYPE_ECN, res6[5]) self.assertEqual(sctp.PTYPE_HOST_ADDR, res6[6]) def test_serialize_with_init_ack(self): self.setUp_with_init_ack() buf = self._test_serialize() res = struct.unpack_from(sctp.chunk_init_ack._PACK_STR, buf) self.assertEqual(sctp.chunk_init_ack.chunk_type(), res[0]) self.assertEqual(self.flags, res[1]) self.assertEqual(self.length, res[2]) self.assertEqual(self.init_tag, res[3]) self.assertEqual(self.a_rwnd, res[4]) self.assertEqual(self.os, res[5]) self.assertEqual(self.mis, res[6]) self.assertEqual(self.i_tsn, res[7]) buf = buf[sctp.chunk_init_ack._MIN_LEN:] res1 = struct.unpack_from(sctp.param_state_cookie._PACK_STR, buf) self.assertEqual(sctp.param_state_cookie.param_type(), res1[0]) self.assertEqual(7, res1[1]) self.assertEqual(b'\x01\x02\x03', buf[sctp.param_state_cookie._MIN_LEN: sctp.param_state_cookie._MIN_LEN + 3]) buf = buf[8:] res2 = struct.unpack_from(sctp.param_ipv4._PACK_STR, buf) self.assertEqual(sctp.param_ipv4.param_type(), res2[0]) self.assertEqual(8, res2[1]) self.assertEqual('192.168.1.1', addrconv.ipv4.bin_to_text( buf[sctp.param_ipv4._MIN_LEN:sctp.param_ipv4._MIN_LEN + 4])) buf = buf[8:] res3 = struct.unpack_from(sctp.param_ipv6._PACK_STR, buf) self.assertEqual(sctp.param_ipv6.param_type(), res3[0]) self.assertEqual(20, res3[1]) self.assertEqual('fe80::647e:1aff:fec4:8284', addrconv.ipv6.bin_to_text( buf[sctp.param_ipv6._MIN_LEN:sctp.param_ipv6._MIN_LEN + 16])) buf = buf[20:] res4 = struct.unpack_from( sctp.param_unrecognized_param._PACK_STR, buf) self.assertEqual(sctp.param_unrecognized_param.param_type(), res4[0]) self.assertEqual(8, res4[1]) self.assertEqual(b'\xff\xff\x00\x04', buf[sctp.param_unrecognized_param._MIN_LEN: sctp.param_unrecognized_param._MIN_LEN + 4]) buf = buf[8:] res5 = struct.unpack_from(sctp.param_ecn._PACK_STR, buf) self.assertEqual(sctp.param_ecn.param_type(), res5[0]) self.assertEqual(4, res5[1]) buf = buf[4:] res6 = struct.unpack_from(sctp.param_host_addr._PACK_STR, buf) self.assertEqual(sctp.param_host_addr.param_type(), res6[0]) self.assertEqual(14, res6[1]) self.assertEqual(b'test host\x00', buf[sctp.param_host_addr._MIN_LEN: sctp.param_host_addr._MIN_LEN + 10]) def test_serialize_with_sack(self): self.setUp_with_sack() buf = self._test_serialize() res = struct.unpack_from(sctp.chunk_sack._PACK_STR, buf) self.assertEqual(sctp.chunk_sack.chunk_type(), res[0]) self.assertEqual(self.flags, res[1]) self.assertEqual(self.length, res[2]) self.assertEqual(self.tsn_ack, res[3]) self.assertEqual(self.a_rwnd, res[4]) self.assertEqual(self.gapack_num, res[5]) self.assertEqual(self.duptsn_num, res[6]) buf = buf[sctp.chunk_sack._MIN_LEN:] gapacks = [] for _ in range(self.gapack_num): (gap_s, gap_e) = struct.unpack_from( sctp.chunk_sack._GAPACK_STR, buf) one = [gap_s, gap_e] gapacks.append(one) buf = buf[sctp.chunk_sack._GAPACK_LEN:] duptsns = [] for _ in range(self.duptsn_num): (duptsn, ) = struct.unpack_from( sctp.chunk_sack._DUPTSN_STR, buf) duptsns.append(duptsn) buf = buf[sctp.chunk_sack._DUPTSN_LEN:] self.assertEqual(self.gapacks, gapacks) self.assertEqual(self.duptsns, duptsns) def test_serialize_with_heartbeat(self): self.setUp_with_heartbeat() buf = self._test_serialize() res = struct.unpack_from(sctp.chunk_heartbeat._PACK_STR, buf) self.assertEqual(sctp.chunk_heartbeat.chunk_type(), res[0]) self.assertEqual(self.flags, res[1]) self.assertEqual(self.length, res[2]) buf = buf[sctp.chunk_heartbeat._MIN_LEN:] res1 = struct.unpack_from(sctp.param_heartbeat._PACK_STR, buf) self.assertEqual(sctp.param_heartbeat.param_type(), res1[0]) self.assertEqual(8, res1[1]) self.assertEqual(b'\x01\x02\x03\x04', buf[sctp.param_heartbeat._MIN_LEN: sctp.param_heartbeat._MIN_LEN + 4]) def test_serialize_with_heartbeat_ack(self): self.setUp_with_heartbeat_ack() buf = self._test_serialize() res = struct.unpack_from(sctp.chunk_heartbeat_ack._PACK_STR, buf) self.assertEqual(sctp.chunk_heartbeat_ack.chunk_type(), res[0]) self.assertEqual(self.flags, res[1]) self.assertEqual(self.length, res[2]) buf = buf[sctp.chunk_heartbeat_ack._MIN_LEN:] res1 = struct.unpack_from(sctp.param_heartbeat._PACK_STR, buf) self.assertEqual(sctp.param_heartbeat.param_type(), res1[0]) self.assertEqual(12, res1[1]) self.assertEqual(b'\xff\xee\xdd\xcc\xbb\xaa\x99\x88', buf[sctp.param_heartbeat._MIN_LEN: sctp.param_heartbeat._MIN_LEN + 8]) def test_serialize_with_abort(self): self.setUp_with_abort() buf = self._test_serialize() res = struct.unpack_from(sctp.chunk_abort._PACK_STR, buf) self.assertEqual(sctp.chunk_abort.chunk_type(), res[0]) flags = self.tflag << 0 self.assertEqual(flags, res[1]) self.assertEqual(self.length, res[2]) buf = buf[sctp.chunk_abort._MIN_LEN:] res1 = struct.unpack_from(sctp.cause_invalid_stream_id._PACK_STR, buf) self.assertEqual(sctp.cause_invalid_stream_id.cause_code(), res1[0]) self.assertEqual(8, res1[1]) self.assertEqual(4096, res1[2]) buf = buf[8:] res2 = struct.unpack_from(sctp.cause_missing_param._PACK_STR, buf) self.assertEqual(sctp.cause_missing_param.cause_code(), res2[0]) self.assertEqual(16, res2[1]) self.assertEqual(4, res2[2]) types = [] for count in range(4): (tmp, ) = struct.unpack_from( '!H', buf, sctp.cause_missing_param._MIN_LEN + 2 * count) types.append(tmp) self.assertEqual(str([sctp.PTYPE_IPV4, sctp.PTYPE_IPV6, sctp.PTYPE_COOKIE_PRESERVE, sctp.PTYPE_HOST_ADDR]), str(types)) buf = buf[16:] res3 = struct.unpack_from(sctp.cause_stale_cookie._PACK_STR, buf) self.assertEqual(sctp.cause_stale_cookie.cause_code(), res3[0]) self.assertEqual(8, res3[1]) self.assertEqual(b'\x00\x00\x13\x88', buf[sctp.cause_stale_cookie._MIN_LEN: sctp.cause_stale_cookie._MIN_LEN + 4]) buf = buf[8:] res4 = struct.unpack_from(sctp.cause_out_of_resource._PACK_STR, buf) self.assertEqual(sctp.cause_out_of_resource.cause_code(), res4[0]) self.assertEqual(4, res4[1]) buf = buf[4:] res5 = struct.unpack_from( sctp.cause_unresolvable_addr._PACK_STR, buf) self.assertEqual(sctp.cause_unresolvable_addr.cause_code(), res5[0]) self.assertEqual(20, res5[1]) self.assertEqual(b'\x00\x0b\x00\x0e\x74\x65\x73\x74' + b'\x20\x68\x6f\x73\x74\x00\x00\x00', buf[sctp.cause_unresolvable_addr._MIN_LEN: sctp.cause_unresolvable_addr._MIN_LEN + 16]) buf = buf[20:] res6 = struct.unpack_from( sctp.cause_unrecognized_chunk._PACK_STR, buf) self.assertEqual(sctp.cause_unrecognized_chunk.cause_code(), res6[0]) self.assertEqual(8, res6[1]) self.assertEqual(b'\xff\x00\x00\x04', buf[sctp.cause_unrecognized_chunk._MIN_LEN: sctp.cause_unrecognized_chunk._MIN_LEN + 4]) buf = buf[8:] res7 = struct.unpack_from(sctp.cause_invalid_param._PACK_STR, buf) self.assertEqual(sctp.cause_invalid_param.cause_code(), res7[0]) self.assertEqual(4, res7[1]) buf = buf[4:] res8 = struct.unpack_from( sctp.cause_unrecognized_param._PACK_STR, buf) self.assertEqual(sctp.cause_unrecognized_param.cause_code(), res8[0]) self.assertEqual(8, res8[1]) self.assertEqual(b'\xff\xff\x00\x04', buf[sctp.cause_unrecognized_param._MIN_LEN: sctp.cause_unrecognized_param._MIN_LEN + 4]) buf = buf[8:] res9 = struct.unpack_from(sctp.cause_no_userdata._PACK_STR, buf) self.assertEqual(sctp.cause_no_userdata.cause_code(), res9[0]) self.assertEqual(8, res9[1]) self.assertEqual(b'\x00\x01\xe2\x40', buf[sctp.cause_no_userdata._MIN_LEN: sctp.cause_no_userdata._MIN_LEN + 4]) buf = buf[8:] res10 = struct.unpack_from( sctp.cause_cookie_while_shutdown._PACK_STR, buf) self.assertEqual(sctp.cause_cookie_while_shutdown.cause_code(), res10[0]) self.assertEqual(4, res10[1]) buf = buf[4:] res11 = struct.unpack_from( sctp.cause_restart_with_new_addr._PACK_STR, buf) self.assertEqual(sctp.cause_restart_with_new_addr.cause_code(), res11[0]) self.assertEqual(12, res11[1]) self.assertEqual(b'\x00\x05\x00\x08\xc0\xa8\x01\x01', buf[sctp.cause_restart_with_new_addr._MIN_LEN: sctp.cause_restart_with_new_addr._MIN_LEN + 8]) buf = buf[12:] res12 = struct.unpack_from( sctp.cause_user_initiated_abort._PACK_STR, buf) self.assertEqual(sctp.cause_user_initiated_abort.cause_code(), res12[0]) self.assertEqual(19, res12[1]) self.assertEqual(b'Key Interrupt.\x00', buf[sctp.cause_user_initiated_abort._MIN_LEN: sctp.cause_user_initiated_abort._MIN_LEN + 15]) buf = buf[20:] res13 = struct.unpack_from( sctp.cause_protocol_violation._PACK_STR, buf) self.assertEqual(sctp.cause_protocol_violation.cause_code(), res13[0]) self.assertEqual(20, res13[1]) self.assertEqual(b'Unknown reason.\x00', buf[sctp.cause_protocol_violation._MIN_LEN: sctp.cause_protocol_violation._MIN_LEN + 16]) def test_serialize_with_shutdown(self): self.setUp_with_shutdown() buf = self._test_serialize() res = struct.unpack_from(sctp.chunk_shutdown._PACK_STR, buf) self.assertEqual(sctp.chunk_shutdown.chunk_type(), res[0]) self.assertEqual(self.flags, res[1]) self.assertEqual(self.length, res[2]) self.assertEqual(self.tsn_ack, res[3]) def test_serialize_with_shutdown_ack(self): self.setUp_with_shutdown_ack() buf = self._test_serialize() res = struct.unpack_from(sctp.chunk_shutdown_ack._PACK_STR, buf) self.assertEqual(sctp.chunk_shutdown_ack.chunk_type(), res[0]) self.assertEqual(self.flags, res[1]) self.assertEqual(self.length, res[2]) def test_serialize_with_error(self): self.setUp_with_error() buf = self._test_serialize() res = struct.unpack_from(sctp.chunk_error._PACK_STR, buf) self.assertEqual(sctp.chunk_error.chunk_type(), res[0]) self.assertEqual(self.flags, res[1]) self.assertEqual(self.length, res[2]) buf = buf[sctp.chunk_error._MIN_LEN:] res1 = struct.unpack_from(sctp.cause_invalid_stream_id._PACK_STR, buf) self.assertEqual(sctp.cause_invalid_stream_id.cause_code(), res1[0]) self.assertEqual(8, res1[1]) self.assertEqual(4096, res1[2]) buf = buf[8:] res2 = struct.unpack_from(sctp.cause_missing_param._PACK_STR, buf) self.assertEqual(sctp.cause_missing_param.cause_code(), res2[0]) self.assertEqual(16, res2[1]) self.assertEqual(4, res2[2]) types = [] for count in range(4): (tmp, ) = struct.unpack_from( '!H', buf, sctp.cause_missing_param._MIN_LEN + 2 * count) types.append(tmp) self.assertEqual(str([sctp.PTYPE_IPV4, sctp.PTYPE_IPV6, sctp.PTYPE_COOKIE_PRESERVE, sctp.PTYPE_HOST_ADDR]), str(types)) buf = buf[16:] res3 = struct.unpack_from(sctp.cause_stale_cookie._PACK_STR, buf) self.assertEqual(sctp.cause_stale_cookie.cause_code(), res3[0]) self.assertEqual(8, res3[1]) self.assertEqual(b'\x00\x00\x13\x88', buf[sctp.cause_stale_cookie._MIN_LEN: sctp.cause_stale_cookie._MIN_LEN + 4]) buf = buf[8:] res4 = struct.unpack_from(sctp.cause_out_of_resource._PACK_STR, buf) self.assertEqual(sctp.cause_out_of_resource.cause_code(), res4[0]) self.assertEqual(4, res4[1]) buf = buf[4:] res5 = struct.unpack_from( sctp.cause_unresolvable_addr._PACK_STR, buf) self.assertEqual(sctp.cause_unresolvable_addr.cause_code(), res5[0]) self.assertEqual(20, res5[1]) self.assertEqual(b'\x00\x0b\x00\x0e\x74\x65\x73\x74' + b'\x20\x68\x6f\x73\x74\x00\x00\x00', buf[sctp.cause_unresolvable_addr._MIN_LEN: sctp.cause_unresolvable_addr._MIN_LEN + 16]) buf = buf[20:] res6 = struct.unpack_from( sctp.cause_unrecognized_chunk._PACK_STR, buf) self.assertEqual(sctp.cause_unrecognized_chunk.cause_code(), res6[0]) self.assertEqual(8, res6[1]) self.assertEqual(b'\xff\x00\x00\x04', buf[sctp.cause_unrecognized_chunk._MIN_LEN: sctp.cause_unrecognized_chunk._MIN_LEN + 4]) buf = buf[8:] res7 = struct.unpack_from(sctp.cause_invalid_param._PACK_STR, buf) self.assertEqual(sctp.cause_invalid_param.cause_code(), res7[0]) self.assertEqual(4, res7[1]) buf = buf[4:] res8 = struct.unpack_from( sctp.cause_unrecognized_param._PACK_STR, buf) self.assertEqual(sctp.cause_unrecognized_param.cause_code(), res8[0]) self.assertEqual(8, res8[1]) self.assertEqual(b'\xff\xff\x00\x04', buf[sctp.cause_unrecognized_param._MIN_LEN: sctp.cause_unrecognized_param._MIN_LEN + 4]) buf = buf[8:] res9 = struct.unpack_from(sctp.cause_no_userdata._PACK_STR, buf) self.assertEqual(sctp.cause_no_userdata.cause_code(), res9[0]) self.assertEqual(8, res9[1]) self.assertEqual(b'\x00\x01\xe2\x40', buf[sctp.cause_no_userdata._MIN_LEN: sctp.cause_no_userdata._MIN_LEN + 4]) buf = buf[8:] res10 = struct.unpack_from( sctp.cause_cookie_while_shutdown._PACK_STR, buf) self.assertEqual(sctp.cause_cookie_while_shutdown.cause_code(), res10[0]) self.assertEqual(4, res10[1]) buf = buf[4:] res11 = struct.unpack_from( sctp.cause_restart_with_new_addr._PACK_STR, buf) self.assertEqual(sctp.cause_restart_with_new_addr.cause_code(), res11[0]) self.assertEqual(12, res11[1]) self.assertEqual(b'\x00\x05\x00\x08\xc0\xa8\x01\x01', buf[sctp.cause_restart_with_new_addr._MIN_LEN: sctp.cause_restart_with_new_addr._MIN_LEN + 8]) buf = buf[12:] res12 = struct.unpack_from( sctp.cause_user_initiated_abort._PACK_STR, buf) self.assertEqual(sctp.cause_user_initiated_abort.cause_code(), res12[0]) self.assertEqual(19, res12[1]) self.assertEqual(b'Key Interrupt.\x00', buf[sctp.cause_user_initiated_abort._MIN_LEN: sctp.cause_user_initiated_abort._MIN_LEN + 15]) buf = buf[20:] res13 = struct.unpack_from( sctp.cause_protocol_violation._PACK_STR, buf) self.assertEqual(sctp.cause_protocol_violation.cause_code(), res13[0]) self.assertEqual(20, res13[1]) self.assertEqual(b'Unknown reason.\x00', buf[sctp.cause_protocol_violation._MIN_LEN: sctp.cause_protocol_violation._MIN_LEN + 16]) def test_serialize_with_cookie_echo(self): self.setUp_with_cookie_echo() buf = self._test_serialize() res = struct.unpack_from(sctp.chunk_cookie_echo._PACK_STR, buf) self.assertEqual(sctp.chunk_cookie_echo.chunk_type(), res[0]) self.assertEqual(self.flags, res[1]) self.assertEqual(self.length, res[2]) self.assertEqual(self.cookie, buf[sctp.chunk_cookie_echo._MIN_LEN: sctp.chunk_cookie_echo._MIN_LEN + 4]) def test_serialize_with_cookie_ack(self): self.setUp_with_cookie_ack() buf = self._test_serialize() res = struct.unpack_from(sctp.chunk_cookie_ack._PACK_STR, buf) self.assertEqual(sctp.chunk_cookie_ack.chunk_type(), res[0]) self.assertEqual(self.flags, res[1]) self.assertEqual(self.length, res[2]) def test_serialize_with_ecn_echo(self): self.setUp_with_ecn_echo() buf = self._test_serialize() res = struct.unpack_from(sctp.chunk_ecn_echo._PACK_STR, buf) self.assertEqual(sctp.chunk_ecn_echo.chunk_type(), res[0]) self.assertEqual(self.flags, res[1]) self.assertEqual(self.length, res[2]) self.assertEqual(self.low_tsn, res[3]) def test_serialize_with_cwr(self): self.setUp_with_cwr() buf = self._test_serialize() res = struct.unpack_from(sctp.chunk_cwr._PACK_STR, buf) self.assertEqual(sctp.chunk_cwr.chunk_type(), res[0]) self.assertEqual(self.flags, res[1]) self.assertEqual(self.length, res[2]) self.assertEqual(self.low_tsn, res[3]) def test_serialize_with_shutdown_complete(self): self.setUp_with_shutdown_complete() buf = self._test_serialize() res = struct.unpack_from( sctp.chunk_shutdown_complete._PACK_STR, buf) self.assertEqual(sctp.chunk_shutdown_complete.chunk_type(), res[0]) flags = self.tflag << 0 self.assertEqual(flags, res[1]) self.assertEqual(self.length, res[2]) def test_serialize_with_multi_chunks(self): self.setUp_with_multi_chunks() buf = self._test_serialize() res = struct.unpack_from(sctp.chunk_sack._PACK_STR, buf) self.assertEqual(sctp.chunk_sack.chunk_type(), res[0]) self.assertEqual(self.s_flags, res[1]) self.assertEqual(self.s_length, res[2]) self.assertEqual(self.s_tsn_ack, res[3]) self.assertEqual(self.s_a_rwnd, res[4]) self.assertEqual(self.s_gapack_num, res[5]) self.assertEqual(self.s_duptsn_num, res[6]) buf = buf[self.s_length:] res = struct.unpack_from(sctp.chunk_data._PACK_STR, buf) self.assertEqual(sctp.chunk_data.chunk_type(), res[0]) d1_flags = ( (self.d1_unordered << 2) | (self.d1_begin << 1) | (self.d1_end << 0)) self.assertEqual(d1_flags, res[1]) self.assertEqual(self.d1_length, res[2]) self.assertEqual(self.d1_tsn, res[3]) self.assertEqual(self.d1_sid, res[4]) self.assertEqual(self.d1_seq, res[5]) self.assertEqual(self.d1_payload_id, res[6]) self.assertEqual(self.d1_payload_data, buf[sctp.chunk_data._MIN_LEN: sctp.chunk_data._MIN_LEN + 10]) buf = buf[self.d1_length:] res = struct.unpack_from(sctp.chunk_data._PACK_STR, buf) self.assertEqual(sctp.chunk_data.chunk_type(), res[0]) d2_flags = ( (self.d2_unordered << 2) | (self.d2_begin << 1) | (self.d2_end << 0)) self.assertEqual(d2_flags, res[1]) self.assertEqual(self.d2_length, res[2]) self.assertEqual(self.d2_tsn, res[3]) self.assertEqual(self.d2_sid, res[4]) self.assertEqual(self.d2_seq, res[5]) self.assertEqual(self.d2_payload_id, res[6]) self.assertEqual(self.d2_payload_data, buf[sctp.chunk_data._MIN_LEN: sctp.chunk_data._MIN_LEN + 10]) def test_build_sctp(self): eth = ethernet.ethernet('00:aa:aa:aa:aa:aa', '00:bb:bb:bb:bb:bb', ether.ETH_TYPE_IP) ip4 = ipv4.ipv4(4, 5, 16, 0, 0, 2, 0, 64, inet.IPPROTO_SCTP, 0, '192.168.1.1', '10.144.1.1') pkt = eth / ip4 / self.sc eth = pkt.get_protocol(ethernet.ethernet) self.assertTrue(eth) self.assertEqual(eth.ethertype, ether.ETH_TYPE_IP) ip4 = pkt.get_protocol(ipv4.ipv4) self.assertTrue(ip4) self.assertEqual(ip4.proto, inet.IPPROTO_SCTP) sc = pkt.get_protocol(sctp.sctp) self.assertTrue(sc) self.assertEqual(sc, self.sc) def test_build_sctp_with_data(self): self.setUp_with_data() self.test_build_sctp() def test_build_sctp_with_init(self): self.setUp_with_init() self.test_build_sctp() def test_build_sctp_with_init_ack(self): self.setUp_with_init_ack() self.test_build_sctp() def test_build_sctp_with_sack(self): self.setUp_with_sack() self.test_build_sctp() def test_build_sctp_with_heartbeat(self): self.setUp_with_heartbeat() self.test_build_sctp() def test_build_sctp_with_heartbeat_ack(self): self.setUp_with_heartbeat_ack() self.test_build_sctp() def test_build_sctp_with_abort(self): self.setUp_with_abort() self.test_build_sctp() def test_build_sctp_with_shutdown(self): self.setUp_with_shutdown() self.test_build_sctp() def test_build_sctp_with_shutdown_ack(self): self.setUp_with_shutdown_ack() self.test_build_sctp() def test_build_sctp_with_error(self): self.setUp_with_error() self.test_build_sctp() def test_build_sctp_with_cookie_echo(self): self.setUp_with_cookie_echo() self.test_build_sctp() def test_build_sctp_with_cookie_ack(self): self.setUp_with_cookie_ack() self.test_build_sctp() def test_build_sctp_with_ecn_echo(self): self.setUp_with_ecn_echo() self.test_build_sctp() def test_build_sctp_with_cwr(self): self.setUp_with_cwr() self.test_build_sctp() def test_build_sctp_with_shutdown_complete(self): self.setUp_with_shutdown_complete() self.test_build_sctp() def tset_build_sctp_with_multi_chunks(self): self.setUp_with_multi_chunks() self.test_build_sctp() def test_to_string(self): sctp_values = {'src_port': self.src_port, 'dst_port': self.dst_port, 'vtag': self.vtag, 'csum': self.csum, 'chunks': self.chunks} _sctp_str = ','.join(['%s=%s' % (k, sctp_values[k]) for k, _ in inspect.getmembers(self.sc) if k in sctp_values]) sctp_str = '%s(%s)' % (sctp.sctp.__name__, _sctp_str) self.assertEqual(str(self.sc), sctp_str) self.assertEqual(repr(self.sc), sctp_str) def test_to_string_with_data(self): self.setUp_with_data() self.test_to_string() def test_to_string_with_init(self): self.setUp_with_init() self.test_to_string() def test_to_string_with_init_ack(self): self.setUp_with_init_ack() self.test_to_string() def test_to_string_with_sack(self): self.setUp_with_sack() self.test_to_string() def test_to_string_with_heartbeat(self): self.setUp_with_heartbeat() self.test_to_string() def test_to_string_with_heartbeat_ack(self): self.setUp_with_heartbeat_ack() self.test_to_string() def test_to_string_with_abort(self): self.setUp_with_abort() self.test_to_string() def test_to_string_with_shutdown(self): self.setUp_with_shutdown() self.test_to_string() def test_to_string_with_shutdown_ack(self): self.setUp_with_shutdown_ack() self.test_to_string() def test_to_string_with_error(self): self.setUp_with_error() self.test_to_string() def test_to_string_with_cookie_echo(self): self.setUp_with_cookie_echo() self.test_to_string() def test_to_string_with_cookie_ack(self): self.setUp_with_cookie_ack() self.test_to_string() def test_to_string_with_ecn_echo(self): self.setUp_with_ecn_echo() self.test_to_string() def test_to_string_with_cwr(self): self.setUp_with_cwr() self.test_to_string() def test_to_string_with_shutdown_complete(self): self.setUp_with_shutdown_complete() self.test_to_string() def test_to_string_with_multi_chunks(self): self.setUp_with_multi_chunks() self.test_to_string() def test_json(self): jsondict = self.sc.to_jsondict() sc = sctp.sctp.from_jsondict(jsondict['sctp']) self.assertEqual(str(self.sc), str(sc)) def test_json_with_data(self): self.setUp_with_data() self.test_json() def test_json_with_init(self): self.setUp_with_init() self.test_json() def test_json_with_init_ack(self): self.setUp_with_init_ack() self.test_json() def test_json_with_sack(self): self.setUp_with_sack() self.test_json() def test_json_with_heartbeat(self): self.setUp_with_heartbeat() self.test_json() def test_json_with_heartbeat_ack(self): self.setUp_with_heartbeat_ack() self.test_json() def test_json_with_abort(self): self.setUp_with_abort() self.test_json() def test_json_with_shutdown(self): self.setUp_with_shutdown() self.test_json() def test_json_with_shutdown_ack(self): self.setUp_with_shutdown_ack() self.test_json() def test_json_with_error(self): self.setUp_with_error() self.test_json() def test_json_with_cookie_echo(self): self.setUp_with_cookie_echo() self.test_json() def test_json_with_cookie_ack(self): self.setUp_with_cookie_ack() self.test_json() def test_json_with_ecn_echo(self): self.setUp_with_ecn_echo() self.test_json() def test_json_with_cwr(self): self.setUp_with_cwr() self.test_json() def test_json_with_shutdown_complete(self): self.setUp_with_shutdown_complete() self.test_json() def test_json_with_multi_chunks(self): self.setUp_with_multi_chunks() self.test_json() ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/packet/test_slow.py0000664000175000017500000014761700000000000022274 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone 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. # vim: tabstop=4 shiftwidth=4 softtabstop=4 import copy import logging from struct import pack, unpack_from import unittest from os_ken.ofproto import ether from os_ken.lib.packet.ethernet import ethernet from os_ken.lib.packet.packet import Packet from os_ken.lib import addrconv from os_ken.lib.packet.slow import slow, lacp from os_ken.lib.packet.slow import SLOW_PROTOCOL_MULTICAST from os_ken.lib.packet.slow import SLOW_SUBTYPE_LACP from os_ken.lib.packet.slow import SLOW_SUBTYPE_MARKER LOG = logging.getLogger(__name__) class Test_slow(unittest.TestCase): """ Test case for Slow Protocol """ def setUp(self): self.subtype = SLOW_SUBTYPE_LACP self.version = lacp.LACP_VERSION_NUMBER self.actor_tag = lacp.LACP_TLV_TYPE_ACTOR self.actor_length = 20 self.actor_system_priority = 65534 self.actor_system = '00:07:0d:af:f4:54' self.actor_key = 1 self.actor_port_priority = 65535 self.actor_port = 1 self.actor_state_activity = lacp.LACP_STATE_ACTIVE self.actor_state_timeout = lacp.LACP_STATE_LONG_TIMEOUT self.actor_state_aggregation = lacp.LACP_STATE_AGGREGATEABLE self.actor_state_synchronization = lacp.LACP_STATE_IN_SYNC self.actor_state_collecting = lacp.LACP_STATE_COLLECTING_ENABLED self.actor_state_distributing = lacp.LACP_STATE_DISTRIBUTING_ENABLED self.actor_state_defaulted = lacp.LACP_STATE_OPERATIONAL_PARTNER self.actor_state_expired = lacp.LACP_STATE_EXPIRED self.actor_state = ( (self.actor_state_activity << 0) | (self.actor_state_timeout << 1) | (self.actor_state_aggregation << 2) | (self.actor_state_synchronization << 3) | (self.actor_state_collecting << 4) | (self.actor_state_distributing << 5) | (self.actor_state_defaulted << 6) | (self.actor_state_expired << 7)) self.partner_tag = lacp.LACP_TLV_TYPE_PARTNER self.partner_length = 20 self.partner_system_priority = 0 self.partner_system = '00:00:00:00:00:00' self.partner_key = 0 self.partner_port_priority = 0 self.partner_port = 0 self.partner_state_activity = 0 self.partner_state_timeout = lacp.LACP_STATE_SHORT_TIMEOUT self.partner_state_aggregation = 0 self.partner_state_synchronization = 0 self.partner_state_collecting = 0 self.partner_state_distributing = 0 self.partner_state_defaulted = 0 self.partner_state_expired = 0 self.partner_state = ( (self.partner_state_activity << 0) | (self.partner_state_timeout << 1) | (self.partner_state_aggregation << 2) | (self.partner_state_synchronization << 3) | (self.partner_state_collecting << 4) | (self.partner_state_distributing << 5) | (self.partner_state_defaulted << 6) | (self.partner_state_expired << 7)) self.collector_tag = lacp.LACP_TLV_TYPE_COLLECTOR self.collector_length = 16 self.collector_max_delay = 0 self.terminator_tag = lacp.LACP_TLV_TYPE_TERMINATOR self.terminator_length = 0 self.head_fmt = lacp._HLEN_PACK_STR self.head_len = lacp._HLEN_PACK_LEN self.act_fmt = lacp._ACTPRT_INFO_PACK_STR self.act_len = lacp._ACTPRT_INFO_PACK_LEN self.prt_fmt = lacp._ACTPRT_INFO_PACK_STR self.prt_len = lacp._ACTPRT_INFO_PACK_LEN self.col_fmt = lacp._COL_INFO_PACK_STR self.col_len = lacp._COL_INFO_PACK_LEN self.trm_fmt = lacp._TRM_PACK_STR self.trm_len = lacp._TRM_PACK_LEN self.length = lacp._ALL_PACK_LEN self.head_buf = pack(self.head_fmt, self.subtype, self.version) self.act_buf = pack(self.act_fmt, self.actor_tag, self.actor_length, self.actor_system_priority, addrconv.mac.text_to_bin(self.actor_system), self.actor_key, self.actor_port_priority, self.actor_port, self.actor_state) self.prt_buf = pack(self.prt_fmt, self.partner_tag, self.partner_length, self.partner_system_priority, addrconv.mac.text_to_bin(self.partner_system), self.partner_key, self.partner_port_priority, self.partner_port, self.partner_state) self.col_buf = pack(self.col_fmt, self.collector_tag, self.collector_length, self.collector_max_delay) self.trm_buf = pack(self.trm_fmt, self.terminator_tag, self.terminator_length) self.buf = self.head_buf + self.act_buf + self.prt_buf + \ self.col_buf + self.trm_buf def tearDown(self): pass def test_parser(self): slow.parser(self.buf) def test_not_implemented_subtype(self): not_implemented_buf = pack( slow._PACK_STR, SLOW_SUBTYPE_MARKER) + self.buf[1:] (instance, nexttype, last) = slow.parser(not_implemented_buf) assert instance is None assert nexttype is None assert last is not None def test_invalid_subtype(self): invalid_buf = b'\xff' + self.buf[1:] (instance, nexttype, last) = slow.parser(invalid_buf) assert instance is None assert nexttype is None assert last is not None class Test_lacp(unittest.TestCase): """ Test case for lacp """ def setUp(self): self.subtype = SLOW_SUBTYPE_LACP self.version = lacp.LACP_VERSION_NUMBER self.actor_tag = lacp.LACP_TLV_TYPE_ACTOR self.actor_length = 20 self.actor_system_priority = 65534 self.actor_system = '00:07:0d:af:f4:54' self.actor_key = 1 self.actor_port_priority = 65535 self.actor_port = 1 self.actor_state_activity = lacp.LACP_STATE_ACTIVE self.actor_state_timeout = lacp.LACP_STATE_LONG_TIMEOUT self.actor_state_aggregation = lacp.LACP_STATE_AGGREGATEABLE self.actor_state_synchronization = lacp.LACP_STATE_IN_SYNC self.actor_state_collecting = lacp.LACP_STATE_COLLECTING_ENABLED self.actor_state_distributing = lacp.LACP_STATE_DISTRIBUTING_ENABLED self.actor_state_defaulted = lacp.LACP_STATE_OPERATIONAL_PARTNER self.actor_state_expired = lacp.LACP_STATE_EXPIRED self.actor_state = ( (self.actor_state_activity << 0) | (self.actor_state_timeout << 1) | (self.actor_state_aggregation << 2) | (self.actor_state_synchronization << 3) | (self.actor_state_collecting << 4) | (self.actor_state_distributing << 5) | (self.actor_state_defaulted << 6) | (self.actor_state_expired << 7)) self.partner_tag = lacp.LACP_TLV_TYPE_PARTNER self.partner_length = 20 self.partner_system_priority = 0 self.partner_system = '00:00:00:00:00:00' self.partner_key = 0 self.partner_port_priority = 0 self.partner_port = 0 self.partner_state_activity = 0 self.partner_state_timeout = lacp.LACP_STATE_SHORT_TIMEOUT self.partner_state_aggregation = 0 self.partner_state_synchronization = 0 self.partner_state_collecting = 0 self.partner_state_distributing = 0 self.partner_state_defaulted = 0 self.partner_state_expired = 0 self.partner_state = ( (self.partner_state_activity << 0) | (self.partner_state_timeout << 1) | (self.partner_state_aggregation << 2) | (self.partner_state_synchronization << 3) | (self.partner_state_collecting << 4) | (self.partner_state_distributing << 5) | (self.partner_state_defaulted << 6) | (self.partner_state_expired << 7)) self.collector_tag = lacp.LACP_TLV_TYPE_COLLECTOR self.collector_length = 16 self.collector_max_delay = 0 self.terminator_tag = lacp.LACP_TLV_TYPE_TERMINATOR self.terminator_length = 0 self.head_fmt = lacp._HLEN_PACK_STR self.head_len = lacp._HLEN_PACK_LEN self.act_fmt = lacp._ACTPRT_INFO_PACK_STR self.act_len = lacp._ACTPRT_INFO_PACK_LEN self.prt_fmt = lacp._ACTPRT_INFO_PACK_STR self.prt_len = lacp._ACTPRT_INFO_PACK_LEN self.col_fmt = lacp._COL_INFO_PACK_STR self.col_len = lacp._COL_INFO_PACK_LEN self.trm_fmt = lacp._TRM_PACK_STR self.trm_len = lacp._TRM_PACK_LEN self.length = lacp._ALL_PACK_LEN self.head_buf = pack(self.head_fmt, self.subtype, self.version) self.act_buf = pack(self.act_fmt, self.actor_tag, self.actor_length, self.actor_system_priority, addrconv.mac.text_to_bin(self.actor_system), self.actor_key, self.actor_port_priority, self.actor_port, self.actor_state) self.prt_buf = pack(self.prt_fmt, self.partner_tag, self.partner_length, self.partner_system_priority, addrconv.mac.text_to_bin(self.partner_system), self.partner_key, self.partner_port_priority, self.partner_port, self.partner_state) self.col_buf = pack(self.col_fmt, self.collector_tag, self.collector_length, self.collector_max_delay) self.trm_buf = pack(self.trm_fmt, self.terminator_tag, self.terminator_length) self.buf = self.head_buf + self.act_buf + self.prt_buf + \ self.col_buf + self.trm_buf self.l = lacp(self.version, self.actor_system_priority, self.actor_system, self.actor_key, self.actor_port_priority, self.actor_port, self.actor_state_activity, self.actor_state_timeout, self.actor_state_aggregation, self.actor_state_synchronization, self.actor_state_collecting, self.actor_state_distributing, self.actor_state_defaulted, self.actor_state_expired, self.partner_system_priority, self.partner_system, self.partner_key, self.partner_port_priority, self.partner_port, self.partner_state_activity, self.partner_state_timeout, self.partner_state_aggregation, self.partner_state_synchronization, self.partner_state_collecting, self.partner_state_distributing, self.partner_state_defaulted, self.partner_state_expired, self.collector_max_delay) def tearDown(self): pass def find_protocol(self, pkt, name): for p in pkt.protocols: if p.protocol_name == name: return p def test_init(self): self.assertEqual(self.subtype, self.l._subtype) self.assertEqual(self.version, self.l.version) self.assertEqual(self.actor_tag, self.l._actor_tag) self.assertEqual(self.actor_length, self.l._actor_length) self.assertEqual(self.actor_system_priority, self.l.actor_system_priority) self.assertEqual(self.actor_system, self.l.actor_system) self.assertEqual(self.actor_key, self.l.actor_key) self.assertEqual(self.actor_port_priority, self.l.actor_port_priority) self.assertEqual(self.actor_port, self.l.actor_port) self.assertEqual(self.actor_state_activity, self.l.actor_state_activity) self.assertEqual(self.actor_state_timeout, self.l.actor_state_timeout) self.assertEqual(self.actor_state_aggregation, self.l.actor_state_aggregation) self.assertEqual(self.actor_state_synchronization, self.l.actor_state_synchronization) self.assertEqual(self.actor_state_collecting, self.l.actor_state_collecting) self.assertEqual(self.actor_state_distributing, self.l.actor_state_distributing) self.assertEqual(self.actor_state_defaulted, self.l.actor_state_defaulted) self.assertEqual(self.actor_state_expired, self.l.actor_state_expired) self.assertEqual(self.actor_state, self.l._actor_state) self.assertEqual(self.partner_tag, self.l._partner_tag) self.assertEqual(self.partner_length, self.l._partner_length) self.assertEqual(self.partner_system_priority, self.l.partner_system_priority) self.assertEqual(self.partner_system, self.l.partner_system) self.assertEqual(self.partner_key, self.l.partner_key) self.assertEqual(self.partner_port_priority, self.l.partner_port_priority) self.assertEqual(self.partner_port, self.l.partner_port) self.assertEqual(self.partner_state_activity, self.l.partner_state_activity) self.assertEqual(self.partner_state_timeout, self.l.partner_state_timeout) self.assertEqual(self.partner_state_aggregation, self.l.partner_state_aggregation) self.assertEqual(self.partner_state_synchronization, self.l.partner_state_synchronization) self.assertEqual(self.partner_state_collecting, self.l.partner_state_collecting) self.assertEqual(self.partner_state_distributing, self.l.partner_state_distributing) self.assertEqual(self.partner_state_defaulted, self.l.partner_state_defaulted) self.assertEqual(self.partner_state_expired, self.l.partner_state_expired) self.assertEqual(self.partner_state, self.l._partner_state) self.assertEqual(self.collector_tag, self.l._collector_tag) self.assertEqual(self.collector_length, self.l._collector_length) self.assertEqual(self.collector_max_delay, self.l.collector_max_delay) self.assertEqual(self.terminator_tag, self.l._terminator_tag) self.assertEqual(self.terminator_length, self.l._terminator_length) def test_parser(self): _res = self.l.parser(self.buf) if type(_res) is tuple: res = _res[0] else: res = _res self.assertEqual(res._subtype, self.subtype) self.assertEqual(res.version, self.version) self.assertEqual(res._actor_tag, self.actor_tag) self.assertEqual(res._actor_length, self.actor_length) self.assertEqual(res.actor_system_priority, self.actor_system_priority) self.assertEqual(res.actor_system, self.actor_system) self.assertEqual(res.actor_key, self.actor_key) self.assertEqual(res.actor_port_priority, self.actor_port_priority) self.assertEqual(res.actor_port, self.actor_port) self.assertEqual(res.actor_state_activity, self.actor_state_activity) self.assertEqual(res.actor_state_timeout, self.actor_state_timeout) self.assertEqual(res.actor_state_aggregation, self.actor_state_aggregation) self.assertEqual(res.actor_state_synchronization, self.actor_state_synchronization) self.assertEqual(res.actor_state_collecting, self.actor_state_collecting) self.assertEqual(res.actor_state_distributing, self.actor_state_distributing) self.assertEqual(res.actor_state_defaulted, self.actor_state_defaulted) self.assertEqual(res.actor_state_expired, self.actor_state_expired) self.assertEqual(res._actor_state, self.actor_state) self.assertEqual(res._partner_tag, self.partner_tag) self.assertEqual(res._partner_length, self.partner_length) self.assertEqual(res.partner_system_priority, self.partner_system_priority) self.assertEqual(res.partner_system, self.partner_system) self.assertEqual(res.partner_key, self.partner_key) self.assertEqual(res.partner_port_priority, self.partner_port_priority) self.assertEqual(res.partner_port, self.partner_port) self.assertEqual(res.partner_state_activity, self.partner_state_activity) self.assertEqual(res.partner_state_timeout, self.partner_state_timeout) self.assertEqual(res.partner_state_aggregation, self.partner_state_aggregation) self.assertEqual(res.partner_state_synchronization, self.partner_state_synchronization) self.assertEqual(res.partner_state_collecting, self.partner_state_collecting) self.assertEqual(res.partner_state_distributing, self.partner_state_distributing) self.assertEqual(res.partner_state_defaulted, self.partner_state_defaulted) self.assertEqual(res.partner_state_expired, self.partner_state_expired) self.assertEqual(res._partner_state, self.partner_state) self.assertEqual(res._collector_tag, self.collector_tag) self.assertEqual(res._collector_length, self.collector_length) self.assertEqual(res.collector_max_delay, self.collector_max_delay) self.assertEqual(res._terminator_tag, self.terminator_tag) self.assertEqual(res._terminator_length, self.terminator_length) def test_serialize(self): data = bytearray() prev = None buf = self.l.serialize(data, prev) offset = 0 head_res = unpack_from(self.head_fmt, buf, offset) offset += self.head_len act_res = unpack_from(self.act_fmt, buf, offset) offset += self.act_len prt_res = unpack_from(self.prt_fmt, buf, offset) offset += self.prt_len col_res = unpack_from(self.col_fmt, buf, offset) offset += self.col_len trm_res = unpack_from(self.trm_fmt, buf, offset) self.assertEqual(head_res[0], self.subtype) self.assertEqual(head_res[1], self.version) self.assertEqual(act_res[0], self.actor_tag) self.assertEqual(act_res[1], self.actor_length) self.assertEqual(act_res[2], self.actor_system_priority) self.assertEqual(act_res[3], addrconv.mac.text_to_bin(self.actor_system)) self.assertEqual(act_res[4], self.actor_key) self.assertEqual(act_res[5], self.actor_port_priority) self.assertEqual(act_res[6], self.actor_port) self.assertEqual(act_res[7], self.actor_state) self.assertEqual(prt_res[0], self.partner_tag) self.assertEqual(prt_res[1], self.partner_length) self.assertEqual(prt_res[2], self.partner_system_priority) self.assertEqual(prt_res[3], addrconv.mac.text_to_bin(self.partner_system)) self.assertEqual(prt_res[4], self.partner_key) self.assertEqual(prt_res[5], self.partner_port_priority) self.assertEqual(prt_res[6], self.partner_port) self.assertEqual(prt_res[7], self.partner_state) self.assertEqual(col_res[0], self.collector_tag) self.assertEqual(col_res[1], self.collector_length) self.assertEqual(col_res[2], self.collector_max_delay) self.assertEqual(trm_res[0], self.terminator_tag) self.assertEqual(trm_res[1], self.terminator_length) def _build_lacp(self): ethertype = ether.ETH_TYPE_SLOW dst = SLOW_PROTOCOL_MULTICAST e = ethernet(dst, self.actor_system, ethertype) p = Packet() p.add_protocol(e) p.add_protocol(self.l) p.serialize() return p def test_build_lacp(self): p = self._build_lacp() e = self.find_protocol(p, "ethernet") self.assertTrue(e) self.assertEqual(e.ethertype, ether.ETH_TYPE_SLOW) l = self.find_protocol(p, "lacp") self.assertTrue(l) self.assertEqual(l._subtype, self.subtype) self.assertEqual(l.version, self.version) self.assertEqual(l._actor_tag, self.actor_tag) self.assertEqual(l._actor_length, self.actor_length) self.assertEqual(l.actor_system_priority, self.actor_system_priority) self.assertEqual(l.actor_system, self.actor_system) self.assertEqual(l.actor_key, self.actor_key) self.assertEqual(l.actor_port_priority, self.actor_port_priority) self.assertEqual(l.actor_port, self.actor_port) self.assertEqual(l.actor_state_activity, self.actor_state_activity) self.assertEqual(l.actor_state_timeout, self.actor_state_timeout) self.assertEqual(l.actor_state_aggregation, self.actor_state_aggregation) self.assertEqual(l.actor_state_synchronization, self.actor_state_synchronization) self.assertEqual(l.actor_state_collecting, self.actor_state_collecting) self.assertEqual(l.actor_state_distributing, self.actor_state_distributing) self.assertEqual(l.actor_state_defaulted, self.actor_state_defaulted) self.assertEqual(l.actor_state_expired, self.actor_state_expired) self.assertEqual(l._actor_state, self.actor_state) self.assertEqual(l._partner_tag, self.partner_tag) self.assertEqual(l._partner_length, self.partner_length) self.assertEqual(l.partner_system_priority, self.partner_system_priority) self.assertEqual(l.partner_system, self.partner_system) self.assertEqual(l.partner_key, self.partner_key) self.assertEqual(l.partner_port_priority, self.partner_port_priority) self.assertEqual(l.partner_port, self.partner_port) self.assertEqual(l.partner_state_activity, self.partner_state_activity) self.assertEqual(l.partner_state_timeout, self.partner_state_timeout) self.assertEqual(l.partner_state_aggregation, self.partner_state_aggregation) self.assertEqual(l.partner_state_synchronization, self.partner_state_synchronization) self.assertEqual(l.partner_state_collecting, self.partner_state_collecting) self.assertEqual(l.partner_state_distributing, self.partner_state_distributing) self.assertEqual(l.partner_state_defaulted, self.partner_state_defaulted) self.assertEqual(l.partner_state_expired, self.partner_state_expired) self.assertEqual(l._partner_state, self.partner_state) self.assertEqual(l._collector_tag, self.collector_tag) self.assertEqual(l._collector_length, self.collector_length) self.assertEqual(l.collector_max_delay, self.collector_max_delay) self.assertEqual(l._terminator_tag, self.terminator_tag) self.assertEqual(l._terminator_length, self.terminator_length) def test_malformed_lacp(self): m_short_buf = self.buf[1:self.length] self.assertRaises(Exception, slow.parser, m_short_buf) def test_invalid_subtype(self): self.skipTest('This test needs to be refactored: "serialize" method ' 'requires two input parameters that are not provided ' 'here.') invalid_lacv = copy.deepcopy(self.l) invalid_lacv.subtype = 0xff invalid_buf = invalid_lacv.serialize() slow.parser(invalid_buf) def test_invalid_version(self): self.skipTest('This test needs to be refactored: "serialize" method ' 'requires two input parameters that are not provided ' 'here.') invalid_lacv = copy.deepcopy(self.l) invalid_lacv.version = 0xff invalid_buf = invalid_lacv.serialize() slow.parser(invalid_buf) def test_invalid_actor_tag(self): self.skipTest('This test needs to be refactored: "serialize" method ' 'requires two input parameters that are not provided ' 'here.') invalid_lacv = copy.deepcopy(self.l) invalid_lacv.actor_tag = 0x04 invalid_buf = invalid_lacv.serialize() slow.parser(invalid_buf) def test_invalid_actor_length(self): self.skipTest('This test needs to be refactored: "serialize" method ' 'requires two input parameters that are not provided ' 'here.') invalid_lacv = copy.deepcopy(self.l) invalid_lacv.actor_length = 50 invalid_buf = invalid_lacv.serialize() slow.parser(invalid_buf) def test_invalid_partner_tag(self): self.skipTest('This test needs to be refactored: "serialize" method ' 'requires two input parameters that are not provided ' 'here.') invalid_lacv = copy.deepcopy(self.l) invalid_lacv.partner_tag = 0x01 invalid_buf = invalid_lacv.serialize() slow.parser(invalid_buf) def test_invalid_partner_length(self): self.skipTest('This test needs to be refactored: "serialize" method ' 'requires two input parameters that are not provided ' 'here.') invalid_lacv = copy.deepcopy(self.l) invalid_lacv.partner_length = 0 invalid_buf = invalid_lacv.serialize() slow.parser(invalid_buf) def test_invalid_collector_tag(self): self.skipTest('This test needs to be refactored: "serialize" method ' 'requires two input parameters that are not provided ' 'here.') invalid_lacv = copy.deepcopy(self.l) invalid_lacv.collector_tag = 0x00 invalid_buf = invalid_lacv.serialize() slow.parser(invalid_buf) def test_invalid_collector_length(self): self.skipTest('This test needs to be refactored: "serialize" method ' 'requires two input parameters that are not provided ' 'here.') invalid_lacv = copy.deepcopy(self.l) invalid_lacv.collector_length = 20 invalid_buf = invalid_lacv.serialize() slow.parser(invalid_buf) def test_invalid_terminator_tag(self): self.skipTest('This test needs to be refactored: "serialize" method ' 'requires two input parameters that are not provided ' 'here.') invalid_lacv = copy.deepcopy(self.l) invalid_lacv.terminator_tag = 0x04 invalid_buf = invalid_lacv.serialize() slow.parser(invalid_buf) def test_invalid_terminator_length(self): self.skipTest('This test needs to be refactored: "serialize" method ' 'requires two input parameters that are not provided ' 'here.') invalid_lacv = copy.deepcopy(self.l) invalid_lacv.terminator_length = self.trm_len invalid_buf = invalid_lacv.serialize() slow.parser(invalid_buf) def test_invalid_actor_state_activity(self): self.assertRaises(AssertionError, lacp, self.version, self.actor_system_priority, self.actor_system, self.actor_key, self.actor_port_priority, self.actor_port, 2, self.actor_state_timeout, self.actor_state_aggregation, self.actor_state_synchronization, self.actor_state_collecting, self.actor_state_distributing, self.actor_state_defaulted, self.actor_state_expired, self.partner_system_priority, self.partner_system, self.partner_key, self.partner_port_priority, self.partner_port, self.partner_state_activity, self.partner_state_timeout, self.partner_state_aggregation, self.partner_state_synchronization, self.partner_state_collecting, self.partner_state_distributing, self.partner_state_defaulted, self.partner_state_expired, self.collector_max_delay) def test_invalid_actor_state_timeout(self): self.assertRaises(AssertionError, lacp, self.version, self.actor_system_priority, self.actor_system, self.actor_key, self.actor_port_priority, self.actor_port, self.actor_state_activity, 2, self.actor_state_aggregation, self.actor_state_synchronization, self.actor_state_collecting, self.actor_state_distributing, self.actor_state_defaulted, self.actor_state_expired, self.partner_system_priority, self.partner_system, self.partner_key, self.partner_port_priority, self.partner_port, self.partner_state_activity, self.partner_state_timeout, self.partner_state_aggregation, self.partner_state_synchronization, self.partner_state_collecting, self.partner_state_distributing, self.partner_state_defaulted, self.partner_state_expired, self.collector_max_delay) def test_invalid_actor_state_aggregation(self): self.assertRaises(AssertionError, lacp, self.version, self.actor_system_priority, self.actor_system, self.actor_key, self.actor_port_priority, self.actor_port, self.actor_state_activity, self.actor_state_timeout, 2, self.actor_state_synchronization, self.actor_state_collecting, self.actor_state_distributing, self.actor_state_defaulted, self.actor_state_expired, self.partner_system_priority, self.partner_system, self.partner_key, self.partner_port_priority, self.partner_port, self.partner_state_activity, self.partner_state_timeout, self.partner_state_aggregation, self.partner_state_synchronization, self.partner_state_collecting, self.partner_state_distributing, self.partner_state_defaulted, self.partner_state_expired, self.collector_max_delay) def test_invalid_actor_state_synchronization(self): self.assertRaises(AssertionError, lacp, self.actor_system_priority, self.actor_system, self.actor_key, self.actor_port_priority, self.actor_port, self.actor_state_activity, self.actor_state_timeout, self.actor_state_aggregation, 2, self.actor_state_collecting, self.actor_state_distributing, self.actor_state_defaulted, self.actor_state_expired, self.partner_system_priority, self.partner_system, self.partner_key, self.partner_port_priority, self.partner_port, self.partner_state_activity, self.partner_state_timeout, self.partner_state_aggregation, self.partner_state_synchronization, self.partner_state_collecting, self.partner_state_distributing, self.partner_state_defaulted, self.partner_state_expired, self.collector_max_delay) def test_invalid_actor_state_collecting(self): self.assertRaises(AssertionError, lacp, self.version, self.actor_system_priority, self.actor_system, self.actor_key, self.actor_port_priority, self.actor_port, self.actor_state_activity, self.actor_state_timeout, self.actor_state_aggregation, self.actor_state_synchronization, 2, self.actor_state_distributing, self.actor_state_defaulted, self.actor_state_expired, self.partner_system_priority, self.partner_system, self.partner_key, self.partner_port_priority, self.partner_port, self.partner_state_activity, self.partner_state_timeout, self.partner_state_aggregation, self.partner_state_synchronization, self.partner_state_collecting, self.partner_state_distributing, self.partner_state_defaulted, self.partner_state_expired, self.collector_max_delay) def test_invalid_actor_state_distributing(self): self.assertRaises(AssertionError, lacp, self.version, self.actor_system_priority, self.actor_system, self.actor_key, self.actor_port_priority, self.actor_port, self.actor_state_activity, self.actor_state_timeout, self.actor_state_aggregation, self.actor_state_synchronization, self.actor_state_collecting, 2, self.actor_state_defaulted, self.actor_state_expired, self.partner_system_priority, self.partner_system, self.partner_key, self.partner_port_priority, self.partner_port, self.partner_state_activity, self.partner_state_timeout, self.partner_state_aggregation, self.partner_state_synchronization, self.partner_state_collecting, self.partner_state_distributing, self.partner_state_defaulted, self.partner_state_expired, self.collector_max_delay) def test_invalid_actor_state_defaulted(self): self.assertRaises(AssertionError, lacp, self.version, self.actor_system_priority, self.actor_system, self.actor_key, self.actor_port_priority, self.actor_port, self.actor_state_activity, self.actor_state_timeout, self.actor_state_aggregation, self.actor_state_synchronization, self.actor_state_collecting, self.actor_state_distributing, 2, self.actor_state_expired, self.partner_system_priority, self.partner_system, self.partner_key, self.partner_port_priority, self.partner_port, self.partner_state_activity, self.partner_state_timeout, self.partner_state_aggregation, self.partner_state_synchronization, self.partner_state_collecting, self.partner_state_distributing, self.partner_state_defaulted, self.partner_state_expired, self.collector_max_delay) def test_invalid_actor_state_expired(self): self.assertRaises(AssertionError, lacp, self.version, self.actor_system_priority, self.actor_system, self.actor_key, self.actor_port_priority, self.actor_port, self.actor_state_activity, self.actor_state_timeout, self.actor_state_aggregation, self.actor_state_synchronization, self.actor_state_collecting, self.actor_state_distributing, self.actor_state_defaulted, 2, self.partner_system_priority, self.partner_system, self.partner_key, self.partner_port_priority, self.partner_port, self.partner_state_activity, self.partner_state_timeout, self.partner_state_aggregation, self.partner_state_synchronization, self.partner_state_collecting, self.partner_state_distributing, self.partner_state_defaulted, self.partner_state_expired, self.collector_max_delay) def test_invalid_partner_state_activity(self): self.assertRaises(AssertionError, lacp, self.version, self.actor_system_priority, self.actor_system, self.actor_key, self.actor_port_priority, self.actor_port, self.actor_state_activity, self.actor_state_timeout, self.actor_state_aggregation, self.actor_state_synchronization, self.actor_state_collecting, self.actor_state_distributing, self.actor_state_defaulted, self.actor_state_expired, self.partner_system_priority, self.partner_system, self.partner_key, self.partner_port_priority, self.partner_port, -1, self.partner_state_timeout, self.partner_state_aggregation, self.partner_state_synchronization, self.partner_state_collecting, self.partner_state_distributing, self.partner_state_defaulted, self.partner_state_expired, self.collector_max_delay) def test_invalid_partner_state_timeout(self): self.assertRaises(AssertionError, lacp, self.version, self.actor_system_priority, self.actor_system, self.actor_key, self.actor_port_priority, self.actor_port, self.actor_state_activity, self.actor_state_timeout, self.actor_state_aggregation, self.actor_state_synchronization, self.actor_state_collecting, self.actor_state_distributing, self.actor_state_defaulted, self.actor_state_expired, self.partner_system_priority, self.partner_system, self.partner_key, self.partner_port_priority, self.partner_port, self.partner_state_activity, -1, self.partner_state_aggregation, self.partner_state_synchronization, self.partner_state_collecting, self.partner_state_distributing, self.partner_state_defaulted, self.partner_state_expired, self.collector_max_delay) def test_invalid_partner_state_aggregation(self): self.assertRaises(AssertionError, lacp, self.version, self.actor_system_priority, self.actor_system, self.actor_key, self.actor_port_priority, self.actor_port, self.actor_state_activity, self.actor_state_timeout, self.actor_state_aggregation, self.actor_state_synchronization, self.actor_state_collecting, self.actor_state_distributing, self.actor_state_defaulted, self.actor_state_expired, self.partner_system_priority, self.partner_system, self.partner_key, self.partner_port_priority, self.partner_port, self.partner_state_activity, self.partner_state_timeout, -1, self.partner_state_synchronization, self.partner_state_collecting, self.partner_state_distributing, self.partner_state_defaulted, self.partner_state_expired, self.collector_max_delay) def test_invalid_partner_state_synchronization(self): self.assertRaises(AssertionError, lacp, self.version, self.actor_system_priority, self.actor_system, self.actor_key, self.actor_port_priority, self.actor_port, self.actor_state_activity, self.actor_state_timeout, self.actor_state_aggregation, self.actor_state_synchronization, self.actor_state_collecting, self.actor_state_distributing, self.actor_state_defaulted, self.actor_state_expired, self.partner_system_priority, self.partner_system, self.partner_key, self.partner_port_priority, self.partner_port, self.partner_state_activity, self.partner_state_timeout, self.partner_state_aggregation, -1, self.partner_state_collecting, self.partner_state_distributing, self.partner_state_defaulted, self.partner_state_expired, self.collector_max_delay) def test_invalid_partner_state_collecting(self): self.assertRaises(AssertionError, lacp, self.version, self.actor_system_priority, self.actor_system, self.actor_key, self.actor_port_priority, self.actor_port, self.actor_state_activity, self.actor_state_timeout, self.actor_state_aggregation, self.actor_state_synchronization, self.actor_state_collecting, self.actor_state_distributing, self.actor_state_defaulted, self.actor_state_expired, self.partner_system_priority, self.partner_system, self.partner_key, self.partner_port_priority, self.partner_port, self.partner_state_activity, self.partner_state_timeout, self.partner_state_aggregation, self.partner_state_synchronization, -1, self.partner_state_distributing, self.partner_state_defaulted, self.partner_state_expired, self.collector_max_delay) def test_invalid_partner_state_distributing(self): self.assertRaises(AssertionError, lacp, self.version, self.actor_system_priority, self.actor_system, self.actor_key, self.actor_port_priority, self.actor_port, self.actor_state_activity, self.actor_state_timeout, self.actor_state_aggregation, self.actor_state_synchronization, self.actor_state_collecting, self.actor_state_distributing, self.actor_state_defaulted, self.actor_state_expired, self.partner_system_priority, self.partner_system, self.partner_key, self.partner_port_priority, self.partner_port, self.partner_state_activity, self.partner_state_timeout, self.partner_state_aggregation, self.partner_state_synchronization, self.partner_state_collecting, -1, self.partner_state_defaulted, self.partner_state_expired, self.collector_max_delay) def test_invalid_partner_state_defaulted(self): self.assertRaises(AssertionError, lacp, self.version, self.actor_system_priority, self.actor_system, self.actor_key, self.actor_port_priority, self.actor_port, self.actor_state_activity, self.actor_state_timeout, self.actor_state_aggregation, self.actor_state_synchronization, self.actor_state_collecting, self.actor_state_distributing, self.actor_state_defaulted, self.actor_state_expired, self.partner_system_priority, self.partner_system, self.partner_key, self.partner_port_priority, self.partner_port, self.partner_state_activity, self.partner_state_timeout, self.partner_state_aggregation, self.partner_state_synchronization, self.partner_state_collecting, self.partner_state_distributing, -1, self.partner_state_expired, self.collector_max_delay) def test_invalid_partner_state_expired(self): self.assertRaises(AssertionError, lacp, self.version, self.actor_system_priority, self.actor_system, self.actor_key, self.actor_port_priority, self.actor_port, self.actor_state_activity, self.actor_state_timeout, self.actor_state_aggregation, self.actor_state_synchronization, self.actor_state_collecting, self.actor_state_distributing, self.actor_state_defaulted, self.actor_state_expired, self.partner_system_priority, self.partner_system, self.partner_key, self.partner_port_priority, self.partner_port, self.partner_state_activity, self.partner_state_timeout, self.partner_state_aggregation, self.partner_state_synchronization, self.partner_state_collecting, self.partner_state_distributing, self.partner_state_defaulted, -1, self.collector_max_delay) def test_json(self): jsondict = self.l.to_jsondict() l = lacp.from_jsondict(jsondict['lacp']) self.assertEqual(str(self.l), str(l)) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/packet/test_tcp.py0000664000175000017500000002213700000000000022063 0ustar00zuulzuul00000000000000# Copyright (C) 2012-2015 Nippon Telegraph and Telephone 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. import unittest import logging import struct from struct import * from os_ken.ofproto import inet from os_ken.lib.packet import tcp from os_ken.lib.packet.ipv4 import ipv4 from os_ken.lib.packet import packet_utils from os_ken.lib import addrconv LOG = logging.getLogger('test_tcp') class Test_tcp(unittest.TestCase): """ Test case for tcp """ src_port = 6431 dst_port = 8080 seq = 5 ack = 1 offset = 6 bits = 0b101010 window_size = 2048 csum = 12345 urgent = 128 option = b'\x01\x02\x03\x04' t = tcp.tcp(src_port, dst_port, seq, ack, offset, bits, window_size, csum, urgent, option) buf = pack(tcp.tcp._PACK_STR, src_port, dst_port, seq, ack, offset << 4, bits, window_size, csum, urgent) buf += option def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(self.src_port, self.t.src_port) self.assertEqual(self.dst_port, self.t.dst_port) self.assertEqual(self.seq, self.t.seq) self.assertEqual(self.ack, self.t.ack) self.assertEqual(self.offset, self.t.offset) self.assertEqual(self.bits, self.t.bits) self.assertEqual(self.window_size, self.t.window_size) self.assertEqual(self.csum, self.t.csum) self.assertEqual(self.urgent, self.t.urgent) self.assertEqual(self.option, self.t.option) def test_parser(self): r1, r2, _ = self.t.parser(self.buf) self.assertEqual(self.src_port, r1.src_port) self.assertEqual(self.dst_port, r1.dst_port) self.assertEqual(self.seq, r1.seq) self.assertEqual(self.ack, r1.ack) self.assertEqual(self.offset, r1.offset) self.assertEqual(self.bits, r1.bits) self.assertEqual(self.window_size, r1.window_size) self.assertEqual(self.csum, r1.csum) self.assertEqual(self.urgent, r1.urgent) self.assertEqual(self.option, r1.option) self.assertEqual(None, r2) def test_serialize(self): offset = 5 csum = 0 src_ip = '192.168.10.1' dst_ip = '192.168.100.1' prev = ipv4(4, 5, 0, 0, 0, 0, 0, 64, inet.IPPROTO_TCP, 0, src_ip, dst_ip) t = tcp.tcp(self.src_port, self.dst_port, self.seq, self.ack, offset, self.bits, self.window_size, csum, self.urgent) buf = t.serialize(bytearray(), prev) res = struct.unpack(tcp.tcp._PACK_STR, bytes(buf)) self.assertEqual(res[0], self.src_port) self.assertEqual(res[1], self.dst_port) self.assertEqual(res[2], self.seq) self.assertEqual(res[3], self.ack) self.assertEqual(res[4], offset << 4) self.assertEqual(res[5], self.bits) self.assertEqual(res[6], self.window_size) self.assertEqual(res[8], self.urgent) # test __len__ # offset indicates the number of 32 bit (= 4 bytes) # words in the TCP Header. # So, we compare len(tcp) with offset * 4, here. self.assertEqual(offset * 4, len(t)) # checksum ph = struct.pack('!4s4sBBH', addrconv.ipv4.text_to_bin(src_ip), addrconv.ipv4.text_to_bin(dst_ip), 0, 6, offset * 4) d = ph + buf s = packet_utils.checksum(d) self.assertEqual(0, s) def test_serialize_option(self): # prepare test data offset = 0 csum = 0 option = [ tcp.TCPOptionMaximumSegmentSize(max_seg_size=1460), tcp.TCPOptionSACKPermitted(), tcp.TCPOptionTimestamps(ts_val=287454020, ts_ecr=1432778632), tcp.TCPOptionNoOperation(), tcp.TCPOptionWindowScale(shift_cnt=9), ] option_buf = ( b'\x02\x04\x05\xb4' b'\x04\x02' b'\x08\x0a\x11\x22\x33\x44\x55\x66\x77\x88' b'\x01' b'\x03\x03\x09' ) prev = ipv4(4, 5, 0, 0, 0, 0, 0, 64, inet.IPPROTO_TCP, 0, '192.168.10.1', '192.168.100.1') # test serializer t = tcp.tcp(self.src_port, self.dst_port, self.seq, self.ack, offset, self.bits, self.window_size, csum, self.urgent, option) buf = t.serialize(bytearray(), prev) r_option_buf = buf[tcp.tcp._MIN_LEN:tcp.tcp._MIN_LEN + len(option_buf)] self.assertEqual(option_buf, r_option_buf) # test parser (r_tcp, _, _) = tcp.tcp.parser(buf) self.assertEqual(str(option), str(r_tcp.option)) def test_malformed_tcp(self): m_short_buf = self.buf[1:tcp.tcp._MIN_LEN] self.assertRaises(Exception, tcp.tcp.parser, m_short_buf) def test_default_args(self): prev = ipv4(proto=inet.IPPROTO_TCP) t = tcp.tcp() buf = t.serialize(bytearray(), prev) res = struct.unpack(tcp.tcp._PACK_STR, buf) self.assertEqual(res[0], 1) self.assertEqual(res[1], 1) self.assertEqual(res[2], 0) self.assertEqual(res[3], 0) self.assertEqual(res[4], 5 << 4) self.assertEqual(res[5], 0) self.assertEqual(res[6], 0) self.assertEqual(res[8], 0) # with option, without offset t = tcp.tcp(option=[tcp.TCPOptionMaximumSegmentSize(1460)]) buf = t.serialize(bytearray(), prev) res = struct.unpack(tcp.tcp._PACK_STR + '4s', buf) self.assertEqual(res[0], 1) self.assertEqual(res[1], 1) self.assertEqual(res[2], 0) self.assertEqual(res[3], 0) self.assertEqual(res[4], 6 << 4) self.assertEqual(res[5], 0) self.assertEqual(res[6], 0) self.assertEqual(res[8], 0) self.assertEqual(res[9], b'\x02\x04\x05\xb4') # with option, with long offset t = tcp.tcp(offset=7, option=[tcp.TCPOptionWindowScale(shift_cnt=9)]) buf = t.serialize(bytearray(), prev) res = struct.unpack(tcp.tcp._PACK_STR + '8s', buf) self.assertEqual(res[0], 1) self.assertEqual(res[1], 1) self.assertEqual(res[2], 0) self.assertEqual(res[3], 0) self.assertEqual(res[4], 7 << 4) self.assertEqual(res[5], 0) self.assertEqual(res[6], 0) self.assertEqual(res[8], 0) self.assertEqual(res[9], b'\x03\x03\x09\x00\x00\x00\x00\x00') def test_json(self): jsondict = self.t.to_jsondict() t = tcp.tcp.from_jsondict(jsondict['tcp']) self.assertEqual(str(self.t), str(t)) class Test_TCPOption(unittest.TestCase): # prepare test data input_options = [ tcp.TCPOptionEndOfOptionList(), tcp.TCPOptionNoOperation(), tcp.TCPOptionMaximumSegmentSize(max_seg_size=1460), tcp.TCPOptionWindowScale(shift_cnt=9), tcp.TCPOptionSACKPermitted(), tcp.TCPOptionSACK(blocks=[(1, 2), (3, 4)], length=18), tcp.TCPOptionTimestamps(ts_val=287454020, ts_ecr=1432778632), tcp.TCPOptionUserTimeout(granularity=1, user_timeout=564), tcp.TCPOptionAuthentication( key_id=1, r_next_key_id=2, mac=b'abcdefghijkl', length=16), tcp.TCPOptionUnknown(value=b'foobar', kind=255, length=8), tcp.TCPOptionUnknown(value=b'', kind=255, length=2), ] input_buf = ( b'\x00' # End of Option List b'\x01' # No-Operation b'\x02\x04\x05\xb4' # Maximum Segment Size b'\x03\x03\x09' # Window Scale b'\x04\x02' # SACK Permitted b'\x05\x12' # SACK b'\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04' b'\x08\x0a' # Timestamps b'\x11\x22\x33\x44\x55\x66\x77\x88' b'\x1c\x04\x82\x34' # User Timeout Option b'\x1d\x10\x01\x02' # TCP Authentication Option (TCP-AO) b'abcdefghijkl' b'\xff\x08' # Unknown with body b'foobar' b'\xff\x02' # Unknown ) def test_serialize(self): output_buf = bytearray() for option in self.input_options: output_buf += option.serialize() self.assertEqual(self.input_buf, output_buf) def test_parser(self): buf = self.input_buf output_options = [] while buf: opt, buf = tcp.TCPOption.parser(buf) output_options.append(opt) self.assertEqual(str(self.input_options), str(output_options)) def test_json(self): for option in self.input_options: json_dict = option.to_jsondict()[option.__class__.__name__] output_option = option.__class__.from_jsondict(json_dict) self.assertEqual(str(option), str(output_option)) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/packet/test_udp.py0000664000175000017500000000653200000000000022066 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone 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. # vim: tabstop=4 shiftwidth=4 softtabstop=4 import unittest import logging import struct from struct import * from os_ken.ofproto import ether, inet from os_ken.lib.packet.packet import Packet from os_ken.lib.packet.udp import udp from os_ken.lib.packet.ipv4 import ipv4 from os_ken.lib.packet import packet_utils from os_ken.lib import addrconv LOG = logging.getLogger('test_udp') class Test_udp(unittest.TestCase): """ Test case for udp """ src_port = 6431 dst_port = 8080 total_length = 65507 csum = 12345 u = udp(src_port, dst_port, total_length, csum) buf = pack(udp._PACK_STR, src_port, dst_port, total_length, csum) def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(self.src_port, self.u.src_port) self.assertEqual(self.dst_port, self.u.dst_port) self.assertEqual(self.total_length, self.u.total_length) self.assertEqual(self.csum, self.u.csum) def test_parser(self): r1, r2, _ = self.u.parser(self.buf) self.assertEqual(self.src_port, r1.src_port) self.assertEqual(self.dst_port, r1.dst_port) self.assertEqual(self.total_length, r1.total_length) self.assertEqual(self.csum, r1.csum) self.assertEqual(None, r2) def test_serialize(self): src_port = 6431 dst_port = 8080 total_length = 0 csum = 0 src_ip = '192.168.10.1' dst_ip = '192.168.100.1' prev = ipv4(4, 5, 0, 0, 0, 0, 0, 64, inet.IPPROTO_UDP, 0, src_ip, dst_ip) u = udp(src_port, dst_port, total_length, csum) buf = u.serialize(bytearray(), prev) res = struct.unpack(udp._PACK_STR, buf) self.assertEqual(res[0], src_port) self.assertEqual(res[1], dst_port) self.assertEqual(res[2], struct.calcsize(udp._PACK_STR)) # checksum ph = struct.pack('!4s4sBBH', addrconv.ipv4.text_to_bin(src_ip), addrconv.ipv4.text_to_bin(dst_ip), 0, 17, res[2]) d = ph + buf + bytearray() s = packet_utils.checksum(d) self.assertEqual(0, s) def test_malformed_udp(self): m_short_buf = self.buf[1:udp._MIN_LEN] self.assertRaises(Exception, udp.parser, m_short_buf) def test_default_args(self): prev = ipv4(proto=inet.IPPROTO_UDP) u = udp() buf = u.serialize(bytearray(), prev) res = struct.unpack(udp._PACK_STR, buf) self.assertEqual(res[0], 1) self.assertEqual(res[1], 1) self.assertEqual(res[2], udp._MIN_LEN) def test_json(self): jsondict = self.u.to_jsondict() u = udp.from_jsondict(jsondict['udp']) self.assertEqual(str(self.u), str(u)) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/packet/test_vlan.py0000664000175000017500000001622700000000000022240 0ustar00zuulzuul00000000000000# Copyright (C) 2012 Nippon Telegraph and Telephone 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. # vim: tabstop=4 shiftwidth=4 softtabstop=4 import unittest import logging import struct from struct import * from os_ken.ofproto import ether, inet from os_ken.lib.packet.ethernet import ethernet from os_ken.lib.packet.packet import Packet from os_ken.lib.packet.ipv4 import ipv4 from os_ken.lib.packet.vlan import vlan from os_ken.lib.packet.vlan import svlan LOG = logging.getLogger('test_vlan') class Test_vlan(unittest.TestCase): """ Test case for vlan """ pcp = 0 cfi = 0 vid = 32 tci = pcp << 15 | cfi << 12 | vid ethertype = ether.ETH_TYPE_IP buf = pack(vlan._PACK_STR, tci, ethertype) v = vlan(pcp, cfi, vid, ethertype) def setUp(self): pass def tearDown(self): pass def find_protocol(self, pkt, name): for p in pkt.protocols: if p.protocol_name == name: return p def test_init(self): self.assertEqual(self.pcp, self.v.pcp) self.assertEqual(self.cfi, self.v.cfi) self.assertEqual(self.vid, self.v.vid) self.assertEqual(self.ethertype, self.v.ethertype) def test_parser(self): res, ptype, _ = self.v.parser(self.buf) self.assertEqual(res.pcp, self.pcp) self.assertEqual(res.cfi, self.cfi) self.assertEqual(res.vid, self.vid) self.assertEqual(res.ethertype, self.ethertype) self.assertEqual(ptype, ipv4) def test_serialize(self): data = bytearray() prev = None buf = self.v.serialize(data, prev) fmt = vlan._PACK_STR res = struct.unpack(fmt, buf) self.assertEqual(res[0], self.tci) self.assertEqual(res[1], self.ethertype) def _build_vlan(self): src_mac = '00:07:0d:af:f4:54' dst_mac = '00:00:00:00:00:00' ethertype = ether.ETH_TYPE_8021Q e = ethernet(dst_mac, src_mac, ethertype) version = 4 header_length = 20 tos = 0 total_length = 24 identification = 0x8a5d flags = 0 offset = 1480 ttl = 64 proto = inet.IPPROTO_ICMP csum = 0xa7f2 src = '131.151.32.21' dst = '131.151.32.129' option = b'TEST' ip = ipv4(version, header_length, tos, total_length, identification, flags, offset, ttl, proto, csum, src, dst, option) p = Packet() p.add_protocol(e) p.add_protocol(self.v) p.add_protocol(ip) p.serialize() return p def test_build_vlan(self): p = self._build_vlan() e = self.find_protocol(p, "ethernet") self.assertTrue(e) self.assertEqual(e.ethertype, ether.ETH_TYPE_8021Q) v = self.find_protocol(p, "vlan") self.assertTrue(v) self.assertEqual(v.ethertype, ether.ETH_TYPE_IP) ip = self.find_protocol(p, "ipv4") self.assertTrue(ip) self.assertEqual(v.pcp, self.pcp) self.assertEqual(v.cfi, self.cfi) self.assertEqual(v.vid, self.vid) self.assertEqual(v.ethertype, self.ethertype) def test_malformed_vlan(self): m_short_buf = self.buf[1:vlan._MIN_LEN] self.assertRaises(Exception, vlan.parser, m_short_buf) def test_json(self): jsondict = self.v.to_jsondict() v = vlan.from_jsondict(jsondict['vlan']) self.assertEqual(str(self.v), str(v)) class Test_svlan(unittest.TestCase): pcp = 0 cfi = 0 vid = 32 tci = pcp << 15 | cfi << 12 | vid ethertype = ether.ETH_TYPE_8021Q buf = pack(svlan._PACK_STR, tci, ethertype) sv = svlan(pcp, cfi, vid, ethertype) def setUp(self): pass def tearDown(self): pass def find_protocol(self, pkt, name): for p in pkt.protocols: if p.protocol_name == name: return p def test_init(self): self.assertEqual(self.pcp, self.sv.pcp) self.assertEqual(self.cfi, self.sv.cfi) self.assertEqual(self.vid, self.sv.vid) self.assertEqual(self.ethertype, self.sv.ethertype) def test_parser(self): res, ptype, _ = self.sv.parser(self.buf) self.assertEqual(res.pcp, self.pcp) self.assertEqual(res.cfi, self.cfi) self.assertEqual(res.vid, self.vid) self.assertEqual(res.ethertype, self.ethertype) self.assertEqual(ptype, vlan) def test_serialize(self): data = bytearray() prev = None buf = self.sv.serialize(data, prev) fmt = svlan._PACK_STR res = struct.unpack(fmt, buf) self.assertEqual(res[0], self.tci) self.assertEqual(res[1], self.ethertype) def _build_svlan(self): src_mac = '00:07:0d:af:f4:54' dst_mac = '00:00:00:00:00:00' ethertype = ether.ETH_TYPE_8021AD e = ethernet(dst_mac, src_mac, ethertype) pcp = 0 cfi = 0 vid = 32 tci = pcp << 15 | cfi << 12 | vid ethertype = ether.ETH_TYPE_IP v = vlan(pcp, cfi, vid, ethertype) version = 4 header_length = 20 tos = 0 total_length = 24 identification = 0x8a5d flags = 0 offset = 1480 ttl = 64 proto = inet.IPPROTO_ICMP csum = 0xa7f2 src = '131.151.32.21' dst = '131.151.32.129' option = b'TEST' ip = ipv4(version, header_length, tos, total_length, identification, flags, offset, ttl, proto, csum, src, dst, option) p = Packet() p.add_protocol(e) p.add_protocol(self.sv) p.add_protocol(v) p.add_protocol(ip) p.serialize() return p def test_build_svlan(self): p = self._build_svlan() e = self.find_protocol(p, "ethernet") self.assertTrue(e) self.assertEqual(e.ethertype, ether.ETH_TYPE_8021AD) sv = self.find_protocol(p, "svlan") self.assertTrue(sv) self.assertEqual(sv.ethertype, ether.ETH_TYPE_8021Q) v = self.find_protocol(p, "vlan") self.assertTrue(v) self.assertEqual(v.ethertype, ether.ETH_TYPE_IP) ip = self.find_protocol(p, "ipv4") self.assertTrue(ip) self.assertEqual(sv.pcp, self.pcp) self.assertEqual(sv.cfi, self.cfi) self.assertEqual(sv.vid, self.vid) self.assertEqual(sv.ethertype, self.ethertype) def test_malformed_svlan(self): m_short_buf = self.buf[1:svlan._MIN_LEN] self.assertRaises(Exception, vlan.parser, m_short_buf) def test_json(self): jsondict = self.sv.to_jsondict() sv = svlan.from_jsondict(jsondict['svlan']) self.assertEqual(str(self.sv), str(sv)) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/packet/test_vrrp.py0000664000175000017500000004465500000000000022277 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013 Isaku Yamahata # # 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. import unittest import logging import struct import inspect from os_ken.ofproto import inet from os_ken.lib.packet import ipv4 from os_ken.lib.packet import ipv6 from os_ken.lib.packet import packet from os_ken.lib.packet import packet_utils from os_ken.lib.packet import vrrp from os_ken.lib import addrconv LOG = logging.getLogger(__name__) class Test_vrrpv2(unittest.TestCase): """ Test case for vrrp v2 """ version = vrrp.VRRP_VERSION_V2 type_ = vrrp.VRRP_TYPE_ADVERTISEMENT vrid = 128 priority = 100 count_ip = 1 auth_type = vrrp.VRRP_AUTH_NO_AUTH max_adver_int = 100 checksum = 0 ip_address = '192.168.0.1' auth_data = (0, 0) vrrpv2 = vrrp.vrrpv2.create(type_, vrid, priority, max_adver_int, [ip_address]) buf = struct.pack(vrrp.vrrpv2._PACK_STR + '4sII', vrrp.vrrp_to_version_type(vrrp.VRRP_VERSION_V2, type_), vrid, priority, count_ip, auth_type, max_adver_int, checksum, addrconv.ipv4.text_to_bin(ip_address), auth_data[0], auth_data[1]) def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(self.type_, self.vrrpv2.type) self.assertEqual(self.vrid, self.vrrpv2.vrid) self.assertEqual(self.priority, self.vrrpv2.priority) self.assertEqual(self.count_ip, self.vrrpv2.count_ip) self.assertEqual(self.auth_type, self.vrrpv2.auth_type) self.assertEqual(1, len(self.vrrpv2.ip_addresses)) self.assertEqual(self.ip_address, self.vrrpv2.ip_addresses[0]) self.assertEqual(self.auth_data, self.vrrpv2.auth_data) def test_parser(self): vrrpv2, _cls, _ = self.vrrpv2.parser(self.buf) self.assertEqual(self.version, vrrpv2.version) self.assertEqual(self.type_, vrrpv2.type) self.assertEqual(self.vrid, vrrpv2.vrid) self.assertEqual(self.priority, vrrpv2.priority) self.assertEqual(self.count_ip, vrrpv2.count_ip) self.assertEqual(self.auth_type, vrrpv2.auth_type) self.assertEqual(self.max_adver_int, vrrpv2.max_adver_int) self.assertEqual(self.checksum, vrrpv2.checksum) self.assertEqual(1, len(vrrpv2.ip_addresses)) self.assertEqual(str, type(vrrpv2.ip_addresses[0])) self.assertEqual(self.ip_address, vrrpv2.ip_addresses[0]) self.assertEqual(self.auth_data, vrrpv2.auth_data) def test_serialize(self): src_ip = '192.168.0.1' dst_ip = vrrp.VRRP_IPV4_DST_ADDRESS prev = ipv4.ipv4(4, 5, 0, 0, 0, 0, 0, vrrp.VRRP_IPV4_TTL, inet.IPPROTO_VRRP, 0, src_ip, dst_ip) type_ = vrrp.VRRP_TYPE_ADVERTISEMENT vrid = 5 priority = 10 max_adver_int = 30 ip_address = '192.168.0.2' ip_addresses = [ip_address] vrrp_ = vrrp.vrrpv2.create( type_, vrid, priority, max_adver_int, ip_addresses) buf = vrrp_.serialize(bytearray(), prev) pack_str = vrrp.vrrpv2._PACK_STR + '4sII' pack_len = struct.calcsize(pack_str) res = struct.unpack(pack_str, bytes(buf)) self.assertEqual(res[0], vrrp.vrrp_to_version_type(vrrp.VRRP_VERSION_V2, type_)) self.assertEqual(res[1], vrid) self.assertEqual(res[2], priority) self.assertEqual(res[3], len(ip_addresses)) self.assertEqual(res[4], vrrp.VRRP_AUTH_NO_AUTH) self.assertEqual(res[5], max_adver_int) # res[6] is checksum self.assertEqual(res[7], addrconv.ipv4.text_to_bin(ip_address)) self.assertEqual(res[8], 0) self.assertEqual(res[9], 0) self.assertEqual(len(buf), pack_len) # checksum s = packet_utils.checksum(buf) self.assertEqual(0, s) def test_malformed_vrrpv2(self): m_short_buf = self.buf[1:vrrp.vrrpv2._MIN_LEN] self.assertRaises(Exception, vrrp.vrrp.parser, m_short_buf) def test_create_packet(self): primary_ip = '192.168.0.2' p0 = self.vrrpv2.create_packet(primary_ip) p0.serialize() p1 = packet.Packet(bytes(p0.data)) p1.serialize() self.assertEqual(p0.data, p1.data) def _test_is_valid(self, type_=None, vrid=None, priority=None, max_adver_int=None): if type_ is None: type_ = self.type_ if vrid is None: vrid = self.vrid if priority is None: priority = self.priority if max_adver_int is None: max_adver_int = self.max_adver_int vrrp_ = vrrp.vrrpv2.create(type_, vrid, priority, max_adver_int, [self.ip_address]) return vrrp_.is_valid() def test_is_valid_ok(self): self.assertTrue(self._test_is_valid()) def test_is_valid_ng_type(self): self.assertTrue(not self._test_is_valid(type_=15)) def test_is_valid_ng_vrid_min(self): vrid = vrrp.VRRP_VRID_MIN - 1 self.assertTrue(not self._test_is_valid(vrid=vrid)) def test_is_valid_ng_vrid_max(self): vrid = vrrp.VRRP_VRID_MAX + 1 self.assertTrue(not self._test_is_valid(vrid=vrid)) def test_is_valid_ng_priority_min(self): priority = vrrp.VRRP_PRIORITY_MIN - 1 self.assertTrue(not self._test_is_valid(priority=priority)) def test_is_valid_ng_priority_max(self): priority = vrrp.VRRP_PRIORITY_MAX + 1 self.assertTrue(not self._test_is_valid(priority=priority)) def test_is_valid_ng_adver_min(self): max_adver_int = vrrp.VRRP_V2_MAX_ADVER_INT_MIN - 1 self.assertTrue(not self._test_is_valid(max_adver_int=max_adver_int)) def test_is_valid_ng_adver_max(self): max_adver_int = vrrp.VRRP_V2_MAX_ADVER_INT_MAX + 1 self.assertTrue(not self._test_is_valid(max_adver_int=max_adver_int)) def test_to_string(self): vrrpv2_values = {'version': self.version, 'type': self.type_, 'vrid': self.vrid, 'priority': self.priority, 'count_ip': self.count_ip, 'max_adver_int': self.max_adver_int, 'checksum': self.vrrpv2.checksum, 'ip_addresses': [self.ip_address], 'auth_type': self.auth_type, 'auth_data': self.auth_data, 'identification': self.vrrpv2.identification} _vrrpv2_str = ','.join(['%s=%s' % (k, repr(vrrpv2_values[k])) for k, v in inspect.getmembers(self.vrrpv2) if k in vrrpv2_values]) vrrpv2_str = '%s(%s)' % (vrrp.vrrpv2.__name__, _vrrpv2_str) self.assertEqual(str(self.vrrpv2), vrrpv2_str) self.assertEqual(repr(self.vrrpv2), vrrpv2_str) class Test_vrrpv3_ipv4(unittest.TestCase): """ Test case for vrrp v3 IPv4 """ version = vrrp.VRRP_VERSION_V3 type_ = vrrp.VRRP_TYPE_ADVERTISEMENT vrid = 128 priority = 99 count_ip = 1 max_adver_int = 111 checksum = 0 ip_address = '192.168.0.1' vrrpv3 = vrrp.vrrpv3.create(type_, vrid, priority, max_adver_int, [ip_address]) buf = struct.pack(vrrp.vrrpv3._PACK_STR + '4s', vrrp.vrrp_to_version_type(vrrp.VRRP_VERSION_V3, type_), vrid, priority, count_ip, max_adver_int, checksum, addrconv.ipv4.text_to_bin(ip_address)) def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(self.type_, self.vrrpv3.type) self.assertEqual(self.vrid, self.vrrpv3.vrid) self.assertEqual(self.priority, self.vrrpv3.priority) self.assertEqual(self.count_ip, self.vrrpv3.count_ip) self.assertEqual(1, len(self.vrrpv3.ip_addresses)) self.assertEqual(self.ip_address, self.vrrpv3.ip_addresses[0]) def test_parser(self): vrrpv3, _cls, _ = self.vrrpv3.parser(self.buf) self.assertEqual(self.version, vrrpv3.version) self.assertEqual(self.type_, vrrpv3.type) self.assertEqual(self.vrid, vrrpv3.vrid) self.assertEqual(self.priority, vrrpv3.priority) self.assertEqual(self.count_ip, vrrpv3.count_ip) self.assertEqual(self.max_adver_int, vrrpv3.max_adver_int) self.assertEqual(self.checksum, vrrpv3.checksum) self.assertEqual(1, len(vrrpv3.ip_addresses)) self.assertEqual(str, type(vrrpv3.ip_addresses[0])) self.assertEqual(self.ip_address, vrrpv3.ip_addresses[0]) def test_serialize(self): src_ip = '192.168.0.1' dst_ip = vrrp.VRRP_IPV4_DST_ADDRESS prev = ipv4.ipv4(4, 5, 0, 0, 0, 0, 0, vrrp.VRRP_IPV4_TTL, inet.IPPROTO_VRRP, 0, src_ip, dst_ip) type_ = vrrp.VRRP_TYPE_ADVERTISEMENT vrid = 5 priority = 10 max_adver_int = 30 ip_address = '192.168.0.2' ip_addresses = [ip_address] vrrp_ = vrrp.vrrpv3.create( type_, vrid, priority, max_adver_int, ip_addresses) buf = vrrp_.serialize(bytearray(), prev) print(len(buf), type(buf), buf) pack_str = vrrp.vrrpv3._PACK_STR + '4s' pack_len = struct.calcsize(pack_str) res = struct.unpack(pack_str, bytes(buf)) self.assertEqual(res[0], vrrp.vrrp_to_version_type(vrrp.VRRP_VERSION_V3, type_)) self.assertEqual(res[1], vrid) self.assertEqual(res[2], priority) self.assertEqual(res[3], len(ip_addresses)) self.assertEqual(res[4], max_adver_int) # res[5] is checksum self.assertEqual(res[6], addrconv.ipv4.text_to_bin(ip_address)) self.assertEqual(len(buf), pack_len) print(res) # checksum ph = struct.pack('!4s4sxBH', addrconv.ipv4.text_to_bin(src_ip), addrconv.ipv4.text_to_bin(dst_ip), inet.IPPROTO_VRRP, pack_len) s = packet_utils.checksum(ph + buf) self.assertEqual(0, s) def test_malformed_vrrpv3(self): m_short_buf = self.buf[1:vrrp.vrrpv3._MIN_LEN] self.assertRaises(Exception, vrrp.vrrp.parser, m_short_buf) def test_create_packet(self): primary_ip = '192.168.0.2' p0 = self.vrrpv3.create_packet(primary_ip) p0.serialize() p1 = packet.Packet(bytes(p0.data)) p1.serialize() self.assertEqual(p0.data, p1.data) def _test_is_valid(self, type_=None, vrid=None, priority=None, max_adver_int=None): if type_ is None: type_ = self.type_ if vrid is None: vrid = self.vrid if priority is None: priority = self.priority if max_adver_int is None: max_adver_int = self.max_adver_int vrrp_ = vrrp.vrrpv3.create(type_, vrid, priority, max_adver_int, [self.ip_address]) return vrrp_.is_valid() def test_is_valid_ok(self): self.assertTrue(self._test_is_valid()) def test_is_valid_ng_type(self): self.assertTrue(not self._test_is_valid(type_=15)) def test_is_valid_ng_vrid_min(self): vrid = vrrp.VRRP_VRID_MIN - 1 self.assertTrue(not self._test_is_valid(vrid=vrid)) def test_is_valid_ng_vrid_max(self): vrid = vrrp.VRRP_VRID_MAX + 1 self.assertTrue(not self._test_is_valid(vrid=vrid)) def test_is_valid_ng_priority_min(self): priority = vrrp.VRRP_PRIORITY_MIN - 1 self.assertTrue(not self._test_is_valid(priority=priority)) def test_is_valid_ng_priority_max(self): priority = vrrp.VRRP_PRIORITY_MAX + 1 self.assertTrue(not self._test_is_valid(priority=priority)) def test_is_valid_ng_adver_min(self): max_adver_int = vrrp.VRRP_V3_MAX_ADVER_INT_MIN - 1 self.assertTrue(not self._test_is_valid(max_adver_int=max_adver_int)) def test_is_valid_ng_adver_max(self): max_adver_int = vrrp.VRRP_V3_MAX_ADVER_INT_MAX + 1 self.assertTrue(not self._test_is_valid(max_adver_int=max_adver_int)) def test_to_string(self): vrrpv3_values = {'version': self.version, 'type': self.type_, 'vrid': self.vrid, 'priority': self.priority, 'count_ip': self.count_ip, 'max_adver_int': self.max_adver_int, 'checksum': self.vrrpv3.checksum, 'ip_addresses': [self.ip_address], 'auth_type': None, 'auth_data': None, 'identification': self.vrrpv3.identification} _vrrpv3_str = ','.join(['%s=%s' % (k, repr(vrrpv3_values[k])) for k, v in inspect.getmembers(self.vrrpv3) if k in vrrpv3_values]) vrrpv3_str = '%s(%s)' % (vrrp.vrrpv3.__name__, _vrrpv3_str) self.assertEqual(str(self.vrrpv3), vrrpv3_str) self.assertEqual(repr(self.vrrpv3), vrrpv3_str) class Test_vrrpv3_ipv6(unittest.TestCase): """ Test case for vrrp v3 IPv6 """ version = vrrp.VRRP_VERSION_V3 type_ = vrrp.VRRP_TYPE_ADVERTISEMENT vrid = 128 priority = 99 count_ip = 1 max_adver_int = 111 checksum = 0 ip_address = '2001:db8:2000::1' vrrpv3 = vrrp.vrrpv3.create(type_, vrid, priority, max_adver_int, [ip_address]) buf = struct.pack(vrrp.vrrpv3._PACK_STR + '16s', vrrp.vrrp_to_version_type(vrrp.VRRP_VERSION_V3, type_), vrid, priority, count_ip, max_adver_int, checksum, addrconv.ipv6.text_to_bin(ip_address)) def setUp(self): pass def tearDown(self): pass def test_init(self): self.assertEqual(self.type_, self.vrrpv3.type) self.assertEqual(self.vrid, self.vrrpv3.vrid) self.assertEqual(self.priority, self.vrrpv3.priority) self.assertEqual(self.count_ip, self.vrrpv3.count_ip) self.assertEqual(1, len(self.vrrpv3.ip_addresses)) self.assertEqual(self.ip_address, self.vrrpv3.ip_addresses[0]) def test_parser(self): vrrpv3, _cls, _ = self.vrrpv3.parser(self.buf) self.assertEqual(self.version, vrrpv3.version) self.assertEqual(self.type_, vrrpv3.type) self.assertEqual(self.vrid, vrrpv3.vrid) self.assertEqual(self.priority, vrrpv3.priority) self.assertEqual(self.count_ip, vrrpv3.count_ip) self.assertEqual(self.max_adver_int, vrrpv3.max_adver_int) self.assertEqual(self.checksum, vrrpv3.checksum) self.assertEqual(1, len(vrrpv3.ip_addresses)) self.assertEqual(str, type(vrrpv3.ip_addresses[0])) self.assertEqual(self.ip_address, vrrpv3.ip_addresses[0]) def test_serialize(self): src_ip = '2001:db8:2000::1' dst_ip = vrrp.VRRP_IPV6_DST_ADDRESS prev = ipv6.ipv6(6, 0, 0, 0, inet.IPPROTO_VRRP, vrrp.VRRP_IPV6_HOP_LIMIT, src_ip, dst_ip) type_ = vrrp.VRRP_TYPE_ADVERTISEMENT vrid = 5 priority = 10 max_adver_int = 30 ip_address = '2001:db8:2000::2' ip_addresses = [ip_address] vrrp_ = vrrp.vrrpv3.create( type_, vrid, priority, max_adver_int, ip_addresses) buf = vrrp_.serialize(bytearray(), prev) print(len(buf), type(buf), buf) pack_str = vrrp.vrrpv3._PACK_STR + '16s' pack_len = struct.calcsize(pack_str) res = struct.unpack(pack_str, bytes(buf)) self.assertEqual(res[0], vrrp.vrrp_to_version_type(vrrp.VRRP_VERSION_V3, type_)) self.assertEqual(res[1], vrid) self.assertEqual(res[2], priority) self.assertEqual(res[3], len(ip_addresses)) self.assertEqual(res[4], max_adver_int) # res[5] is checksum self.assertEqual(res[6], addrconv.ipv6.text_to_bin(ip_address)) self.assertEqual(len(buf), pack_len) print(res) # checksum ph = struct.pack('!16s16sI3xB', addrconv.ipv6.text_to_bin(src_ip), addrconv.ipv6.text_to_bin(dst_ip), pack_len, inet.IPPROTO_VRRP) s = packet_utils.checksum(ph + buf) self.assertEqual(0, s) def test_malformed_vrrpv3(self): m_short_buf = self.buf[1:vrrp.vrrpv3._MIN_LEN] self.assertRaises(Exception, vrrp.vrrp.parser, m_short_buf) def test_create_packet(self): primary_ip = '2001:db8:2000::3' p0 = self.vrrpv3.create_packet(primary_ip) p0.serialize() print(len(p0.data), p0.data) p1 = packet.Packet(bytes(p0.data)) p1.serialize() print(len(p0.data), p0.data) print(len(p1.data), p1.data) self.assertEqual(p0.data, p1.data) def test_to_string(self): vrrpv3_values = {'version': self.version, 'type': self.type_, 'vrid': self.vrid, 'priority': self.priority, 'count_ip': self.count_ip, 'max_adver_int': self.max_adver_int, 'checksum': self.vrrpv3.checksum, 'ip_addresses': [self.ip_address], 'auth_type': None, 'auth_data': None, 'identification': self.vrrpv3.identification} _vrrpv3_str = ','.join(['%s=%s' % (k, repr(vrrpv3_values[k])) for k, v in inspect.getmembers(self.vrrpv3) if k in vrrpv3_values]) vrrpv3_str = '%s(%s)' % (vrrp.vrrpv3.__name__, _vrrpv3_str) self.assertEqual(str(self.vrrpv3), vrrpv3_str) self.assertEqual(repr(self.vrrpv3), vrrpv3_str) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/packet/test_vxlan.py0000664000175000017500000000473100000000000022425 0ustar00zuulzuul00000000000000# Copyright (C) 2016 Nippon Telegraph and Telephone 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. import logging import unittest from os_ken.lib.packet import ethernet from os_ken.lib.packet import vxlan LOG = logging.getLogger(__name__) class Test_vxlan(unittest.TestCase): """ Test case for VXLAN (RFC 7348) header encoder/decoder class. """ vni = 0x123456 buf = ( b'\x08\x00\x00\x00' # flags = R|R|R|R|I|R|R|R (8 bits) b'\x12\x34\x56\x00' # vni = 0x123456 (24 bits) b'test_payload' # for test ) pkt = vxlan.vxlan(vni) jsondict = { 'vxlan': { 'vni': vni } } def test_init(self): self.assertEqual(self.vni, self.pkt.vni) def test_parser(self): parsed_pkt, next_proto_cls, rest_buf = vxlan.vxlan.parser(self.buf) self.assertEqual(self.vni, parsed_pkt.vni) self.assertEqual(ethernet.ethernet, next_proto_cls) self.assertEqual(b'test_payload', rest_buf) def test_invalid_flags(self): invalid_flags_bug = ( b'\x00\x00\x00\x00' # all bits are set to zero b'\x12\x34\x56\x00' # vni = 0x123456 (24 bits) ) self.assertRaises(Exception, vxlan.vxlan.parser, invalid_flags_bug) def test_serialize(self): serialized_buf = self.pkt.serialize(payload=None, prev=None) self.assertEqual(self.buf[:vxlan.vxlan._MIN_LEN], serialized_buf) def test_from_jsondict(self): pkt_from_json = vxlan.vxlan.from_jsondict( self.jsondict[vxlan.vxlan.__name__]) self.assertEqual(self.vni, pkt_from_json.vni) def test_to_jsondict(self): jsondict_from_pkt = self.pkt.to_jsondict() self.assertEqual(self.jsondict, jsondict_from_pkt) def test_vni_from_bin(self): vni = vxlan.vni_from_bin(b'\x12\x34\x56') self.assertEqual(self.vni, vni) def test_vni_to_bin(self): self.assertEqual(b'\x12\x34\x56', vxlan.vni_to_bin(self.vni)) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/packet/test_zebra.py0000664000175000017500000005464300000000000022407 0ustar00zuulzuul00000000000000# Copyright (C) 2017 Nippon Telegraph and Telephone 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. import os import socket import sys import unittest from unittest import mock from os_ken.lib import pcaplib from os_ken.lib.packet import packet from os_ken.lib.packet import zebra from os_ken.utils import binary_str PCAP_DATA_DIR = os.path.join( os.path.dirname(sys.modules[__name__].__file__), '../../packet_data/pcap/') _patch_frr_v2 = mock.patch( 'os_ken.lib.packet.zebra._is_frr_version_ge', mock.MagicMock(side_effect=lambda x: x == zebra._FRR_VERSION_2_0)) class Test_zebra(unittest.TestCase): """ Test case for os_ken.lib.packet.zebra. """ def _test_pcap_single(self, f): zebra_pcap_file = os.path.join(PCAP_DATA_DIR, f + '.pcap') # print('*** testing %s' % zebra_pcap_file) for _, buf in pcaplib.Reader(open(zebra_pcap_file, 'rb')): # Checks if Zebra message can be parsed as expected. pkt = packet.Packet(buf) zebra_pkts = pkt.get_protocols(zebra.ZebraMessage) for zebra_pkt in zebra_pkts: self.assertTrue(isinstance(zebra_pkt, zebra.ZebraMessage), 'Failed to parse Zebra message: %s' % pkt) self.assertTrue(not isinstance(pkt.protocols[-1], (bytes, bytearray)), 'Some messages could not be parsed in %s: %s' % (f, pkt)) # Checks if Zebra message can be serialized as expected. pkt.serialize() self.assertEqual(binary_str(buf), binary_str(pkt.data)) def test_pcap_quagga(self): files = [ 'zebra_v2', 'zebra_v3', ] for f in files: self._test_pcap_single(f) @_patch_frr_v2 def test_pcap_frr_v2(self): files = [ 'zebra_v4_frr_v2', # API version 4 on FRRouting v2.0 ] for f in files: self._test_pcap_single(f) class TestZebraMessage(unittest.TestCase): def test_get_header_size(self): self.assertEqual(zebra.ZebraMessage.V0_HEADER_SIZE, zebra.ZebraMessage.get_header_size(0)) self.assertEqual(zebra.ZebraMessage.V1_HEADER_SIZE, zebra.ZebraMessage.get_header_size(2)) self.assertEqual(zebra.ZebraMessage.V3_HEADER_SIZE, zebra.ZebraMessage.get_header_size(3)) self.assertEqual(zebra.ZebraMessage.V3_HEADER_SIZE, zebra.ZebraMessage.get_header_size(4)) def test_get_header_size_invalid_version(self): self.assertRaises(ValueError, zebra.ZebraMessage.get_header_size, 0xff) class TestZebraRedistributeAdd(unittest.TestCase): buf = ( b'\x02' # route_type ) route_type = zebra.ZEBRA_ROUTE_CONNECT def test_parser(self): body = zebra.ZebraRedistributeAdd.parse(self.buf, version=3) self.assertEqual(self.route_type, body.route_type) buf = body.serialize(version=3) self.assertEqual(binary_str(self.buf), binary_str(buf)) class TestZebraIPv4ImportLookup(unittest.TestCase): buf = ( b'\x18' b'\xc0\xa8\x01\x01' # prefix ) prefix = '192.168.1.1/24' metric = None nexthop_num = 0 from_zebra = False def test_parser(self): body = zebra.ZebraIPv4ImportLookup.parse(self.buf) self.assertEqual(self.prefix, body.prefix) self.assertEqual(self.metric, body.metric) self.assertEqual(self.nexthop_num, len(body.nexthops)) self.assertEqual(self.from_zebra, body.from_zebra) buf = body.serialize() self.assertEqual(binary_str(self.buf), binary_str(buf)) class TestZebraIPv4ImportLookupFromZebra(unittest.TestCase): buf = ( b'\xc0\xa8\x01\x01' # prefix b'\x00\x00\x00\x14' # metric b'\x01' # nexthop_num b'\x01' # nexthop_type b'\x00\x00\x00\x02' # ifindex ) prefix = '192.168.1.1' metric = 0x14 nexthop_num = 1 nexthop_type = zebra.ZEBRA_NEXTHOP_IFINDEX ifindex = 2 from_zebra = True def test_parser(self): body = zebra.ZebraIPv4ImportLookup.parse_from_zebra(self.buf) self.assertEqual(self.prefix, body.prefix) self.assertEqual(self.metric, body.metric) self.assertEqual(self.nexthop_num, len(body.nexthops)) self.assertEqual(self.nexthop_type, body.nexthops[0].type) self.assertEqual(self.ifindex, body.nexthops[0].ifindex) self.assertEqual(self.from_zebra, body.from_zebra) buf = body.serialize() self.assertEqual(binary_str(self.buf), binary_str(buf)) class TestZebraIPv4NexthopLookupMRib(unittest.TestCase): buf = ( b'\xc0\xa8\x01\x01' # addr ) addr = '192.168.1.1' distance = None metric = None nexthop_num = 0 def test_parser(self): body = zebra.ZebraIPv4NexthopLookupMRib.parse(self.buf) self.assertEqual(self.addr, body.addr) self.assertEqual(self.distance, body.distance) self.assertEqual(self.metric, body.metric) self.assertEqual(self.nexthop_num, len(body.nexthops)) buf = body.serialize() self.assertEqual(binary_str(self.buf), binary_str(buf)) class TestZebraIPv4NexthopLookupMRibFromZebra(unittest.TestCase): buf = ( b'\xc0\xa8\x01\x01' # addr b'\x01' # distance b'\x00\x00\x00\x14' # metric b'\x01' # nexthop_num b'\x01' # nexthop_type b'\x00\x00\x00\x02' # ifindex ) addr = '192.168.1.1' distance = 1 metric = 0x14 nexthop_num = 1 nexthop_type = zebra.ZEBRA_NEXTHOP_IFINDEX ifindex = 2 def test_parser(self): body = zebra.ZebraIPv4NexthopLookupMRib.parse(self.buf) self.assertEqual(self.addr, body.addr) self.assertEqual(self.distance, body.distance) self.assertEqual(self.metric, body.metric) self.assertEqual(self.nexthop_num, len(body.nexthops)) self.assertEqual(self.nexthop_type, body.nexthops[0].type) self.assertEqual(self.ifindex, body.nexthops[0].ifindex) buf = body.serialize() self.assertEqual(binary_str(self.buf), binary_str(buf)) class TestZebraNexthopUpdateIPv6(unittest.TestCase): buf = ( b'\x00\x0a' # family b'\x40' # prefix_len b'\x20\x01\x0d\xb8' # prefix b'\x00\x00\x00\x00' b'\x00\x00\x00\x14' # metric b'\x01' # nexthop_num b'\x01' # nexthop_type b'\x00\x00\x00\x02' # ifindex ) family = socket.AF_INET6 prefix = '2001:db8::/64' metric = 0x14 nexthop_num = 1 nexthop_type = zebra.ZEBRA_NEXTHOP_IFINDEX ifindex = 2 @_patch_frr_v2 def test_parser(self): body = zebra.ZebraNexthopUpdate.parse(self.buf) self.assertEqual(self.family, body.family) self.assertEqual(self.prefix, body.prefix) self.assertEqual(self.metric, body.metric) self.assertEqual(self.nexthop_num, len(body.nexthops)) self.assertEqual(self.nexthop_type, body.nexthops[0].type) self.assertEqual(self.ifindex, body.nexthops[0].ifindex) buf = body.serialize() self.assertEqual(binary_str(self.buf), binary_str(buf)) class TestZebraInterfaceNbrAddressAdd(unittest.TestCase): buf = ( b'\x00\x00\x00\x01' # ifindex b'\x02' # family b'\xc0\xa8\x01\x00' # prefix b'\x18' # prefix_len ) ifindex = 1 family = socket.AF_INET prefix = '192.168.1.0/24' @_patch_frr_v2 def test_parser(self): body = zebra.ZebraInterfaceNbrAddressAdd.parse(self.buf) self.assertEqual(self.ifindex, body.ifindex) self.assertEqual(self.family, body.family) self.assertEqual(self.prefix, body.prefix) buf = body.serialize() self.assertEqual(binary_str(self.buf), binary_str(buf)) class TestZebraInterfaceBfdDestinationUpdate(unittest.TestCase): buf = ( b'\x00\x00\x00\x01' # ifindex b'\x02' # dst_family b'\xc0\xa8\x01\x01' # dst_prefix b'\x18' # dst_prefix_len b'\x04' # status b'\x02' # src_family b'\xc0\xa8\x01\x02' # src_prefix b'\x18' # src_prefix_len ) ifindex = 1 dst_family = socket.AF_INET dst_prefix = '192.168.1.1/24' status = zebra.BFD_STATUS_UP src_family = socket.AF_INET src_prefix = '192.168.1.2/24' @_patch_frr_v2 def test_parser(self): body = zebra.ZebraInterfaceBfdDestinationUpdate.parse(self.buf) self.assertEqual(self.ifindex, body.ifindex) self.assertEqual(self.dst_family, body.dst_family) self.assertEqual(self.dst_prefix, body.dst_prefix) self.assertEqual(self.status, body.status) self.assertEqual(self.src_family, body.src_family) self.assertEqual(self.src_prefix, body.src_prefix) buf = body.serialize() self.assertEqual(binary_str(self.buf), binary_str(buf)) class TestZebraBfdDestinationRegisterMultiHopEnabled(unittest.TestCase): buf = ( b'\x00\x00\x00\x01' # pid b'\x00\x02' # dst_family b'\xc0\xa8\x01\x01' # dst_prefix b'\x00\x00\x00\x10' # min_rx_timer b'\x00\x00\x00\x20' # min_tx_timer b'\x01' # detect_mult b'\x01' # multi_hop b'\x00\x02' # src_family b'\xc0\xa8\x01\x02' # src_prefix b'\x05' # multi_hop_count ) pid = 1 dst_family = socket.AF_INET dst_prefix = '192.168.1.1' min_rx_timer = 0x10 min_tx_timer = 0x20 detect_mult = 1 multi_hop = 1 src_family = socket.AF_INET src_prefix = '192.168.1.2' multi_hop_count = 5 ifname = None @_patch_frr_v2 def test_parser(self): body = zebra.ZebraBfdDestinationRegister.parse(self.buf) self.assertEqual(self.pid, body.pid) self.assertEqual(self.dst_family, body.dst_family) self.assertEqual(self.dst_prefix, body.dst_prefix) self.assertEqual(self.min_rx_timer, body.min_rx_timer) self.assertEqual(self.min_tx_timer, body.min_tx_timer) self.assertEqual(self.detect_mult, body.detect_mult) self.assertEqual(self.multi_hop, body.multi_hop) self.assertEqual(self.src_family, body.src_family) self.assertEqual(self.src_prefix, body.src_prefix) self.assertEqual(self.multi_hop_count, body.multi_hop_count) self.assertEqual(self.ifname, body.ifname) buf = body.serialize() self.assertEqual(binary_str(self.buf), binary_str(buf)) class TestZebraBfdDestinationRegisterMultiHopDisabled(unittest.TestCase): buf = ( b'\x00\x00\x00\x01' # pid b'\x00\x02' # dst_family b'\xc0\xa8\x01\x01' # dst_prefix b'\x00\x00\x00\x10' # min_rx_timer b'\x00\x00\x00\x20' # min_tx_timer b'\x01' # detect_mult b'\x00' # multi_hop b'\x00\x02' # src_family b'\xc0\xa8\x01\x02' # src_prefix b'\x04' # ifname_len b'eth0' # ifname ) pid = 1 dst_family = socket.AF_INET dst_prefix = '192.168.1.1' min_rx_timer = 0x10 min_tx_timer = 0x20 detect_mult = 1 multi_hop = 0 src_family = socket.AF_INET src_prefix = '192.168.1.2' multi_hop_count = None ifname = 'eth0' @_patch_frr_v2 def test_parser(self): body = zebra.ZebraBfdDestinationRegister.parse(self.buf) self.assertEqual(self.pid, body.pid) self.assertEqual(self.dst_family, body.dst_family) self.assertEqual(self.dst_prefix, body.dst_prefix) self.assertEqual(self.min_rx_timer, body.min_rx_timer) self.assertEqual(self.min_tx_timer, body.min_tx_timer) self.assertEqual(self.detect_mult, body.detect_mult) self.assertEqual(self.multi_hop, body.multi_hop) self.assertEqual(self.src_family, body.src_family) self.assertEqual(self.src_prefix, body.src_prefix) self.assertEqual(self.multi_hop_count, body.multi_hop_count) self.assertEqual(self.ifname, body.ifname) buf = body.serialize() self.assertEqual(binary_str(self.buf), binary_str(buf)) class TestZebraBfdDestinationRegisterMultiHopEnabledIPv6(unittest.TestCase): buf = ( b'\x00\x00\x00\x01' # pid b'\x00\x0a' # dst_family b'\x20\x01\x0d\xb8' # dst_prefix b'\x00\x00\x00\x00' b'\x00\x00\x00\x00' b'\x00\x00\x00\x01' b'\x00\x00\x00\x10' # min_rx_timer b'\x00\x00\x00\x20' # min_tx_timer b'\x01' # detect_mult b'\x01' # multi_hop b'\x00\x0a' # src_family b'\x20\x01\x0d\xb8' # src_prefix b'\x00\x00\x00\x00' b'\x00\x00\x00\x00' b'\x00\x00\x00\x02' b'\x05' # multi_hop_count ) pid = 1 dst_family = socket.AF_INET6 dst_prefix = '2001:db8::1' min_rx_timer = 0x10 min_tx_timer = 0x20 detect_mult = 1 multi_hop = 1 src_family = socket.AF_INET6 src_prefix = '2001:db8::2' multi_hop_count = 5 ifname = None @_patch_frr_v2 def test_parser(self): body = zebra.ZebraBfdDestinationRegister.parse(self.buf) self.assertEqual(self.pid, body.pid) self.assertEqual(self.dst_family, body.dst_family) self.assertEqual(self.dst_prefix, body.dst_prefix) self.assertEqual(self.min_rx_timer, body.min_rx_timer) self.assertEqual(self.min_tx_timer, body.min_tx_timer) self.assertEqual(self.detect_mult, body.detect_mult) self.assertEqual(self.multi_hop, body.multi_hop) self.assertEqual(self.src_family, body.src_family) self.assertEqual(self.src_prefix, body.src_prefix) self.assertEqual(self.multi_hop_count, body.multi_hop_count) self.assertEqual(self.ifname, body.ifname) buf = body.serialize() self.assertEqual(binary_str(self.buf), binary_str(buf)) class TestZebraBfdDestinationDeregisterMultiHopEnabled(unittest.TestCase): buf = ( b'\x00\x00\x00\x01' # pid b'\x00\x02' # dst_family b'\xc0\xa8\x01\x01' # dst_prefix b'\x01' # multi_hop b'\x00\x02' # src_family b'\xc0\xa8\x01\x02' # src_prefix b'\x05' # multi_hop_count ) pid = 1 dst_family = socket.AF_INET dst_prefix = '192.168.1.1' multi_hop = 1 src_family = socket.AF_INET src_prefix = '192.168.1.2' multi_hop_count = 5 ifname = None @_patch_frr_v2 def test_parser(self): body = zebra.ZebraBfdDestinationDeregister.parse(self.buf) self.assertEqual(self.pid, body.pid) self.assertEqual(self.dst_family, body.dst_family) self.assertEqual(self.dst_prefix, body.dst_prefix) self.assertEqual(self.multi_hop, body.multi_hop) self.assertEqual(self.src_family, body.src_family) self.assertEqual(self.src_prefix, body.src_prefix) self.assertEqual(self.multi_hop_count, body.multi_hop_count) self.assertEqual(self.ifname, body.ifname) buf = body.serialize() self.assertEqual(binary_str(self.buf), binary_str(buf)) class TestZebraBfdDestinationDeregisterMultiHopDisabled(unittest.TestCase): buf = ( b'\x00\x00\x00\x01' # pid b'\x00\x02' # dst_family b'\xc0\xa8\x01\x01' # dst_prefix b'\x00' # multi_hop b'\x00\x02' # src_family b'\xc0\xa8\x01\x02' # src_prefix b'\x04' # ifname_len b'eth0' # ifname ) pid = 1 dst_family = socket.AF_INET dst_prefix = '192.168.1.1' multi_hop = 0 src_family = socket.AF_INET src_prefix = '192.168.1.2' multi_hop_count = None ifname = 'eth0' @_patch_frr_v2 def test_parser(self): body = zebra.ZebraBfdDestinationDeregister.parse(self.buf) self.assertEqual(self.pid, body.pid) self.assertEqual(self.dst_family, body.dst_family) self.assertEqual(self.dst_prefix, body.dst_prefix) self.assertEqual(self.multi_hop, body.multi_hop) self.assertEqual(self.src_family, body.src_family) self.assertEqual(self.src_prefix, body.src_prefix) self.assertEqual(self.multi_hop_count, body.multi_hop_count) self.assertEqual(self.ifname, body.ifname) buf = body.serialize() self.assertEqual(binary_str(self.buf), binary_str(buf)) class TestZebraBfdDestinationDeregisterMultiHopEnabledIPv6(unittest.TestCase): buf = ( b'\x00\x00\x00\x01' # pid b'\x00\x0a' # dst_family b'\x20\x01\x0d\xb8' # dst_prefix b'\x00\x00\x00\x00' b'\x00\x00\x00\x00' b'\x00\x00\x00\x01' b'\x01' # multi_hop b'\x00\x0a' # src_family b'\x20\x01\x0d\xb8' # src_prefix b'\x00\x00\x00\x00' b'\x00\x00\x00\x00' b'\x00\x00\x00\x02' b'\x05' # multi_hop_count ) pid = 1 dst_family = socket.AF_INET6 dst_prefix = '2001:db8::1' multi_hop = 1 src_family = socket.AF_INET6 src_prefix = '2001:db8::2' multi_hop_count = 5 ifname = None @_patch_frr_v2 def test_parser(self): body = zebra.ZebraBfdDestinationDeregister.parse(self.buf) self.assertEqual(self.pid, body.pid) self.assertEqual(self.dst_family, body.dst_family) self.assertEqual(self.dst_prefix, body.dst_prefix) self.assertEqual(self.multi_hop, body.multi_hop) self.assertEqual(self.src_family, body.src_family) self.assertEqual(self.src_prefix, body.src_prefix) self.assertEqual(self.multi_hop_count, body.multi_hop_count) self.assertEqual(self.ifname, body.ifname) buf = body.serialize() self.assertEqual(binary_str(self.buf), binary_str(buf)) class TestZebraVrfAdd(unittest.TestCase): buf = ( b'VRF1' # vrf_name b'\x00\x00\x00\x00' b'\x00\x00\x00\x00' b'\x00\x00\x00\x00' b'\x00\x00\x00\x00' b'\x00\x00\x00\x00' b'\x00\x00\x00\x00' b'\x00\x00\x00\x00' b'\x00\x00\x00\x00' ) vrf_name = 'VRF1' @_patch_frr_v2 def test_parser(self): body = zebra.ZebraVrfAdd.parse(self.buf) self.assertEqual(self.vrf_name, body.vrf_name) buf = body.serialize() self.assertEqual(binary_str(self.buf), binary_str(buf)) class TestZebraInterfaceVrfUpdate(unittest.TestCase): buf = ( b'\x00\x00\x00\x01' # ifindex b'\x00\x02' # vrf_id ) ifindex = 1 vrf_id = 2 @_patch_frr_v2 def test_parser(self): body = zebra.ZebraInterfaceVrfUpdate.parse(self.buf) self.assertEqual(self.ifindex, body.ifindex) self.assertEqual(self.vrf_id, body.vrf_id) buf = body.serialize() self.assertEqual(binary_str(self.buf), binary_str(buf)) class TestZebraInterfaceEnableRadv(unittest.TestCase): buf = ( b'\x00\x00\x00\x01' # ifindex b'\x00\x00\x01\x00' # interval ) ifindex = 1 interval = 0x100 @_patch_frr_v2 def test_parser(self): body = zebra.ZebraInterfaceEnableRadv.parse(self.buf) self.assertEqual(self.ifindex, body.ifindex) self.assertEqual(self.interval, body.interval) buf = body.serialize() self.assertEqual(binary_str(self.buf), binary_str(buf)) class TestZebraMplsLabelsAddIPv4(unittest.TestCase): buf = ( b'\x09' # route_type b'\x00\x00\x00\x02' # family b'\xc0\xa8\x01\x00' # prefix b'\x18' # prefix_len b'\xc0\xa8\x01\x01' # gate_addr b'\x10' # distance b'\x00\x00\x00\x64' # in_label b'\x00\x00\x00\x03' # out_label ) route_type = zebra.ZEBRA_ROUTE_BGP family = socket.AF_INET prefix = '192.168.1.0/24' gate_addr = '192.168.1.1' distance = 0x10 in_label = 100 out_label = zebra.MPLS_IMP_NULL_LABEL @_patch_frr_v2 def test_parser(self): body = zebra.ZebraMplsLabelsAdd.parse(self.buf) self.assertEqual(self.route_type, body.route_type) self.assertEqual(self.family, body.family) self.assertEqual(self.prefix, body.prefix) self.assertEqual(self.gate_addr, body.gate_addr) self.assertEqual(self.distance, body.distance) self.assertEqual(self.in_label, body.in_label) self.assertEqual(self.out_label, body.out_label) buf = body.serialize() self.assertEqual(binary_str(self.buf), binary_str(buf)) class TestZebraMplsLabelsAddIPv6(unittest.TestCase): buf = ( b'\x09' # route_type b'\x00\x00\x00\x0a' # family b'\x20\x01\x0d\xb8' # prefix b'\x00\x00\x00\x00' b'\x00\x00\x00\x00' b'\x00\x00\x00\x00' b'\x40' # prefix_len b'\x20\x01\x0d\xb8' # gate_addr b'\x00\x00\x00\x00' b'\x00\x00\x00\x00' b'\x00\x00\x00\x01' b'\x10' # distance b'\x00\x00\x00\x64' # in_label b'\x00\x00\x00\x03' # out_label ) route_type = zebra.ZEBRA_ROUTE_BGP family = socket.AF_INET6 prefix = '2001:db8::/64' gate_addr = '2001:db8::1' distance = 0x10 in_label = 100 out_label = zebra.MPLS_IMP_NULL_LABEL @_patch_frr_v2 def test_parser(self): body = zebra.ZebraMplsLabelsAdd.parse(self.buf) self.assertEqual(self.route_type, body.route_type) self.assertEqual(self.family, body.family) self.assertEqual(self.prefix, body.prefix) self.assertEqual(self.gate_addr, body.gate_addr) self.assertEqual(self.distance, body.distance) self.assertEqual(self.in_label, body.in_label) self.assertEqual(self.out_label, body.out_label) buf = body.serialize() self.assertEqual(binary_str(self.buf), binary_str(buf)) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.3661208 os-ken-2.10.0/os_ken/tests/unit/services/0000775000175000017500000000000000000000000020233 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/services/__init__.py0000664000175000017500000000000000000000000022332 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.3661208 os-ken-2.10.0/os_ken/tests/unit/services/protocols/0000775000175000017500000000000000000000000022257 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/services/protocols/__init__.py0000664000175000017500000000000000000000000024356 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.3661208 os-ken-2.10.0/os_ken/tests/unit/services/protocols/bgp/0000775000175000017500000000000000000000000023027 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/services/protocols/bgp/__init__.py0000664000175000017500000000000000000000000025126 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.3661208 os-ken-2.10.0/os_ken/tests/unit/services/protocols/bgp/core_managers/0000775000175000017500000000000000000000000025634 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/services/protocols/bgp/core_managers/__init__.py0000664000175000017500000000000000000000000027733 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/services/protocols/bgp/core_managers/test_table_manager.py0000664000175000017500000010003500000000000032025 0ustar00zuulzuul00000000000000# Copyright (C) 2016 Nippon Telegraph and Telephone 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. from collections import OrderedDict import logging import unittest from unittest import mock from os_ken.lib.packet.bgp import BGPPathAttributeOrigin from os_ken.lib.packet.bgp import BGPPathAttributeAsPath from os_ken.lib.packet.bgp import BGP_ATTR_ORIGIN_IGP from os_ken.lib.packet.bgp import BGP_ATTR_TYPE_ORIGIN from os_ken.lib.packet.bgp import BGP_ATTR_TYPE_AS_PATH from os_ken.lib.packet.bgp import IPAddrPrefix from os_ken.lib.packet.bgp import IP6AddrPrefix from os_ken.lib.packet.bgp import EvpnArbitraryEsi from os_ken.lib.packet.bgp import EvpnLACPEsi from os_ken.lib.packet.bgp import EvpnEthernetAutoDiscoveryNLRI from os_ken.lib.packet.bgp import EvpnMacIPAdvertisementNLRI from os_ken.lib.packet.bgp import EvpnInclusiveMulticastEthernetTagNLRI from os_ken.services.protocols.bgp.bgpspeaker import EVPN_MAX_ET from os_ken.services.protocols.bgp.bgpspeaker import ESI_TYPE_LACP from os_ken.services.protocols.bgp.core import BgpCoreError from os_ken.services.protocols.bgp.core_managers import table_manager from os_ken.services.protocols.bgp.rtconf.vrfs import VRF_RF_IPV4 from os_ken.services.protocols.bgp.rtconf.vrfs import VRF_RF_IPV6 from os_ken.services.protocols.bgp.rtconf.vrfs import VRF_RF_L2_EVPN LOG = logging.getLogger(__name__) class Test_TableCoreManager(unittest.TestCase): """ Test case for bgp.core_managers.table_manager.TableCoreManager """ @mock.patch( 'os_ken.services.protocols.bgp.core_managers.TableCoreManager.__init__', mock.MagicMock(return_value=None)) def _test_update_vrf_table(self, prefix_inst, route_dist, prefix_str, next_hop, route_family, route_type, is_withdraw=False, **kwargs): # Instantiate TableCoreManager tbl_mng = table_manager.TableCoreManager(None, None) vrf_table_mock = mock.MagicMock() tbl_mng._tables = {(route_dist, route_family): vrf_table_mock} # Test tbl_mng.update_vrf_table( route_dist=route_dist, prefix=prefix_str, next_hop=next_hop, route_family=route_family, route_type=route_type, is_withdraw=is_withdraw, **kwargs) # Check call_args_list = vrf_table_mock.insert_vrf_path.call_args_list self.assertTrue(len(call_args_list) == 1) # insert_vrf_path should be called once args, kwargs = call_args_list[0] self.assertTrue(len(args) == 0) # no positional argument self.assertEqual(str(prefix_inst), str(kwargs['nlri'])) self.assertEqual(is_withdraw, kwargs['is_withdraw']) if is_withdraw: self.assertEqual(None, kwargs['next_hop']) self.assertEqual(False, kwargs['gen_lbl']) else: self.assertEqual(next_hop, kwargs['next_hop']) self.assertEqual(True, kwargs['gen_lbl']) def test_update_vrf_table_ipv4(self): # Prepare test data route_dist = '65000:100' ip_network = '192.168.0.0' ip_prefix_len = 24 prefix_str = '%s/%d' % (ip_network, ip_prefix_len) prefix_inst = IPAddrPrefix(ip_prefix_len, ip_network) next_hop = '10.0.0.1' route_family = VRF_RF_IPV4 route_type = None # should be ignored kwargs = {} # should be ignored self._test_update_vrf_table(prefix_inst, route_dist, prefix_str, next_hop, route_family, route_type, **kwargs) def test_update_vrf_table_ipv6(self): # Prepare test data route_dist = '65000:100' ip_network = 'fe80::' ip_prefix_len = 64 prefix_str = '%s/%d' % (ip_network, ip_prefix_len) prefix_inst = IP6AddrPrefix(ip_prefix_len, ip_network) next_hop = 'fe80::0011:aabb:ccdd:eeff' route_family = VRF_RF_IPV6 route_type = None # should be ignored kwargs = {} # should be ignored self._test_update_vrf_table(prefix_inst, route_dist, prefix_str, next_hop, route_family, route_type, **kwargs) def test_update_vrf_table_l2_evpn_with_esi_int(self): # Prepare test data route_dist = '65000:100' prefix_str = None # should be ignored kwargs = { 'ethernet_tag_id': 100, 'mac_addr': 'aa:bb:cc:dd:ee:ff', 'ip_addr': '192.168.0.1', 'mpls_labels': [], # not be used } esi = EvpnArbitraryEsi(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00') prefix_inst = EvpnMacIPAdvertisementNLRI( route_dist=route_dist, esi=esi, **kwargs) next_hop = '10.0.0.1' route_family = VRF_RF_L2_EVPN route_type = EvpnMacIPAdvertisementNLRI.ROUTE_TYPE_NAME kwargs['esi'] = 0 self._test_update_vrf_table(prefix_inst, route_dist, prefix_str, next_hop, route_family, route_type, **kwargs) def test_update_vrf_table_l2_evpn_with_esi_dict(self): # Prepare test data route_dist = '65000:100' prefix_str = None # should be ignored kwargs = { 'ethernet_tag_id': EVPN_MAX_ET, } esi = EvpnLACPEsi(mac_addr='aa:bb:cc:dd:ee:ff', port_key=100) prefix_inst = EvpnEthernetAutoDiscoveryNLRI( route_dist=route_dist, esi=esi, **kwargs) next_hop = '0.0.0.0' route_family = VRF_RF_L2_EVPN route_type = EvpnEthernetAutoDiscoveryNLRI.ROUTE_TYPE_NAME kwargs['esi'] = { 'type': ESI_TYPE_LACP, 'mac_addr': 'aa:bb:cc:dd:ee:ff', 'port_key': 100, } self._test_update_vrf_table(prefix_inst, route_dist, prefix_str, next_hop, route_family, route_type, **kwargs) def test_update_vrf_table_l2_evpn_without_esi(self): # Prepare test data route_dist = '65000:100' prefix_str = None # should be ignored kwargs = { 'ethernet_tag_id': 100, 'ip_addr': '192.168.0.1', } prefix_inst = EvpnInclusiveMulticastEthernetTagNLRI( route_dist=route_dist, **kwargs) next_hop = '10.0.0.1' route_family = VRF_RF_L2_EVPN route_type = EvpnInclusiveMulticastEthernetTagNLRI.ROUTE_TYPE_NAME self._test_update_vrf_table(prefix_inst, route_dist, prefix_str, next_hop, route_family, route_type, **kwargs) @mock.patch( 'os_ken.services.protocols.bgp.core_managers.TableCoreManager.__init__', mock.MagicMock(return_value=None)) def test_update_vrf_table_l2_evpn_with_vni(self): # Prepare test data route_dist = '65000:100' prefix_str = None # should be ignored kwargs = { 'ethernet_tag_id': 100, 'mac_addr': 'aa:bb:cc:dd:ee:ff', 'ip_addr': '192.168.0.1', 'vni': 500, } esi = EvpnArbitraryEsi(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00') prefix_inst = EvpnMacIPAdvertisementNLRI( route_dist=route_dist, esi=esi, **kwargs) next_hop = '10.0.0.1' route_family = VRF_RF_L2_EVPN route_type = EvpnMacIPAdvertisementNLRI.ROUTE_TYPE_NAME tunnel_type = 'vxlan' kwargs['esi'] = 0 # Instantiate TableCoreManager tbl_mng = table_manager.TableCoreManager(None, None) vrf_table_mock = mock.MagicMock() tbl_mng._tables = {(route_dist, route_family): vrf_table_mock} # Test tbl_mng.update_vrf_table( route_dist=route_dist, prefix=prefix_str, next_hop=next_hop, route_family=route_family, route_type=route_type, tunnel_type=tunnel_type, **kwargs) # Check call_args_list = vrf_table_mock.insert_vrf_path.call_args_list self.assertTrue( len(call_args_list) == 1) # insert_vrf_path should be called once args, kwargs = call_args_list[0] self.assertTrue(len(args) == 0) # no positional argument self.assertEqual(str(prefix_inst), str(kwargs['nlri'])) self.assertEqual(next_hop, kwargs['next_hop']) self.assertEqual( False, kwargs['gen_lbl']) # should not generate MPLS labels self.assertEqual(tunnel_type, kwargs['tunnel_type']) def test_update_vrf_table_ipv4_withdraw(self): # Prepare test data route_dist = '65000:100' ip_network = '192.168.0.0' ip_prefix_len = 24 prefix_str = '%s/%d' % (ip_network, ip_prefix_len) prefix_inst = IPAddrPrefix(ip_prefix_len, ip_network) next_hop = '10.0.0.1' route_family = VRF_RF_IPV4 route_type = None # should be ignored kwargs = {} # should be ignored self._test_update_vrf_table(prefix_inst, route_dist, prefix_str, next_hop, route_family, route_type, is_withdraw=True, **kwargs) @mock.patch( 'os_ken.services.protocols.bgp.core_managers.TableCoreManager.__init__', mock.MagicMock(return_value=None)) def test_update_vrf_table_no_vrf(self): # Prepare test data route_dist = '65000:100' ip_network = '192.168.0.0' ip_prefix_len = 24 prefix_str = '%s/%d' % (ip_network, ip_prefix_len) next_hop = '10.0.0.1' route_family = VRF_RF_IPV4 route_type = None # should be ignored kwargs = {} # should be ignored # Instantiate TableCoreManager tbl_mng = table_manager.TableCoreManager(None, None) tbl_mng._tables = {} # no table # Test self.assertRaises(BgpCoreError, tbl_mng.update_vrf_table, route_dist=route_dist, prefix=prefix_str, next_hop=next_hop, route_family=route_family, route_type=route_type, **kwargs) def test_update_vrf_table_invalid_next_hop(self): # Prepare test data route_dist = '65000:100' ip_network = '192.168.0.0' ip_prefix_len = 24 prefix_str = '%s/%d' % (ip_network, ip_prefix_len) prefix_inst = IPAddrPrefix(ip_prefix_len, ip_network) next_hop = 'xxx.xxx.xxx.xxx' # invalid route_family = VRF_RF_IPV4 route_type = None # should be ignored kwargs = {} # should be ignored self.assertRaises(BgpCoreError, self._test_update_vrf_table, prefix_inst, route_dist, prefix_str, next_hop, route_family, route_type, **kwargs) def test_update_vrf_table_invalid_ipv4_prefix(self): # Prepare test data route_dist = '65000:100' ip_network = 'xxx.xxx.xxx.xxx' # invalid ip_prefix_len = 24 prefix_str = '%s/%d' % (ip_network, ip_prefix_len) prefix_inst = IPAddrPrefix(ip_prefix_len, ip_network) next_hop = '10.0.0.1' route_family = VRF_RF_IPV4 route_type = None # should be ignored kwargs = {} # should be ignored self.assertRaises(BgpCoreError, self._test_update_vrf_table, prefix_inst, route_dist, prefix_str, next_hop, route_family, route_type, **kwargs) def test_update_vrf_table_invalid_ipv6_prefix(self): # Prepare test data route_dist = '65000:100' ip_network = 'xxxx::' # invalid ip_prefix_len = 64 prefix_str = '%s/%d' % (ip_network, ip_prefix_len) prefix_inst = IP6AddrPrefix(ip_prefix_len, ip_network) next_hop = 'fe80::0011:aabb:ccdd:eeff' route_family = VRF_RF_IPV6 route_type = None # should be ignored kwargs = {} # should be ignored self.assertRaises(BgpCoreError, self._test_update_vrf_table, prefix_inst, route_dist, prefix_str, next_hop, route_family, route_type, **kwargs) def test_update_vrf_table_invalid_route_family(self): # Prepare test data route_dist = '65000:100' ip_network = '192.168.0.0' ip_prefix_len = 24 prefix_str = '%s/%d' % (ip_network, ip_prefix_len) prefix_inst = IPAddrPrefix(ip_prefix_len, ip_network) next_hop = '10.0.0.1' route_family = 'foobar' # invalid route_type = None # should be ignored kwargs = {} # should be ignored self.assertRaises(BgpCoreError, self._test_update_vrf_table, prefix_inst, route_dist, prefix_str, next_hop, route_family, route_type, **kwargs) @mock.patch( 'os_ken.services.protocols.bgp.core_managers.TableCoreManager.__init__', mock.MagicMock(return_value=None)) @mock.patch( 'os_ken.services.protocols.bgp.core_managers.TableCoreManager.learn_path') def _test_update_global_table(self, learn_path_mock, prefix, next_hop, is_withdraw, expected_next_hop): # Prepare test data origin = BGPPathAttributeOrigin(BGP_ATTR_ORIGIN_IGP) aspath = BGPPathAttributeAsPath([[]]) pathattrs = OrderedDict() pathattrs[BGP_ATTR_TYPE_ORIGIN] = origin pathattrs[BGP_ATTR_TYPE_AS_PATH] = aspath pathattrs = str(pathattrs) # Instantiate TableCoreManager tbl_mng = table_manager.TableCoreManager(None, None) # Test tbl_mng.update_global_table( prefix=prefix, next_hop=next_hop, is_withdraw=is_withdraw, ) # Check call_args_list = learn_path_mock.call_args_list self.assertTrue(len(call_args_list) == 1) # learn_path should be called once args, kwargs = call_args_list[0] self.assertTrue(len(kwargs) == 0) # no keyword argument output_path = args[0] self.assertEqual(None, output_path.source) self.assertEqual(prefix, output_path.nlri.prefix) self.assertEqual(pathattrs, str(output_path.pathattr_map)) self.assertEqual(expected_next_hop, output_path.nexthop) self.assertEqual(is_withdraw, output_path.is_withdraw) def test_update_global_table_ipv4(self): self._test_update_global_table( prefix='192.168.0.0/24', next_hop='10.0.0.1', is_withdraw=False, expected_next_hop='10.0.0.1', ) def test_update_global_table_ipv4_withdraw(self): self._test_update_global_table( prefix='192.168.0.0/24', next_hop='10.0.0.1', is_withdraw=True, expected_next_hop='10.0.0.1', ) def test_update_global_table_ipv4_no_next_hop(self): self._test_update_global_table( prefix='192.168.0.0/24', next_hop=None, is_withdraw=True, expected_next_hop='0.0.0.0', ) def test_update_global_table_ipv6(self): self._test_update_global_table( prefix='fe80::/64', next_hop='fe80::0011:aabb:ccdd:eeff', is_withdraw=False, expected_next_hop='fe80::0011:aabb:ccdd:eeff', ) def test_update_global_table_ipv6_withdraw(self): self._test_update_global_table( prefix='fe80::/64', next_hop='fe80::0011:aabb:ccdd:eeff', is_withdraw=True, expected_next_hop='fe80::0011:aabb:ccdd:eeff', ) def test_update_global_table_ipv6_no_next_hop(self): self._test_update_global_table( prefix='fe80::/64', next_hop=None, is_withdraw=True, expected_next_hop='::', ) @mock.patch( 'os_ken.services.protocols.bgp.core_managers.TableCoreManager.__init__', mock.MagicMock(return_value=None)) def _test_update_flowspec_vrf_table(self, flowspec_family, route_family, route_dist, rules, prefix, is_withdraw, actions=None): # Instantiate TableCoreManager tbl_mng = table_manager.TableCoreManager(None, None) vrf_table_mock = mock.MagicMock() tbl_mng._tables = {(route_dist, route_family): vrf_table_mock} # Test tbl_mng.update_flowspec_vrf_table( flowspec_family=flowspec_family, route_dist=route_dist, rules=rules, actions=actions, is_withdraw=is_withdraw, ) # Check call_args_list = vrf_table_mock.insert_vrffs_path.call_args_list self.assertTrue(len( call_args_list) == 1) # insert_vrffs_path should be called once args, kwargs = call_args_list[0] self.assertTrue(len(args) == 0) # no positional argument self.assertEqual(prefix, kwargs['nlri'].prefix) self.assertEqual(is_withdraw, kwargs['is_withdraw']) def test_update_flowspec_vrf_table_vpnv4(self): flowspec_family = 'vpnv4fs' route_family = 'ipv4fs' route_dist = '65001:100' rules = { 'dst_prefix': '10.70.1.0/24', } actions = { 'traffic_rate': { 'as_number': 0, 'rate_info': 100.0, }, } prefix = 'ipv4fs(dst_prefix:10.70.1.0/24)' self._test_update_flowspec_vrf_table( flowspec_family=flowspec_family, route_family=route_family, route_dist=route_dist, rules=rules, prefix=prefix, is_withdraw=False, actions=actions, ) def test_update_flowspec_vrf_table_vpnv4_without_actions(self): flowspec_family = 'vpnv4fs' route_family = 'ipv4fs' route_dist = '65001:100' rules = { 'dst_prefix': '10.70.1.0/24', } prefix = 'ipv4fs(dst_prefix:10.70.1.0/24)' self._test_update_flowspec_vrf_table( flowspec_family=flowspec_family, route_family=route_family, route_dist=route_dist, rules=rules, prefix=prefix, is_withdraw=False, ) def test_update_flowspec_vrf_table_vpnv4_invalid_actions(self): flowspec_family = 'vpnv4fs' route_family = 'ipv4fs' route_dist = '65001:100' rules = { 'dst_prefix': '10.70.1.0/24', } actions = { 'invalid_actions': { 'invalid_param': 10, }, } prefix = 'ipv4fs(dst_prefix:10.70.1.0/24)' self.assertRaises(BgpCoreError, self._test_update_flowspec_vrf_table, flowspec_family=flowspec_family, route_family=route_family, route_dist=route_dist, rules=rules, prefix=prefix, is_withdraw=False, actions=actions) def test_update_flowspec_vrf_table_vpnv4_invalid_flowspec_family(self): flowspec_family = 'invalid' route_family = 'ipv4fs' route_dist = '65001:100' rules = { 'dst_prefix': '10.70.1.0/24', } prefix = 'ipv4fs(dst_prefix:10.70.1.0/24)' self.assertRaises(BgpCoreError, self._test_update_flowspec_vrf_table, flowspec_family=flowspec_family, route_family=route_family, route_dist=route_dist, rules=rules, prefix=prefix, is_withdraw=False) def test_update_flowspec_vrf_table_vpnv4_invalid_route_family(self): flowspec_family = 'vpnv4fs' route_family = 'invalid' route_dist = '65001:100' rules = { 'dst_prefix': '10.70.1.0/24', } prefix = 'ipv4fs(dst_prefix:10.70.1.0/24)' self.assertRaises(BgpCoreError, self._test_update_flowspec_vrf_table, flowspec_family=flowspec_family, route_family=route_family, route_dist=route_dist, rules=rules, prefix=prefix, is_withdraw=False) @mock.patch( 'os_ken.services.protocols.bgp.core_managers.TableCoreManager.__init__', mock.MagicMock(return_value=None)) @mock.patch( 'os_ken.services.protocols.bgp.core_managers.TableCoreManager.learn_path') def _test_update_flowspec_global_table(self, learn_path_mock, flowspec_family, rules, prefix, is_withdraw, actions=None): # Instantiate TableCoreManager tbl_mng = table_manager.TableCoreManager(None, None) # Test tbl_mng.update_flowspec_global_table( flowspec_family=flowspec_family, rules=rules, actions=actions, is_withdraw=is_withdraw, ) # Check call_args_list = learn_path_mock.call_args_list self.assertTrue(len(call_args_list) == 1) # learn_path should be called once args, kwargs = call_args_list[0] self.assertTrue(len(kwargs) == 0) # no keyword argument output_path = args[0] self.assertEqual(None, output_path.source) self.assertEqual(prefix, output_path.nlri.prefix) self.assertEqual(None, output_path.nexthop) self.assertEqual(is_withdraw, output_path.is_withdraw) def test_update_flowspec_global_table_ipv4(self): flowspec_family = 'ipv4fs' rules = { 'dst_prefix': '10.60.1.0/24', } actions = { 'traffic_rate': { 'as_number': 0, 'rate_info': 100.0, }, } prefix = 'ipv4fs(dst_prefix:10.60.1.0/24)' self._test_update_flowspec_global_table( flowspec_family=flowspec_family, rules=rules, prefix=prefix, is_withdraw=False, actions=actions, ) def test_update_flowspec_global_table_ipv4_without_actions(self): flowspec_family = 'ipv4fs' rules = { 'dst_prefix': '10.60.1.0/24', } prefix = 'ipv4fs(dst_prefix:10.60.1.0/24)' self._test_update_flowspec_global_table( flowspec_family=flowspec_family, rules=rules, prefix=prefix, is_withdraw=False, ) def test_update_flowspec_global_table_ipv4_invalid_actions(self): flowspec_family = 'ipv4fs' rules = { 'dst_prefix': '10.60.1.0/24', } actions = { 'invalid_actions': { 'invalid_param': 10, }, } prefix = 'ipv4fs(dst_prefix:10.60.1.0/24)' self.assertRaises(BgpCoreError, self._test_update_flowspec_global_table, flowspec_family=flowspec_family, rules=rules, prefix=prefix, is_withdraw=False, actions=actions) def test_update_flowspec_global_table_ipv4_invalid_flowspec_family(self): flowspec_family = 'invalid' rules = { 'dst_prefix': '10.60.1.0/24', } actions = { 'traffic_rate': { 'as_number': 0, 'rate_info': 100.0, }, } prefix = 'ipv4fs(dst_prefix:10.60.1.0/24)' self.assertRaises(BgpCoreError, self._test_update_flowspec_global_table, flowspec_family=flowspec_family, rules=rules, prefix=prefix, is_withdraw=False, actions=actions) def test_update_flowspec_global_table_ipv6(self): flowspec_family = 'ipv6fs' rules = { 'dst_prefix': '2001::3/128/32', } actions = { 'traffic_rate': { 'as_number': 0, 'rate_info': 100.0, }, } prefix = 'ipv6fs(dst_prefix:2001::3/128/32)' self._test_update_flowspec_global_table( flowspec_family=flowspec_family, rules=rules, prefix=prefix, is_withdraw=False, actions=actions, ) def test_update_flowspec_global_table_ipv6_without_actions(self): flowspec_family = 'ipv6fs' rules = { 'dst_prefix': '2001::3/128/32', } prefix = 'ipv6fs(dst_prefix:2001::3/128/32)' self._test_update_flowspec_global_table( flowspec_family=flowspec_family, rules=rules, prefix=prefix, is_withdraw=False, ) def test_update_flowspec_global_table_ipv6_invalid_actions(self): flowspec_family = 'ipv6fs' rules = { 'dst_prefix': '2001::3/128/32', } actions = { 'invalid_actions': { 'invalid_param': 10, }, } prefix = 'ipv4fs(dst_prefix:2001::3/128/32)' self.assertRaises(BgpCoreError, self._test_update_flowspec_global_table, flowspec_family=flowspec_family, rules=rules, prefix=prefix, is_withdraw=False, actions=actions) def test_update_flowspec_global_table_ipv6_invalid_flowspec_family(self): flowspec_family = 'invalid' rules = { 'dst_prefix': '2001::3/128/32', } actions = { 'traffic_rate': { 'as_number': 0, 'rate_info': 100.0, }, } prefix = 'ipv4fs(dst_prefix:2001::3/128/32)' self.assertRaises(BgpCoreError, self._test_update_flowspec_global_table, flowspec_family=flowspec_family, rules=rules, prefix=prefix, is_withdraw=False, actions=actions) def test_update_flowspec_vrf_table_vpnv6(self): flowspec_family = 'vpnv6fs' route_family = 'ipv6fs' route_dist = '65001:100' rules = { 'dst_prefix': '2001::3/128/32', } actions = { 'traffic_rate': { 'as_number': 0, 'rate_info': 100.0, }, } prefix = 'ipv6fs(dst_prefix:2001::3/128/32)' self._test_update_flowspec_vrf_table( flowspec_family=flowspec_family, route_family=route_family, route_dist=route_dist, rules=rules, prefix=prefix, is_withdraw=False, actions=actions, ) def test_update_flowspec_vrf_table_vpnv6_without_actions(self): flowspec_family = 'vpnv6fs' route_family = 'ipv6fs' route_dist = '65001:100' rules = { 'dst_prefix': '2001::3/128/32', } prefix = 'ipv6fs(dst_prefix:2001::3/128/32)' self._test_update_flowspec_vrf_table( flowspec_family=flowspec_family, route_family=route_family, route_dist=route_dist, rules=rules, prefix=prefix, is_withdraw=False, ) def test_update_flowspec_vrf_table_vpnv6_invalid_actions(self): flowspec_family = 'vpnv6fs' route_family = 'ipv6fs' route_dist = '65001:100' rules = { 'dst_prefix': '2001::3/128/32', } actions = { 'invalid_actions': { 'invalid_param': 10, }, } prefix = 'ipv6fs(dst_prefix:2001::3/128/32)' self.assertRaises(BgpCoreError, self._test_update_flowspec_vrf_table, flowspec_family=flowspec_family, route_family=route_family, route_dist=route_dist, rules=rules, prefix=prefix, is_withdraw=False, actions=actions) def test_update_flowspec_vrf_table_vpnv6_invalid_route_family(self): flowspec_family = 'vpnv6fs' route_family = 'invalid' route_dist = '65001:100' rules = { 'dst_prefix': '2001::3/128/32', } prefix = 'ipv4fs(dst_prefix:2001::3/128/32)' self.assertRaises(BgpCoreError, self._test_update_flowspec_vrf_table, flowspec_family=flowspec_family, route_family=route_family, route_dist=route_dist, rules=rules, prefix=prefix, is_withdraw=False) def test_update_flowspec_vrf_table_l2vpn(self): flowspec_family = 'l2vpnfs' route_family = 'l2vpnfs' route_dist = '65001:100' rules = { 'dst_mac': '12:34:56:78:9a:bc', } actions = { 'traffic_rate': { 'as_number': 0, 'rate_info': 100.0, }, } prefix = 'l2vpnfs(dst_mac:12:34:56:78:9a:bc)' self._test_update_flowspec_vrf_table( flowspec_family=flowspec_family, route_family=route_family, route_dist=route_dist, rules=rules, prefix=prefix, is_withdraw=False, actions=actions, ) def test_update_flowspec_vrf_table_l2vpn_without_actions(self): flowspec_family = 'l2vpnfs' route_family = 'l2vpnfs' route_dist = '65001:100' rules = { 'dst_mac': '12:34:56:78:9a:bc', } prefix = 'l2vpnfs(dst_mac:12:34:56:78:9a:bc)' self._test_update_flowspec_vrf_table( flowspec_family=flowspec_family, route_family=route_family, route_dist=route_dist, rules=rules, prefix=prefix, is_withdraw=False, ) def test_update_flowspec_vrf_table_l2vpn_invalid_actions(self): flowspec_family = 'l2vpnfs' route_family = 'l2vpnfs' route_dist = '65001:100' rules = { 'dst_mac': '12:34:56:78:9a:bc', } actions = { 'invalid_actions': { 'invalid_param': 10, }, } prefix = 'l2vpnfs(dst_mac:12:34:56:78:9a:bc)' self.assertRaises(BgpCoreError, self._test_update_flowspec_vrf_table, flowspec_family=flowspec_family, route_family=route_family, route_dist=route_dist, rules=rules, prefix=prefix, is_withdraw=False, actions=actions) def test_update_flowspec_vrf_table_l2vpn_invalid_route_family(self): flowspec_family = 'l2vpnfs' route_family = 'invalid' route_dist = '65001:100' rules = { 'dst_mac': '12:34:56:78:9a:bc', } prefix = 'l2vpnfs(dst_mac:12:34:56:78:9a:bc)' self.assertRaises(BgpCoreError, self._test_update_flowspec_vrf_table, flowspec_family=flowspec_family, route_family=route_family, route_dist=route_dist, rules=rules, prefix=prefix, is_withdraw=False) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/services/protocols/bgp/test_bgpspeaker.py0000664000175000017500000010532700000000000026573 0ustar00zuulzuul00000000000000# Copyright (C) 2016 Nippon Telegraph and Telephone 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. import logging import unittest from unittest import mock from os_ken.services.protocols.bgp import bgpspeaker from os_ken.services.protocols.bgp.bgpspeaker import EVPN_MAX_ET from os_ken.services.protocols.bgp.bgpspeaker import ESI_TYPE_LACP from os_ken.services.protocols.bgp.api.prefix import ESI_TYPE_L2_BRIDGE from os_ken.services.protocols.bgp.bgpspeaker import ESI_TYPE_MAC_BASED from os_ken.services.protocols.bgp.api.prefix import REDUNDANCY_MODE_ALL_ACTIVE from os_ken.services.protocols.bgp.api.prefix import REDUNDANCY_MODE_SINGLE_ACTIVE LOG = logging.getLogger(__name__) class Test_BGPSpeaker(unittest.TestCase): """ Test case for bgp.bgpspeaker.BGPSpeaker """ @mock.patch('os_ken.services.protocols.bgp.bgpspeaker.BGPSpeaker.__init__', mock.MagicMock(return_value=None)) @mock.patch('os_ken.services.protocols.bgp.bgpspeaker.call') def test_evpn_prefix_add_eth_auto_discovery(self, mock_call): # Prepare test data route_type = bgpspeaker.EVPN_ETH_AUTO_DISCOVERY route_dist = '65000:100' esi = { 'type': ESI_TYPE_LACP, 'mac_addr': 'aa:bb:cc:dd:ee:ff', 'port_key': 100, } ethernet_tag_id = EVPN_MAX_ET redundancy_mode = REDUNDANCY_MODE_ALL_ACTIVE next_hop = '0.0.0.0' expected_kwargs = { 'route_type': route_type, 'route_dist': route_dist, 'esi': esi, 'ethernet_tag_id': ethernet_tag_id, 'redundancy_mode': redundancy_mode, 'next_hop': next_hop, } # Test speaker = bgpspeaker.BGPSpeaker(65000, '10.0.0.1') speaker.evpn_prefix_add( route_type=route_type, route_dist=route_dist, esi=esi, ethernet_tag_id=ethernet_tag_id, redundancy_mode=redundancy_mode, ) # Check mock_call.assert_called_with( 'evpn_prefix.add_local', **expected_kwargs) @mock.patch( 'os_ken.services.protocols.bgp.bgpspeaker.BGPSpeaker.__init__', mock.MagicMock(return_value=None)) @mock.patch('os_ken.services.protocols.bgp.bgpspeaker.call') def test_evpn_prefix_add_eth_auto_discovery_vni(self, mock_call): # Prepare test data route_type = bgpspeaker.EVPN_ETH_AUTO_DISCOVERY route_dist = '65000:100' esi = { 'type': ESI_TYPE_L2_BRIDGE, 'mac_addr': 'aa:bb:cc:dd:ee:ff', 'priority': 100, } ethernet_tag_id = EVPN_MAX_ET redundancy_mode = REDUNDANCY_MODE_SINGLE_ACTIVE vni = 500 next_hop = '0.0.0.0' expected_kwargs = { 'route_type': route_type, 'route_dist': route_dist, 'esi': esi, 'ethernet_tag_id': ethernet_tag_id, 'redundancy_mode': redundancy_mode, 'vni': vni, 'next_hop': next_hop, } # Test speaker = bgpspeaker.BGPSpeaker(65000, '10.0.0.1') speaker.evpn_prefix_add( route_type=route_type, route_dist=route_dist, esi=esi, ethernet_tag_id=ethernet_tag_id, redundancy_mode=redundancy_mode, vni=vni ) # Check mock_call.assert_called_with( 'evpn_prefix.add_local', **expected_kwargs) @mock.patch('os_ken.services.protocols.bgp.bgpspeaker.BGPSpeaker.__init__', mock.MagicMock(return_value=None)) @mock.patch('os_ken.services.protocols.bgp.bgpspeaker.call') def test_evpn_prefix_add_mac_ip_adv(self, mock_call): # Prepare test data route_type = bgpspeaker.EVPN_MAC_IP_ADV_ROUTE route_dist = '65000:100' esi = 0 # denotes single-homed ethernet_tag_id = 200 mac_addr = 'aa:bb:cc:dd:ee:ff' ip_addr = '192.168.0.1' next_hop = '10.0.0.1' expected_kwargs = { 'route_type': route_type, 'route_dist': route_dist, 'esi': esi, 'ethernet_tag_id': ethernet_tag_id, 'mac_addr': mac_addr, 'ip_addr': ip_addr, 'next_hop': next_hop, } # Test speaker = bgpspeaker.BGPSpeaker(65000, '10.0.0.1') speaker.evpn_prefix_add( route_type=route_type, route_dist=route_dist, esi=esi, ethernet_tag_id=ethernet_tag_id, mac_addr=mac_addr, ip_addr=ip_addr, next_hop=next_hop, ) # Check mock_call.assert_called_with( 'evpn_prefix.add_local', **expected_kwargs) @mock.patch('os_ken.services.protocols.bgp.bgpspeaker.BGPSpeaker.__init__', mock.MagicMock(return_value=None)) @mock.patch('os_ken.services.protocols.bgp.bgpspeaker.call') def test_evpn_prefix_add_mac_ip_adv_vni(self, mock_call): # Prepare test data route_type = bgpspeaker.EVPN_MAC_IP_ADV_ROUTE route_dist = '65000:100' esi = 0 # denotes single-homed ethernet_tag_id = 200 mac_addr = 'aa:bb:cc:dd:ee:ff' ip_addr = '192.168.0.1' vni = 500 next_hop = '10.0.0.1' tunnel_type = bgpspeaker.TUNNEL_TYPE_VXLAN expected_kwargs = { 'route_type': route_type, 'route_dist': route_dist, 'esi': esi, 'ethernet_tag_id': ethernet_tag_id, 'mac_addr': mac_addr, 'ip_addr': ip_addr, 'vni': vni, 'next_hop': next_hop, 'tunnel_type': tunnel_type, } # Test speaker = bgpspeaker.BGPSpeaker(65000, '10.0.0.1') speaker.evpn_prefix_add( route_type=route_type, route_dist=route_dist, esi=esi, ethernet_tag_id=ethernet_tag_id, mac_addr=mac_addr, ip_addr=ip_addr, vni=vni, next_hop=next_hop, tunnel_type=tunnel_type, ) # Check mock_call.assert_called_with( 'evpn_prefix.add_local', **expected_kwargs) @mock.patch('os_ken.services.protocols.bgp.bgpspeaker.BGPSpeaker.__init__', mock.MagicMock(return_value=None)) @mock.patch('os_ken.services.protocols.bgp.bgpspeaker.call') def test_evpn_prefix_add_multicast_etag(self, mock_call): # Prepare test data route_type = bgpspeaker.EVPN_MULTICAST_ETAG_ROUTE route_dist = '65000:100' esi = 0 # denotes single-homed ethernet_tag_id = 200 mac_addr = 'aa:bb:cc:dd:ee:ff' ip_addr = '192.168.0.1' next_hop = '10.0.0.1' expected_kwargs = { 'route_type': route_type, 'route_dist': route_dist, # 'esi': esi, # should be ignored 'ethernet_tag_id': ethernet_tag_id, # 'mac_addr': mac_addr, # should be ignored 'ip_addr': ip_addr, 'next_hop': next_hop, } # Test speaker = bgpspeaker.BGPSpeaker(65000, '10.0.0.1') speaker.evpn_prefix_add( route_type=route_type, route_dist=route_dist, esi=esi, ethernet_tag_id=ethernet_tag_id, mac_addr=mac_addr, ip_addr=ip_addr, next_hop=next_hop, ) # Check mock_call.assert_called_with( 'evpn_prefix.add_local', **expected_kwargs) @mock.patch('os_ken.services.protocols.bgp.bgpspeaker.BGPSpeaker.__init__', mock.MagicMock(return_value=None)) @mock.patch('os_ken.services.protocols.bgp.bgpspeaker.call') def test_evpn_prefix_add_multicast_etag_no_next_hop(self, mock_call): # Prepare test data route_type = bgpspeaker.EVPN_MULTICAST_ETAG_ROUTE route_dist = '65000:100' esi = 0 # denotes single-homed ethernet_tag_id = 200 mac_addr = 'aa:bb:cc:dd:ee:ff' ip_addr = '192.168.0.1' next_hop = '0.0.0.0' # the default value expected_kwargs = { 'route_type': route_type, 'route_dist': route_dist, # 'esi': esi, # should be ignored 'ethernet_tag_id': ethernet_tag_id, # 'mac_addr': mac_addr, # should be ignored 'ip_addr': ip_addr, 'next_hop': next_hop, } # Test speaker = bgpspeaker.BGPSpeaker(65000, '10.0.0.1') speaker.evpn_prefix_add( route_type=route_type, route_dist=route_dist, esi=esi, ethernet_tag_id=ethernet_tag_id, mac_addr=mac_addr, ip_addr=ip_addr, # next_hop=next_hop, # omitted ) # Check mock_call.assert_called_with( 'evpn_prefix.add_local', **expected_kwargs) @mock.patch( 'os_ken.services.protocols.bgp.bgpspeaker.BGPSpeaker.__init__', mock.MagicMock(return_value=None)) @mock.patch('os_ken.services.protocols.bgp.bgpspeaker.call') def test_evpn_prefix_add_eth_segment(self, mock_call): # Prepare test data route_type = bgpspeaker.EVPN_ETH_SEGMENT route_dist = '65000:100' esi = { 'type': ESI_TYPE_MAC_BASED, 'mac_addr': 'aa:bb:cc:dd:ee:ff', 'local_disc': 100, } ip_addr = '192.168.0.1' next_hop = '0.0.0.0' expected_kwargs = { 'route_type': route_type, 'route_dist': route_dist, 'esi': esi, 'ip_addr': ip_addr, 'next_hop': next_hop, } # Test speaker = bgpspeaker.BGPSpeaker(65000, '10.0.0.1') speaker.evpn_prefix_add( route_type=route_type, route_dist=route_dist, esi=esi, ip_addr=ip_addr, ) # Check mock_call.assert_called_with( 'evpn_prefix.add_local', **expected_kwargs) @mock.patch( 'os_ken.services.protocols.bgp.bgpspeaker.BGPSpeaker.__init__', mock.MagicMock(return_value=None)) @mock.patch('os_ken.services.protocols.bgp.bgpspeaker.call') def test_evpn_prefix_add_ip_prefix_route(self, mock_call): # Prepare test data route_type = bgpspeaker.EVPN_IP_PREFIX_ROUTE route_dist = '65000:100' esi = 0 # denotes single-homed ethernet_tag_id = 200 ip_prefix = '192.168.0.0/24' gw_ip_addr = '172.16.0.1' next_hop = '0.0.0.0' expected_kwargs = { 'route_type': route_type, 'route_dist': route_dist, 'esi': esi, 'ethernet_tag_id': ethernet_tag_id, 'ip_prefix': ip_prefix, 'gw_ip_addr': gw_ip_addr, 'next_hop': next_hop, } # Test speaker = bgpspeaker.BGPSpeaker(65000, '10.0.0.1') speaker.evpn_prefix_add( route_type=route_type, route_dist=route_dist, esi=esi, ethernet_tag_id=ethernet_tag_id, ip_prefix=ip_prefix, gw_ip_addr=gw_ip_addr, ) # Check mock_call.assert_called_with( 'evpn_prefix.add_local', **expected_kwargs) @mock.patch( 'os_ken.services.protocols.bgp.bgpspeaker.BGPSpeaker.__init__', mock.MagicMock(return_value=None)) @mock.patch('os_ken.services.protocols.bgp.bgpspeaker.call') def test_evpn_prefix_add_ip_prefix_route_vni(self, mock_call): # Prepare test data route_type = bgpspeaker.EVPN_IP_PREFIX_ROUTE route_dist = '65000:100' esi = 0 # denotes single-homed ethernet_tag_id = 200 ip_prefix = '192.168.0.0/24' gw_ip_addr = '172.16.0.1' vni = 500 tunnel_type = bgpspeaker.TUNNEL_TYPE_VXLAN next_hop = '0.0.0.0' expected_kwargs = { 'route_type': route_type, 'route_dist': route_dist, 'esi': esi, 'ethernet_tag_id': ethernet_tag_id, 'ip_prefix': ip_prefix, 'gw_ip_addr': gw_ip_addr, 'tunnel_type': tunnel_type, 'vni': vni, 'next_hop': next_hop, } # Test speaker = bgpspeaker.BGPSpeaker(65000, '10.0.0.1') speaker.evpn_prefix_add( route_type=route_type, route_dist=route_dist, esi=esi, ethernet_tag_id=ethernet_tag_id, ip_prefix=ip_prefix, gw_ip_addr=gw_ip_addr, tunnel_type=tunnel_type, vni=vni, ) # Check mock_call.assert_called_with( 'evpn_prefix.add_local', **expected_kwargs) @mock.patch('os_ken.services.protocols.bgp.bgpspeaker.BGPSpeaker.__init__', mock.MagicMock(return_value=None)) @mock.patch('os_ken.services.protocols.bgp.bgpspeaker.call') def test_evpn_prefix_add_invalid_route_type(self, mock_call): # Prepare test data route_type = 'foobar' # Invalid EVPN route type route_dist = '65000:100' esi = 0 # denotes single-homed ethernet_tag_id = 200 mac_addr = 'aa:bb:cc:dd:ee:ff' ip_addr = '192.168.0.1' next_hop = '10.0.0.1' # Test speaker = bgpspeaker.BGPSpeaker(65000, '10.0.0.1') self.assertRaises(ValueError, speaker.evpn_prefix_add, route_type=route_type, route_dist=route_dist, esi=esi, ethernet_tag_id=ethernet_tag_id, mac_addr=mac_addr, ip_addr=ip_addr, next_hop=next_hop) @mock.patch( 'os_ken.services.protocols.bgp.bgpspeaker.BGPSpeaker.__init__', mock.MagicMock(return_value=None)) @mock.patch('os_ken.services.protocols.bgp.bgpspeaker.call') def test_evpn_prefix_del_auto_discovery(self, mock_call): # Prepare test data route_type = bgpspeaker.EVPN_ETH_AUTO_DISCOVERY route_dist = '65000:100' esi = { 'type': ESI_TYPE_LACP, 'mac_addr': 'aa:bb:cc:dd:ee:ff', 'port_key': 100, } ethernet_tag_id = EVPN_MAX_ET expected_kwargs = { 'route_type': route_type, 'route_dist': route_dist, 'esi': esi, 'ethernet_tag_id': ethernet_tag_id, } # Test speaker = bgpspeaker.BGPSpeaker(65000, '10.0.0.1') speaker.evpn_prefix_del( route_type=route_type, route_dist=route_dist, esi=esi, ethernet_tag_id=ethernet_tag_id, ) # Check mock_call.assert_called_with( 'evpn_prefix.delete_local', **expected_kwargs) @mock.patch('os_ken.services.protocols.bgp.bgpspeaker.BGPSpeaker.__init__', mock.MagicMock(return_value=None)) @mock.patch('os_ken.services.protocols.bgp.bgpspeaker.call') def test_evpn_prefix_del_mac_ip_adv(self, mock_call): # Prepare test data route_type = bgpspeaker.EVPN_MAC_IP_ADV_ROUTE route_dist = '65000:100' ethernet_tag_id = 200 mac_addr = 'aa:bb:cc:dd:ee:ff' ip_addr = '192.168.0.1' expected_kwargs = { 'route_type': route_type, 'route_dist': route_dist, 'ethernet_tag_id': ethernet_tag_id, 'mac_addr': mac_addr, 'ip_addr': ip_addr, } # Test speaker = bgpspeaker.BGPSpeaker(65000, '10.0.0.1') speaker.evpn_prefix_del( route_type=route_type, route_dist=route_dist, ethernet_tag_id=ethernet_tag_id, mac_addr=mac_addr, ip_addr=ip_addr, ) # Check mock_call.assert_called_with( 'evpn_prefix.delete_local', **expected_kwargs) @mock.patch('os_ken.services.protocols.bgp.bgpspeaker.BGPSpeaker.__init__', mock.MagicMock(return_value=None)) @mock.patch('os_ken.services.protocols.bgp.bgpspeaker.call') def test_evpn_prefix_del_multicast_etag(self, mock_call): # Prepare test data route_type = bgpspeaker.EVPN_MULTICAST_ETAG_ROUTE route_dist = '65000:100' esi = 0 # denotes single-homed ethernet_tag_id = 200 mac_addr = 'aa:bb:cc:dd:ee:ff' ip_addr = '192.168.0.1' expected_kwargs = { 'route_type': route_type, 'route_dist': route_dist, # 'esi': esi, # should be ignored 'ethernet_tag_id': ethernet_tag_id, # 'mac_addr': mac_addr, # should be ignored 'ip_addr': ip_addr, } # Test speaker = bgpspeaker.BGPSpeaker(65000, '10.0.0.1') speaker.evpn_prefix_del( route_type=route_type, route_dist=route_dist, esi=esi, ethernet_tag_id=ethernet_tag_id, mac_addr=mac_addr, ip_addr=ip_addr, ) # Check mock_call.assert_called_with( 'evpn_prefix.delete_local', **expected_kwargs) @mock.patch('os_ken.services.protocols.bgp.bgpspeaker.BGPSpeaker.__init__', mock.MagicMock(return_value=None)) @mock.patch('os_ken.services.protocols.bgp.bgpspeaker.call') def test_evpn_prefix_del_invalid_route_type(self, mock_call): # Prepare test data route_type = 'foobar' # Invalid EVPN route type route_dist = '65000:100' esi = 0 # denotes single-homed ethernet_tag_id = 200 mac_addr = 'aa:bb:cc:dd:ee:ff' ip_addr = '192.168.0.1' # Test speaker = bgpspeaker.BGPSpeaker(65000, '10.0.0.1') self.assertRaises(ValueError, speaker.evpn_prefix_del, route_type=route_type, route_dist=route_dist, esi=esi, ethernet_tag_id=ethernet_tag_id, mac_addr=mac_addr, ip_addr=ip_addr) @mock.patch( 'os_ken.services.protocols.bgp.bgpspeaker.BGPSpeaker.__init__', mock.MagicMock(return_value=None)) @mock.patch('os_ken.services.protocols.bgp.bgpspeaker.call') def test_evpn_prefix_del_eth_segment(self, mock_call): # Prepare test data route_type = bgpspeaker.EVPN_ETH_SEGMENT route_dist = '65000:100' esi = { 'esi_type': ESI_TYPE_MAC_BASED, 'mac_addr': 'aa:bb:cc:dd:ee:ff', 'local_disc': 100, } ip_addr = '192.168.0.1' expected_kwargs = { 'route_type': route_type, 'route_dist': route_dist, 'esi': esi, 'ip_addr': ip_addr, } # Test speaker = bgpspeaker.BGPSpeaker(65000, '10.0.0.1') speaker.evpn_prefix_del( route_type=route_type, route_dist=route_dist, esi=esi, ip_addr=ip_addr, ) # Check mock_call.assert_called_with( 'evpn_prefix.delete_local', **expected_kwargs) @mock.patch( 'os_ken.services.protocols.bgp.bgpspeaker.BGPSpeaker.__init__', mock.MagicMock(return_value=None)) @mock.patch('os_ken.services.protocols.bgp.bgpspeaker.call') def test_evpn_prefix_del_ip_prefix_route(self, mock_call): # Prepare test data route_type = bgpspeaker.EVPN_IP_PREFIX_ROUTE route_dist = '65000:100' ethernet_tag_id = 200 ip_prefix = '192.168.0.0/24' expected_kwargs = { 'route_type': route_type, 'route_dist': route_dist, 'ethernet_tag_id': ethernet_tag_id, 'ip_prefix': ip_prefix, } # Test speaker = bgpspeaker.BGPSpeaker(65000, '10.0.0.1') speaker.evpn_prefix_del( route_type=route_type, route_dist=route_dist, ethernet_tag_id=ethernet_tag_id, ip_prefix=ip_prefix, ) # Check mock_call.assert_called_with( 'evpn_prefix.delete_local', **expected_kwargs) @mock.patch('os_ken.services.protocols.bgp.bgpspeaker.BGPSpeaker.__init__', mock.MagicMock(return_value=None)) @mock.patch('os_ken.services.protocols.bgp.bgpspeaker.call') def test_evpn_prefix_add_pmsi_no_tunnel_info(self, mock_call): # Prepare test data route_type = bgpspeaker.EVPN_MULTICAST_ETAG_ROUTE route_dist = '65000:100' ethernet_tag_id = 200 next_hop = '0.0.0.0' ip_addr = '192.168.0.1' pmsi_tunnel_type = bgpspeaker.PMSI_TYPE_NO_TUNNEL_INFO expected_kwargs = { 'route_type': route_type, 'route_dist': route_dist, 'ethernet_tag_id': ethernet_tag_id, 'next_hop': next_hop, 'ip_addr': ip_addr, 'pmsi_tunnel_type': pmsi_tunnel_type, } # Test speaker = bgpspeaker.BGPSpeaker(65000, '10.0.0.1') speaker.evpn_prefix_add( route_type=route_type, route_dist=route_dist, ethernet_tag_id=ethernet_tag_id, ip_addr=ip_addr, pmsi_tunnel_type=pmsi_tunnel_type, ) # Check mock_call.assert_called_with( 'evpn_prefix.add_local', **expected_kwargs) @mock.patch( 'os_ken.services.protocols.bgp.bgpspeaker.BGPSpeaker.__init__', mock.MagicMock(return_value=None)) @mock.patch('os_ken.services.protocols.bgp.bgpspeaker.call') def test_evpn_prefix_add_pmsi_ingress_rep(self, mock_call): # Prepare test data route_type = bgpspeaker.EVPN_MULTICAST_ETAG_ROUTE route_dist = '65000:100' ethernet_tag_id = 200 next_hop = '0.0.0.0' ip_addr = '192.168.0.1' pmsi_tunnel_type = bgpspeaker.PMSI_TYPE_INGRESS_REP expected_kwargs = { 'route_type': route_type, 'route_dist': route_dist, 'ethernet_tag_id': ethernet_tag_id, 'next_hop': next_hop, 'ip_addr': ip_addr, 'pmsi_tunnel_type': pmsi_tunnel_type, } # Test speaker = bgpspeaker.BGPSpeaker(65000, '10.0.0.1') speaker.evpn_prefix_add( route_type=route_type, route_dist=route_dist, ethernet_tag_id=ethernet_tag_id, ip_addr=ip_addr, pmsi_tunnel_type=pmsi_tunnel_type, ) # Check mock_call.assert_called_with( 'evpn_prefix.add_local', **expected_kwargs) @mock.patch( 'os_ken.services.protocols.bgp.bgpspeaker.BGPSpeaker.__init__', mock.MagicMock(return_value=None)) @mock.patch('os_ken.services.protocols.bgp.bgpspeaker.call') def test_evpn_prefix_add_invalid_pmsi_tunnel_type(self, mock_call): # Prepare test data route_type = bgpspeaker.EVPN_MULTICAST_ETAG_ROUTE route_dist = '65000:100' ethernet_tag_id = 200 next_hop = '0.0.0.0' ip_addr = '192.168.0.1' pmsi_tunnel_type = 1 # Test speaker = bgpspeaker.BGPSpeaker(65000, '10.0.0.1') self.assertRaises(ValueError, speaker.evpn_prefix_add, route_type=route_type, route_dist=route_dist, ethernet_tag_id=ethernet_tag_id, ip_addr=ip_addr, pmsi_tunnel_type=pmsi_tunnel_type) @mock.patch( 'os_ken.services.protocols.bgp.bgpspeaker.BGPSpeaker.__init__', mock.MagicMock(return_value=None)) @mock.patch('os_ken.services.protocols.bgp.bgpspeaker.call') def test_flowspec_prefix_add_ipv4(self, mock_call): # Prepare test data flowspec_family = bgpspeaker.FLOWSPEC_FAMILY_IPV4 rules = { 'dst_prefix': '10.60.1.0/24', } actions = { 'traffic_marking': { 'dscp': 24, } } expected_kwargs = { 'flowspec_family': flowspec_family, 'rules': rules, 'actions': actions, } # Test speaker = bgpspeaker.BGPSpeaker(65000, '10.0.0.1') speaker.flowspec_prefix_add( flowspec_family=flowspec_family, rules=rules, actions=actions) # Check mock_call.assert_called_with( 'flowspec.add', **expected_kwargs) @mock.patch( 'os_ken.services.protocols.bgp.bgpspeaker.BGPSpeaker.__init__', mock.MagicMock(return_value=None)) @mock.patch('os_ken.services.protocols.bgp.bgpspeaker.call') def test_flowspec_prefix_add_ipv4_without_actions(self, mock_call): # Prepare test data flowspec_family = bgpspeaker.FLOWSPEC_FAMILY_IPV4 rules = { 'dst_prefix': '10.60.1.0/24', } expected_kwargs = { 'flowspec_family': flowspec_family, 'rules': rules, 'actions': {}, } # Test speaker = bgpspeaker.BGPSpeaker(65000, '10.0.0.1') speaker.flowspec_prefix_add( flowspec_family=flowspec_family, rules=rules) # Check mock_call.assert_called_with( 'flowspec.add', **expected_kwargs) @mock.patch( 'os_ken.services.protocols.bgp.bgpspeaker.BGPSpeaker.__init__', mock.MagicMock(return_value=None)) @mock.patch('os_ken.services.protocols.bgp.bgpspeaker.call') def test_flowspec_prefix_del_ipv4(self, mock_call): # Prepare test data flowspec_family = bgpspeaker.FLOWSPEC_FAMILY_IPV4 rules = { 'dst_prefix': '10.60.1.0/24', } expected_kwargs = { 'flowspec_family': flowspec_family, 'rules': rules, } # Test speaker = bgpspeaker.BGPSpeaker(65000, '10.0.0.1') speaker.flowspec_prefix_del( flowspec_family=flowspec_family, rules=rules) # Check mock_call.assert_called_with( 'flowspec.del', **expected_kwargs) @mock.patch( 'os_ken.services.protocols.bgp.bgpspeaker.BGPSpeaker.__init__', mock.MagicMock(return_value=None)) @mock.patch('os_ken.services.protocols.bgp.bgpspeaker.call') def test_flowspec_prefix_add_vpnv4(self, mock_call): # Prepare test data flowspec_family = bgpspeaker.FLOWSPEC_FAMILY_VPNV4 route_dist = '65001:100' rules = { 'dst_prefix': '10.70.1.0/24', } actions = { 'traffic_marking': { 'dscp': 24, } } expected_kwargs = { 'flowspec_family': flowspec_family, 'route_dist': route_dist, 'rules': rules, 'actions': actions, } # Test speaker = bgpspeaker.BGPSpeaker(65000, '10.0.0.1') speaker.flowspec_prefix_add( flowspec_family=flowspec_family, route_dist=route_dist, rules=rules, actions=actions) # Check mock_call.assert_called_with( 'flowspec.add_local', **expected_kwargs) @mock.patch( 'os_ken.services.protocols.bgp.bgpspeaker.BGPSpeaker.__init__', mock.MagicMock(return_value=None)) @mock.patch('os_ken.services.protocols.bgp.bgpspeaker.call') def test_flowspec_prefix_del_vpnv4(self, mock_call): # Prepare test data flowspec_family = bgpspeaker.FLOWSPEC_FAMILY_VPNV4 route_dist = '65001:100' rules = { 'dst_prefix': '10.70.1.0/24', } expected_kwargs = { 'flowspec_family': flowspec_family, 'route_dist': route_dist, 'rules': rules, } # Test speaker = bgpspeaker.BGPSpeaker(65000, '10.0.0.1') speaker.flowspec_prefix_del( flowspec_family=flowspec_family, route_dist=route_dist, rules=rules) # Check mock_call.assert_called_with( 'flowspec.del_local', **expected_kwargs) @mock.patch( 'os_ken.services.protocols.bgp.bgpspeaker.BGPSpeaker.__init__', mock.MagicMock(return_value=None)) @mock.patch('os_ken.services.protocols.bgp.bgpspeaker.call') def test_flowspec_prefix_add_ipv6(self, mock_call): # Prepare test data flowspec_family = bgpspeaker.FLOWSPEC_FAMILY_IPV6 rules = { 'dst_prefix': '2001::3/128/32', } actions = { 'traffic_marking': { 'dscp': 24, } } expected_kwargs = { 'flowspec_family': flowspec_family, 'rules': rules, 'actions': actions, } # Test speaker = bgpspeaker.BGPSpeaker(65000, '10.0.0.1') speaker.flowspec_prefix_add( flowspec_family=flowspec_family, rules=rules, actions=actions) # Check mock_call.assert_called_with( 'flowspec.add', **expected_kwargs) @mock.patch( 'os_ken.services.protocols.bgp.bgpspeaker.BGPSpeaker.__init__', mock.MagicMock(return_value=None)) @mock.patch('os_ken.services.protocols.bgp.bgpspeaker.call') def test_flowspec_prefix_add_ipv6_without_actions(self, mock_call): # Prepare test data flowspec_family = bgpspeaker.FLOWSPEC_FAMILY_IPV6 rules = { 'dst_prefix': '2001::3/128/32', } expected_kwargs = { 'flowspec_family': flowspec_family, 'rules': rules, 'actions': {}, } # Test speaker = bgpspeaker.BGPSpeaker(65000, '10.0.0.1') speaker.flowspec_prefix_add( flowspec_family=flowspec_family, rules=rules) # Check mock_call.assert_called_with( 'flowspec.add', **expected_kwargs) @mock.patch( 'os_ken.services.protocols.bgp.bgpspeaker.BGPSpeaker.__init__', mock.MagicMock(return_value=None)) @mock.patch('os_ken.services.protocols.bgp.bgpspeaker.call') def test_flowspec_prefix_del_ipv6(self, mock_call): # Prepare test data flowspec_family = bgpspeaker.FLOWSPEC_FAMILY_IPV6 rules = { 'dst_prefix': '2001::3/128/32', } expected_kwargs = { 'flowspec_family': flowspec_family, 'rules': rules, } # Test speaker = bgpspeaker.BGPSpeaker(65000, '10.0.0.1') speaker.flowspec_prefix_del( flowspec_family=flowspec_family, rules=rules) # Check mock_call.assert_called_with( 'flowspec.del', **expected_kwargs) @mock.patch( 'os_ken.services.protocols.bgp.bgpspeaker.BGPSpeaker.__init__', mock.MagicMock(return_value=None)) @mock.patch('os_ken.services.protocols.bgp.bgpspeaker.call') def test_flowspec_prefix_add_vpnv6(self, mock_call): # Prepare test data flowspec_family = bgpspeaker.FLOWSPEC_FAMILY_VPNV6 route_dist = '65001:100' rules = { 'dst_prefix': '2001::3/128/32', } actions = { 'traffic_marking': { 'dscp': 24, } } expected_kwargs = { 'flowspec_family': flowspec_family, 'route_dist': route_dist, 'rules': rules, 'actions': actions, } # Test speaker = bgpspeaker.BGPSpeaker(65000, '10.0.0.1') speaker.flowspec_prefix_add( flowspec_family=flowspec_family, route_dist=route_dist, rules=rules, actions=actions) # Check mock_call.assert_called_with( 'flowspec.add_local', **expected_kwargs) @mock.patch( 'os_ken.services.protocols.bgp.bgpspeaker.BGPSpeaker.__init__', mock.MagicMock(return_value=None)) @mock.patch('os_ken.services.protocols.bgp.bgpspeaker.call') def test_flowspec_prefix_del_vpnv6(self, mock_call): # Prepare test data flowspec_family = bgpspeaker.FLOWSPEC_FAMILY_VPNV6 route_dist = '65001:100' rules = { 'dst_prefix': '2001::3/128/32', } expected_kwargs = { 'flowspec_family': flowspec_family, 'route_dist': route_dist, 'rules': rules, } # Test speaker = bgpspeaker.BGPSpeaker(65000, '10.0.0.1') speaker.flowspec_prefix_del( flowspec_family=flowspec_family, route_dist=route_dist, rules=rules) # Check mock_call.assert_called_with( 'flowspec.del_local', **expected_kwargs) @mock.patch( 'os_ken.services.protocols.bgp.bgpspeaker.BGPSpeaker.__init__', mock.MagicMock(return_value=None)) @mock.patch('os_ken.services.protocols.bgp.bgpspeaker.call') def test_flowspec_prefix_add_l2vpn(self, mock_call): # Prepare test data flowspec_family = bgpspeaker.FLOWSPEC_FAMILY_L2VPN route_dist = '65001:100' rules = { 'dst_mac': '12:34:56:78:9a:bc', } actions = { 'traffic_marking': { 'dscp': 24, } } expected_kwargs = { 'flowspec_family': flowspec_family, 'route_dist': route_dist, 'rules': rules, 'actions': actions, } # Test speaker = bgpspeaker.BGPSpeaker(65000, '10.0.0.1') speaker.flowspec_prefix_add( flowspec_family=flowspec_family, route_dist=route_dist, rules=rules, actions=actions) # Check mock_call.assert_called_with( 'flowspec.add_local', **expected_kwargs) @mock.patch( 'os_ken.services.protocols.bgp.bgpspeaker.BGPSpeaker.__init__', mock.MagicMock(return_value=None)) @mock.patch('os_ken.services.protocols.bgp.bgpspeaker.call') def test_flowspec_prefix_del_l2vpn(self, mock_call): # Prepare test data flowspec_family = bgpspeaker.FLOWSPEC_FAMILY_L2VPN route_dist = '65001:100' rules = { 'dst_mac': '12:34:56:78:9a:bc', } expected_kwargs = { 'flowspec_family': flowspec_family, 'route_dist': route_dist, 'rules': rules, } # Test speaker = bgpspeaker.BGPSpeaker(65000, '10.0.0.1') speaker.flowspec_prefix_del( flowspec_family=flowspec_family, route_dist=route_dist, rules=rules) # Check mock_call.assert_called_with( 'flowspec.del_local', **expected_kwargs) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/services/protocols/bgp/test_peer.py0000664000175000017500000003254500000000000025404 0ustar00zuulzuul00000000000000# Copyright (C) 2016 Nippon Telegraph and Telephone 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. import logging import unittest from unittest import mock from os_ken.lib.packet import bgp from os_ken.services.protocols.bgp import peer LOG = logging.getLogger(__name__) class Test_Peer(unittest.TestCase): """ Test case for peer.Peer """ @mock.patch.object( peer.Peer, '__init__', mock.MagicMock(return_value=None)) def _test_construct_as_path_attr( self, input_as_path, input_as4_path, expected_as_path): # Prepare input data input_as_path_attr = bgp.BGPPathAttributeAsPath(input_as_path) input_as4_path_attr = bgp.BGPPathAttributeAs4Path(input_as4_path) _peer = peer.Peer(None, None, None, None, None) # TEST output_as_path_attr = _peer._construct_as_path_attr( input_as_path_attr, input_as4_path_attr) self.assertEqual(bgp.BGP_ATTR_TYPE_AS_PATH, output_as_path_attr.type) self.assertEqual(expected_as_path, output_as_path_attr.path_seg_list) def test_construct_as_path_attr_sequence_only(self): # Test Data # Input: input_as_path = [[65000, 4000, 23456, 23456, 40001]] input_as4_path = [[400000, 300000, 40001]] # Expected: expected_as_path = [[65000, 4000, 400000, 300000, 40001]] self._test_construct_as_path_attr( input_as_path, input_as4_path, expected_as_path) def test_construct_as_path_attr_aggregated_as_path_1(self): # Test Data # Input: input_as_path = [[65000, 4000], {10, 20, 30}, [23456, 23456, 40001]] input_as4_path = [[400000, 300000, 40001]] # Expected: expected_as_path = [[65000, 4000], {10, 20, 30}, [400000, 300000, 40001]] self._test_construct_as_path_attr( input_as_path, input_as4_path, expected_as_path) def test_construct_as_path_attr_aggregated_as_path_2(self): # Test Data # Input: input_as_path = [[65000, 4000], {10, 20, 30}, [23456, 23456, 40001]] input_as4_path = [[3000, 400000, 300000, 40001]] # Expected: expected_as_path = [[65000, 4000, 3000, 400000, 300000, 40001]] self._test_construct_as_path_attr( input_as_path, input_as4_path, expected_as_path) def test_construct_as_path_attr_aggregated_path_3(self): # Test Data # Input: input_as_path = [[65000, 4000, 23456, 23456, 40001]] input_as4_path = [[400000, 300000, 40001], {10, 20, 30}] # Expected: expected_as_path = [[65000, 400000, 300000, 40001], {10, 20, 30}] self._test_construct_as_path_attr( input_as_path, input_as4_path, expected_as_path) def test_construct_as_path_attr_aggregated_as4_path(self): # Test Data # Input: input_as_path = [[65000, 4000, 23456, 23456, 40001]] input_as4_path = [{10, 20, 30}, [400000, 300000, 40001]] # Expected: expected_as_path = [[65000], {10, 20, 30}, [400000, 300000, 40001]] self._test_construct_as_path_attr( input_as_path, input_as4_path, expected_as_path) def test_construct_as_path_attr_too_short_as_path(self): # Test Data # Input: input_as_path = [[65000, 4000, 23456, 23456, 40001]] input_as4_path = [[100000, 65000, 4000, 400000, 300000, 40001]] # Expected: expected_as_path = [[65000, 4000, 23456, 23456, 40001]] self._test_construct_as_path_attr( input_as_path, input_as4_path, expected_as_path) def test_construct_as_path_attr_too_short_as4_path(self): # Test Data # Input: input_as_path = [[65000, 4000, 23456, 23456, 40001]] input_as4_path = [[300000, 40001]] # Expected: expected_as_path = [[65000, 4000, 23456, 300000, 40001]] self._test_construct_as_path_attr( input_as_path, input_as4_path, expected_as_path) def test_construct_as_path_attr_empty_as4_path(self): # Test Data # Input: input_as_path = [[65000, 4000, 23456, 23456, 40001]] input_as4_path = [[]] # Expected: expected_as_path = [[65000, 4000, 23456, 23456, 40001]] self._test_construct_as_path_attr( input_as_path, input_as4_path, expected_as_path) @mock.patch.object( peer.Peer, '__init__', mock.MagicMock(return_value=None)) def test_construct_as_path_attr_as4_path_None(self): # Test Data # Input: input_as_path = [[65000, 4000, 23456, 23456, 40001]] # input_as4_path = None # Expected: expected_as_path = [[65000, 4000, 23456, 23456, 40001]] # Prepare input data input_as_path_attr = bgp.BGPPathAttributeAsPath(input_as_path) input_as4_path_attr = None _peer = peer.Peer(None, None, None, None, None) # TEST output_as_path_attr = _peer._construct_as_path_attr( input_as_path_attr, input_as4_path_attr) self.assertEqual(bgp.BGP_ATTR_TYPE_AS_PATH, output_as_path_attr.type) self.assertEqual(expected_as_path, output_as_path_attr.path_seg_list) @mock.patch.object( peer.Peer, '__init__', mock.MagicMock(return_value=None)) def _test_trans_as_path( self, input_as_path, expected_as_path, expected_as4_path): # Prepare input data _peer = peer.Peer(None, None, None, None, None) # TEST output_as_path, output_as4_path = _peer._trans_as_path(input_as_path) self.assertEqual(expected_as_path, output_as_path) self.assertEqual(expected_as4_path, output_as4_path) @mock.patch.object( peer.Peer, 'is_four_octet_as_number_cap_valid', mock.MagicMock(return_value=True)) def test_trans_as_path_as4_path_is_supported(self): # Test Data # Input: input_as_path = [[65000, 4000, 400000, 300000, 40001]] # Expected: expected_as_path = [[65000, 4000, 400000, 300000, 40001]] expected_as4_path = None self._test_trans_as_path( input_as_path, expected_as_path, expected_as4_path) @mock.patch.object( peer.Peer, 'is_four_octet_as_number_cap_valid', mock.MagicMock(return_value=False)) def test_trans_as_path_sequence_only(self): # Test Data # Input: input_as_path = [[65000, 4000, 400000, 300000, 40001]] # Expected: expected_as_path = [[65000, 4000, 23456, 23456, 40001]] expected_as4_path = [[65000, 4000, 400000, 300000, 40001]] self._test_trans_as_path( input_as_path, expected_as_path, expected_as4_path) @mock.patch.object( peer.Peer, 'is_four_octet_as_number_cap_valid', mock.MagicMock(return_value=False)) def test_trans_as_path_no_trans(self): # Test Data # Input: input_as_path = [[65000, 4000, 40000, 30000, 40001]] # Expected: expected_as_path = [[65000, 4000, 40000, 30000, 40001]] expected_as4_path = None self._test_trans_as_path( input_as_path, expected_as_path, expected_as4_path) @mock.patch.object( peer.Peer, '__init__', mock.MagicMock(return_value=None)) def _test_extract_and_reconstruct_as_path( self, path_attributes, ex_as_path_value, ex_aggregator_as_number, ex_aggregator_addr): # Prepare test data update_msg = bgp.BGPUpdate(path_attributes=path_attributes) _peer = peer.Peer(None, None, None, None, None) # Test _peer._extract_and_reconstruct_as_path(update_msg) umsg_pattrs = update_msg.pathattr_map as_path_attr = umsg_pattrs.get( bgp.BGP_ATTR_TYPE_AS_PATH, None) as4_path_attr = umsg_pattrs.get( bgp.BGP_ATTR_TYPE_AS4_PATH, None) aggregator_attr = umsg_pattrs.get( bgp.BGP_ATTR_TYPE_AGGREGATOR, None) as4_aggregator_attr = umsg_pattrs.get( bgp.BGP_ATTR_TYPE_AS4_AGGREGATOR, None) self.assertEqual(ex_as_path_value, as_path_attr.value) self.assertEqual(None, as4_path_attr) self.assertEqual(ex_aggregator_as_number, aggregator_attr.as_number) self.assertEqual(ex_aggregator_addr, aggregator_attr.addr) self.assertEqual(None, as4_aggregator_attr) @mock.patch.object( peer.Peer, '__init__', mock.MagicMock(return_value=None)) def test_extract_and_reconstruct_as_path_with_no_as4_attr(self): # Input values in_as_path_value = [[1000, 2000, 3000]] # in_as4_path_value in_aggregator_as_number = 4000 in_aggregator_addr = '10.0.0.1' # in_as4_aggregator_as_number # in_as4_aggregator_addr # Expected values ex_as_path_value = [[1000, 2000, 3000]] ex_aggregator_as_number = 4000 ex_aggregator_addr = '10.0.0.1' # Prepare test data path_attributes = [ bgp.BGPPathAttributeAsPath( value=in_as_path_value), bgp.BGPPathAttributeAggregator( as_number=in_aggregator_as_number, addr=in_aggregator_addr), ] # Test self._test_extract_and_reconstruct_as_path( path_attributes, ex_as_path_value, ex_aggregator_as_number, ex_aggregator_addr) @mock.patch.object( peer.Peer, '__init__', mock.MagicMock(return_value=None)) def test_extract_and_reconstruct_as_path_with_as4_attr(self): # Input values in_as_path_value = [[1000, 23456, 3000]] in_as4_path_value = [[2000, 3000]] in_aggregator_as_number = 23456 in_aggregator_addr = '10.0.0.1' in_as4_aggregator_as_number = 4000 in_as4_aggregator_addr = '10.0.0.1' # Expected values ex_as_path_value = [[1000, 2000, 3000]] ex_aggregator_as_number = 4000 ex_aggregator_addr = '10.0.0.1' # Prepare test data path_attributes = [ bgp.BGPPathAttributeAsPath( value=in_as_path_value), bgp.BGPPathAttributeAs4Path( value=in_as4_path_value), bgp.BGPPathAttributeAggregator( as_number=in_aggregator_as_number, addr=in_aggregator_addr), bgp.BGPPathAttributeAs4Aggregator( as_number=in_as4_aggregator_as_number, addr=in_as4_aggregator_addr), ] # Test self._test_extract_and_reconstruct_as_path( path_attributes, ex_as_path_value, ex_aggregator_as_number, ex_aggregator_addr) @mock.patch.object( peer.Peer, '__init__', mock.MagicMock(return_value=None)) def test_extract_and_reconstruct_as_path_with_not_trans_as_aggr(self): # Input values in_as_path_value = [[1000, 23456, 3000]] in_as4_path_value = [[2000, 3000]] in_aggregator_as_number = 4000 # not AS_TRANS in_aggregator_addr = '10.0.0.1' in_as4_aggregator_as_number = 4000 in_as4_aggregator_addr = '10.0.0.1' # Expected values ex_as_path_value = [[1000, 23456, 3000]] ex_aggregator_as_number = 4000 ex_aggregator_addr = '10.0.0.1' # Prepare test data path_attributes = [ bgp.BGPPathAttributeAsPath( value=in_as_path_value), bgp.BGPPathAttributeAs4Path( value=in_as4_path_value), bgp.BGPPathAttributeAggregator( as_number=in_aggregator_as_number, addr=in_aggregator_addr), bgp.BGPPathAttributeAs4Aggregator( as_number=in_as4_aggregator_as_number, addr=in_as4_aggregator_addr), ] # Test self._test_extract_and_reconstruct_as_path( path_attributes, ex_as_path_value, ex_aggregator_as_number, ex_aggregator_addr) @mock.patch.object( peer.Peer, '__init__', mock.MagicMock(return_value=None)) def test_extract_and_reconstruct_as_path_with_short_as_path(self): # Input values in_as_path_value = [[1000, 23456, 3000]] in_as4_path_value = [[2000, 3000, 4000, 5000]] # longer than AS_PATH in_aggregator_as_number = 4000 in_aggregator_addr = '10.0.0.1' # in_as4_aggregator_as_number # in_as4_aggregator_addr # Expected values ex_as_path_value = [[1000, 23456, 3000]] ex_aggregator_as_number = 4000 ex_aggregator_addr = '10.0.0.1' # Prepare test data path_attributes = [ bgp.BGPPathAttributeAsPath( value=in_as_path_value), bgp.BGPPathAttributeAs4Path( value=in_as4_path_value), bgp.BGPPathAttributeAggregator( as_number=in_aggregator_as_number, addr=in_aggregator_addr), ] # Test self._test_extract_and_reconstruct_as_path( path_attributes, ex_as_path_value, ex_aggregator_as_number, ex_aggregator_addr) ././@PaxHeader0000000000000000000000000000003300000000000011451 xustar000000000000000027 mtime=1724334546.370121 os-ken-2.10.0/os_ken/tests/unit/services/protocols/bgp/utils/0000775000175000017500000000000000000000000024167 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/services/protocols/bgp/utils/__init__.py0000664000175000017500000000000000000000000026266 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/services/protocols/bgp/utils/test_bgp.py0000664000175000017500000001670400000000000026360 0ustar00zuulzuul00000000000000# Copyright (C) 2017 Nippon Telegraph and Telephone 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. import logging import unittest from os_ken.lib.packet.bgp import ( BGPFlowSpecTrafficRateCommunity, BGPFlowSpecTrafficActionCommunity, BGPFlowSpecRedirectCommunity, BGPFlowSpecTrafficMarkingCommunity, BGPFlowSpecVlanActionCommunity, BGPFlowSpecTPIDActionCommunity, ) from os_ken.services.protocols.bgp.utils.bgp import create_v4flowspec_actions from os_ken.services.protocols.bgp.utils.bgp import create_v6flowspec_actions from os_ken.services.protocols.bgp.utils.bgp import create_l2vpnflowspec_actions LOG = logging.getLogger(__name__) class Test_Utils_BGP(unittest.TestCase): """ Test case for os_ken.services.protocols.bgp.utils.bgp """ def _test_create_v4flowspec_actions(self, actions, expected_communities): communities = create_v4flowspec_actions(actions) expected_communities.sort(key=lambda x: x.subtype) communities.sort(key=lambda x: x.subtype) self.assertEqual(str(expected_communities), str(communities)) def test_create_v4flowspec_actions_all_actions(self): actions = { 'traffic_rate': { 'as_number': 0, 'rate_info': 100.0, }, 'traffic_action': { 'action': 3, }, 'redirect': { 'as_number': 10, 'local_administrator': 10, }, 'traffic_marking': { 'dscp': 24, } } expected_communities = [ BGPFlowSpecTrafficRateCommunity(as_number=0, rate_info=100.0), BGPFlowSpecTrafficActionCommunity(action=3), BGPFlowSpecRedirectCommunity(as_number=10, local_administrator=10), BGPFlowSpecTrafficMarkingCommunity(dscp=24), ] self._test_create_v4flowspec_actions(actions, expected_communities) def test_create_v4flowspec_actions_without_actions(self): actions = None expected_communities = [] self._test_create_v4flowspec_actions(actions, expected_communities) def test_create_v4flowspec_actions_not_exist_actions(self): actions = { 'traffic_test': { 'test': 10, }, } expected_communities = [] self.assertRaises(ValueError, self._test_create_v4flowspec_actions, actions, expected_communities) def _test_create_v6flowspec_actions(self, actions, expected_communities): communities = create_v6flowspec_actions(actions) expected_communities.sort(key=lambda x: x.subtype) communities.sort(key=lambda x: x.subtype) self.assertEqual(str(expected_communities), str(communities)) def test_create_v6flowspec_actions_all_actions(self): actions = { 'traffic_rate': { 'as_number': 0, 'rate_info': 100.0, }, 'traffic_action': { 'action': 3, }, 'redirect': { 'as_number': 10, 'local_administrator': 10, }, 'traffic_marking': { 'dscp': 24, } } expected_communities = [ BGPFlowSpecTrafficRateCommunity(as_number=0, rate_info=100.0), BGPFlowSpecTrafficActionCommunity(action=3), BGPFlowSpecRedirectCommunity(as_number=10, local_administrator=10), BGPFlowSpecTrafficMarkingCommunity(dscp=24), ] self._test_create_v6flowspec_actions(actions, expected_communities) def test_create_v6flowspec_actions_without_actions(self): actions = None expected_communities = [] self._test_create_v6flowspec_actions(actions, expected_communities) def test_create_v6flowspec_actions_not_exist_actions(self): actions = { 'traffic_test': { 'test': 10, }, } expected_communities = [] self.assertRaises(ValueError, self._test_create_v6flowspec_actions, actions, expected_communities) def _test_create_l2vpnflowspec_actions(self, actions, expected_communities): communities = create_l2vpnflowspec_actions(actions) expected_communities.sort(key=lambda x: x.subtype) communities.sort(key=lambda x: x.subtype) self.assertEqual(str(expected_communities), str(communities)) def test_create_l2vpnflowspec_actions_all_actions(self): actions = { 'traffic_rate': { 'as_number': 0, 'rate_info': 100.0, }, 'traffic_action': { 'action': 3, }, 'redirect': { 'as_number': 10, 'local_administrator': 10, }, 'traffic_marking': { 'dscp': 24, }, 'vlan_action': { 'actions_1': (BGPFlowSpecVlanActionCommunity.POP | BGPFlowSpecVlanActionCommunity.SWAP), 'vlan_1': 3000, 'cos_1': 3, 'actions_2': BGPFlowSpecVlanActionCommunity.PUSH, 'vlan_2': 4000, 'cos_2': 2, }, 'tpid_action': { 'actions': (BGPFlowSpecTPIDActionCommunity.TI | BGPFlowSpecTPIDActionCommunity.TO), 'tpid_1': 5, 'tpid_2': 6, } } expected_communities = [ BGPFlowSpecTrafficRateCommunity(as_number=0, rate_info=100.0), BGPFlowSpecTrafficActionCommunity(action=3), BGPFlowSpecRedirectCommunity(as_number=10, local_administrator=10), BGPFlowSpecTrafficMarkingCommunity(dscp=24), BGPFlowSpecVlanActionCommunity( actions_1=(BGPFlowSpecVlanActionCommunity.POP | BGPFlowSpecVlanActionCommunity.SWAP), vlan_1=3000, cos_1=3, actions_2=BGPFlowSpecVlanActionCommunity.PUSH, vlan_2=4000, cos_2=2, ), BGPFlowSpecTPIDActionCommunity( actions=(BGPFlowSpecTPIDActionCommunity.TI | BGPFlowSpecTPIDActionCommunity.TO), tpid_1=5, tpid_2=6, ), ] self._test_create_l2vpnflowspec_actions(actions, expected_communities) def test_create_l2vpnflowspec_actions_without_actions(self): actions = None expected_communities = [] self._test_create_l2vpnflowspec_actions(actions, expected_communities) def test_create_l2vpnflowspec_actions_not_exist_actions(self): actions = { 'traffic_test': { 'test': 10, }, } expected_communities = [] self.assertRaises(ValueError, self._test_create_l2vpnflowspec_actions, actions, expected_communities) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/tests/unit/services/protocols/bgp/utils/test_validation.py0000664000175000017500000002022400000000000027732 0ustar00zuulzuul00000000000000# Copyright (C) 2016 Nippon Telegraph and Telephone 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. import logging import unittest from os_ken.services.protocols.bgp.utils import validation LOG = logging.getLogger(__name__) class Test_Utils_Validation(unittest.TestCase): """ Test case for os_ken.services.protocols.bgp.utils.validation """ def test_is_valid_mac(self): self.assertTrue(validation.is_valid_mac('aa:bb:cc:dd:ee:ff')) def test_is_valid_mac_hyphenation(self): self.assertTrue(validation.is_valid_mac('aa-bb-cc-dd-ee-ff')) def test_is_valid_mac_short(self): self.assertEqual(False, validation.is_valid_mac('aa:bb:cc:dd:ee')) def test_is_valid_ip_prefix(self): self.assertTrue(validation.is_valid_ip_prefix(24, 32)) def test_is_valid_ip_prefix_str(self): self.assertTrue(validation.is_valid_ip_prefix('24', 32)) def test_is_valid_ip_prefix_not_digit(self): self.assertEqual(False, validation.is_valid_ip_prefix('foo', 32)) def test_is_valid_ip_prefix_over(self): self.assertEqual(False, validation.is_valid_ip_prefix(100, 32)) def test_is_valid_ipv4(self): self.assertTrue(validation.is_valid_ipv4('10.0.0.1')) def test_is_valid_ipv4_not_dot(self): self.assertEqual(False, validation.is_valid_ipv4('192:168:0:1')) def test_is_valid_ipv4_prefix(self): self.assertTrue(validation.is_valid_ipv4_prefix('10.0.0.1/24')) def test_is_valid_ipv4_prefix_not_str(self): self.assertEqual(False, validation.is_valid_ipv4_prefix(1234)) def test_is_valid_ipv4_prefix_without_prefix(self): self.assertEqual(False, validation.is_valid_ipv4_prefix('10.0.0.1')) def test_is_valid_ipv4_prefix_invalid_addr(self): self.assertEqual(False, validation.is_valid_ipv4_prefix('xxx.xxx.xxx.xxx/24')) def test_is_valid_ipv6(self): self.assertTrue(validation.is_valid_ipv6('fe80::0011:aabb:ccdd:eeff')) def test_is_valid_ipv6_not_colon(self): self.assertEqual(False, validation.is_valid_ipv6('fe80--0011-aabb-ccdd-eeff')) def test_is_valid_ipv6_prefix(self): self.assertTrue( validation.is_valid_ipv6_prefix('fe80::0011:aabb:ccdd:eeff/64')) def test_is_valid_ipv6_prefix_not_str(self): self.assertEqual(False, validation.is_valid_ipv6_prefix(1234)) def test_is_valid_ipv6_prefix_without_prefix(self): self.assertEqual( False, validation.is_valid_ipv6_prefix('fe80::0011:aabb:ccdd:eeff')) def test_is_valid_ipv6_prefix_invalid_addr(self): self.assertEqual(False, validation.is_valid_ipv6_prefix('xxxx::xxxx/64')) def test_is_valid_old_asn(self): self.assertTrue(validation.is_valid_old_asn(65000)) def test_is_valid_old_asn_negative(self): self.assertEqual(False, validation.is_valid_old_asn(-1)) def test_is_valid_old_asn_over(self): self.assertEqual(False, validation.is_valid_old_asn(0xffff + 1)) def test_is_valid_asn(self): self.assertTrue(validation.is_valid_asn(6553800)) def test_is_valid_asn_old(self): self.assertTrue(validation.is_valid_asn(65000)) def test_is_valid_asn_negative(self): self.assertEqual(False, validation.is_valid_asn(-1)) def test_is_valid_asn_over(self): self.assertEqual(False, validation.is_valid_asn(0xffffffff + 1)) def test_is_valid_vpnv4_prefix(self): self.assertTrue( validation.is_valid_vpnv4_prefix('100:200:10.0.0.1/24')) def test_is_valid_vpnv4_prefix_not_str(self): self.assertEqual(False, validation.is_valid_vpnv4_prefix(1234)) def test_is_valid_vpnv4_prefix_short_rd(self): self.assertEqual(False, validation.is_valid_vpnv4_prefix('100:10.0.0.1/24')) def test_is_valid_vpnv4_prefix_invalid_rd(self): self.assertEqual( False, validation.is_valid_vpnv4_prefix('foo:bar:10.0.0.1/24')) def test_is_valid_vpnv6_prefix(self): self.assertTrue(validation.is_valid_vpnv6_prefix( '100:200:fe80::0011:aabb:ccdd:eeff/64')) def test_is_valid_vpnv6_prefix_not_str(self): self.assertEqual(False, validation.is_valid_vpnv6_prefix(1234)) def test_is_valid_vpnv6_prefix_short_rd(self): self.assertEqual(False, validation.is_valid_vpnv6_prefix('100:eeff/64')) def test_is_valid_vpnv6_prefix_invalid_rd(self): self.assertEqual( False, validation.is_valid_vpnv6_prefix('foo:bar:10.0.0.1/24')) def test_is_valid_med(self): self.assertTrue(validation.is_valid_med(100)) def test_is_valid_med_not_num(self): self.assertEqual(False, validation.is_valid_med('foo')) def test_is_valid_med_negative(self): self.assertEqual(False, validation.is_valid_med(-1)) def test_is_valid_med_over(self): self.assertEqual(False, validation.is_valid_med(0xffffffff + 1)) def test_is_valid_mpls_label(self): self.assertTrue(validation.is_valid_mpls_label(100)) def test_is_valid_mpls_label_reserved(self): self.assertEqual(False, validation.is_valid_mpls_label(4)) def test_is_valid_mpls_label_not_num(self): self.assertEqual(False, validation.is_valid_mpls_label('foo')) def test_is_valid_mpls_label_negative(self): self.assertEqual(False, validation.is_valid_mpls_label(-1)) def test_is_valid_mpls_label_over(self): self.assertEqual(False, validation.is_valid_mpls_label(0x100000 + 1)) def test_is_valid_mpls_labels(self): self.assertTrue(validation.is_valid_mpls_labels([100, 200])) def test_is_valid_mpls_labels_not_list(self): self.assertEqual(False, validation.is_valid_mpls_labels(100)) def test_is_valid_mpls_labels_with_invalid_label(self): self.assertEqual(False, validation.is_valid_mpls_labels(['foo', 200])) def test_is_valid_route_dist(self): self.assertTrue(validation.is_valid_route_dist('65000:222')) def test_is_valid_route_dist_ipv4_based(self): self.assertTrue(validation.is_valid_route_dist('10.0.0.1:333')) def test_is_valid_route_not_str(self): self.assertEqual(False, validation.is_valid_route_dist(65000)) def test_is_valid_route_dist_short(self): self.assertEqual(False, validation.is_valid_route_dist('65000')) def test_is_valid_route_dist_invalid_ipv4_addr(self): self.assertEqual(False, validation.is_valid_route_dist('xxx.xxx.xxx.xxx:333')) def test_is_valid_esi(self): self.assertTrue(validation.is_valid_esi(100)) def test_is_valid_esi_not_int(self): self.assertEqual(False, validation.is_valid_esi('foo')) def test_is_valid_ethernet_tag_id(self): self.assertTrue(validation.is_valid_ethernet_tag_id(100)) def test_is_valid_ethernet_tag_id_not_int(self): self.assertEqual(False, validation.is_valid_ethernet_tag_id('foo')) def test_is_valid_ethernet_tag_id_negative(self): self.assertEqual(False, validation.is_valid_ethernet_tag_id(-1)) def test_is_valid_ethernet_tag_id_over(self): self.assertEqual(False, validation.is_valid_ethernet_tag_id(0xffffffff + 1)) def test_is_valid_vni(self): self.assertTrue(validation.is_valid_vni(100)) def test_is_valid_vni_not_int(self): self.assertEqual(False, validation.is_valid_vni('foo')) def test_is_valid_vni_negative(self): self.assertEqual(False, validation.is_valid_vni(-1)) def test_is_valid_vni_over(self): self.assertEqual(False, validation.is_valid_vni(0xffffff + 1)) ././@PaxHeader0000000000000000000000000000003300000000000011451 xustar000000000000000027 mtime=1724334546.370121 os-ken-2.10.0/os_ken/topology/0000775000175000017500000000000000000000000016143 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/topology/__init__.py0000664000175000017500000000012600000000000020253 0ustar00zuulzuul00000000000000""" Switch and link discovery module. Planned to replace os_ken/controller/dpset. """ ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/topology/api.py0000664000175000017500000000233400000000000017270 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone 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. from os_ken.base import app_manager from os_ken.topology import event def get_switch(app, dpid=None): rep = app.send_request(event.EventSwitchRequest(dpid)) return rep.switches def get_all_switch(app): return get_switch(app) def get_link(app, dpid=None): rep = app.send_request(event.EventLinkRequest(dpid)) return rep.links def get_all_link(app): return get_link(app) def get_host(app, dpid=None): rep = app.send_request(event.EventHostRequest(dpid)) return rep.hosts def get_all_host(app): return get_host(app) app_manager.require_app('os_ken.topology.switches', api_style=True) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/topology/dumper.py0000664000175000017500000001271500000000000020017 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone 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. import logging import time from os_ken.base import app_manager from os_ken.controller import handler from os_ken.lib import hub from os_ken.topology import event from os_ken.topology import switches LOG = logging.getLogger(__name__) class DiscoveryEventDumper(app_manager.OSKenApp): ''' This app dumps discovery events ''' _CONTEXTS = { 'switches': switches.Switches, } def __init__(self, *args, **kwargs): super(DiscoveryEventDumper, self).__init__(*args, **kwargs) # For testing when sync and async request. # self.threads.append( # hub.spawn(self._switch_request_sync, 5)) # self.threads.append( # hub.spawn(self._switch_request_async, 10)) # # self.threads.append( # hub.spawn(self._link_request_sync, 5)) # self.threads.append( # hub.spawn(self._link_request_async, 10)) self.is_active = True @handler.set_ev_cls(event.EventSwitchEnter) def switch_enter_handler(self, ev): LOG.debug(ev) @handler.set_ev_cls(event.EventSwitchLeave) def switch_leave_handler(self, ev): LOG.debug(ev) @handler.set_ev_cls(event.EventPortAdd) def port_add_handler(self, ev): LOG.debug(ev) @handler.set_ev_cls(event.EventPortDelete) def port_delete_handler(self, ev): LOG.debug(ev) @handler.set_ev_cls(event.EventPortModify) def port_modify_handler(self, ev): LOG.debug(ev) @handler.set_ev_cls(event.EventLinkAdd) def link_add_handler(self, ev): LOG.debug(ev) @handler.set_ev_cls(event.EventLinkDelete) def link_del_handler(self, ev): LOG.debug(ev) def _switch_request_sync(self, interval): while self.is_active: request = event.EventSwitchRequest() LOG.debug('switch_request sync %s thread(%s)', request, id(hub.getcurrent())) reply = self.send_request(request) LOG.debug('switch_reply sync %s', reply) if len(reply.switches) > 0: for sw in reply.switches: LOG.debug(' %s', sw) hub.sleep(interval) def _switch_request_async(self, interval): while self.is_active: request = event.EventSwitchRequest() LOG.debug('switch_request async %s thread(%s)', request, id(hub.getcurrent())) self.send_event(request.dst, request) start = time.time() busy = interval / 2 i = 0 while i < busy: if time.time() > start + i: i += 1 LOG.debug(' thread is busy... %s/%s thread(%s)', i, busy, id(hub.getcurrent())) LOG.debug(' thread yield to switch_reply handler. thread(%s)', id(hub.getcurrent())) # yield hub.sleep(0) LOG.debug(' thread get back. thread(%s)', id(hub.getcurrent())) hub.sleep(interval - busy) @handler.set_ev_cls(event.EventSwitchReply) def switch_reply_handler(self, reply): LOG.debug('switch_reply async %s', reply) if len(reply.switches) > 0: for sw in reply.switches: LOG.debug(' %s', sw) def _link_request_sync(self, interval): while self.is_active: request = event.EventLinkRequest() LOG.debug('link_request sync %s thread(%s)', request, id(hub.getcurrent())) reply = self.send_request(request) LOG.debug('link_reply sync %s', reply) if len(reply.links) > 0: for link in reply.links: LOG.debug(' %s', link) hub.sleep(interval) def _link_request_async(self, interval): while self.is_active: request = event.EventLinkRequest() LOG.debug('link_request async %s thread(%s)', request, id(hub.getcurrent())) self.send_event(request.dst, request) start = time.time() busy = interval / 2 i = 0 while i < busy: if time.time() > start + i: i += 1 LOG.debug(' thread is busy... %s/%s thread(%s)', i, busy, id(hub.getcurrent())) LOG.debug(' thread yield to link_reply handler. thread(%s)', id(hub.getcurrent())) # yield hub.sleep(0) LOG.debug(' thread get back. thread(%s)', id(hub.getcurrent())) hub.sleep(interval - busy) @handler.set_ev_cls(event.EventLinkReply) def link_reply_handler(self, reply): LOG.debug('link_reply async %s', reply) if len(reply.links) > 0: for link in reply.links: LOG.debug(' %s', link) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/topology/event.py0000664000175000017500000001250400000000000017640 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone 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. import logging from os_ken.controller import handler from os_ken.controller import event LOG = logging.getLogger(__name__) class EventSwitchBase(event.EventBase): def __init__(self, switch): super(EventSwitchBase, self).__init__() self.switch = switch def __str__(self): return '%s' % \ (self.__class__.__name__, self.switch.dp.id, len(self.switch.ports)) class EventSwitchEnter(EventSwitchBase): def __init__(self, switch): super(EventSwitchEnter, self).__init__(switch) class EventSwitchLeave(EventSwitchBase): def __init__(self, switch): super(EventSwitchLeave, self).__init__(switch) class EventSwitchReconnected(EventSwitchBase): def __init__(self, switch): super(EventSwitchReconnected, self).__init__(switch) class EventPortBase(event.EventBase): def __init__(self, port): super(EventPortBase, self).__init__() self.port = port def __str__(self): return '%s<%s>' % (self.__class__.__name__, self.port) class EventPortAdd(EventPortBase): def __init__(self, port): super(EventPortAdd, self).__init__(port) class EventPortDelete(EventPortBase): def __init__(self, port): super(EventPortDelete, self).__init__(port) class EventPortModify(EventPortBase): def __init__(self, port): super(EventPortModify, self).__init__(port) class EventSwitchRequest(event.EventRequestBase): # If dpid is None, reply all list def __init__(self, dpid=None): super(EventSwitchRequest, self).__init__() self.dst = 'switches' self.dpid = dpid def __str__(self): return 'EventSwitchRequest' % \ (self.src, self.dpid) class EventSwitchReply(event.EventReplyBase): def __init__(self, dst, switches): super(EventSwitchReply, self).__init__(dst) self.switches = switches def __str__(self): return 'EventSwitchReply' % \ (self.dst, self.switches) class EventLinkBase(event.EventBase): def __init__(self, link): super(EventLinkBase, self).__init__() self.link = link def __str__(self): return '%s<%s>' % (self.__class__.__name__, self.link) class EventLinkAdd(EventLinkBase): def __init__(self, link): super(EventLinkAdd, self).__init__(link) class EventLinkDelete(EventLinkBase): def __init__(self, link): super(EventLinkDelete, self).__init__(link) class EventLinkRequest(event.EventRequestBase): # If dpid is None, reply all list def __init__(self, dpid=None): super(EventLinkRequest, self).__init__() self.dst = 'switches' self.dpid = dpid def __str__(self): return 'EventLinkRequest' % \ (self.src, self.dpid) class EventLinkReply(event.EventReplyBase): def __init__(self, dst, dpid, links): super(EventLinkReply, self).__init__(dst) self.dpid = dpid self.links = links def __str__(self): return 'EventLinkReply' % \ (self.dst, self.dpid, len(self.links)) class EventHostRequest(event.EventRequestBase): # if dpid is None, replay all hosts def __init__(self, dpid=None): super(EventHostRequest, self).__init__() self.dst = 'switches' self.dpid = dpid def __str__(self): return 'EventHostRequest' % \ (self.src, self.dpid) class EventHostReply(event.EventReplyBase): def __init__(self, dst, dpid, hosts): super(EventHostReply, self).__init__(dst) self.dpid = dpid self.hosts = hosts def __str__(self): return 'EventHostReply' % \ (self.dst, self.dpid, len(self.hosts)) class EventHostBase(event.EventBase): def __init__(self, host): super(EventHostBase, self).__init__() self.host = host def __str__(self): return '%s<%s>' % (self.__class__.__name__, self.host) class EventHostAdd(EventHostBase): def __init__(self, host): super(EventHostAdd, self).__init__(host) # Note: Currently, EventHostDelete will never be raised, because we have no # appropriate way to detect the disconnection of hosts. Just defined for # future use. class EventHostDelete(EventHostBase): def __init__(self, host): super(EventHostDelete, self).__init__(host) class EventHostMove(event.EventBase): def __init__(self, src, dst): super(EventHostMove, self).__init__() self.src = src self.dst = dst def __str__(self): return '%s' % ( self.__class__.__name__, self.src, self.dst) handler.register_service('os_ken.topology.switches') ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/topology/switches.py0000664000175000017500000010252200000000000020350 0ustar00zuulzuul00000000000000# Copyright (C) 2013 Nippon Telegraph and Telephone 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. import logging import struct import time from os_ken import cfg from collections import defaultdict from os_ken.topology import event from os_ken.base import app_manager from os_ken.controller import ofp_event from os_ken.controller.handler import set_ev_cls from os_ken.controller.handler import MAIN_DISPATCHER, DEAD_DISPATCHER from os_ken.exception import OSKenException from os_ken.lib import addrconv, hub from os_ken.lib.mac import DONTCARE_STR from os_ken.lib.dpid import dpid_to_str, str_to_dpid from os_ken.lib.port_no import port_no_to_str from os_ken.lib.packet import packet, ethernet from os_ken.lib.packet import lldp, ether_types from os_ken.ofproto.ether import ETH_TYPE_LLDP from os_ken.ofproto.ether import ETH_TYPE_CFM from os_ken.ofproto import nx_match from os_ken.ofproto import ofproto_v1_0 from os_ken.ofproto import ofproto_v1_2 from os_ken.ofproto import ofproto_v1_3 from os_ken.ofproto import ofproto_v1_4 LOG = logging.getLogger(__name__) CONF = cfg.CONF CONF.register_cli_opts([ cfg.BoolOpt('observe-links', default=False, help='observe link discovery events.'), cfg.BoolOpt('install-lldp-flow', default=True, help='link discovery: explicitly install flow entry ' 'to send lldp packet to controller'), cfg.BoolOpt('explicit-drop', default=True, help='link discovery: explicitly drop lldp packet in') ]) class Port(object): # This is data class passed by EventPortXXX def __init__(self, dpid, ofproto, ofpport): super(Port, self).__init__() self.dpid = dpid self._ofproto = ofproto self._config = ofpport.config self._state = ofpport.state self.port_no = ofpport.port_no self.hw_addr = ofpport.hw_addr self.name = ofpport.name def is_reserved(self): return self.port_no > self._ofproto.OFPP_MAX def is_down(self): return (self._state & self._ofproto.OFPPS_LINK_DOWN) > 0 \ or (self._config & self._ofproto.OFPPC_PORT_DOWN) > 0 def is_live(self): # NOTE: OF1.2 has OFPPS_LIVE state # return (self._state & self._ofproto.OFPPS_LIVE) > 0 return not self.is_down() def to_dict(self): return {'dpid': dpid_to_str(self.dpid), 'port_no': port_no_to_str(self.port_no), 'hw_addr': self.hw_addr, 'name': self.name.decode('utf-8')} # for Switch.del_port() def __eq__(self, other): return self.dpid == other.dpid and self.port_no == other.port_no def __ne__(self, other): return not self.__eq__(other) def __hash__(self): return hash((self.dpid, self.port_no)) def __str__(self): LIVE_MSG = {False: 'DOWN', True: 'LIVE'} return 'Port' % \ (self.dpid, self.port_no, LIVE_MSG[self.is_live()]) class Switch(object): # This is data class passed by EventSwitchXXX def __init__(self, dp): super(Switch, self).__init__() self.dp = dp self.ports = [] def add_port(self, ofpport): port = Port(self.dp.id, self.dp.ofproto, ofpport) if not port.is_reserved(): self.ports.append(port) def del_port(self, ofpport): self.ports.remove(Port(ofpport)) def to_dict(self): d = {'dpid': dpid_to_str(self.dp.id), 'ports': [port.to_dict() for port in self.ports]} return d def __str__(self): msg = 'Switch Host class def __init__(self): super(HostState, self).__init__() def add(self, host): mac = host.mac self.setdefault(mac, host) def update_ip(self, host, ip_v4=None, ip_v6=None): mac = host.mac host = None if mac in self: host = self[mac] if not host: return if ip_v4 is not None: if ip_v4 in host.ipv4: host.ipv4.remove(ip_v4) host.ipv4.append(ip_v4) if ip_v6 is not None: if ip_v6 in host.ipv6: host.ipv6.remove(ip_v6) host.ipv6.append(ip_v6) def get_by_dpid(self, dpid): result = [] for mac in self: host = self[mac] if host.port.dpid == dpid: result.append(host) return result class PortState(dict): # dict: int port_no -> OFPPort port # OFPPort is defined in os_ken.ofproto.ofproto_v1_X_parser def __init__(self): super(PortState, self).__init__() def add(self, port_no, port): self[port_no] = port def remove(self, port_no): del self[port_no] def modify(self, port_no, port): self[port_no] = port class PortData(object): def __init__(self, is_down, lldp_data): super(PortData, self).__init__() self.is_down = is_down self.lldp_data = lldp_data self.timestamp = None self.sent = 0 def lldp_sent(self): self.timestamp = time.time() self.sent += 1 def lldp_received(self): self.sent = 0 def lldp_dropped(self): return self.sent def clear_timestamp(self): self.timestamp = None def set_down(self, is_down): self.is_down = is_down def __str__(self): return 'PortData' \ % (not self.is_down, self.timestamp, self.sent) class PortDataState(dict): # dict: Port class -> PortData class # slimed down version of OrderedDict as python 2.6 doesn't support it. _PREV = 0 _NEXT = 1 _KEY = 2 def __init__(self): super(PortDataState, self).__init__() self._root = root = [] # sentinel node root[:] = [root, root, None] # [_PREV, _NEXT, _KEY] doubly linked list self._map = {} def _remove_key(self, key): link_prev, link_next, key = self._map.pop(key) link_prev[self._NEXT] = link_next link_next[self._PREV] = link_prev def _append_key(self, key): root = self._root last = root[self._PREV] last[self._NEXT] = root[self._PREV] = self._map[key] = [last, root, key] def _prepend_key(self, key): root = self._root first = root[self._NEXT] first[self._PREV] = root[self._NEXT] = self._map[key] = [root, first, key] def _move_last_key(self, key): self._remove_key(key) self._append_key(key) def _move_front_key(self, key): self._remove_key(key) self._prepend_key(key) def add_port(self, port, lldp_data): if port not in self: self._prepend_key(port) self[port] = PortData(port.is_down(), lldp_data) else: self[port].is_down = port.is_down() def lldp_sent(self, port): port_data = self[port] port_data.lldp_sent() self._move_last_key(port) return port_data def lldp_received(self, port): self[port].lldp_received() def move_front(self, port): port_data = self.get(port, None) if port_data is not None: port_data.clear_timestamp() self._move_front_key(port) def set_down(self, port): is_down = port.is_down() port_data = self[port] port_data.set_down(is_down) port_data.clear_timestamp() if not is_down: self._move_front_key(port) return is_down def get_port(self, port): return self[port] def del_port(self, port): del self[port] self._remove_key(port) def __iter__(self): root = self._root curr = root[self._NEXT] while curr is not root: yield curr[self._KEY] curr = curr[self._NEXT] def clear(self): for node in self._map.values(): del node[:] root = self._root root[:] = [root, root, None] self._map.clear() dict.clear(self) def items(self): 'od.items() -> list of (key, value) pairs in od' return [(key, self[key]) for key in self] def iteritems(self): 'od.iteritems -> an iterator over the (key, value) pairs in od' for k in self: yield (k, self[k]) class LinkState(dict): # dict: Link class -> timestamp def __init__(self): super(LinkState, self).__init__() self._map = defaultdict(lambda: defaultdict(lambda: None)) def get_peers(self, src): return self._map[src].keys() def update_link(self, src, dst): link = Link(src, dst) self[link] = time.time() self._map[src][dst] = link # return if the reverse link is also up or not rev_link = Link(dst, src) return rev_link in self def link_down(self, link): del self[link] del self._map[link.src][link.dst] def rev_link_set_timestamp(self, rev_link, timestamp): # rev_link may or may not in LinkSet if rev_link in self: self[rev_link] = timestamp def port_deleted(self, src): dsts = self.get_peers(src) rev_link_dsts = [] for dst in dsts: link = Link(src, dst) rev_link = Link(dst, src) del self[link] self.pop(rev_link, None) if src in self._map[dst]: del self._map[dst][src] rev_link_dsts.append(dst) del self._map[src] return dsts, rev_link_dsts class LLDPPacket(object): # make a LLDP packet for link discovery. CHASSIS_ID_PREFIX = 'dpid:' CHASSIS_ID_PREFIX_LEN = len(CHASSIS_ID_PREFIX) CHASSIS_ID_FMT = CHASSIS_ID_PREFIX + '%s' PORT_ID_STR = '!I' # uint32_t PORT_ID_SIZE = 4 class LLDPUnknownFormat(OSKenException): message = '%(msg)s' @staticmethod def lldp_packet(dpid, port_no, dl_addr, ttl): pkt = packet.Packet() dst = lldp.LLDP_MAC_NEAREST_BRIDGE src = dl_addr ethertype = ETH_TYPE_LLDP eth_pkt = ethernet.ethernet(dst, src, ethertype) pkt.add_protocol(eth_pkt) tlv_chassis_id = lldp.ChassisID( subtype=lldp.ChassisID.SUB_LOCALLY_ASSIGNED, chassis_id=(LLDPPacket.CHASSIS_ID_FMT % dpid_to_str(dpid)).encode('ascii')) tlv_port_id = lldp.PortID(subtype=lldp.PortID.SUB_PORT_COMPONENT, port_id=struct.pack( LLDPPacket.PORT_ID_STR, port_no)) tlv_ttl = lldp.TTL(ttl=ttl) tlv_end = lldp.End() tlvs = (tlv_chassis_id, tlv_port_id, tlv_ttl, tlv_end) lldp_pkt = lldp.lldp(tlvs) pkt.add_protocol(lldp_pkt) pkt.serialize() return pkt.data @staticmethod def lldp_parse(data): pkt = packet.Packet(data) i = iter(pkt) eth_pkt = next(i) assert type(eth_pkt) == ethernet.ethernet lldp_pkt = next(i) if type(lldp_pkt) != lldp.lldp: raise LLDPPacket.LLDPUnknownFormat() tlv_chassis_id = lldp_pkt.tlvs[0] if tlv_chassis_id.subtype != lldp.ChassisID.SUB_LOCALLY_ASSIGNED: raise LLDPPacket.LLDPUnknownFormat( msg='unknown chassis id subtype %d' % tlv_chassis_id.subtype) chassis_id = tlv_chassis_id.chassis_id.decode('utf-8') if not chassis_id.startswith(LLDPPacket.CHASSIS_ID_PREFIX): raise LLDPPacket.LLDPUnknownFormat( msg='unknown chassis id format %s' % chassis_id) src_dpid = str_to_dpid(chassis_id[LLDPPacket.CHASSIS_ID_PREFIX_LEN:]) tlv_port_id = lldp_pkt.tlvs[1] if tlv_port_id.subtype != lldp.PortID.SUB_PORT_COMPONENT: raise LLDPPacket.LLDPUnknownFormat( msg='unknown port id subtype %d' % tlv_port_id.subtype) port_id = tlv_port_id.port_id if len(port_id) != LLDPPacket.PORT_ID_SIZE: raise LLDPPacket.LLDPUnknownFormat( msg='unknown port id %d' % port_id) (src_port_no, ) = struct.unpack(LLDPPacket.PORT_ID_STR, port_id) return src_dpid, src_port_no class Switches(app_manager.OSKenApp): OFP_VERSIONS = [ofproto_v1_0.OFP_VERSION, ofproto_v1_2.OFP_VERSION, ofproto_v1_3.OFP_VERSION, ofproto_v1_4.OFP_VERSION] _EVENTS = [event.EventSwitchEnter, event.EventSwitchLeave, event.EventSwitchReconnected, event.EventPortAdd, event.EventPortDelete, event.EventPortModify, event.EventLinkAdd, event.EventLinkDelete, event.EventHostAdd] DEFAULT_TTL = 120 # unused. ignored. LLDP_PACKET_LEN = len(LLDPPacket.lldp_packet(0, 0, DONTCARE_STR, 0)) LLDP_SEND_GUARD = .05 LLDP_SEND_PERIOD_PER_PORT = .9 TIMEOUT_CHECK_PERIOD = 5. LINK_TIMEOUT = TIMEOUT_CHECK_PERIOD * 2 def __init__(self, *args, **kwargs): super(Switches, self).__init__(*args, **kwargs) self.name = 'switches' self.dps = {} # datapath_id => Datapath class self.port_state = {} # datapath_id => ports self.ports = PortDataState() # Port class -> PortData class self.links = LinkState() # Link class -> timestamp self.hosts = HostState() # mac address -> Host class list self.is_active = True self.link_discovery = self.CONF.observe_links if self.link_discovery: self.install_flow = self.CONF.install_lldp_flow self.explicit_drop = self.CONF.explicit_drop self.lldp_event = hub.Event() self.link_event = hub.Event() self.threads.append(hub.spawn(self.lldp_loop)) self.threads.append(hub.spawn(self.link_loop)) def close(self): self.is_active = False if self.link_discovery: self.lldp_event.set() self.link_event.set() hub.joinall(self.threads) def _register(self, dp): assert dp.id is not None self.dps[dp.id] = dp if dp.id not in self.port_state: self.port_state[dp.id] = PortState() for port in dp.ports.values(): self.port_state[dp.id].add(port.port_no, port) def _unregister(self, dp): if dp.id in self.dps: if (self.dps[dp.id] == dp): del self.dps[dp.id] del self.port_state[dp.id] def _get_switch(self, dpid): if dpid in self.dps: switch = Switch(self.dps[dpid]) for ofpport in self.port_state[dpid].values(): switch.add_port(ofpport) return switch def _get_port(self, dpid, port_no): switch = self._get_switch(dpid) if switch: for p in switch.ports: if p.port_no == port_no: return p def _port_added(self, port): lldp_data = LLDPPacket.lldp_packet( port.dpid, port.port_no, port.hw_addr, self.DEFAULT_TTL) self.ports.add_port(port, lldp_data) # LOG.debug('_port_added dpid=%s, port_no=%s, live=%s', # port.dpid, port.port_no, port.is_live()) def _link_down(self, port): try: dsts, rev_link_dsts = self.links.port_deleted(port) except KeyError: # LOG.debug('key error. src=%s, dst=%s', # port, self.links.get_peer(port)) return for dst in dsts: link = Link(port, dst) self.send_event_to_observers(event.EventLinkDelete(link)) for rev_link_dst in rev_link_dsts: rev_link = Link(rev_link_dst, port) self.send_event_to_observers(event.EventLinkDelete(rev_link)) self.ports.move_front(rev_link_dst) def _is_edge_port(self, port): for link in self.links: if port == link.src or port == link.dst: return False return True @set_ev_cls(ofp_event.EventOFPStateChange, [MAIN_DISPATCHER, DEAD_DISPATCHER]) def state_change_handler(self, ev): dp = ev.datapath assert dp is not None LOG.debug(dp) if ev.state == MAIN_DISPATCHER: dp_multiple_conns = False if dp.id in self.dps: LOG.warning('Multiple connections from %s', dpid_to_str(dp.id)) dp_multiple_conns = True (self.dps[dp.id]).close() self._register(dp) switch = self._get_switch(dp.id) LOG.debug('register %s', switch) if not dp_multiple_conns: self.send_event_to_observers(event.EventSwitchEnter(switch)) else: evt = event.EventSwitchReconnected(switch) self.send_event_to_observers(evt) if not self.link_discovery: return if self.install_flow: ofproto = dp.ofproto ofproto_parser = dp.ofproto_parser # TODO:XXX need other versions if ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION: rule = nx_match.ClsRule() rule.set_dl_dst(addrconv.mac.text_to_bin( lldp.LLDP_MAC_NEAREST_BRIDGE)) rule.set_dl_type(ETH_TYPE_LLDP) actions = [ofproto_parser.OFPActionOutput( ofproto.OFPP_CONTROLLER, self.LLDP_PACKET_LEN)] dp.send_flow_mod( rule=rule, cookie=0, command=ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=0, actions=actions, priority=0xFFFF) elif ofproto.OFP_VERSION >= ofproto_v1_2.OFP_VERSION: match = ofproto_parser.OFPMatch( eth_type=ETH_TYPE_LLDP, eth_dst=lldp.LLDP_MAC_NEAREST_BRIDGE) # OFPCML_NO_BUFFER is set so that the LLDP is not # buffered on switch parser = ofproto_parser actions = [parser.OFPActionOutput(ofproto.OFPP_CONTROLLER, ofproto.OFPCML_NO_BUFFER )] inst = [parser.OFPInstructionActions( ofproto.OFPIT_APPLY_ACTIONS, actions)] mod = parser.OFPFlowMod(datapath=dp, match=match, idle_timeout=0, hard_timeout=0, instructions=inst, priority=0xFFFF) dp.send_msg(mod) else: LOG.error('cannot install flow. unsupported version. %x', dp.ofproto.OFP_VERSION) # Do not add ports while dp has multiple connections to controller. if not dp_multiple_conns: for port in switch.ports: if not port.is_reserved(): self._port_added(port) self.lldp_event.set() elif ev.state == DEAD_DISPATCHER: # dp.id is None when datapath dies before handshake if dp.id is None: return switch = self._get_switch(dp.id) if switch: if switch.dp is dp: self._unregister(dp) LOG.debug('unregister %s', switch) evt = event.EventSwitchLeave(switch) self.send_event_to_observers(evt) if not self.link_discovery: return for port in switch.ports: if not port.is_reserved(): self.ports.del_port(port) self._link_down(port) self.lldp_event.set() @set_ev_cls(ofp_event.EventOFPPortStatus, MAIN_DISPATCHER) def port_status_handler(self, ev): msg = ev.msg reason = msg.reason dp = msg.datapath ofpport = msg.desc if reason == dp.ofproto.OFPPR_ADD: # LOG.debug('A port was added.' + # '(datapath id = %s, port number = %s)', # dp.id, ofpport.port_no) self.port_state[dp.id].add(ofpport.port_no, ofpport) self.send_event_to_observers( event.EventPortAdd(Port(dp.id, dp.ofproto, ofpport))) if not self.link_discovery: return port = self._get_port(dp.id, ofpport.port_no) if port and not port.is_reserved(): self._port_added(port) self.lldp_event.set() elif reason == dp.ofproto.OFPPR_DELETE: # LOG.debug('A port was deleted.' + # '(datapath id = %s, port number = %s)', # dp.id, ofpport.port_no) self.send_event_to_observers( event.EventPortDelete(Port(dp.id, dp.ofproto, ofpport))) if not self.link_discovery: return port = self._get_port(dp.id, ofpport.port_no) if port and not port.is_reserved(): self.ports.del_port(port) self._link_down(port) self.lldp_event.set() self.port_state[dp.id].remove(ofpport.port_no) else: assert reason == dp.ofproto.OFPPR_MODIFY # LOG.debug('A port was modified.' + # '(datapath id = %s, port number = %s)', # dp.id, ofpport.port_no) self.port_state[dp.id].modify(ofpport.port_no, ofpport) self.send_event_to_observers( event.EventPortModify(Port(dp.id, dp.ofproto, ofpport))) if not self.link_discovery: return port = self._get_port(dp.id, ofpport.port_no) if port and not port.is_reserved(): if self.ports.set_down(port): self._link_down(port) self.lldp_event.set() @staticmethod def _drop_packet(msg): buffer_id = msg.buffer_id if buffer_id == msg.datapath.ofproto.OFP_NO_BUFFER: return dp = msg.datapath # TODO:XXX if dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION: dp.send_packet_out(buffer_id, msg.in_port, []) elif dp.ofproto.OFP_VERSION >= ofproto_v1_2.OFP_VERSION: dp.send_packet_out(buffer_id, msg.match['in_port'], []) else: LOG.error('cannot drop_packet. unsupported version. %x', dp.ofproto.OFP_VERSION) @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER) def lldp_packet_in_handler(self, ev): if not self.link_discovery: return msg = ev.msg try: src_dpid, src_port_no = LLDPPacket.lldp_parse(msg.data) except LLDPPacket.LLDPUnknownFormat: # This handler can receive all the packets which can be # not-LLDP packet. Ignore it silently return dst_dpid = msg.datapath.id if msg.datapath.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION: dst_port_no = msg.in_port elif msg.datapath.ofproto.OFP_VERSION >= ofproto_v1_2.OFP_VERSION: dst_port_no = msg.match['in_port'] else: LOG.error('cannot accept LLDP. unsupported version. %x', msg.datapath.ofproto.OFP_VERSION) src = self._get_port(src_dpid, src_port_no) if not src or src.dpid == dst_dpid: return try: self.ports.lldp_received(src) except KeyError: # There are races between EventOFPPacketIn and # EventDPPortAdd. So packet-in event can happend before # port add event. In that case key error can happend. # LOG.debug('lldp_received error', exc_info=True) pass dst = self._get_port(dst_dpid, dst_port_no) if not dst: return # LOG.debug("Packet-In") # LOG.debug(" src=%s", src) # LOG.debug(" dst=%s", dst) link = Link(src, dst) if link not in self.links: self.send_event_to_observers(event.EventLinkAdd(link)) # remove hosts if it's not attached to edge port host_to_del = [] for host in self.hosts.values(): if not self._is_edge_port(host.port): host_to_del.append(host.mac) for host_mac in host_to_del: del self.hosts[host_mac] if not self.links.update_link(src, dst): # reverse link is not detected yet. # So schedule the check early because it's very likely it's up self.ports.move_front(dst) self.lldp_event.set() if self.explicit_drop: self._drop_packet(msg) @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER) def host_discovery_packet_in_handler(self, ev): msg = ev.msg eth, pkt_type, pkt_data = ethernet.ethernet.parser(msg.data) # ignore lldp and cfm packets if eth.ethertype in (ETH_TYPE_LLDP, ETH_TYPE_CFM): return datapath = msg.datapath dpid = datapath.id port_no = -1 if msg.datapath.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION: port_no = msg.in_port else: port_no = msg.match['in_port'] port = self._get_port(dpid, port_no) # can't find this port(ex: logic port) if not port: return # ignore switch-to-switch port if not self._is_edge_port(port): return host_mac = eth.src host = Host(host_mac, port) if host_mac not in self.hosts: self.hosts.add(host) ev = event.EventHostAdd(host) self.send_event_to_observers(ev) elif self.hosts[host_mac].port != port: # assumes the host is moved to another port ev = event.EventHostMove(src=self.hosts[host_mac], dst=host) self.hosts[host_mac] = host self.send_event_to_observers(ev) # arp packet, update ip address if eth.ethertype == ether_types.ETH_TYPE_ARP: arp_pkt, _, _ = pkt_type.parser(pkt_data) self.hosts.update_ip(host, ip_v4=arp_pkt.src_ip) # ipv4 packet, update ipv4 address elif eth.ethertype == ether_types.ETH_TYPE_IP: ipv4_pkt, _, _ = pkt_type.parser(pkt_data) self.hosts.update_ip(host, ip_v4=ipv4_pkt.src) # ipv6 packet, update ipv6 address elif eth.ethertype == ether_types.ETH_TYPE_IPV6: # TODO: need to handle NDP ipv6_pkt, _, _ = pkt_type.parser(pkt_data) self.hosts.update_ip(host, ip_v6=ipv6_pkt.src) def send_lldp_packet(self, port): try: port_data = self.ports.lldp_sent(port) except KeyError: # ports can be modified during our sleep in self.lldp_loop() # LOG.debug('send_lld error', exc_info=True) return if port_data.is_down: return dp = self.dps.get(port.dpid, None) if dp is None: # datapath was already deleted return # LOG.debug('lldp sent dpid=%s, port_no=%d', dp.id, port.port_no) # TODO:XXX if dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION: actions = [dp.ofproto_parser.OFPActionOutput(port.port_no)] dp.send_packet_out(actions=actions, data=port_data.lldp_data) elif dp.ofproto.OFP_VERSION >= ofproto_v1_2.OFP_VERSION: actions = [dp.ofproto_parser.OFPActionOutput(port.port_no)] out = dp.ofproto_parser.OFPPacketOut( datapath=dp, in_port=dp.ofproto.OFPP_CONTROLLER, buffer_id=dp.ofproto.OFP_NO_BUFFER, actions=actions, data=port_data.lldp_data) dp.send_msg(out) else: LOG.error('cannot send lldp packet. unsupported version. %x', dp.ofproto.OFP_VERSION) def lldp_loop(self): while self.is_active: self.lldp_event.clear() now = time.time() timeout = None ports_now = [] ports = [] for (key, data) in self.ports.items(): if data.timestamp is None: ports_now.append(key) continue expire = data.timestamp + self.LLDP_SEND_PERIOD_PER_PORT if expire <= now: ports.append(key) continue timeout = expire - now break for port in ports_now: self.send_lldp_packet(port) for port in ports: self.send_lldp_packet(port) hub.sleep(self.LLDP_SEND_GUARD) # don't burst if timeout is not None and ports: timeout = 0 # We have already slept # LOG.debug('lldp sleep %s', timeout) self.lldp_event.wait(timeout=timeout) def link_loop(self): while self.is_active: self.link_event.clear() now = time.time() deleted = [] for (link, timestamp) in self.links.items(): # LOG.debug('%s timestamp %d (now %d)', link, timestamp, now) if timestamp + self.LINK_TIMEOUT < now: deleted.append(link) for link in deleted: self.links.link_down(link) # LOG.debug('delete %s', link) self.send_event_to_observers(event.EventLinkDelete(link)) dst = link.dst rev_link = Link(dst, link.src) if rev_link not in deleted: # It is very likely that the reverse link is also # disconnected. Check it early. expire = now - self.LINK_TIMEOUT self.links.rev_link_set_timestamp(rev_link, expire) if dst in self.ports: self.ports.move_front(dst) self.lldp_event.set() self.link_event.wait(timeout=self.TIMEOUT_CHECK_PERIOD) @set_ev_cls(event.EventSwitchRequest) def switch_request_handler(self, req): # LOG.debug(req) dpid = req.dpid switches = [] if dpid is None: # reply all list for dp in self.dps.values(): switches.append(self._get_switch(dp.id)) elif dpid in self.dps: switches.append(self._get_switch(dpid)) rep = event.EventSwitchReply(req.src, switches) self.reply_to_request(req, rep) @set_ev_cls(event.EventLinkRequest) def link_request_handler(self, req): # LOG.debug(req) dpid = req.dpid if dpid is None: links = self.links else: links = [link for link in self.links if link.src.dpid == dpid] rep = event.EventLinkReply(req.src, dpid, links) self.reply_to_request(req, rep) @set_ev_cls(event.EventHostRequest) def host_request_handler(self, req): dpid = req.dpid hosts = [] if dpid is None: for mac in self.hosts: hosts.append(self.hosts[mac]) else: hosts = self.hosts.get_by_dpid(dpid) rep = event.EventHostReply(req.src, dpid, hosts) self.reply_to_request(req, rep) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/os_ken/utils.py0000664000175000017500000000701700000000000016006 0ustar00zuulzuul00000000000000# Copyright (C) 2011 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2011 Isaku Yamahata # # 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. import importlib import logging import os import sys LOG = logging.getLogger('os_ken.utils') def load_source(name, pathname): """ :param name: Name used to create or access a module object. :param pathname: Path pointing to the source file. :return: Loaded and initialized module. """ loader = importlib.machinery.SourceFileLoader(name, pathname) return loader.load_module(name) def chop_py_suffix(p): for suf in ['.py', '.pyc', '.pyo']: if p.endswith(suf): return p[:-len(suf)] return p def _likely_same(a, b): try: # Samefile not availible on windows if sys.platform == 'win32': if os.stat(a) == os.stat(b): return True else: if os.path.samefile(a, b): return True except OSError: # m.__file__ is not always accessible. eg. egg return False if chop_py_suffix(a) == chop_py_suffix(b): return True return False def _find_loaded_module(modpath): # copy() to avoid RuntimeError: dictionary changed size during iteration for k, m in sys.modules.copy().items(): if k == '__main__': continue if not hasattr(m, '__file__'): continue if _likely_same(m.__file__, modpath): return m return None def _import_module_file(path): abspath = os.path.abspath(path) # Backup original sys.path before appending path to file original_path = list(sys.path) sys.path.append(os.path.dirname(abspath)) modname = chop_py_suffix(os.path.basename(abspath)) try: return load_source(modname, abspath) finally: # Restore original sys.path sys.path = original_path def import_module(modname): if os.path.exists(modname): try: # Try to import module since 'modname' is a valid path to a file # e.g.) modname = './path/to/module/name.py' return _import_module_file(modname) except SyntaxError: # The file didn't parse as valid Python code, try # importing module assuming 'modname' is a Python module name # e.g.) modname = 'path.to.module.name' return importlib.import_module(modname) else: # Import module assuming 'modname' is a Python module name # e.g.) modname = 'path.to.module.name' return importlib.import_module(modname) def round_up(x, y): return ((x + y - 1) // y) * y def hex_array(data): """ Convert bytes or bytearray into array of hexes to be printed. """ # convert data into bytearray explicitly return ' '.join('0x%02x' % byte for byte in bytearray(data)) def binary_str(data): """ Convert bytes or bytearray into str to be printed. """ # convert data into bytearray explicitly return ''.join('\\x%02x' % byte for byte in bytearray(data)) ././@PaxHeader0000000000000000000000000000003300000000000011451 xustar000000000000000027 mtime=1724334546.066103 os-ken-2.10.0/os_ken.egg-info/0000775000175000017500000000000000000000000015761 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334545.0 os-ken-2.10.0/os_ken.egg-info/PKG-INFO0000664000175000017500000000260500000000000017061 0ustar00zuulzuul00000000000000Metadata-Version: 1.2 Name: os-ken Version: 2.10.0 Summary: A component-based software defined networking framework for OpenStack. Home-page: http://www.openstack.org/ Author: OpenStack Author-email: openstack-discuss@lists.openstack.org License: UNKNOWN Description: ====== os-ken ====== A component-based software defined networking framework in OpenStack. This is a fork of the Ryu library tailored for OpenStack Neutron. * License: Apache License, Version 2.0 * Documentation: https://docs.openstack.org/os-ken/latest/ * Source: https://opendev.org/openstack/os-ken/ * Bugs: https://storyboard.openstack.org/#!/project/openstack/os-ken * Release Notes: https://docs.openstack.org/releasenotes/os-ken Platform: UNKNOWN Classifier: Environment :: OpenStack Classifier: Intended Audience :: Information Technology Classifier: Intended Audience :: System Administrators Classifier: License :: OSI Approved :: Apache Software License Classifier: Operating System :: POSIX :: Linux Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 Classifier: Programming Language :: Python :: 3.10 Classifier: Programming Language :: Python :: 3.11 Requires-Python: >=3.8 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334546.0 os-ken-2.10.0/os_ken.egg-info/SOURCES.txt0000664000175000017500000025132100000000000017651 0ustar00zuulzuul00000000000000.coveragerc .mailmap .pre-commit-config.yaml .pylintrc .stestr.conf .travis.yml .zuul.yaml AUTHORS CONTRIBUTING.rst ChangeLog HACKING.rst LICENSE MANIFEST.in README.rst requirements.txt setup.cfg setup.py test-requirements.txt tox.ini doc/Makefile doc/requirements.txt doc/source/api_ref.rst doc/source/app.rst doc/source/archive.rst doc/source/components.rst doc/source/conf.py doc/source/configuration.rst doc/source/developing.rst doc/source/docutils.conf doc/source/gui.png doc/source/index.rst doc/source/library.rst doc/source/library_bgp_speaker.rst doc/source/library_bgp_speaker_ref.rst doc/source/library_mrt.rst doc/source/library_of_config.rst doc/source/library_ovsdb.rst doc/source/library_ovsdb_manager.rst doc/source/library_packet.rst doc/source/library_packet_ref.rst doc/source/library_pcap.rst doc/source/nicira_ext_ref.rst doc/source/ofproto_base.rst doc/source/ofproto_ref.rst doc/source/ofproto_v1_0_ref.rst doc/source/ofproto_v1_2_ref.rst doc/source/ofproto_v1_3_ref.rst doc/source/ofproto_v1_4_ref.rst doc/source/ofproto_v1_5_ref.rst doc/source/os_ken_app_api.rst doc/source/parameters.rst doc/source/readme.rst doc/source/snort_integrate.rst doc/source/test-of-config-with-linc.rst doc/source/test-vrrp.rst doc/source/tests.rst doc/source/tls.rst doc/source/writing_os_ken_app.rst doc/source/_static/.placeholder doc/source/_templates/.placeholder doc/source/admin/index.rst doc/source/app/ofctl.rst doc/source/configuration/index.rst doc/source/contributor/index.rst doc/source/library/index.rst doc/source/library_packet_ref/packet_arp.rst doc/source/library_packet_ref/packet_base.rst doc/source/library_packet_ref/packet_bfd.rst doc/source/library_packet_ref/packet_bgp.rst doc/source/library_packet_ref/packet_bmp.rst doc/source/library_packet_ref/packet_bpdu.rst doc/source/library_packet_ref/packet_cfm.rst doc/source/library_packet_ref/packet_dhcp.rst doc/source/library_packet_ref/packet_dhcp6.rst doc/source/library_packet_ref/packet_ethernet.rst doc/source/library_packet_ref/packet_geneve.rst doc/source/library_packet_ref/packet_gre.rst doc/source/library_packet_ref/packet_icmp.rst doc/source/library_packet_ref/packet_icmpv6.rst doc/source/library_packet_ref/packet_igmp.rst doc/source/library_packet_ref/packet_ipv4.rst doc/source/library_packet_ref/packet_ipv6.rst doc/source/library_packet_ref/packet_llc.rst doc/source/library_packet_ref/packet_lldp.rst doc/source/library_packet_ref/packet_mpls.rst doc/source/library_packet_ref/packet_openflow.rst doc/source/library_packet_ref/packet_ospf.rst doc/source/library_packet_ref/packet_pbb.rst doc/source/library_packet_ref/packet_sctp.rst doc/source/library_packet_ref/packet_slow.rst doc/source/library_packet_ref/packet_tcp.rst doc/source/library_packet_ref/packet_udp.rst doc/source/library_packet_ref/packet_vlan.rst doc/source/library_packet_ref/packet_vrrp.rst doc/source/library_packet_ref/packet_vxlan.rst doc/source/library_packet_ref/packet_zebra.rst doc/source/man/osken.rst doc/source/man/osken_manager.rst doc/source/quantumclient/__init__.py doc/source/quantumclient/client.py doc/source/quantumclient/common/__init__.py doc/source/quantumclient/common/exceptions.py doc/source/quantumclient/v2_0/__init__.py doc/source/quantumclient/v2_0/client.py doc/source/reference/index.rst doc/source/user/index.rst etc/os_ken/os_ken.conf os_ken/__init__.py os_ken/cfg.py os_ken/exception.py os_ken/flags.py os_ken/hooks.py os_ken/log.py os_ken/utils.py os_ken.egg-info/PKG-INFO os_ken.egg-info/SOURCES.txt os_ken.egg-info/dependency_links.txt os_ken.egg-info/entry_points.txt os_ken.egg-info/not-zip-safe os_ken.egg-info/pbr.json os_ken.egg-info/requires.txt os_ken.egg-info/top_level.txt os_ken/app/__init__.py os_ken/app/ofctl/__init__.py os_ken/app/ofctl/api.py os_ken/app/ofctl/event.py os_ken/app/ofctl/exception.py os_ken/app/ofctl/service.py os_ken/base/__init__.py os_ken/base/app_manager.py os_ken/cmd/__init__.py os_ken/cmd/manager.py os_ken/cmd/of_config_cli.py os_ken/cmd/ofa_neutron_agent.py os_ken/cmd/osken_base.py os_ken/cmd/rpc_cli.py os_ken/contrib/__init__.py os_ken/controller/__init__.py os_ken/controller/conf_switch.py os_ken/controller/controller.py os_ken/controller/dpset.py os_ken/controller/event.py os_ken/controller/handler.py os_ken/controller/mac_to_network.py os_ken/controller/mac_to_port.py os_ken/controller/network.py os_ken/controller/ofp_api.py os_ken/controller/ofp_event.py os_ken/controller/ofp_handler.py os_ken/controller/tunnels.py os_ken/lib/__init__.py os_ken/lib/addrconv.py os_ken/lib/alert.py os_ken/lib/bfdlib.py os_ken/lib/dpid.py os_ken/lib/hub.py os_ken/lib/igmplib.py os_ken/lib/ip.py os_ken/lib/lacplib.py os_ken/lib/mac.py os_ken/lib/mrtlib.py os_ken/lib/netdevice.py os_ken/lib/ofctl_nicira_ext.py os_ken/lib/ofctl_string.py os_ken/lib/ofctl_utils.py os_ken/lib/ofctl_v1_0.py os_ken/lib/ofctl_v1_2.py os_ken/lib/ofctl_v1_3.py os_ken/lib/ofctl_v1_4.py os_ken/lib/ofctl_v1_5.py os_ken/lib/ofp_pktinfilter.py os_ken/lib/pack_utils.py os_ken/lib/pcaplib.py os_ken/lib/port_no.py os_ken/lib/rpc.py os_ken/lib/snortlib.py os_ken/lib/sockaddr.py os_ken/lib/sockopt.py os_ken/lib/stplib.py os_ken/lib/stringify.py os_ken/lib/type_desc.py os_ken/lib/netconf/__init__.py os_ken/lib/netconf/constants.py os_ken/lib/netconf/netconf.xsd os_ken/lib/netconf/xml.xsd os_ken/lib/of_config/__init__.py os_ken/lib/of_config/base.py os_ken/lib/of_config/capable_switch.py os_ken/lib/of_config/classes.py os_ken/lib/of_config/constants.py os_ken/lib/of_config/generated_classes.py os_ken/lib/of_config/ietf-inet-types.xsd os_ken/lib/of_config/ietf-yang-types.xsd os_ken/lib/of_config/of-config-1.0.xsd os_ken/lib/of_config/of-config-1.1.1.xsd os_ken/lib/of_config/of-config-1.1.xsd os_ken/lib/of_config/xmldsig-core-schema.xsd os_ken/lib/ovs/__init__.py os_ken/lib/ovs/bridge.py os_ken/lib/ovs/db_client.py os_ken/lib/ovs/vsctl.py os_ken/lib/ovs/vswitch_idl.py os_ken/lib/packet/__init__.py os_ken/lib/packet/afi.py os_ken/lib/packet/arp.py os_ken/lib/packet/bfd.py os_ken/lib/packet/bgp.py os_ken/lib/packet/bmp.py os_ken/lib/packet/bpdu.py os_ken/lib/packet/cfm.py os_ken/lib/packet/dhcp.py os_ken/lib/packet/dhcp6.py os_ken/lib/packet/ether_types.py os_ken/lib/packet/ethernet.py os_ken/lib/packet/geneve.py os_ken/lib/packet/gre.py os_ken/lib/packet/icmp.py os_ken/lib/packet/icmpv6.py os_ken/lib/packet/igmp.py os_ken/lib/packet/in_proto.py os_ken/lib/packet/ipv4.py os_ken/lib/packet/ipv6.py os_ken/lib/packet/linux.py os_ken/lib/packet/llc.py os_ken/lib/packet/lldp.py os_ken/lib/packet/mpls.py os_ken/lib/packet/openflow.py os_ken/lib/packet/ospf.py os_ken/lib/packet/packet.py os_ken/lib/packet/packet_base.py os_ken/lib/packet/packet_utils.py os_ken/lib/packet/pbb.py os_ken/lib/packet/safi.py os_ken/lib/packet/sctp.py os_ken/lib/packet/slow.py os_ken/lib/packet/stream_parser.py os_ken/lib/packet/tcp.py os_ken/lib/packet/udp.py os_ken/lib/packet/vlan.py os_ken/lib/packet/vrrp.py os_ken/lib/packet/vxlan.py os_ken/lib/packet/zebra.py os_ken/lib/xflow/__init__.py os_ken/lib/xflow/netflow.py os_ken/lib/xflow/sflow.py os_ken/ofproto/__init__.py os_ken/ofproto/ether.py os_ken/ofproto/inet.py os_ken/ofproto/nicira_ext.py os_ken/ofproto/nx_actions.py os_ken/ofproto/nx_match.py os_ken/ofproto/ofproto_common.py os_ken/ofproto/ofproto_parser.py os_ken/ofproto/ofproto_protocol.py os_ken/ofproto/ofproto_utils.py os_ken/ofproto/ofproto_v1_0.py os_ken/ofproto/ofproto_v1_0_parser.py os_ken/ofproto/ofproto_v1_2.py os_ken/ofproto/ofproto_v1_2_parser.py os_ken/ofproto/ofproto_v1_3.py os_ken/ofproto/ofproto_v1_3_parser.py os_ken/ofproto/ofproto_v1_4.py os_ken/ofproto/ofproto_v1_4_parser.py os_ken/ofproto/ofproto_v1_5.py os_ken/ofproto/ofproto_v1_5_parser.py os_ken/ofproto/oxm_fields.py os_ken/ofproto/oxs_fields.py os_ken/ofproto/oxx_fields.py os_ken/services/__init__.py os_ken/services/protocols/__init__.py os_ken/services/protocols/bgp/__init__.py os_ken/services/protocols/bgp/application.py os_ken/services/protocols/bgp/base.py os_ken/services/protocols/bgp/bgp_sample_conf.py os_ken/services/protocols/bgp/bgpspeaker.py os_ken/services/protocols/bgp/bmp.py os_ken/services/protocols/bgp/constants.py os_ken/services/protocols/bgp/core.py os_ken/services/protocols/bgp/core_manager.py os_ken/services/protocols/bgp/model.py os_ken/services/protocols/bgp/net_ctrl.py os_ken/services/protocols/bgp/peer.py os_ken/services/protocols/bgp/processor.py os_ken/services/protocols/bgp/protocol.py os_ken/services/protocols/bgp/speaker.py os_ken/services/protocols/bgp/api/__init__.py os_ken/services/protocols/bgp/api/all.py os_ken/services/protocols/bgp/api/base.py os_ken/services/protocols/bgp/api/core.py os_ken/services/protocols/bgp/api/import_map.py os_ken/services/protocols/bgp/api/operator.py os_ken/services/protocols/bgp/api/prefix.py os_ken/services/protocols/bgp/api/rpc_log_handler.py os_ken/services/protocols/bgp/api/rtconf.py os_ken/services/protocols/bgp/core_managers/__init__.py os_ken/services/protocols/bgp/core_managers/configuration_manager.py os_ken/services/protocols/bgp/core_managers/import_map_manager.py os_ken/services/protocols/bgp/core_managers/peer_manager.py os_ken/services/protocols/bgp/core_managers/table_manager.py os_ken/services/protocols/bgp/info_base/__init__.py os_ken/services/protocols/bgp/info_base/base.py os_ken/services/protocols/bgp/info_base/evpn.py os_ken/services/protocols/bgp/info_base/ipv4.py os_ken/services/protocols/bgp/info_base/ipv4fs.py os_ken/services/protocols/bgp/info_base/ipv6.py os_ken/services/protocols/bgp/info_base/ipv6fs.py os_ken/services/protocols/bgp/info_base/l2vpnfs.py os_ken/services/protocols/bgp/info_base/rtc.py os_ken/services/protocols/bgp/info_base/vpn.py os_ken/services/protocols/bgp/info_base/vpnv4.py os_ken/services/protocols/bgp/info_base/vpnv4fs.py os_ken/services/protocols/bgp/info_base/vpnv6.py os_ken/services/protocols/bgp/info_base/vpnv6fs.py os_ken/services/protocols/bgp/info_base/vrf.py os_ken/services/protocols/bgp/info_base/vrf4.py os_ken/services/protocols/bgp/info_base/vrf4fs.py os_ken/services/protocols/bgp/info_base/vrf6.py os_ken/services/protocols/bgp/info_base/vrf6fs.py os_ken/services/protocols/bgp/info_base/vrfevpn.py os_ken/services/protocols/bgp/info_base/vrffs.py os_ken/services/protocols/bgp/info_base/vrfl2vpnfs.py os_ken/services/protocols/bgp/operator/__init__.py os_ken/services/protocols/bgp/operator/command.py os_ken/services/protocols/bgp/operator/internal_api.py os_ken/services/protocols/bgp/operator/ssh.py os_ken/services/protocols/bgp/operator/commands/__init__.py os_ken/services/protocols/bgp/operator/commands/clear.py os_ken/services/protocols/bgp/operator/commands/responses.py os_ken/services/protocols/bgp/operator/commands/root.py os_ken/services/protocols/bgp/operator/commands/set.py os_ken/services/protocols/bgp/operator/commands/show/__init__.py os_ken/services/protocols/bgp/operator/commands/show/count.py os_ken/services/protocols/bgp/operator/commands/show/importmap.py os_ken/services/protocols/bgp/operator/commands/show/memory.py os_ken/services/protocols/bgp/operator/commands/show/neighbor.py os_ken/services/protocols/bgp/operator/commands/show/rib.py os_ken/services/protocols/bgp/operator/commands/show/route_formatter_mixin.py os_ken/services/protocols/bgp/operator/commands/show/vrf.py os_ken/services/protocols/bgp/operator/views/__init__.py os_ken/services/protocols/bgp/operator/views/base.py os_ken/services/protocols/bgp/operator/views/bgp.py os_ken/services/protocols/bgp/operator/views/conf.py os_ken/services/protocols/bgp/operator/views/fields.py os_ken/services/protocols/bgp/operator/views/other.py os_ken/services/protocols/bgp/rtconf/__init__.py os_ken/services/protocols/bgp/rtconf/base.py os_ken/services/protocols/bgp/rtconf/common.py os_ken/services/protocols/bgp/rtconf/neighbors.py os_ken/services/protocols/bgp/rtconf/vrfs.py os_ken/services/protocols/bgp/signals/__init__.py os_ken/services/protocols/bgp/signals/base.py os_ken/services/protocols/bgp/signals/emit.py os_ken/services/protocols/bgp/utils/__init__.py os_ken/services/protocols/bgp/utils/bgp.py os_ken/services/protocols/bgp/utils/circlist.py os_ken/services/protocols/bgp/utils/evtlet.py os_ken/services/protocols/bgp/utils/rtfilter.py os_ken/services/protocols/bgp/utils/stats.py os_ken/services/protocols/bgp/utils/validation.py os_ken/services/protocols/ovsdb/__init__.py os_ken/services/protocols/ovsdb/api.py os_ken/services/protocols/ovsdb/client.py os_ken/services/protocols/ovsdb/event.py os_ken/services/protocols/ovsdb/manager.py os_ken/services/protocols/ovsdb/model.py os_ken/services/protocols/vrrp/__init__.py os_ken/services/protocols/vrrp/api.py os_ken/services/protocols/vrrp/dumper.py os_ken/services/protocols/vrrp/event.py os_ken/services/protocols/vrrp/manager.py os_ken/services/protocols/vrrp/monitor.py os_ken/services/protocols/vrrp/monitor_linux.py os_ken/services/protocols/vrrp/monitor_openflow.py os_ken/services/protocols/vrrp/router.py os_ken/services/protocols/vrrp/rpc_manager.py os_ken/services/protocols/vrrp/sample_manager.py os_ken/services/protocols/vrrp/sample_router.py os_ken/services/protocols/vrrp/utils.py os_ken/services/protocols/zebra/__init__.py os_ken/services/protocols/zebra/event.py os_ken/services/protocols/zebra/client/__init__.py os_ken/services/protocols/zebra/client/event.py os_ken/services/protocols/zebra/client/sample_dumper.py os_ken/services/protocols/zebra/client/zclient.py os_ken/services/protocols/zebra/db/__init__.py os_ken/services/protocols/zebra/db/base.py os_ken/services/protocols/zebra/db/interface.py os_ken/services/protocols/zebra/db/route.py os_ken/services/protocols/zebra/server/__init__.py os_ken/services/protocols/zebra/server/event.py os_ken/services/protocols/zebra/server/sample_dumper.py os_ken/services/protocols/zebra/server/zserver.py os_ken/tests/__init__.py os_ken/tests/integrated/__init__.py os_ken/tests/integrated/run_test.py os_ken/tests/integrated/run_tests_with_ovs12.py os_ken/tests/integrated/test_add_flow_v10.py os_ken/tests/integrated/test_add_flow_v12_actions.py os_ken/tests/integrated/test_add_flow_v12_matches.py os_ken/tests/integrated/test_of_config.py os_ken/tests/integrated/test_request_reply_v12.py os_ken/tests/integrated/test_vrrp_linux_multi.py os_ken/tests/integrated/test_vrrp_linux_multi.sh os_ken/tests/integrated/test_vrrp_multi.py os_ken/tests/integrated/test_vrrp_multi.sh os_ken/tests/integrated/tester.py os_ken/tests/integrated/vrrp_common.py os_ken/tests/integrated/bgp/__init__.py os_ken/tests/integrated/bgp/base.py os_ken/tests/integrated/bgp/base_ip6.py os_ken/tests/integrated/bgp/test_basic.py os_ken/tests/integrated/bgp/test_ip6_basic.py os_ken/tests/integrated/common/__init__.py os_ken/tests/integrated/common/docker_base.py os_ken/tests/integrated/common/install_docker_test_pkg.sh os_ken/tests/integrated/common/install_docker_test_pkg_common.sh os_ken/tests/integrated/common/install_docker_test_pkg_for_travis.sh os_ken/tests/integrated/common/oskenbgp.py os_ken/tests/integrated/common/quagga.py os_ken/tests/mininet/run_mnet-test.sh os_ken/tests/mininet/l2/mpls/PopMPLS_mpls.mn os_ken/tests/mininet/l2/mpls/PushMPLS_ip.mn os_ken/tests/mininet/l2/mpls/PushMPLS_mpls.mn os_ken/tests/mininet/l2/mpls/test_mpls.py os_ken/tests/mininet/l2/vlan/PopVLAN_vlan.mn os_ken/tests/mininet/l2/vlan/PopVLAN_vlanvlan.mn os_ken/tests/mininet/l2/vlan/PushVLAN_icmp.mn os_ken/tests/mininet/l2/vlan/test_vlan.py os_ken/tests/mininet/l3/icmp/ICMP_ping.mn os_ken/tests/mininet/l3/icmp/ICMP_reply.mn os_ken/tests/mininet/l3/icmp/test_icmp.py os_ken/tests/mininet/l3/ip_ttl/DecNwTtl.mn os_ken/tests/mininet/l3/ip_ttl/test_ip_ttl.py os_ken/tests/mininet/packet_lib/arp/ARP_gratuitous.mn os_ken/tests/mininet/packet_lib/arp/ARP_reply.mn os_ken/tests/mininet/packet_lib/arp/ARP_request.mn os_ken/tests/mininet/packet_lib/arp/test_arp.py os_ken/tests/packet_data/bgp4/bgp4-keepalive.pcap os_ken/tests/packet_data/bgp4/bgp4-open.pcap os_ken/tests/packet_data/bgp4/bgp4-update.pcap os_ken/tests/packet_data/bgp4/bgp4-update_ipv6.pcap os_ken/tests/packet_data/bgp4/bgp4-update_vpnv6.pcap os_ken/tests/packet_data/bgp4/evpn_esi_arbitrary.pcap os_ken/tests/packet_data/bgp4/evpn_esi_as_based.pcap os_ken/tests/packet_data/bgp4/evpn_esi_l2_bridge.pcap os_ken/tests/packet_data/bgp4/evpn_esi_lacp.pcap os_ken/tests/packet_data/bgp4/evpn_esi_mac_base.pcap os_ken/tests/packet_data/bgp4/evpn_esi_router_id.pcap os_ken/tests/packet_data/bgp4/evpn_nlri_eth_a-d.pcap os_ken/tests/packet_data/bgp4/evpn_nlri_eth_seg.pcap os_ken/tests/packet_data/bgp4/evpn_nlri_inc_multi_eth_tag.pcap os_ken/tests/packet_data/bgp4/evpn_nlri_ip_prefix.pcap os_ken/tests/packet_data/bgp4/evpn_nlri_mac_ip_ad.pcap os_ken/tests/packet_data/bgp4/flowspec_action_redirect.pcap os_ken/tests/packet_data/bgp4/flowspec_action_traffic_action.pcap os_ken/tests/packet_data/bgp4/flowspec_action_traffic_marking.pcap os_ken/tests/packet_data/bgp4/flowspec_action_traffic_rate.pcap os_ken/tests/packet_data/bgp4/flowspec_nlri_ipv4.pcap os_ken/tests/packet_data/bgp4/flowspec_nlri_ipv6.pcap os_ken/tests/packet_data/bgp4/flowspec_nlri_l2vpn.pcap os_ken/tests/packet_data/bgp4/flowspec_nlri_vpn4.pcap os_ken/tests/packet_data/bgp4/flowspec_nlri_vpn6.pcap os_ken/tests/packet_data/mrt/rib.20161101.0000_pick.bz2 os_ken/tests/packet_data/mrt/updates.20161101.0000.bz2 os_ken/tests/packet_data/of10/1-1-ofp_packet_out.packet os_ken/tests/packet_data/of10/1-2-ofp_flow_mod.packet os_ken/tests/packet_data/of10/1-4-ofp_packet_in.packet os_ken/tests/packet_data/of10/1-5-features_request.packet os_ken/tests/packet_data/of10/1-6-ofp_switch_features.packet os_ken/tests/packet_data/of10/libofproto-OFP10-ofp_packet_out_packet_library.packet os_ken/tests/packet_data/of10/ovs-ofctl-of10-action_dec_mpls_ttl.packet os_ken/tests/packet_data/of10/ovs-ofctl-of10-action_dec_nw_ttl.packet os_ken/tests/packet_data/of10/ovs-ofctl-of10-action_pop_mpls.packet os_ken/tests/packet_data/of10/ovs-ofctl-of10-action_push_mpls.packet os_ken/tests/packet_data/of10/ovs-ofctl-of10-action_set_mpls_label.packet os_ken/tests/packet_data/of10/ovs-ofctl-of10-action_set_mpls_tc.packet os_ken/tests/packet_data/of10/ovs-ofctl-of10-action_set_mpls_ttl.packet os_ken/tests/packet_data/of12/3-0-ofp_desc_stats_reply.packet os_ken/tests/packet_data/of12/3-1-ofp_packet_out.packet os_ken/tests/packet_data/of12/3-10-ofp_hello.packet os_ken/tests/packet_data/of12/3-11-ofp_flow_stats_request.packet os_ken/tests/packet_data/of12/3-12-ofp_flow_stats_reply.packet os_ken/tests/packet_data/of12/3-13-ofp_echo_request.packet os_ken/tests/packet_data/of12/3-14-ofp_echo_reply.packet os_ken/tests/packet_data/of12/3-15-ofp_error_msg.packet os_ken/tests/packet_data/of12/3-16-ofp_experimenter.packet os_ken/tests/packet_data/of12/3-17-ofp_barrier_request.packet os_ken/tests/packet_data/of12/3-18-ofp_barrier_reply.packet os_ken/tests/packet_data/of12/3-19-ofp_role_request.packet os_ken/tests/packet_data/of12/3-2-ofp_flow_mod.packet os_ken/tests/packet_data/of12/3-20-ofp_role_reply.packet os_ken/tests/packet_data/of12/3-21-ofp_group_mod.packet os_ken/tests/packet_data/of12/3-22-ofp_port_mod.packet os_ken/tests/packet_data/of12/3-23-ofp_table_mod.packet os_ken/tests/packet_data/of12/3-24-ofp_desc_stats_request.packet os_ken/tests/packet_data/of12/3-25-ofp_aggregate_stats_request.packet os_ken/tests/packet_data/of12/3-26-ofp_aggregate_stats_reply.packet os_ken/tests/packet_data/of12/3-27-ofp_table_stats_request.packet os_ken/tests/packet_data/of12/3-28-ofp_table_stats_reply.packet os_ken/tests/packet_data/of12/3-29-ofp_port_stats_request.packet os_ken/tests/packet_data/of12/3-3-ofp_flow_mod.packet os_ken/tests/packet_data/of12/3-30-ofp_port_stats_reply.packet os_ken/tests/packet_data/of12/3-31-ofp_group_features_stats_request.packet os_ken/tests/packet_data/of12/3-32-ofp_group_features_stats_reply.packet os_ken/tests/packet_data/of12/3-33-ofp_group_desc_stats_request.packet os_ken/tests/packet_data/of12/3-34-ofp_group_desc_stats_reply.packet os_ken/tests/packet_data/of12/3-35-ofp_queue_get_config_request.packet os_ken/tests/packet_data/of12/3-36-ofp_queue_get_config_reply.packet os_ken/tests/packet_data/of12/3-37-ofp_queue_stats_request.packet os_ken/tests/packet_data/of12/3-38-ofp_queue_stats_reply.packet os_ken/tests/packet_data/of12/3-39-ofp_port_status.packet os_ken/tests/packet_data/of12/3-4-ofp_packet_in.packet os_ken/tests/packet_data/of12/3-40-ofp_flow_removed.packet os_ken/tests/packet_data/of12/3-41-ofp_error_msg_experimenter.packet os_ken/tests/packet_data/of12/3-5-ofp_features_request.packet os_ken/tests/packet_data/of12/3-59-ofp_packet_in.packet os_ken/tests/packet_data/of12/3-6-ofp_features_reply.packet os_ken/tests/packet_data/of12/3-60-ofp_flow_mod.packet os_ken/tests/packet_data/of12/3-61-ofp_group_stats_request.packet os_ken/tests/packet_data/of12/3-62-ofp_group_stats_reply.packet os_ken/tests/packet_data/of12/3-7-ofp_set_config.packet os_ken/tests/packet_data/of12/3-8-ofp_get_config_request.packet os_ken/tests/packet_data/of12/3-9-ofp_get_config_reply.packet os_ken/tests/packet_data/of12/libofproto-OFP12-ofp_packet_out_packet_library.packet os_ken/tests/packet_data/of13/4-0-ofp_desc_reply.packet os_ken/tests/packet_data/of13/4-1-ofp_packet_out.packet os_ken/tests/packet_data/of13/4-10-ofp_hello.packet os_ken/tests/packet_data/of13/4-11-ofp_flow_stats_request.packet os_ken/tests/packet_data/of13/4-12-ofp_flow_stats_reply.packet os_ken/tests/packet_data/of13/4-13-ofp_echo_request.packet os_ken/tests/packet_data/of13/4-14-ofp_echo_reply.packet os_ken/tests/packet_data/of13/4-15-ofp_error_msg.packet os_ken/tests/packet_data/of13/4-16-ofp_experimenter.packet os_ken/tests/packet_data/of13/4-17-ofp_barrier_request.packet os_ken/tests/packet_data/of13/4-18-ofp_barrier_reply.packet os_ken/tests/packet_data/of13/4-19-ofp_role_request.packet os_ken/tests/packet_data/of13/4-2-ofp_flow_mod.packet os_ken/tests/packet_data/of13/4-20-ofp_role_reply.packet os_ken/tests/packet_data/of13/4-21-ofp_group_mod.packet os_ken/tests/packet_data/of13/4-22-ofp_port_mod.packet os_ken/tests/packet_data/of13/4-23-ofp_table_mod.packet os_ken/tests/packet_data/of13/4-24-ofp_desc_request.packet os_ken/tests/packet_data/of13/4-25-ofp_aggregate_stats_request.packet os_ken/tests/packet_data/of13/4-26-ofp_aggregate_stats_reply.packet os_ken/tests/packet_data/of13/4-27-ofp_table_stats_request.packet os_ken/tests/packet_data/of13/4-28-ofp_table_stats_reply.packet os_ken/tests/packet_data/of13/4-29-ofp_port_stats_request.packet os_ken/tests/packet_data/of13/4-3-ofp_flow_mod.packet os_ken/tests/packet_data/of13/4-30-ofp_port_stats_reply.packet os_ken/tests/packet_data/of13/4-31-ofp_group_features_request.packet os_ken/tests/packet_data/of13/4-32-ofp_group_features_reply.packet os_ken/tests/packet_data/of13/4-33-ofp_group_desc_request.packet os_ken/tests/packet_data/of13/4-34-ofp_group_desc_reply.packet os_ken/tests/packet_data/of13/4-35-ofp_queue_get_config_request.packet os_ken/tests/packet_data/of13/4-36-ofp_queue_get_config_reply.packet os_ken/tests/packet_data/of13/4-37-ofp_queue_stats_request.packet os_ken/tests/packet_data/of13/4-38-ofp_queue_stats_reply.packet os_ken/tests/packet_data/of13/4-39-ofp_port_status.packet os_ken/tests/packet_data/of13/4-4-ofp_packet_in.packet os_ken/tests/packet_data/of13/4-40-ofp_flow_removed.packet os_ken/tests/packet_data/of13/4-41-ofp_error_msg_experimenter.packet os_ken/tests/packet_data/of13/4-42-ofp_get_async_request.packet os_ken/tests/packet_data/of13/4-43-ofp_get_async_reply.packet os_ken/tests/packet_data/of13/4-44-ofp_set_async.packet os_ken/tests/packet_data/of13/4-45-ofp_meter_mod.packet os_ken/tests/packet_data/of13/4-46-ofp_flow_mod.packet os_ken/tests/packet_data/of13/4-47-ofp_meter_config_request.packet os_ken/tests/packet_data/of13/4-48-ofp_meter_config_reply.packet os_ken/tests/packet_data/of13/4-49-ofp_meter_stats_request.packet os_ken/tests/packet_data/of13/4-5-ofp_features_request.packet os_ken/tests/packet_data/of13/4-50-ofp_meter_stats_reply.packet os_ken/tests/packet_data/of13/4-51-ofp_meter_features_request.packet os_ken/tests/packet_data/of13/4-52-ofp_meter_features_reply.packet os_ken/tests/packet_data/of13/4-53-ofp_port_desc_request.packet os_ken/tests/packet_data/of13/4-54-ofp_port_desc_reply.packet os_ken/tests/packet_data/of13/4-55-ofp_table_features_request.packet os_ken/tests/packet_data/of13/4-56-ofp_table_features_reply.packet os_ken/tests/packet_data/of13/4-57-ofp_group_stats_request.packet os_ken/tests/packet_data/of13/4-58-ofp_group_stats_reply.packet os_ken/tests/packet_data/of13/4-59-ofp_packet_in.packet os_ken/tests/packet_data/of13/4-6-ofp_features_reply.packet os_ken/tests/packet_data/of13/4-60-ofp_flow_mod.packet os_ken/tests/packet_data/of13/4-61-ofp_experimenter_request.packet os_ken/tests/packet_data/of13/4-62-ofp_experimenter_reply.packet os_ken/tests/packet_data/of13/4-63-onf_flow_monitor_request.packet os_ken/tests/packet_data/of13/4-7-ofp_set_config.packet os_ken/tests/packet_data/of13/4-8-ofp_get_config_request.packet os_ken/tests/packet_data/of13/4-9-ofp_get_config_reply.packet os_ken/tests/packet_data/of13/libofproto-OFP13-echo_reply.packet os_ken/tests/packet_data/of13/libofproto-OFP13-echo_request.packet os_ken/tests/packet_data/of13/libofproto-OFP13-error_msg.packet os_ken/tests/packet_data/of13/libofproto-OFP13-features_reply.packet os_ken/tests/packet_data/of13/libofproto-OFP13-flow_mod.packet os_ken/tests/packet_data/of13/libofproto-OFP13-flow_mod.truncated64 os_ken/tests/packet_data/of13/libofproto-OFP13-flow_mod_conjunction.packet os_ken/tests/packet_data/of13/libofproto-OFP13-flow_mod_match_conj.packet os_ken/tests/packet_data/of13/libofproto-OFP13-flow_removed.packet os_ken/tests/packet_data/of13/libofproto-OFP13-get_config_reply.packet os_ken/tests/packet_data/of13/libofproto-OFP13-hello.packet os_ken/tests/packet_data/of13/libofproto-OFP13-meter_mod.packet os_ken/tests/packet_data/of13/libofproto-OFP13-ofp_packet_out_packet_library.packet os_ken/tests/packet_data/of13/libofproto-OFP13-packet_in.packet os_ken/tests/packet_data/of13/libofproto-OFP13-port_mod.packet os_ken/tests/packet_data/of13/libofproto-OFP13-port_status.packet os_ken/tests/packet_data/of13/libofproto-OFP13-set_config.packet os_ken/tests/packet_data/of13/libofproto-OFP13-table_mod.packet os_ken/tests/packet_data/of13/ovs-ofctl-of13-action_conjunction.packet os_ken/tests/packet_data/of13/ovs-ofctl-of13-action_controller.packet os_ken/tests/packet_data/of13/ovs-ofctl-of13-action_controller2.packet os_ken/tests/packet_data/of13/ovs-ofctl-of13-action_ct.packet os_ken/tests/packet_data/of13/ovs-ofctl-of13-action_ct_clear.packet os_ken/tests/packet_data/of13/ovs-ofctl-of13-action_ct_exec.packet os_ken/tests/packet_data/of13/ovs-ofctl-of13-action_ct_nat.packet os_ken/tests/packet_data/of13/ovs-ofctl-of13-action_ct_nat_v6.packet os_ken/tests/packet_data/of13/ovs-ofctl-of13-action_dec_ttl_cnt_ids.packet os_ken/tests/packet_data/of13/ovs-ofctl-of13-action_fintimeout.packet os_ken/tests/packet_data/of13/ovs-ofctl-of13-action_learn.packet os_ken/tests/packet_data/of13/ovs-ofctl-of13-action_note.packet os_ken/tests/packet_data/of13/ovs-ofctl-of13-action_output_trunc.packet os_ken/tests/packet_data/of13/ovs-ofctl-of13-action_resubmit.packet os_ken/tests/packet_data/of13/ovs-ofctl-of13-action_sample.packet os_ken/tests/packet_data/of13/ovs-ofctl-of13-action_sample2.packet os_ken/tests/packet_data/of13/ovs-ofctl-of13-action_stack_pop.packet os_ken/tests/packet_data/of13/ovs-ofctl-of13-action_stack_push.packet os_ken/tests/packet_data/of13/ovs-ofctl-of13-match_conj.packet os_ken/tests/packet_data/of13/ovs-ofctl-of13-match_load_nx_register.packet os_ken/tests/packet_data/of13/ovs-ofctl-of13-match_move_nx_register.packet os_ken/tests/packet_data/of13/ovs-ofctl-of13-match_pkt_mark.packet os_ken/tests/packet_data/of13/ovs-ofctl-of13-match_pkt_mark_masked.packet os_ken/tests/packet_data/of14/5-0-ofp_desc_reply.packet os_ken/tests/packet_data/of14/5-1-ofp_packet_out.packet os_ken/tests/packet_data/of14/5-10-ofp_hello.packet os_ken/tests/packet_data/of14/5-11-ofp_flow_stats_request.packet os_ken/tests/packet_data/of14/5-12-ofp_flow_stats_reply.packet os_ken/tests/packet_data/of14/5-13-ofp_echo_request.packet os_ken/tests/packet_data/of14/5-14-ofp_echo_reply.packet os_ken/tests/packet_data/of14/5-15-ofp_error_msg.packet os_ken/tests/packet_data/of14/5-16-ofp_experimenter.packet os_ken/tests/packet_data/of14/5-17-ofp_barrier_request.packet os_ken/tests/packet_data/of14/5-18-ofp_barrier_reply.packet os_ken/tests/packet_data/of14/5-19-ofp_role_request.packet os_ken/tests/packet_data/of14/5-2-ofp_flow_mod.packet os_ken/tests/packet_data/of14/5-20-ofp_role_reply.packet os_ken/tests/packet_data/of14/5-21-ofp_group_mod.packet os_ken/tests/packet_data/of14/5-22-ofp_port_mod.packet os_ken/tests/packet_data/of14/5-23-ofp_table_mod.packet os_ken/tests/packet_data/of14/5-24-ofp_desc_request.packet os_ken/tests/packet_data/of14/5-25-ofp_aggregate_stats_request.packet os_ken/tests/packet_data/of14/5-26-ofp_aggregate_stats_reply.packet os_ken/tests/packet_data/of14/5-27-ofp_table_stats_request.packet os_ken/tests/packet_data/of14/5-28-ofp_table_stats_reply.packet os_ken/tests/packet_data/of14/5-29-ofp_port_stats_request.packet os_ken/tests/packet_data/of14/5-3-ofp_flow_mod.packet os_ken/tests/packet_data/of14/5-30-ofp_port_stats_reply.packet os_ken/tests/packet_data/of14/5-31-ofp_group_features_request.packet os_ken/tests/packet_data/of14/5-32-ofp_group_features_reply.packet os_ken/tests/packet_data/of14/5-33-ofp_group_desc_request.packet os_ken/tests/packet_data/of14/5-34-ofp_group_desc_reply.packet os_ken/tests/packet_data/of14/5-35-ofp_queue_stats_request.packet os_ken/tests/packet_data/of14/5-36-ofp_queue_stats_reply.packet os_ken/tests/packet_data/of14/5-37-ofp_port_status.packet os_ken/tests/packet_data/of14/5-38-ofp_flow_removed.packet os_ken/tests/packet_data/of14/5-39-ofp_error_msg_experimenter.packet os_ken/tests/packet_data/of14/5-4-ofp_packet_in.packet os_ken/tests/packet_data/of14/5-40-ofp_get_async_request.packet os_ken/tests/packet_data/of14/5-41-ofp_get_async_reply.packet os_ken/tests/packet_data/of14/5-42-ofp_set_async.packet os_ken/tests/packet_data/of14/5-43-ofp_meter_mod.packet os_ken/tests/packet_data/of14/5-44-ofp_flow_mod.packet os_ken/tests/packet_data/of14/5-45-ofp_meter_config_request.packet os_ken/tests/packet_data/of14/5-46-ofp_meter_config_reply.packet os_ken/tests/packet_data/of14/5-47-ofp_meter_stats_request.packet os_ken/tests/packet_data/of14/5-48-ofp_meter_stats_reply.packet os_ken/tests/packet_data/of14/5-49-ofp_meter_features_request.packet os_ken/tests/packet_data/of14/5-5-ofp_features_request.packet os_ken/tests/packet_data/of14/5-50-ofp_meter_features_reply.packet os_ken/tests/packet_data/of14/5-51-ofp_port_desc_request.packet os_ken/tests/packet_data/of14/5-52-ofp_port_desc_reply.packet os_ken/tests/packet_data/of14/5-53-ofp_table_features_request.packet os_ken/tests/packet_data/of14/5-54-ofp_table_features_reply.packet os_ken/tests/packet_data/of14/5-55-ofp_group_stats_request.packet os_ken/tests/packet_data/of14/5-56-ofp_group_stats_reply.packet os_ken/tests/packet_data/of14/5-57-ofp_packet_in.packet os_ken/tests/packet_data/of14/5-58-ofp_flow_mod.packet os_ken/tests/packet_data/of14/5-59-ofp_experimenter_request.packet os_ken/tests/packet_data/of14/5-6-ofp_features_reply.packet os_ken/tests/packet_data/of14/5-60-ofp_experimenter_reply.packet os_ken/tests/packet_data/of14/5-61-ofp_table_desc_request.packet os_ken/tests/packet_data/of14/5-62-ofp_table_desc_reply.packet os_ken/tests/packet_data/of14/5-63-ofp_queue_desc_request.packet os_ken/tests/packet_data/of14/5-64-ofp_queue_desc_reply.packet os_ken/tests/packet_data/of14/5-65-ofp_role_status.packet os_ken/tests/packet_data/of14/5-66-ofp_flow_monitor_request.packet os_ken/tests/packet_data/of14/5-67-ofp_flow_monitor_reply.packet os_ken/tests/packet_data/of14/5-68-ofp_table_status.packet os_ken/tests/packet_data/of14/5-69-ofp_bundle_ctrl_msg.packet os_ken/tests/packet_data/of14/5-7-ofp_set_config.packet os_ken/tests/packet_data/of14/5-70-ofp_bundle_add_msg.packet os_ken/tests/packet_data/of14/5-71-ofp_requestforward.packet os_ken/tests/packet_data/of14/5-8-ofp_get_config_request.packet os_ken/tests/packet_data/of14/5-9-ofp_get_config_reply.packet os_ken/tests/packet_data/of14/libofproto-OFP14-ofp_packet_out_packet_library.packet os_ken/tests/packet_data/of15/libofproto-OFP15-aggregate_stats_reply.packet os_ken/tests/packet_data/of15/libofproto-OFP15-aggregate_stats_request.packet os_ken/tests/packet_data/of15/libofproto-OFP15-barrier_reply.packet os_ken/tests/packet_data/of15/libofproto-OFP15-barrier_request.packet os_ken/tests/packet_data/of15/libofproto-OFP15-bundle_add.packet os_ken/tests/packet_data/of15/libofproto-OFP15-bundle_ctrl.packet os_ken/tests/packet_data/of15/libofproto-OFP15-bundle_features_reply.packet os_ken/tests/packet_data/of15/libofproto-OFP15-bundle_features_request.packet os_ken/tests/packet_data/of15/libofproto-OFP15-controller_status.packet os_ken/tests/packet_data/of15/libofproto-OFP15-controller_status_reply.packet os_ken/tests/packet_data/of15/libofproto-OFP15-controller_status_request.packet os_ken/tests/packet_data/of15/libofproto-OFP15-desc_reply.packet os_ken/tests/packet_data/of15/libofproto-OFP15-desc_request.packet os_ken/tests/packet_data/of15/libofproto-OFP15-echo_reply.packet os_ken/tests/packet_data/of15/libofproto-OFP15-echo_request.packet os_ken/tests/packet_data/of15/libofproto-OFP15-error_msg.packet os_ken/tests/packet_data/of15/libofproto-OFP15-error_msg_experimenter.packet os_ken/tests/packet_data/of15/libofproto-OFP15-experimenter.packet os_ken/tests/packet_data/of15/libofproto-OFP15-experimenter_reply.packet os_ken/tests/packet_data/of15/libofproto-OFP15-experimenter_request.packet os_ken/tests/packet_data/of15/libofproto-OFP15-features_reply.packet os_ken/tests/packet_data/of15/libofproto-OFP15-features_request.packet os_ken/tests/packet_data/of15/libofproto-OFP15-flow_desc_reply.packet os_ken/tests/packet_data/of15/libofproto-OFP15-flow_desc_request.packet os_ken/tests/packet_data/of15/libofproto-OFP15-flow_mod.packet os_ken/tests/packet_data/of15/libofproto-OFP15-flow_mod_conjunction.packet os_ken/tests/packet_data/of15/libofproto-OFP15-flow_mod_match_conj.packet os_ken/tests/packet_data/of15/libofproto-OFP15-flow_monitor_reply.packet os_ken/tests/packet_data/of15/libofproto-OFP15-flow_monitor_request.packet os_ken/tests/packet_data/of15/libofproto-OFP15-flow_removed.packet os_ken/tests/packet_data/of15/libofproto-OFP15-flow_stats_reply.packet os_ken/tests/packet_data/of15/libofproto-OFP15-flow_stats_request.packet os_ken/tests/packet_data/of15/libofproto-OFP15-get_async_reply.packet os_ken/tests/packet_data/of15/libofproto-OFP15-get_async_request.packet os_ken/tests/packet_data/of15/libofproto-OFP15-get_config_reply.packet os_ken/tests/packet_data/of15/libofproto-OFP15-get_config_request.packet os_ken/tests/packet_data/of15/libofproto-OFP15-group_desc_reply.packet os_ken/tests/packet_data/of15/libofproto-OFP15-group_desc_request.packet os_ken/tests/packet_data/of15/libofproto-OFP15-group_features_reply.packet os_ken/tests/packet_data/of15/libofproto-OFP15-group_features_request.packet os_ken/tests/packet_data/of15/libofproto-OFP15-group_mod.packet os_ken/tests/packet_data/of15/libofproto-OFP15-group_stats_reply.packet os_ken/tests/packet_data/of15/libofproto-OFP15-group_stats_request.packet os_ken/tests/packet_data/of15/libofproto-OFP15-hello.packet os_ken/tests/packet_data/of15/libofproto-OFP15-meter_desc_reply.packet os_ken/tests/packet_data/of15/libofproto-OFP15-meter_desc_request.packet os_ken/tests/packet_data/of15/libofproto-OFP15-meter_features_reply.packet os_ken/tests/packet_data/of15/libofproto-OFP15-meter_features_request.packet os_ken/tests/packet_data/of15/libofproto-OFP15-meter_mod.packet os_ken/tests/packet_data/of15/libofproto-OFP15-meter_stats_reply.packet os_ken/tests/packet_data/of15/libofproto-OFP15-meter_stats_request.packet os_ken/tests/packet_data/of15/libofproto-OFP15-packet_in.packet os_ken/tests/packet_data/of15/libofproto-OFP15-packet_out.packet os_ken/tests/packet_data/of15/libofproto-OFP15-port_desc_reply.packet os_ken/tests/packet_data/of15/libofproto-OFP15-port_desc_request.packet os_ken/tests/packet_data/of15/libofproto-OFP15-port_mod.packet os_ken/tests/packet_data/of15/libofproto-OFP15-port_stats_reply.packet os_ken/tests/packet_data/of15/libofproto-OFP15-port_stats_request.packet os_ken/tests/packet_data/of15/libofproto-OFP15-port_status.packet os_ken/tests/packet_data/of15/libofproto-OFP15-queue_desc_reply.packet os_ken/tests/packet_data/of15/libofproto-OFP15-queue_desc_request.packet os_ken/tests/packet_data/of15/libofproto-OFP15-queue_stats_reply.packet os_ken/tests/packet_data/of15/libofproto-OFP15-queue_stats_request.packet os_ken/tests/packet_data/of15/libofproto-OFP15-requestforward.packet os_ken/tests/packet_data/of15/libofproto-OFP15-role_reply.packet os_ken/tests/packet_data/of15/libofproto-OFP15-role_request.packet os_ken/tests/packet_data/of15/libofproto-OFP15-role_status.packet os_ken/tests/packet_data/of15/libofproto-OFP15-set_async.packet os_ken/tests/packet_data/of15/libofproto-OFP15-set_config.packet os_ken/tests/packet_data/of15/libofproto-OFP15-table_desc_reply.packet os_ken/tests/packet_data/of15/libofproto-OFP15-table_desc_request.packet os_ken/tests/packet_data/of15/libofproto-OFP15-table_features_reply.packet os_ken/tests/packet_data/of15/libofproto-OFP15-table_features_request.packet os_ken/tests/packet_data/of15/libofproto-OFP15-table_mod.packet os_ken/tests/packet_data/of15/libofproto-OFP15-table_stats_reply.packet os_ken/tests/packet_data/of15/libofproto-OFP15-table_stats_request.packet os_ken/tests/packet_data/of15/libofproto-OFP15-table_status.packet os_ken/tests/packet_data/pcap/big_endian.pcap os_ken/tests/packet_data/pcap/geneve_unknown.pcap os_ken/tests/packet_data/pcap/gre_full_options.pcap os_ken/tests/packet_data/pcap/gre_no_option.pcap os_ken/tests/packet_data/pcap/gre_nvgre_option.pcap os_ken/tests/packet_data/pcap/little_endian.pcap os_ken/tests/packet_data/pcap/openflow_flowmod.pcap os_ken/tests/packet_data/pcap/openflow_flowstats_req.pcap os_ken/tests/packet_data/pcap/openflow_invalid_version.pcap os_ken/tests/packet_data/pcap/zebra_v2.pcap os_ken/tests/packet_data/pcap/zebra_v3.pcap os_ken/tests/packet_data/pcap/zebra_v4_frr_v2.pcap os_ken/tests/packet_data_generator3/gen.py os_ken/tests/switch/__init__.py os_ken/tests/switch/run_mininet.py os_ken/tests/switch/tester.py os_ken/tests/switch/of10/action/00_OUTPUT.json os_ken/tests/switch/of10/action/01_SET_VLAN_VID.json os_ken/tests/switch/of10/action/02_SET_VLAN_PCP.json os_ken/tests/switch/of10/action/03_STRIP_VLAN.json os_ken/tests/switch/of10/action/04_SET_DL_SRC.json os_ken/tests/switch/of10/action/05_SET_DL_DST.json os_ken/tests/switch/of10/action/06_SET_NW_SRC.json os_ken/tests/switch/of10/action/07_SET_NW_DST.json os_ken/tests/switch/of10/action/08_SET_NW_TOS_IPv4.json os_ken/tests/switch/of10/action/08_SET_NW_TOS_IPv6.json os_ken/tests/switch/of10/action/09_SET_TP_SRC_IPv4_TCP.json os_ken/tests/switch/of10/action/09_SET_TP_SRC_IPv4_UDP.json os_ken/tests/switch/of10/action/09_SET_TP_SRC_IPv6_TCP.json os_ken/tests/switch/of10/action/09_SET_TP_SRC_IPv6_UDP.json os_ken/tests/switch/of10/action/10_SET_TP_DST_IPv4_TCP.json os_ken/tests/switch/of10/action/10_SET_TP_DST_IPv4_UDP.json os_ken/tests/switch/of10/action/10_SET_TP_DST_IPv6_TCP.json os_ken/tests/switch/of10/action/10_SET_TP_DST_IPv6_UDP.json os_ken/tests/switch/of10/match/00_IN_PORT.json os_ken/tests/switch/of10/match/01_DL_SRC.json os_ken/tests/switch/of10/match/02_DL_DST.json os_ken/tests/switch/of10/match/03_DL_VLAN.json os_ken/tests/switch/of10/match/04_DL_VLAN_PCP.json os_ken/tests/switch/of10/match/05_DL_TYPE.json os_ken/tests/switch/of10/match/06_NW_TOS_IPv4.json os_ken/tests/switch/of10/match/06_NW_TOS_IPv6.json os_ken/tests/switch/of10/match/07_NW_PROTO_IPv4.json os_ken/tests/switch/of10/match/07_NW_PROTO_IPv6.json os_ken/tests/switch/of10/match/08_NW_SRC.json os_ken/tests/switch/of10/match/08_NW_SRC_Mask.json os_ken/tests/switch/of10/match/09_NW_DST.json os_ken/tests/switch/of10/match/09_NW_DST_Mask.json os_ken/tests/switch/of10/match/10_TP_SRC_IPv4_TCP.json os_ken/tests/switch/of10/match/10_TP_SRC_IPv4_UDP.json os_ken/tests/switch/of10/match/10_TP_SRC_IPv6_TCP.json os_ken/tests/switch/of10/match/10_TP_SRC_IPv6_UDP.json os_ken/tests/switch/of10/match/11_TP_DST_IPv4_TCP.json os_ken/tests/switch/of10/match/11_TP_DST_IPv4_UDP.json os_ken/tests/switch/of10/match/11_TP_DST_IPv6_TCP.json os_ken/tests/switch/of10/match/11_TP_DST_IPv6_UDP.json os_ken/tests/switch/of13/action/00_OUTPUT.json os_ken/tests/switch/of13/action/11_COPY_TTL_OUT.json os_ken/tests/switch/of13/action/12_COPY_TTL_IN.json os_ken/tests/switch/of13/action/15_SET_MPLS_TTL.json os_ken/tests/switch/of13/action/16_DEC_MPLS_TTL.json os_ken/tests/switch/of13/action/17_PUSH_VLAN.json os_ken/tests/switch/of13/action/17_PUSH_VLAN_multiple.json os_ken/tests/switch/of13/action/18_POP_VLAN.json os_ken/tests/switch/of13/action/19_PUSH_MPLS.json os_ken/tests/switch/of13/action/19_PUSH_MPLS_multiple.json os_ken/tests/switch/of13/action/20_POP_MPLS.json os_ken/tests/switch/of13/action/23_SET_NW_TTL_IPv4.json os_ken/tests/switch/of13/action/23_SET_NW_TTL_IPv6.json os_ken/tests/switch/of13/action/24_DEC_NW_TTL_IPv4.json os_ken/tests/switch/of13/action/24_DEC_NW_TTL_IPv6.json os_ken/tests/switch/of13/action/26_PUSH_PBB.json os_ken/tests/switch/of13/action/26_PUSH_PBB_multiple.json os_ken/tests/switch/of13/action/27_POP_PBB.json os_ken/tests/switch/of13/action/25_SET_FIELD/03_ETH_DST.json os_ken/tests/switch/of13/action/25_SET_FIELD/04_ETH_SRC.json os_ken/tests/switch/of13/action/25_SET_FIELD/05_ETH_TYPE.json os_ken/tests/switch/of13/action/25_SET_FIELD/06_VLAN_VID.json os_ken/tests/switch/of13/action/25_SET_FIELD/07_VLAN_PCP.json os_ken/tests/switch/of13/action/25_SET_FIELD/08_IP_DSCP_IPv4.json os_ken/tests/switch/of13/action/25_SET_FIELD/08_IP_DSCP_IPv6.json os_ken/tests/switch/of13/action/25_SET_FIELD/09_IP_ECN_IPv4.json os_ken/tests/switch/of13/action/25_SET_FIELD/09_IP_ECN_IPv6.json os_ken/tests/switch/of13/action/25_SET_FIELD/10_IP_PROTO_IPv4.json os_ken/tests/switch/of13/action/25_SET_FIELD/10_IP_PROTO_IPv6.json os_ken/tests/switch/of13/action/25_SET_FIELD/11_IPV4_SRC.json os_ken/tests/switch/of13/action/25_SET_FIELD/12_IPV4_DST.json os_ken/tests/switch/of13/action/25_SET_FIELD/13_TCP_SRC_IPv4.json os_ken/tests/switch/of13/action/25_SET_FIELD/13_TCP_SRC_IPv6.json os_ken/tests/switch/of13/action/25_SET_FIELD/14_TCP_DST_IPv4.json os_ken/tests/switch/of13/action/25_SET_FIELD/14_TCP_DST_IPv6.json os_ken/tests/switch/of13/action/25_SET_FIELD/15_UDP_SRC_IPv4.json os_ken/tests/switch/of13/action/25_SET_FIELD/15_UDP_SRC_IPv6.json os_ken/tests/switch/of13/action/25_SET_FIELD/16_UDP_DST_IPv4.json os_ken/tests/switch/of13/action/25_SET_FIELD/16_UDP_DST_IPv6.json os_ken/tests/switch/of13/action/25_SET_FIELD/17_SCTP_SRC_IPv4.json os_ken/tests/switch/of13/action/25_SET_FIELD/17_SCTP_SRC_IPv6.json os_ken/tests/switch/of13/action/25_SET_FIELD/18_SCTP_DST_IPv4.json os_ken/tests/switch/of13/action/25_SET_FIELD/18_SCTP_DST_IPv6.json os_ken/tests/switch/of13/action/25_SET_FIELD/19_ICMPV4_TYPE.json os_ken/tests/switch/of13/action/25_SET_FIELD/20_ICMPV4_CODE.json os_ken/tests/switch/of13/action/25_SET_FIELD/21_ARP_OP.json os_ken/tests/switch/of13/action/25_SET_FIELD/22_ARP_SPA.json os_ken/tests/switch/of13/action/25_SET_FIELD/23_ARP_TPA.json os_ken/tests/switch/of13/action/25_SET_FIELD/24_ARP_SHA.json os_ken/tests/switch/of13/action/25_SET_FIELD/25_ARP_THA.json os_ken/tests/switch/of13/action/25_SET_FIELD/26_IPV6_SRC.json os_ken/tests/switch/of13/action/25_SET_FIELD/27_IPV6_DST.json os_ken/tests/switch/of13/action/25_SET_FIELD/28_IPV6_FLABEL.json os_ken/tests/switch/of13/action/25_SET_FIELD/29_ICMPV6_TYPE.json os_ken/tests/switch/of13/action/25_SET_FIELD/30_ICMPV6_CODE.json os_ken/tests/switch/of13/action/25_SET_FIELD/31_IPV6_ND_TARGET.json os_ken/tests/switch/of13/action/25_SET_FIELD/32_IPV6_ND_SLL.json os_ken/tests/switch/of13/action/25_SET_FIELD/33_IPV6_ND_TLL.json os_ken/tests/switch/of13/action/25_SET_FIELD/34_MPLS_LABEL.json os_ken/tests/switch/of13/action/25_SET_FIELD/35_MPLS_TC.json os_ken/tests/switch/of13/action/25_SET_FIELD/36_MPLS_BOS.json os_ken/tests/switch/of13/action/25_SET_FIELD/37_PBB_ISID.json os_ken/tests/switch/of13/action/25_SET_FIELD/38_TUNNEL_ID.json os_ken/tests/switch/of13/group/00_ALL.json os_ken/tests/switch/of13/group/01_SELECT_Ether.json os_ken/tests/switch/of13/group/01_SELECT_IP.json os_ken/tests/switch/of13/group/01_SELECT_Weight_Ether.json os_ken/tests/switch/of13/group/01_SELECT_Weight_IP.json os_ken/tests/switch/of13/match/00_IN_PORT.json os_ken/tests/switch/of13/match/02_METADATA.json os_ken/tests/switch/of13/match/02_METADATA_Mask.json os_ken/tests/switch/of13/match/03_ETH_DST.json os_ken/tests/switch/of13/match/03_ETH_DST_Mask.json os_ken/tests/switch/of13/match/04_ETH_SRC.json os_ken/tests/switch/of13/match/04_ETH_SRC_Mask.json os_ken/tests/switch/of13/match/05_ETH_TYPE.json os_ken/tests/switch/of13/match/06_VLAN_VID.json os_ken/tests/switch/of13/match/06_VLAN_VID_Mask.json os_ken/tests/switch/of13/match/07_VLAN_PCP.json os_ken/tests/switch/of13/match/08_IP_DSCP_IPv4.json os_ken/tests/switch/of13/match/08_IP_DSCP_IPv6.json os_ken/tests/switch/of13/match/09_IP_ECN_IPv4.json os_ken/tests/switch/of13/match/09_IP_ECN_IPv6.json os_ken/tests/switch/of13/match/10_IP_PROTO_IPv4.json os_ken/tests/switch/of13/match/10_IP_PROTO_IPv6.json os_ken/tests/switch/of13/match/11_IPV4_SRC.json os_ken/tests/switch/of13/match/11_IPV4_SRC_Mask.json os_ken/tests/switch/of13/match/12_IPV4_DST.json os_ken/tests/switch/of13/match/12_IPV4_DST_Mask.json os_ken/tests/switch/of13/match/13_TCP_SRC_IPv4.json os_ken/tests/switch/of13/match/13_TCP_SRC_IPv6.json os_ken/tests/switch/of13/match/14_TCP_DST_IPv4.json os_ken/tests/switch/of13/match/14_TCP_DST_IPv6.json os_ken/tests/switch/of13/match/15_UDP_SRC_IPv4.json os_ken/tests/switch/of13/match/15_UDP_SRC_IPv6.json os_ken/tests/switch/of13/match/16_UDP_DST_IPv4.json os_ken/tests/switch/of13/match/16_UDP_DST_IPv6.json os_ken/tests/switch/of13/match/17_SCTP_SRC_IPv4.json os_ken/tests/switch/of13/match/17_SCTP_SRC_IPv6.json os_ken/tests/switch/of13/match/18_SCTP_DST_IPv4.json os_ken/tests/switch/of13/match/18_SCTP_DST_IPv6.json os_ken/tests/switch/of13/match/19_ICMPV4_TYPE.json os_ken/tests/switch/of13/match/20_ICMPV4_CODE.json os_ken/tests/switch/of13/match/21_ARP_OP.json os_ken/tests/switch/of13/match/22_ARP_SPA.json os_ken/tests/switch/of13/match/22_ARP_SPA_Mask.json os_ken/tests/switch/of13/match/23_ARP_TPA.json os_ken/tests/switch/of13/match/23_ARP_TPA_Mask.json os_ken/tests/switch/of13/match/24_ARP_SHA.json os_ken/tests/switch/of13/match/24_ARP_SHA_Mask.json os_ken/tests/switch/of13/match/25_ARP_THA.json os_ken/tests/switch/of13/match/25_ARP_THA_Mask.json os_ken/tests/switch/of13/match/26_IPV6_SRC.json os_ken/tests/switch/of13/match/26_IPV6_SRC_Mask.json os_ken/tests/switch/of13/match/27_IPV6_DST.json os_ken/tests/switch/of13/match/27_IPV6_DST_Mask.json os_ken/tests/switch/of13/match/28_IPV6_FLABEL.json os_ken/tests/switch/of13/match/28_IPV6_FLABEL_Mask.json os_ken/tests/switch/of13/match/29_ICMPV6_TYPE.json os_ken/tests/switch/of13/match/30_ICMPV6_CODE.json os_ken/tests/switch/of13/match/31_IPV6_ND_TARGET.json os_ken/tests/switch/of13/match/32_IPV6_ND_SLL.json os_ken/tests/switch/of13/match/33_IPV6_ND_TLL.json os_ken/tests/switch/of13/match/34_MPLS_LABEL.json os_ken/tests/switch/of13/match/35_MPLS_TC.json os_ken/tests/switch/of13/match/36_MPLS_BOS.json os_ken/tests/switch/of13/match/37_PBB_ISID.json os_ken/tests/switch/of13/match/37_PBB_ISID_Mask.json os_ken/tests/switch/of13/match/38_TUNNEL_ID.json os_ken/tests/switch/of13/match/38_TUNNEL_ID_Mask.json os_ken/tests/switch/of13/match/39_IPV6_EXTHDR.json os_ken/tests/switch/of13/match/39_IPV6_EXTHDR_Mask.json os_ken/tests/switch/of13/meter/01_DROP_00_KBPS_00_1M.json os_ken/tests/switch/of13/meter/01_DROP_00_KBPS_01_10M.json os_ken/tests/switch/of13/meter/01_DROP_00_KBPS_02_100M.json os_ken/tests/switch/of13/meter/01_DROP_01_PKTPS_00_100.json os_ken/tests/switch/of13/meter/01_DROP_01_PKTPS_01_1000.json os_ken/tests/switch/of13/meter/01_DROP_01_PKTPS_02_10000.json os_ken/tests/switch/of13/meter/02_DSCP_REMARK_00_KBPS_00_1M.json os_ken/tests/switch/of13/meter/02_DSCP_REMARK_00_KBPS_01_10M.json os_ken/tests/switch/of13/meter/02_DSCP_REMARK_00_KBPS_02_100M.json os_ken/tests/switch/of13/meter/02_DSCP_REMARK_01_PKTPS_00_100.json os_ken/tests/switch/of13/meter/02_DSCP_REMARK_01_PKTPS_01_1000.json os_ken/tests/switch/of13/meter/02_DSCP_REMARK_01_PKTPS_02_10000.json os_ken/tests/switch/of14/action/00_OUTPUT.json os_ken/tests/switch/of14/action/11_COPY_TTL_OUT.json os_ken/tests/switch/of14/action/12_COPY_TTL_IN.json os_ken/tests/switch/of14/action/15_SET_MPLS_TTL.json os_ken/tests/switch/of14/action/16_DEC_MPLS_TTL.json os_ken/tests/switch/of14/action/17_PUSH_VLAN.json os_ken/tests/switch/of14/action/17_PUSH_VLAN_multiple.json os_ken/tests/switch/of14/action/18_POP_VLAN.json os_ken/tests/switch/of14/action/19_PUSH_MPLS.json os_ken/tests/switch/of14/action/19_PUSH_MPLS_multiple.json os_ken/tests/switch/of14/action/20_POP_MPLS.json os_ken/tests/switch/of14/action/23_SET_NW_TTL_IPv4.json os_ken/tests/switch/of14/action/23_SET_NW_TTL_IPv6.json os_ken/tests/switch/of14/action/24_DEC_NW_TTL_IPv4.json os_ken/tests/switch/of14/action/24_DEC_NW_TTL_IPv6.json os_ken/tests/switch/of14/action/26_PUSH_PBB.json os_ken/tests/switch/of14/action/26_PUSH_PBB_multiple.json os_ken/tests/switch/of14/action/27_POP_PBB.json os_ken/tests/switch/of14/action/25_SET_FIELD/03_ETH_DST.json os_ken/tests/switch/of14/action/25_SET_FIELD/04_ETH_SRC.json os_ken/tests/switch/of14/action/25_SET_FIELD/05_ETH_TYPE.json os_ken/tests/switch/of14/action/25_SET_FIELD/06_VLAN_VID.json os_ken/tests/switch/of14/action/25_SET_FIELD/07_VLAN_PCP.json os_ken/tests/switch/of14/action/25_SET_FIELD/08_IP_DSCP_IPv4.json os_ken/tests/switch/of14/action/25_SET_FIELD/08_IP_DSCP_IPv6.json os_ken/tests/switch/of14/action/25_SET_FIELD/09_IP_ECN_IPv4.json os_ken/tests/switch/of14/action/25_SET_FIELD/09_IP_ECN_IPv6.json os_ken/tests/switch/of14/action/25_SET_FIELD/10_IP_PROTO_IPv4.json os_ken/tests/switch/of14/action/25_SET_FIELD/10_IP_PROTO_IPv6.json os_ken/tests/switch/of14/action/25_SET_FIELD/11_IPV4_SRC.json os_ken/tests/switch/of14/action/25_SET_FIELD/12_IPV4_DST.json os_ken/tests/switch/of14/action/25_SET_FIELD/13_TCP_SRC_IPv4.json os_ken/tests/switch/of14/action/25_SET_FIELD/13_TCP_SRC_IPv6.json os_ken/tests/switch/of14/action/25_SET_FIELD/14_TCP_DST_IPv4.json os_ken/tests/switch/of14/action/25_SET_FIELD/14_TCP_DST_IPv6.json os_ken/tests/switch/of14/action/25_SET_FIELD/15_UDP_SRC_IPv4.json os_ken/tests/switch/of14/action/25_SET_FIELD/15_UDP_SRC_IPv6.json os_ken/tests/switch/of14/action/25_SET_FIELD/16_UDP_DST_IPv4.json os_ken/tests/switch/of14/action/25_SET_FIELD/16_UDP_DST_IPv6.json os_ken/tests/switch/of14/action/25_SET_FIELD/17_SCTP_SRC_IPv4.json os_ken/tests/switch/of14/action/25_SET_FIELD/17_SCTP_SRC_IPv6.json os_ken/tests/switch/of14/action/25_SET_FIELD/18_SCTP_DST_IPv4.json os_ken/tests/switch/of14/action/25_SET_FIELD/18_SCTP_DST_IPv6.json os_ken/tests/switch/of14/action/25_SET_FIELD/19_ICMPV4_TYPE.json os_ken/tests/switch/of14/action/25_SET_FIELD/20_ICMPV4_CODE.json os_ken/tests/switch/of14/action/25_SET_FIELD/21_ARP_OP.json os_ken/tests/switch/of14/action/25_SET_FIELD/22_ARP_SPA.json os_ken/tests/switch/of14/action/25_SET_FIELD/23_ARP_TPA.json os_ken/tests/switch/of14/action/25_SET_FIELD/24_ARP_SHA.json os_ken/tests/switch/of14/action/25_SET_FIELD/25_ARP_THA.json os_ken/tests/switch/of14/action/25_SET_FIELD/26_IPV6_SRC.json os_ken/tests/switch/of14/action/25_SET_FIELD/27_IPV6_DST.json os_ken/tests/switch/of14/action/25_SET_FIELD/28_IPV6_FLABEL.json os_ken/tests/switch/of14/action/25_SET_FIELD/29_ICMPV6_TYPE.json os_ken/tests/switch/of14/action/25_SET_FIELD/30_ICMPV6_CODE.json os_ken/tests/switch/of14/action/25_SET_FIELD/31_IPV6_ND_TARGET.json os_ken/tests/switch/of14/action/25_SET_FIELD/32_IPV6_ND_SLL.json os_ken/tests/switch/of14/action/25_SET_FIELD/33_IPV6_ND_TLL.json os_ken/tests/switch/of14/action/25_SET_FIELD/34_MPLS_LABEL.json os_ken/tests/switch/of14/action/25_SET_FIELD/35_MPLS_TC.json os_ken/tests/switch/of14/action/25_SET_FIELD/36_MPLS_BOS.json os_ken/tests/switch/of14/action/25_SET_FIELD/37_PBB_ISID.json os_ken/tests/switch/of14/action/25_SET_FIELD/38_TUNNEL_ID.json os_ken/tests/switch/of14/action/25_SET_FIELD/41_PBB_UCA.json os_ken/tests/switch/of14/group/00_ALL.json os_ken/tests/switch/of14/group/01_SELECT_Ether.json os_ken/tests/switch/of14/group/01_SELECT_IP.json os_ken/tests/switch/of14/group/01_SELECT_Weight_Ether.json os_ken/tests/switch/of14/group/01_SELECT_Weight_IP.json os_ken/tests/switch/of14/match/00_IN_PORT.json os_ken/tests/switch/of14/match/02_METADATA.json os_ken/tests/switch/of14/match/02_METADATA_Mask.json os_ken/tests/switch/of14/match/03_ETH_DST.json os_ken/tests/switch/of14/match/03_ETH_DST_Mask.json os_ken/tests/switch/of14/match/04_ETH_SRC.json os_ken/tests/switch/of14/match/04_ETH_SRC_Mask.json os_ken/tests/switch/of14/match/05_ETH_TYPE.json os_ken/tests/switch/of14/match/06_VLAN_VID.json os_ken/tests/switch/of14/match/06_VLAN_VID_Mask.json os_ken/tests/switch/of14/match/07_VLAN_PCP.json os_ken/tests/switch/of14/match/08_IP_DSCP_IPv4.json os_ken/tests/switch/of14/match/08_IP_DSCP_IPv6.json os_ken/tests/switch/of14/match/09_IP_ECN_IPv4.json os_ken/tests/switch/of14/match/09_IP_ECN_IPv6.json os_ken/tests/switch/of14/match/10_IP_PROTO_IPv4.json os_ken/tests/switch/of14/match/10_IP_PROTO_IPv6.json os_ken/tests/switch/of14/match/11_IPV4_SRC.json os_ken/tests/switch/of14/match/11_IPV4_SRC_Mask.json os_ken/tests/switch/of14/match/12_IPV4_DST.json os_ken/tests/switch/of14/match/12_IPV4_DST_Mask.json os_ken/tests/switch/of14/match/13_TCP_SRC_IPv4.json os_ken/tests/switch/of14/match/13_TCP_SRC_IPv6.json os_ken/tests/switch/of14/match/14_TCP_DST_IPv4.json os_ken/tests/switch/of14/match/14_TCP_DST_IPv6.json os_ken/tests/switch/of14/match/15_UDP_SRC_IPv4.json os_ken/tests/switch/of14/match/15_UDP_SRC_IPv6.json os_ken/tests/switch/of14/match/16_UDP_DST_IPv4.json os_ken/tests/switch/of14/match/16_UDP_DST_IPv6.json os_ken/tests/switch/of14/match/17_SCTP_SRC_IPv4.json os_ken/tests/switch/of14/match/17_SCTP_SRC_IPv6.json os_ken/tests/switch/of14/match/18_SCTP_DST_IPv4.json os_ken/tests/switch/of14/match/18_SCTP_DST_IPv6.json os_ken/tests/switch/of14/match/19_ICMPV4_TYPE.json os_ken/tests/switch/of14/match/20_ICMPV4_CODE.json os_ken/tests/switch/of14/match/21_ARP_OP.json os_ken/tests/switch/of14/match/22_ARP_SPA.json os_ken/tests/switch/of14/match/22_ARP_SPA_Mask.json os_ken/tests/switch/of14/match/23_ARP_TPA.json os_ken/tests/switch/of14/match/23_ARP_TPA_Mask.json os_ken/tests/switch/of14/match/24_ARP_SHA.json os_ken/tests/switch/of14/match/24_ARP_SHA_Mask.json os_ken/tests/switch/of14/match/25_ARP_THA.json os_ken/tests/switch/of14/match/25_ARP_THA_Mask.json os_ken/tests/switch/of14/match/26_IPV6_SRC.json os_ken/tests/switch/of14/match/26_IPV6_SRC_Mask.json os_ken/tests/switch/of14/match/27_IPV6_DST.json os_ken/tests/switch/of14/match/27_IPV6_DST_Mask.json os_ken/tests/switch/of14/match/28_IPV6_FLABEL.json os_ken/tests/switch/of14/match/28_IPV6_FLABEL_Mask.json os_ken/tests/switch/of14/match/29_ICMPV6_TYPE.json os_ken/tests/switch/of14/match/30_ICMPV6_CODE.json os_ken/tests/switch/of14/match/31_IPV6_ND_TARGET.json os_ken/tests/switch/of14/match/32_IPV6_ND_SLL.json os_ken/tests/switch/of14/match/33_IPV6_ND_TLL.json os_ken/tests/switch/of14/match/34_MPLS_LABEL.json os_ken/tests/switch/of14/match/35_MPLS_TC.json os_ken/tests/switch/of14/match/36_MPLS_BOS.json os_ken/tests/switch/of14/match/37_PBB_ISID.json os_ken/tests/switch/of14/match/37_PBB_ISID_Mask.json os_ken/tests/switch/of14/match/38_TUNNEL_ID.json os_ken/tests/switch/of14/match/38_TUNNEL_ID_Mask.json os_ken/tests/switch/of14/match/39_IPV6_EXTHDR.json os_ken/tests/switch/of14/match/39_IPV6_EXTHDR_Mask.json os_ken/tests/switch/of14/match/41_PBB_UCA.json os_ken/tests/switch/of14/meter/01_DROP_00_KBPS_00_1M.json os_ken/tests/switch/of14/meter/01_DROP_00_KBPS_01_10M.json os_ken/tests/switch/of14/meter/01_DROP_00_KBPS_02_100M.json os_ken/tests/switch/of14/meter/01_DROP_01_PKTPS_00_100.json os_ken/tests/switch/of14/meter/01_DROP_01_PKTPS_01_1000.json os_ken/tests/switch/of14/meter/01_DROP_01_PKTPS_02_10000.json os_ken/tests/switch/of14/meter/02_DSCP_REMARK_00_KBPS_00_1M.json os_ken/tests/switch/of14/meter/02_DSCP_REMARK_00_KBPS_01_10M.json os_ken/tests/switch/of14/meter/02_DSCP_REMARK_00_KBPS_02_100M.json os_ken/tests/switch/of14/meter/02_DSCP_REMARK_01_PKTPS_00_100.json os_ken/tests/switch/of14/meter/02_DSCP_REMARK_01_PKTPS_01_1000.json os_ken/tests/switch/of14/meter/02_DSCP_REMARK_01_PKTPS_02_10000.json os_ken/tests/unit/__init__.py os_ken/tests/unit/cmd/__init__.py os_ken/tests/unit/cmd/dummy_app.py os_ken/tests/unit/cmd/dummy_openflow_app.py os_ken/tests/unit/cmd/test_manager.py os_ken/tests/unit/controller/__init__.py os_ken/tests/unit/controller/cert.crt os_ken/tests/unit/controller/cert.key os_ken/tests/unit/controller/test_controller.py os_ken/tests/unit/lib/__init__.py os_ken/tests/unit/lib/test_sockaddr.py os_ken/tests/unit/ofproto/__init__.py os_ken/tests/unit/ofproto/test_ether.py os_ken/tests/unit/ofproto/test_inet.py os_ken/tests/unit/ofproto/test_nx_flow_spec.py os_ken/tests/unit/ofproto/test_ofproto.py os_ken/tests/unit/ofproto/test_ofproto_common.py os_ken/tests/unit/ofproto/test_ofproto_parser.py os_ken/tests/unit/ofproto/test_ofproto_v12.py os_ken/tests/unit/ofproto/test_oxm.py os_ken/tests/unit/ofproto/test_oxs.py os_ken/tests/unit/ofproto/test_parser.py os_ken/tests/unit/ofproto/test_parser_compat.py os_ken/tests/unit/ofproto/test_parser_ofpmatch.py os_ken/tests/unit/ofproto/test_parser_ofpstats.py os_ken/tests/unit/ofproto/test_parser_v10.py os_ken/tests/unit/ofproto/test_parser_v12.py os_ken/tests/unit/ofproto/test_parser_v13.py os_ken/tests/unit/ofproto/json/of10/1-1-ofp_packet_out.packet.json os_ken/tests/unit/ofproto/json/of10/1-2-ofp_flow_mod.packet.json os_ken/tests/unit/ofproto/json/of10/1-4-ofp_packet_in.packet.json os_ken/tests/unit/ofproto/json/of10/1-5-features_request.packet.json os_ken/tests/unit/ofproto/json/of10/1-6-ofp_switch_features.packet.json os_ken/tests/unit/ofproto/json/of10/libofproto-OFP10-ofp_packet_out_packet_library.packet.json os_ken/tests/unit/ofproto/json/of10/ovs-ofctl-of10-action_dec_mpls_ttl.packet.json os_ken/tests/unit/ofproto/json/of10/ovs-ofctl-of10-action_dec_nw_ttl.packet.json os_ken/tests/unit/ofproto/json/of10/ovs-ofctl-of10-action_pop_mpls.packet.json os_ken/tests/unit/ofproto/json/of10/ovs-ofctl-of10-action_push_mpls.packet.json os_ken/tests/unit/ofproto/json/of10/ovs-ofctl-of10-action_set_mpls_label.packet.json os_ken/tests/unit/ofproto/json/of10/ovs-ofctl-of10-action_set_mpls_tc.packet.json os_ken/tests/unit/ofproto/json/of10/ovs-ofctl-of10-action_set_mpls_ttl.packet.json os_ken/tests/unit/ofproto/json/of12/3-0-ofp_desc_stats_reply.packet.json os_ken/tests/unit/ofproto/json/of12/3-1-ofp_packet_out.packet.json os_ken/tests/unit/ofproto/json/of12/3-10-ofp_hello.packet.json os_ken/tests/unit/ofproto/json/of12/3-11-ofp_flow_stats_request.packet.json os_ken/tests/unit/ofproto/json/of12/3-12-ofp_flow_stats_reply.packet.json os_ken/tests/unit/ofproto/json/of12/3-13-ofp_echo_request.packet.json os_ken/tests/unit/ofproto/json/of12/3-14-ofp_echo_reply.packet.json os_ken/tests/unit/ofproto/json/of12/3-15-ofp_error_msg.packet.json os_ken/tests/unit/ofproto/json/of12/3-16-ofp_experimenter.packet.json os_ken/tests/unit/ofproto/json/of12/3-17-ofp_barrier_request.packet.json os_ken/tests/unit/ofproto/json/of12/3-18-ofp_barrier_reply.packet.json os_ken/tests/unit/ofproto/json/of12/3-19-ofp_role_request.packet.json os_ken/tests/unit/ofproto/json/of12/3-2-ofp_flow_mod.packet.json os_ken/tests/unit/ofproto/json/of12/3-20-ofp_role_reply.packet.json os_ken/tests/unit/ofproto/json/of12/3-21-ofp_group_mod.packet.json os_ken/tests/unit/ofproto/json/of12/3-22-ofp_port_mod.packet.json os_ken/tests/unit/ofproto/json/of12/3-23-ofp_table_mod.packet.json os_ken/tests/unit/ofproto/json/of12/3-24-ofp_desc_stats_request.packet.json os_ken/tests/unit/ofproto/json/of12/3-25-ofp_aggregate_stats_request.packet.json os_ken/tests/unit/ofproto/json/of12/3-26-ofp_aggregate_stats_reply.packet.json os_ken/tests/unit/ofproto/json/of12/3-27-ofp_table_stats_request.packet.json os_ken/tests/unit/ofproto/json/of12/3-28-ofp_table_stats_reply.packet.json os_ken/tests/unit/ofproto/json/of12/3-29-ofp_port_stats_request.packet.json os_ken/tests/unit/ofproto/json/of12/3-3-ofp_flow_mod.packet.json os_ken/tests/unit/ofproto/json/of12/3-30-ofp_port_stats_reply.packet.json os_ken/tests/unit/ofproto/json/of12/3-31-ofp_group_features_stats_request.packet.json os_ken/tests/unit/ofproto/json/of12/3-32-ofp_group_features_stats_reply.packet.json os_ken/tests/unit/ofproto/json/of12/3-33-ofp_group_desc_stats_request.packet.json os_ken/tests/unit/ofproto/json/of12/3-34-ofp_group_desc_stats_reply.packet.json os_ken/tests/unit/ofproto/json/of12/3-35-ofp_queue_get_config_request.packet.json os_ken/tests/unit/ofproto/json/of12/3-36-ofp_queue_get_config_reply.packet.json os_ken/tests/unit/ofproto/json/of12/3-37-ofp_queue_stats_request.packet.json os_ken/tests/unit/ofproto/json/of12/3-38-ofp_queue_stats_reply.packet.json os_ken/tests/unit/ofproto/json/of12/3-39-ofp_port_status.packet.json os_ken/tests/unit/ofproto/json/of12/3-4-ofp_packet_in.packet.json os_ken/tests/unit/ofproto/json/of12/3-40-ofp_flow_removed.packet.json os_ken/tests/unit/ofproto/json/of12/3-41-ofp_error_msg_experimenter.packet.json os_ken/tests/unit/ofproto/json/of12/3-5-ofp_features_request.packet.json os_ken/tests/unit/ofproto/json/of12/3-59-ofp_packet_in.packet.json os_ken/tests/unit/ofproto/json/of12/3-6-ofp_features_reply.packet.json os_ken/tests/unit/ofproto/json/of12/3-60-ofp_flow_mod.packet.json os_ken/tests/unit/ofproto/json/of12/3-61-ofp_group_stats_request.packet.json os_ken/tests/unit/ofproto/json/of12/3-62-ofp_group_stats_reply.packet.json os_ken/tests/unit/ofproto/json/of12/3-7-ofp_set_config.packet.json os_ken/tests/unit/ofproto/json/of12/3-8-ofp_get_config_request.packet.json os_ken/tests/unit/ofproto/json/of12/3-9-ofp_get_config_reply.packet.json os_ken/tests/unit/ofproto/json/of12/lib-ofctl-ofp_group_stats_request.packet.json os_ken/tests/unit/ofproto/json/of12/lib-ofctl-ofp_port_stats_request.packet.json os_ken/tests/unit/ofproto/json/of12/lib-ofctl-ofp_queue_get_config_request.packet.json os_ken/tests/unit/ofproto/json/of12/lib-ofctl-ofp_queue_stats_request.packet1.json os_ken/tests/unit/ofproto/json/of12/lib-ofctl-ofp_queue_stats_request.packet2.json os_ken/tests/unit/ofproto/json/of12/lib-ofctl-ofp_queue_stats_request.packet3.json os_ken/tests/unit/ofproto/json/of12/libofproto-OFP12-ofp_packet_out_packet_library.packet.json os_ken/tests/unit/ofproto/json/of13/4-0-ofp_desc_reply.packet.json os_ken/tests/unit/ofproto/json/of13/4-1-ofp_packet_out.packet.json os_ken/tests/unit/ofproto/json/of13/4-10-ofp_hello.packet.json os_ken/tests/unit/ofproto/json/of13/4-11-ofp_flow_stats_request.packet.json os_ken/tests/unit/ofproto/json/of13/4-12-ofp_flow_stats_reply.packet.json os_ken/tests/unit/ofproto/json/of13/4-13-ofp_echo_request.packet.json os_ken/tests/unit/ofproto/json/of13/4-14-ofp_echo_reply.packet.json os_ken/tests/unit/ofproto/json/of13/4-15-ofp_error_msg.packet.json os_ken/tests/unit/ofproto/json/of13/4-16-ofp_experimenter.packet.json os_ken/tests/unit/ofproto/json/of13/4-17-ofp_barrier_request.packet.json os_ken/tests/unit/ofproto/json/of13/4-18-ofp_barrier_reply.packet.json os_ken/tests/unit/ofproto/json/of13/4-19-ofp_role_request.packet.json os_ken/tests/unit/ofproto/json/of13/4-2-ofp_flow_mod.packet.json os_ken/tests/unit/ofproto/json/of13/4-20-ofp_role_reply.packet.json os_ken/tests/unit/ofproto/json/of13/4-21-ofp_group_mod.packet.json os_ken/tests/unit/ofproto/json/of13/4-22-ofp_port_mod.packet.json os_ken/tests/unit/ofproto/json/of13/4-23-ofp_table_mod.packet.json os_ken/tests/unit/ofproto/json/of13/4-24-ofp_desc_request.packet.json os_ken/tests/unit/ofproto/json/of13/4-25-ofp_aggregate_stats_request.packet.json os_ken/tests/unit/ofproto/json/of13/4-26-ofp_aggregate_stats_reply.packet.json os_ken/tests/unit/ofproto/json/of13/4-27-ofp_table_stats_request.packet.json os_ken/tests/unit/ofproto/json/of13/4-28-ofp_table_stats_reply.packet.json os_ken/tests/unit/ofproto/json/of13/4-29-ofp_port_stats_request.packet.json os_ken/tests/unit/ofproto/json/of13/4-3-ofp_flow_mod.packet.json os_ken/tests/unit/ofproto/json/of13/4-30-ofp_port_stats_reply.packet.json os_ken/tests/unit/ofproto/json/of13/4-31-ofp_group_features_request.packet.json os_ken/tests/unit/ofproto/json/of13/4-32-ofp_group_features_reply.packet.json os_ken/tests/unit/ofproto/json/of13/4-33-ofp_group_desc_request.packet.json os_ken/tests/unit/ofproto/json/of13/4-34-ofp_group_desc_reply.packet.json os_ken/tests/unit/ofproto/json/of13/4-35-ofp_queue_get_config_request.packet.json os_ken/tests/unit/ofproto/json/of13/4-36-ofp_queue_get_config_reply.packet.json os_ken/tests/unit/ofproto/json/of13/4-37-ofp_queue_stats_request.packet.json os_ken/tests/unit/ofproto/json/of13/4-38-ofp_queue_stats_reply.packet.json os_ken/tests/unit/ofproto/json/of13/4-39-ofp_port_status.packet.json os_ken/tests/unit/ofproto/json/of13/4-4-ofp_packet_in.packet.json os_ken/tests/unit/ofproto/json/of13/4-40-ofp_flow_removed.packet.json os_ken/tests/unit/ofproto/json/of13/4-41-ofp_error_msg_experimenter.packet.json os_ken/tests/unit/ofproto/json/of13/4-42-ofp_get_async_request.packet.json os_ken/tests/unit/ofproto/json/of13/4-43-ofp_get_async_reply.packet.json os_ken/tests/unit/ofproto/json/of13/4-44-ofp_set_async.packet.json os_ken/tests/unit/ofproto/json/of13/4-45-ofp_meter_mod.packet.json os_ken/tests/unit/ofproto/json/of13/4-46-ofp_flow_mod.packet.json os_ken/tests/unit/ofproto/json/of13/4-47-ofp_meter_config_request.packet.json os_ken/tests/unit/ofproto/json/of13/4-48-ofp_meter_config_reply.packet.json os_ken/tests/unit/ofproto/json/of13/4-49-ofp_meter_stats_request.packet.json os_ken/tests/unit/ofproto/json/of13/4-5-ofp_features_request.packet.json os_ken/tests/unit/ofproto/json/of13/4-50-ofp_meter_stats_reply.packet.json os_ken/tests/unit/ofproto/json/of13/4-51-ofp_meter_features_request.packet.json os_ken/tests/unit/ofproto/json/of13/4-52-ofp_meter_features_reply.packet.json os_ken/tests/unit/ofproto/json/of13/4-53-ofp_port_desc_request.packet.json os_ken/tests/unit/ofproto/json/of13/4-54-ofp_port_desc_reply.packet.json os_ken/tests/unit/ofproto/json/of13/4-55-ofp_table_features_request.packet.json os_ken/tests/unit/ofproto/json/of13/4-56-ofp_table_features_reply.packet.json os_ken/tests/unit/ofproto/json/of13/4-57-ofp_group_stats_request.packet.json os_ken/tests/unit/ofproto/json/of13/4-58-ofp_group_stats_reply.packet.json os_ken/tests/unit/ofproto/json/of13/4-59-ofp_packet_in.packet.json os_ken/tests/unit/ofproto/json/of13/4-6-ofp_features_reply.packet.json os_ken/tests/unit/ofproto/json/of13/4-60-ofp_flow_mod.packet.json os_ken/tests/unit/ofproto/json/of13/4-61-ofp_experimenter_request.packet.json os_ken/tests/unit/ofproto/json/of13/4-62-ofp_experimenter_reply.packet.json os_ken/tests/unit/ofproto/json/of13/4-63-onf_flow_monitor_request.packet.json os_ken/tests/unit/ofproto/json/of13/4-7-ofp_set_config.packet.json os_ken/tests/unit/ofproto/json/of13/4-8-ofp_get_config_request.packet.json os_ken/tests/unit/ofproto/json/of13/4-9-ofp_get_config_reply.packet.json os_ken/tests/unit/ofproto/json/of13/lib-ofctl-ofp_group_stats_request.packet.json os_ken/tests/unit/ofproto/json/of13/lib-ofctl-ofp_meter_config_request.packet.json os_ken/tests/unit/ofproto/json/of13/lib-ofctl-ofp_meter_stats_request.packet.json os_ken/tests/unit/ofproto/json/of13/lib-ofctl-ofp_port_stats_request.packet.json os_ken/tests/unit/ofproto/json/of13/lib-ofctl-ofp_queue_get_config_request.packet.json os_ken/tests/unit/ofproto/json/of13/lib-ofctl-ofp_queue_stats_request.packet1.json os_ken/tests/unit/ofproto/json/of13/lib-ofctl-ofp_queue_stats_request.packet2.json os_ken/tests/unit/ofproto/json/of13/lib-ofctl-ofp_queue_stats_request.packet3.json os_ken/tests/unit/ofproto/json/of13/lib-ofctl-ofp_table_features_request.packet.json os_ken/tests/unit/ofproto/json/of13/libofproto-OFP13-echo_reply.packet.json os_ken/tests/unit/ofproto/json/of13/libofproto-OFP13-echo_request.packet.json os_ken/tests/unit/ofproto/json/of13/libofproto-OFP13-error_msg.packet.json os_ken/tests/unit/ofproto/json/of13/libofproto-OFP13-features_reply.packet.json os_ken/tests/unit/ofproto/json/of13/libofproto-OFP13-flow_mod.packet.json os_ken/tests/unit/ofproto/json/of13/libofproto-OFP13-flow_mod.packet.truncated64.json os_ken/tests/unit/ofproto/json/of13/libofproto-OFP13-flow_mod_conjunction.packet.json os_ken/tests/unit/ofproto/json/of13/libofproto-OFP13-flow_mod_match_conj.packet.json os_ken/tests/unit/ofproto/json/of13/libofproto-OFP13-flow_removed.packet.json os_ken/tests/unit/ofproto/json/of13/libofproto-OFP13-get_config_reply.packet.json os_ken/tests/unit/ofproto/json/of13/libofproto-OFP13-hello.packet.json os_ken/tests/unit/ofproto/json/of13/libofproto-OFP13-meter_mod.packet.json os_ken/tests/unit/ofproto/json/of13/libofproto-OFP13-ofp_packet_out_packet_library.packet.json os_ken/tests/unit/ofproto/json/of13/libofproto-OFP13-packet_in.packet.json os_ken/tests/unit/ofproto/json/of13/libofproto-OFP13-port_mod.packet.json os_ken/tests/unit/ofproto/json/of13/libofproto-OFP13-port_status.packet.json os_ken/tests/unit/ofproto/json/of13/libofproto-OFP13-set_config.packet.json os_ken/tests/unit/ofproto/json/of13/libofproto-OFP13-table_mod.packet.json os_ken/tests/unit/ofproto/json/of13/ovs-ofctl-of13-action_conjunction.packet.json os_ken/tests/unit/ofproto/json/of13/ovs-ofctl-of13-action_controller.packet.json os_ken/tests/unit/ofproto/json/of13/ovs-ofctl-of13-action_controller2.packet.json os_ken/tests/unit/ofproto/json/of13/ovs-ofctl-of13-action_ct.packet.json os_ken/tests/unit/ofproto/json/of13/ovs-ofctl-of13-action_ct_clear.packet.json os_ken/tests/unit/ofproto/json/of13/ovs-ofctl-of13-action_ct_exec.packet.json os_ken/tests/unit/ofproto/json/of13/ovs-ofctl-of13-action_ct_nat.packet.json os_ken/tests/unit/ofproto/json/of13/ovs-ofctl-of13-action_ct_nat_v6.packet.json os_ken/tests/unit/ofproto/json/of13/ovs-ofctl-of13-action_dec_ttl_cnt_ids.packet.json os_ken/tests/unit/ofproto/json/of13/ovs-ofctl-of13-action_fintimeout.packet.json os_ken/tests/unit/ofproto/json/of13/ovs-ofctl-of13-action_learn.packet.json os_ken/tests/unit/ofproto/json/of13/ovs-ofctl-of13-action_note.packet.json os_ken/tests/unit/ofproto/json/of13/ovs-ofctl-of13-action_output_trunc.packet.json os_ken/tests/unit/ofproto/json/of13/ovs-ofctl-of13-action_resubmit.packet.json os_ken/tests/unit/ofproto/json/of13/ovs-ofctl-of13-action_sample.packet.json os_ken/tests/unit/ofproto/json/of13/ovs-ofctl-of13-action_sample2.packet.json os_ken/tests/unit/ofproto/json/of13/ovs-ofctl-of13-action_stack_pop.packet.json os_ken/tests/unit/ofproto/json/of13/ovs-ofctl-of13-action_stack_push.packet.json os_ken/tests/unit/ofproto/json/of13/ovs-ofctl-of13-match_conj.packet.json os_ken/tests/unit/ofproto/json/of13/ovs-ofctl-of13-match_load_nx_register.packet.json os_ken/tests/unit/ofproto/json/of13/ovs-ofctl-of13-match_move_nx_register.packet.json os_ken/tests/unit/ofproto/json/of13/ovs-ofctl-of13-match_pkt_mark.packet.json os_ken/tests/unit/ofproto/json/of13/ovs-ofctl-of13-match_pkt_mark_masked.packet.json os_ken/tests/unit/ofproto/json/of14/5-0-ofp_desc_reply.packet.json os_ken/tests/unit/ofproto/json/of14/5-1-ofp_packet_out.packet.json os_ken/tests/unit/ofproto/json/of14/5-10-ofp_hello.packet.json os_ken/tests/unit/ofproto/json/of14/5-11-ofp_flow_stats_request.packet.json os_ken/tests/unit/ofproto/json/of14/5-12-ofp_flow_stats_reply.packet.json os_ken/tests/unit/ofproto/json/of14/5-13-ofp_echo_request.packet.json os_ken/tests/unit/ofproto/json/of14/5-14-ofp_echo_reply.packet.json os_ken/tests/unit/ofproto/json/of14/5-15-ofp_error_msg.packet.json os_ken/tests/unit/ofproto/json/of14/5-16-ofp_experimenter.packet.json os_ken/tests/unit/ofproto/json/of14/5-17-ofp_barrier_request.packet.json os_ken/tests/unit/ofproto/json/of14/5-18-ofp_barrier_reply.packet.json os_ken/tests/unit/ofproto/json/of14/5-19-ofp_role_request.packet.json os_ken/tests/unit/ofproto/json/of14/5-2-ofp_flow_mod.packet.json os_ken/tests/unit/ofproto/json/of14/5-20-ofp_role_reply.packet.json os_ken/tests/unit/ofproto/json/of14/5-21-ofp_group_mod.packet.json os_ken/tests/unit/ofproto/json/of14/5-22-ofp_port_mod.packet.json os_ken/tests/unit/ofproto/json/of14/5-23-ofp_table_mod.packet.json os_ken/tests/unit/ofproto/json/of14/5-24-ofp_desc_request.packet.json os_ken/tests/unit/ofproto/json/of14/5-25-ofp_aggregate_stats_request.packet.json os_ken/tests/unit/ofproto/json/of14/5-26-ofp_aggregate_stats_reply.packet.json os_ken/tests/unit/ofproto/json/of14/5-27-ofp_table_stats_request.packet.json os_ken/tests/unit/ofproto/json/of14/5-28-ofp_table_stats_reply.packet.json os_ken/tests/unit/ofproto/json/of14/5-29-ofp_port_stats_request.packet.json os_ken/tests/unit/ofproto/json/of14/5-3-ofp_flow_mod.packet.json os_ken/tests/unit/ofproto/json/of14/5-30-ofp_port_stats_reply.packet.json os_ken/tests/unit/ofproto/json/of14/5-31-ofp_group_features_request.packet.json os_ken/tests/unit/ofproto/json/of14/5-32-ofp_group_features_reply.packet.json os_ken/tests/unit/ofproto/json/of14/5-33-ofp_group_desc_request.packet.json os_ken/tests/unit/ofproto/json/of14/5-34-ofp_group_desc_reply.packet.json os_ken/tests/unit/ofproto/json/of14/5-35-ofp_queue_stats_request.packet.json os_ken/tests/unit/ofproto/json/of14/5-36-ofp_queue_stats_reply.packet.json os_ken/tests/unit/ofproto/json/of14/5-37-ofp_port_status.packet.json os_ken/tests/unit/ofproto/json/of14/5-38-ofp_flow_removed.packet.json os_ken/tests/unit/ofproto/json/of14/5-39-ofp_error_msg_experimenter.packet.json os_ken/tests/unit/ofproto/json/of14/5-4-ofp_packet_in.packet.json os_ken/tests/unit/ofproto/json/of14/5-40-ofp_get_async_request.packet.json os_ken/tests/unit/ofproto/json/of14/5-41-ofp_get_async_reply.packet.json os_ken/tests/unit/ofproto/json/of14/5-42-ofp_set_async.packet.json os_ken/tests/unit/ofproto/json/of14/5-43-ofp_meter_mod.packet.json os_ken/tests/unit/ofproto/json/of14/5-44-ofp_flow_mod.packet.json os_ken/tests/unit/ofproto/json/of14/5-45-ofp_meter_config_request.packet.json os_ken/tests/unit/ofproto/json/of14/5-46-ofp_meter_config_reply.packet.json os_ken/tests/unit/ofproto/json/of14/5-47-ofp_meter_stats_request.packet.json os_ken/tests/unit/ofproto/json/of14/5-48-ofp_meter_stats_reply.packet.json os_ken/tests/unit/ofproto/json/of14/5-49-ofp_meter_features_request.packet.json os_ken/tests/unit/ofproto/json/of14/5-5-ofp_features_request.packet.json os_ken/tests/unit/ofproto/json/of14/5-50-ofp_meter_features_reply.packet.json os_ken/tests/unit/ofproto/json/of14/5-51-ofp_port_desc_request.packet.json os_ken/tests/unit/ofproto/json/of14/5-52-ofp_port_desc_reply.packet.json os_ken/tests/unit/ofproto/json/of14/5-53-ofp_table_features_request.packet.json os_ken/tests/unit/ofproto/json/of14/5-54-ofp_table_features_reply.packet.json os_ken/tests/unit/ofproto/json/of14/5-55-ofp_group_stats_request.packet.json os_ken/tests/unit/ofproto/json/of14/5-56-ofp_group_stats_reply.packet.json os_ken/tests/unit/ofproto/json/of14/5-57-ofp_packet_in.packet.json os_ken/tests/unit/ofproto/json/of14/5-58-ofp_flow_mod.packet.json os_ken/tests/unit/ofproto/json/of14/5-59-ofp_experimenter_request.packet.json os_ken/tests/unit/ofproto/json/of14/5-6-ofp_features_reply.packet.json os_ken/tests/unit/ofproto/json/of14/5-60-ofp_experimenter_reply.packet.json os_ken/tests/unit/ofproto/json/of14/5-61-ofp_table_desc_request.packet.json os_ken/tests/unit/ofproto/json/of14/5-62-ofp_table_desc_reply.packet.json os_ken/tests/unit/ofproto/json/of14/5-63-ofp_queue_desc_request.packet.json os_ken/tests/unit/ofproto/json/of14/5-64-ofp_queue_desc_reply.packet.json os_ken/tests/unit/ofproto/json/of14/5-65-ofp_role_status.packet.json os_ken/tests/unit/ofproto/json/of14/5-66-ofp_flow_monitor_request.packet.json os_ken/tests/unit/ofproto/json/of14/5-67-ofp_flow_monitor_reply.packet.json os_ken/tests/unit/ofproto/json/of14/5-68-ofp_table_status.packet.json os_ken/tests/unit/ofproto/json/of14/5-69-ofp_bundle_ctrl_msg.packet.json os_ken/tests/unit/ofproto/json/of14/5-7-ofp_set_config.packet.json os_ken/tests/unit/ofproto/json/of14/5-70-ofp_bundle_add_msg.packet.json os_ken/tests/unit/ofproto/json/of14/5-71-ofp_requestforward.packet.json os_ken/tests/unit/ofproto/json/of14/5-8-ofp_get_config_request.packet.json os_ken/tests/unit/ofproto/json/of14/5-9-ofp_get_config_reply.packet.json os_ken/tests/unit/ofproto/json/of14/lib-ofctl-ofp_table_features_request.packet.json os_ken/tests/unit/ofproto/json/of14/libofproto-OFP14-ofp_packet_out_packet_library.packet.json os_ken/tests/unit/ofproto/json/of15/lib-ofctl-OFP15-flow_desc_reply.packet.json os_ken/tests/unit/ofproto/json/of15/lib-ofctl-OFP15-flow_desc_request.packet.json os_ken/tests/unit/ofproto/json/of15/lib-ofctl-OFP15-flow_mod.packet.json os_ken/tests/unit/ofproto/json/of15/lib-ofctl-ofp_queue_stats_request.packet.json os_ken/tests/unit/ofproto/json/of15/lib-ofctl-ofp_table_features_request.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-aggregate_stats_reply.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-aggregate_stats_request.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-barrier_reply.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-barrier_request.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-bundle_add.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-bundle_ctrl.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-bundle_features_reply.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-bundle_features_request.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-controller_status.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-controller_status_reply.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-controller_status_request.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-desc_reply.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-desc_request.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-echo_reply.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-echo_request.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-error_msg.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-error_msg_experimenter.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-experimenter.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-experimenter_reply.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-experimenter_request.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-features_reply.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-features_request.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-flow_desc_reply.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-flow_desc_request.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-flow_mod.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-flow_mod_conjunction.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-flow_mod_match_conj.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-flow_mod_no_nx.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-flow_monitor_reply.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-flow_monitor_request.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-flow_removed.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-flow_stats_reply.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-flow_stats_request.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-get_async_reply.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-get_async_request.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-get_config_reply.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-get_config_request.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-group_desc_reply.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-group_desc_request.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-group_features_reply.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-group_features_request.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-group_mod.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-group_stats_reply.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-group_stats_request.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-hello.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-meter_desc_reply.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-meter_desc_request.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-meter_features_reply.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-meter_features_request.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-meter_mod.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-meter_stats_reply.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-meter_stats_request.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-packet_in.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-packet_out.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-port_desc_reply.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-port_desc_request.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-port_mod.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-port_stats_reply.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-port_stats_request.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-port_status.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-queue_desc_reply.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-queue_desc_request.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-queue_stats_reply.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-queue_stats_request.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-requestforward.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-role_reply.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-role_request.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-role_status.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-set_async.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-set_config.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-table_desc_reply.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-table_desc_request.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-table_features_reply.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-table_features_request.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-table_mod.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-table_stats_reply.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-table_stats_request.packet.json os_ken/tests/unit/ofproto/json/of15/libofproto-OFP15-table_status.packet.json os_ken/tests/unit/packet/__init__.py os_ken/tests/unit/packet/test_arp.py os_ken/tests/unit/packet/test_bfd.py os_ken/tests/unit/packet/test_bgp.py os_ken/tests/unit/packet/test_bmp.py os_ken/tests/unit/packet/test_bpdu.py os_ken/tests/unit/packet/test_cfm.py os_ken/tests/unit/packet/test_dhcp.py os_ken/tests/unit/packet/test_ethernet.py os_ken/tests/unit/packet/test_geneve.py os_ken/tests/unit/packet/test_gre.py os_ken/tests/unit/packet/test_icmp.py os_ken/tests/unit/packet/test_icmpv6.py os_ken/tests/unit/packet/test_igmp.py os_ken/tests/unit/packet/test_ipv4.py os_ken/tests/unit/packet/test_ipv6.py os_ken/tests/unit/packet/test_llc.py os_ken/tests/unit/packet/test_lldp.py os_ken/tests/unit/packet/test_mpls.py os_ken/tests/unit/packet/test_openflow.py os_ken/tests/unit/packet/test_ospf.py os_ken/tests/unit/packet/test_packet.py os_ken/tests/unit/packet/test_pbb.py os_ken/tests/unit/packet/test_sctp.py os_ken/tests/unit/packet/test_slow.py os_ken/tests/unit/packet/test_tcp.py os_ken/tests/unit/packet/test_udp.py os_ken/tests/unit/packet/test_vlan.py os_ken/tests/unit/packet/test_vrrp.py os_ken/tests/unit/packet/test_vxlan.py os_ken/tests/unit/packet/test_zebra.py os_ken/tests/unit/services/__init__.py os_ken/tests/unit/services/protocols/__init__.py os_ken/tests/unit/services/protocols/bgp/__init__.py os_ken/tests/unit/services/protocols/bgp/test_bgpspeaker.py os_ken/tests/unit/services/protocols/bgp/test_peer.py os_ken/tests/unit/services/protocols/bgp/core_managers/__init__.py os_ken/tests/unit/services/protocols/bgp/core_managers/test_table_manager.py os_ken/tests/unit/services/protocols/bgp/utils/__init__.py os_ken/tests/unit/services/protocols/bgp/utils/test_bgp.py os_ken/tests/unit/services/protocols/bgp/utils/test_validation.py os_ken/topology/__init__.py os_ken/topology/api.py os_ken/topology/dumper.py os_ken/topology/event.py os_ken/topology/switches.py releasenotes/notes/.placeholder releasenotes/notes/drop-python-3-6-and-3-7-c06450ace51c101d.yaml releasenotes/notes/update-quagga-ebdaa99f7de660d7.yaml releasenotes/source/2023.1.rst releasenotes/source/2023.2.rst releasenotes/source/2024.1.rst releasenotes/source/conf.py releasenotes/source/index.rst releasenotes/source/stein.rst releasenotes/source/train.rst releasenotes/source/unreleased.rst releasenotes/source/ussuri.rst releasenotes/source/victoria.rst releasenotes/source/wallaby.rst releasenotes/source/xena.rst releasenotes/source/yoga.rst releasenotes/source/zed.rst releasenotes/source/_static/.placeholder releasenotes/source/_templates/.placeholder tools/normalize_json.py tools/topology_graphviz.py tools/with_venv.sh tools/pyang_plugins/__init__.py tools/pyang_plugins/osken.py././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334545.0 os-ken-2.10.0/os_ken.egg-info/dependency_links.txt0000664000175000017500000000000100000000000022027 0ustar00zuulzuul00000000000000 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334545.0 os-ken-2.10.0/os_ken.egg-info/entry_points.txt0000664000175000017500000000013600000000000021257 0ustar00zuulzuul00000000000000[console_scripts] osken = os_ken.cmd.osken_base:main osken-manager = os_ken.cmd.manager:main ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334545.0 os-ken-2.10.0/os_ken.egg-info/not-zip-safe0000664000175000017500000000000100000000000020207 0ustar00zuulzuul00000000000000 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334545.0 os-ken-2.10.0/os_ken.egg-info/pbr.json0000664000175000017500000000005700000000000017441 0ustar00zuulzuul00000000000000{"git_version": "fc77cfdb", "is_release": true}././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334545.0 os-ken-2.10.0/os_ken.egg-info/requires.txt0000664000175000017500000000022500000000000020360 0ustar00zuulzuul00000000000000Routes>=2.3.1 WebOb>=1.8.2 eventlet>=0.26.1 msgpack>=1.0.0 ncclient>=0.6.13 netaddr>=0.7.18 oslo.config>=5.1.0 ovs>=2.8.0 packaging>=20.4 pbr>=2.0.0 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334545.0 os-ken-2.10.0/os_ken.egg-info/top_level.txt0000664000175000017500000000000700000000000020510 0ustar00zuulzuul00000000000000os_ken ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.0381014 os-ken-2.10.0/releasenotes/0000775000175000017500000000000000000000000015502 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003300000000000011451 xustar000000000000000027 mtime=1724334546.370121 os-ken-2.10.0/releasenotes/notes/0000775000175000017500000000000000000000000016632 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/releasenotes/notes/.placeholder0000664000175000017500000000000000000000000021103 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/releasenotes/notes/drop-python-3-6-and-3-7-c06450ace51c101d.yaml0000664000175000017500000000020100000000000025530 0ustar00zuulzuul00000000000000--- upgrade: - | Python 3.6 & 3.7 support has been dropped. The minimum version of Python now supported is Python 3.8. ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/releasenotes/notes/update-quagga-ebdaa99f7de660d7.yaml0000664000175000017500000000071100000000000024713 0ustar00zuulzuul00000000000000--- upgrade: - | The default docker base image used in testing has been updated to ``ubuntu:20.04``. You may need to update your testing code accordingly. fixes: - | The quagga container used for testing neutron-dynamic-routing was failing to start due to permission issues. A startup script has been added to dynamically set the correct permissions. See bug `2031526 `_. ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.3741212 os-ken-2.10.0/releasenotes/source/0000775000175000017500000000000000000000000017002 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/releasenotes/source/2023.1.rst0000664000175000017500000000020200000000000020253 0ustar00zuulzuul00000000000000=========================== 2023.1 Series Release Notes =========================== .. release-notes:: :branch: stable/2023.1 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/releasenotes/source/2023.2.rst0000664000175000017500000000020200000000000020254 0ustar00zuulzuul00000000000000=========================== 2023.2 Series Release Notes =========================== .. release-notes:: :branch: stable/2023.2 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/releasenotes/source/2024.1.rst0000664000175000017500000000020200000000000020254 0ustar00zuulzuul00000000000000=========================== 2024.1 Series Release Notes =========================== .. release-notes:: :branch: stable/2024.1 ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.3741212 os-ken-2.10.0/releasenotes/source/_static/0000775000175000017500000000000000000000000020430 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/releasenotes/source/_static/.placeholder0000664000175000017500000000000000000000000022701 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.3741212 os-ken-2.10.0/releasenotes/source/_templates/0000775000175000017500000000000000000000000021137 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/releasenotes/source/_templates/.placeholder0000664000175000017500000000000000000000000023410 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/releasenotes/source/conf.py0000664000175000017500000002164500000000000020311 0ustar00zuulzuul00000000000000# -*- coding: utf-8 -*- # 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 is execfile()d with the current directory set to its # containing dir. # # Note that not all possible configuration values are present in this # autogenerated file. # # All configuration values have a default; values that are commented out # serve to show the default. # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. # sys.path.insert(0, os.path.abspath('.')) # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. # needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ 'openstackdocstheme', 'reno.sphinxext', ] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix of source filenames. source_suffix = '.rst' # The encoding of source files. # source_encoding = 'utf-8-sig' # The master toctree document. master_doc = 'index' # General information about the project. project = 'os_ken Release Notes' copyright = '2018, OpenStack Developers' # openstackdocstheme options openstackdocs_repo_name = 'openstack/os-ken' openstackdocs_auto_name = False openstackdocs_bug_project = 'neutron' openstackdocs_bug_tag = '' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. # The full version, including alpha/beta/rc tags. release = '' # The short X.Y version. version = '' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. # language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: # today = '' # Else, today_fmt is used as the format for a strftime call. # today_fmt = '%B %d, %Y' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. exclude_patterns = [] # The reST default role (used for this markup: `text`) to use for all # documents. # default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. # add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). # add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. # show_authors = False # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'native' # A list of ignored prefixes for module index sorting. # modindex_common_prefix = [] # If true, keep warnings as "system message" paragraphs in the built documents. # keep_warnings = False # -- Options for HTML output ---------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. html_theme = 'openstackdocs' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. # html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. # html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". # html_title = None # A shorter title for the navigation bar. Default is the same as html_title. # html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. # html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. # html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] # Add any extra paths that contain custom files (such as robots.txt or # .htaccess) here, relative to this directory. These files are copied # directly to the root of the documentation. # html_extra_path = [] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. # html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. # html_use_smartypants = True # Custom sidebar templates, maps document names to template names. # html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. # html_additional_pages = {} # If false, no module index is generated. # html_domain_indices = True # If false, no index is generated. # html_use_index = True # If true, the index is split into individual pages for each letter. # html_split_index = False # If true, links to the reST sources are added to the pages. # html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. # html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. # html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. # html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). # html_file_suffix = None # Output file base name for HTML help builder. htmlhelp_basename = 'os_kenReleaseNotesdoc' # -- Options for LaTeX output --------------------------------------------- latex_elements = { # The paper size ('letterpaper' or 'a4paper'). # 'papersize': 'letterpaper', # The font size ('10pt', '11pt' or '12pt'). # 'pointsize': '10pt', # Additional stuff for the LaTeX preamble. # 'preamble': '', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ ('index', 'os_kenReleaseNotes.tex', 'os_ken Release Notes Documentation', 'OpenStack Foundation', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of # the title page. # latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. # latex_use_parts = False # If true, show page references after internal links. # latex_show_pagerefs = False # If true, show URL addresses after external links. # latex_show_urls = False # Documents to append as an appendix to all manuals. # latex_appendices = [] # If false, no module index is generated. # latex_domain_indices = True # -- Options for manual page output --------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ ('index', 'os_kenrereleasenotes', 'os_ken Release Notes Documentation', ['OpenStack Foundation'], 1) ] # If true, show URL addresses after external links. # man_show_urls = False # -- Options for Texinfo output ------------------------------------------- # Grouping the document tree into Texinfo files. List of tuples # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ ('index', 'os_ken ReleaseNotes', 'os_ken Release Notes Documentation', 'OpenStack Foundation', 'os_kenReleaseNotes', 'One line description of project.', 'Miscellaneous'), ] # Documents to append as an appendix to all manuals. # texinfo_appendices = [] # If false, no module index is generated. # texinfo_domain_indices = True # How to display URL addresses: 'footnote', 'no', or 'inline'. # texinfo_show_urls = 'footnote' # If true, do not generate a @detailmenu in the "Top" node's menu. # texinfo_no_detailmenu = False # -- Options for Internationalization output ------------------------------ locale_dirs = ['locale/'] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/releasenotes/source/index.rst0000664000175000017500000000040500000000000020642 0ustar00zuulzuul00000000000000============================================ os_ken Release Notes ============================================ .. toctree:: :maxdepth: 1 unreleased 2024.1 2023.2 2023.1 zed yoga xena wallaby victoria ussuri train stein ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/releasenotes/source/stein.rst0000664000175000017500000000022100000000000020651 0ustar00zuulzuul00000000000000=================================== Stein Series Release Notes =================================== .. release-notes:: :branch: stable/stein ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/releasenotes/source/train.rst0000664000175000017500000000017600000000000020655 0ustar00zuulzuul00000000000000========================== Train Series Release Notes ========================== .. release-notes:: :branch: stable/train ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/releasenotes/source/unreleased.rst0000664000175000017500000000016000000000000021660 0ustar00zuulzuul00000000000000============================== Current Series Release Notes ============================== .. release-notes:: ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/releasenotes/source/ussuri.rst0000664000175000017500000000020200000000000021060 0ustar00zuulzuul00000000000000=========================== Ussuri Series Release Notes =========================== .. release-notes:: :branch: stable/ussuri ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/releasenotes/source/victoria.rst0000664000175000017500000000022000000000000021346 0ustar00zuulzuul00000000000000============================= Victoria Series Release Notes ============================= .. release-notes:: :branch: unmaintained/victoria ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/releasenotes/source/wallaby.rst0000664000175000017500000000021400000000000021164 0ustar00zuulzuul00000000000000============================ Wallaby Series Release Notes ============================ .. release-notes:: :branch: unmaintained/wallaby ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/releasenotes/source/xena.rst0000664000175000017500000000020000000000000020457 0ustar00zuulzuul00000000000000========================= Xena Series Release Notes ========================= .. release-notes:: :branch: unmaintained/xena ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/releasenotes/source/yoga.rst0000664000175000017500000000020000000000000020463 0ustar00zuulzuul00000000000000========================= Yoga Series Release Notes ========================= .. release-notes:: :branch: unmaintained/yoga ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/releasenotes/source/zed.rst0000664000175000017500000000017400000000000020320 0ustar00zuulzuul00000000000000======================== Zed Series Release Notes ======================== .. release-notes:: :branch: unmaintained/zed ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/requirements.txt0000664000175000017500000000075100000000000016300 0ustar00zuulzuul00000000000000# Requirements lower bounds listed here are our best effort to keep them up to # date but we do not test them so no guarantee of having them all correct. If # you find any incorrect lower bounds, let us know or propose a fix. pbr>=2.0.0 # Apache-2.0 eventlet>=0.26.1 # MIT msgpack>=1.0.0 # RPC library, BGP speaker(net_cntl) ncclient>=0.6.13 # Apache-2.0 netaddr>=0.7.18 # BSD oslo.config>=5.1.0 ovs>=2.8.0 # OVSDB packaging>=20.4 # Apache-2.0 Routes>=2.3.1 # MIT WebOb>=1.8.2 # wsgi ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.3741212 os-ken-2.10.0/setup.cfg0000664000175000017500000000160000000000000014627 0ustar00zuulzuul00000000000000[metadata] name = os-ken summary = A component-based software defined networking framework for OpenStack. description_file = README.rst author = OpenStack author_email = openstack-discuss@lists.openstack.org home_page = http://www.openstack.org/ python_requires = >=3.8 classifier = Environment :: OpenStack Intended Audience :: Information Technology Intended Audience :: System Administrators License :: OSI Approved :: Apache Software License Operating System :: POSIX :: Linux Programming Language :: Python Programming Language :: Python :: 3 Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.9 Programming Language :: Python :: 3.10 Programming Language :: Python :: 3.11 [files] packages = os_ken [entry_points] console_scripts = osken = os_ken.cmd.osken_base:main osken-manager = os_ken.cmd.manager:main [egg_info] tag_build = tag_date = 0 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/setup.py0000664000175000017500000000126300000000000014525 0ustar00zuulzuul00000000000000# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. # # 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. import setuptools setuptools.setup( setup_requires=['pbr'], pbr=True) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/test-requirements.txt0000664000175000017500000000041200000000000017247 0ustar00zuulzuul00000000000000hacking>=3.2.0,<3.3.0 # Apache-2.0 coverage>=4.4.1 # Apache-2.0 python-subunit>=1.0.0 # Apache-2.0/BSD oslotest>=3.2.0 # Apache-2.0 stestr>=1.0.0 # Apache-2.0 testtools>=2.2.0 # MIT pycodestyle>=2.0.0 # MIT pylint==1.9.2 # GPLv2 testscenarios>=0.4 # Apache-2.0/BSD ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.3741212 os-ken-2.10.0/tools/0000775000175000017500000000000000000000000014151 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/tools/normalize_json.py0000775000175000017500000000170300000000000017560 0ustar00zuulzuul00000000000000#! /usr/bin/env python3 # Copyright (C) 2013 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013 YAMAMOTO Takashi # # 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. # usage example: # for x in ../os_ken/tests/unit/ofproto/json/**/*.json;do echo $x;./normalize_json.py < $x > xx&& mv xx $x;done import json import sys j = sys.stdin.read() d = json.loads(j) print(json.dumps(d, ensure_ascii=True, indent=3, sort_keys=True)) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1724334546.3741212 os-ken-2.10.0/tools/pyang_plugins/0000775000175000017500000000000000000000000017030 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/tools/pyang_plugins/__init__.py0000664000175000017500000000126000000000000021140 0ustar00zuulzuul00000000000000# Copyright (C) 2013,2014 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013,2014 YAMAMOTO Takashi # # 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. ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/tools/pyang_plugins/osken.py0000664000175000017500000001252300000000000020524 0ustar00zuulzuul00000000000000# Copyright (C) 2013,2014 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013,2014 YAMAMOTO Takashi # # 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 is a pyang plugin to generate os_ken/lib/of_config/generated_classes.py # usage example: # PYTHONPATH=. ./bin/pyang --plugindir ~/git/os_ken/tools/pyang_plugins -f os_ken ~/git/os_ken/tools/of-config1.1.1.yang > ~/git/os_ken/lib/of_config/generated_classes.py _COPYRIGHT_NOTICE = """ # Copyright (C) 2013,2014 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013,2014 YAMAMOTO Takashi # # 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. """ import sys import StringIO import pyang from pyang import plugin def pyang_plugin_init(): plugin.register_plugin(OSKenPlugin()) class OSKenPlugin(plugin.PyangPlugin): def add_output_format(self, fmts): fmts['os_ken'] = self def emit(self, ctx, modules, fd): emit_os_ken(ctx, modules[0], fd) def emit_os_ken(ctx, module, fd): ctx.i_os_ken_queue = [] visit_children(ctx, module, fd, module.i_children) ctx.i_os_ken_queue.reverse() generate_header(ctx) done = set() for s in ctx.i_os_ken_queue: name = generate_type_name(s) if name in done: continue generate_class(s) done.add(name) def visit_children(ctx, module, fd, children, prefix=''): for c in children: if not is_leaf(c): ctx.i_os_ken_queue.append(c) if hasattr(c, 'i_children'): visit_children(ctx, module, fd, c.i_children, prefix + ' ') def is_leaf(s): return s.keyword in ['leaf', 'leaf-list'] def generate_header(ctx): print(_COPYRIGHT_NOTICE) print('# do not edit.') print('# this file was mechanically generated with:') print('# pyang %s' % pyang.__version__) print('# os_ken.tools.pyang_plugins.osken') for mod, ver in sorted(ctx.modules): print('# %s@%s' % (mod, ver)) print('') print('from os_ken.lib.of_config.base import _Base, _e, _ct') def generate_class_def(s): try: return s.i_os_ken_class_def except AttributeError: pass s.i_os_ken_class_def = _generate_class_def(s) return s.i_os_ken_class_def def _generate_class_def(s): if is_leaf(s): return generate_type_name(s) o = StringIO.StringIO() print >> o, 'class %s(_Base):' % (generate_type_name(s),) print >> o, ' _ELEMENTS = [' for c in s.i_children: if is_leaf(c): print >> o, ' _e(\'%s\', is_list=%s), # %s' % \ (c.arg, c.keyword == 'leaf-list', generate_type_name(c),) else: print >> o, ' _ct(\'%s\',' % (c.arg,) print >> o, ' %s,' % (generate_type_name(c),) print >> o, ' is_list=%s),' % (c.keyword == 'list',) print >> o, ' ]' return o.getvalue() def generate_class(s): print('') print('') sys.stdout.write(generate_class_def(s)) def same_class_def(s1, s2): return generate_class_def(s1) == generate_class_def(s2) # 'hoge-hoge' -> 'HogeHoge' def pythonify(name): a = name.split('-') a = map(lambda x: x.capitalize(), a) # XXX locale sensitive return ''.join(a) def chop_suf(s, suf): if not s.endswith(suf): return s return s[:-len(suf)] _classes = {} def generate_type_name(s): try: return s.i_os_ken_class_name except AttributeError: pass s.i_os_ken_class_name = name = _generate_type_name(s) assert (name not in _classes) or same_class_def(_classes[name], s) _classes[name] = s return name def _generate_type_name(s): # 1. use the hardcoded name for the top level capable-switch. if s.arg == 'capable-switch': return 'OFCapableSwitchType' # 2. pick the name from the first yang grouping. # this relies on the way OF-Config yang specification is written. t = s.search_one('uses') if t: return t.arg # 3. pick the name of yang type. t = s.search_one('type') if t: return t.arg # 4. infer from the parent's name. # if the parent is 'OFFooType' and our name is 'bar-baz', # use 'OFFooBarBazType'. # again, this relies on the way OF-Config yang specification is written. return (chop_suf(generate_type_name(s.parent), 'Type') + pythonify(s.arg) + 'Type') ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/tools/topology_graphviz.py0000775000175000017500000000200300000000000020307 0ustar00zuulzuul00000000000000#! /usr/bin/env python3 # Copyright (C) 2013 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2013 YAMAMOTO Takashi # # 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. # usage example: # curl http://localhost:8080/v1.0/topology/links|./topology_graphviz.py|neato -Tx11 import json import sys j = sys.stdin.read() l = json.loads(j) print('digraph {') print('node [shape=box]') for d in l: print('"%s" -> "%s";' % (d['src']['dpid'], d['dst']['dpid'])) print('overlap=false') print('}') ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/tools/with_venv.sh0000775000175000017500000000136000000000000016521 0ustar00zuulzuul00000000000000#!/bin/sh # vim: tabstop=4 shiftwidth=4 softtabstop=4 # Copyright 2011 OpenStack LLC. # All Rights Reserved. # # 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=`dirname $0` VENV=$TOOLS/../.venv . $VENV/bin/activate && $@ ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1724334516.0 os-ken-2.10.0/tox.ini0000664000175000017500000000701000000000000014322 0ustar00zuulzuul00000000000000[tox] minversion = 3.18.0 envlist = py3,pep8 ignore_basepython_conflict = True [testenv] basepython = {env:TOX_PYTHON:python3} usedevelop = True setenv = VIRTUAL_ENV={envdir} PYTHONWARNINGS=default::DeprecationWarning OS_STDOUT_CAPTURE=1 OS_STDERR_CAPTURE=1 OS_TEST_TIMEOUT=60 deps = -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master} -r{toxinidir}/requirements.txt -r{toxinidir}/test-requirements.txt commands = stestr run {posargs} [testenv:pep8] commands = flake8 {posargs} [testenv:venv] commands = {posargs} [testenv:cover] setenv = VIRTUAL_ENV={envdir} PYTHON=coverage run --source os_ken --parallel-mode commands = stestr run {posargs} coverage combine coverage html -d cover coverage xml -o cover/coverage.xml [testenv:docs] deps = -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master} -r{toxinidir}/doc/requirements.txt -r{toxinidir}/requirements.txt commands = sphinx-build -W -b html doc/source doc/build/html [testenv:pdf-docs] deps = {[testenv:docs]deps} allowlist_externals = make commands = sphinx-build -W -b latex doc/source doc/build/pdf make -C doc/build/pdf [testenv:releasenotes] deps = {[testenv:docs]deps} commands = sphinx-build -a -E -W -d releasenotes/build/doctrees -b html releasenotes/source releasenotes/build/html [testenv:debug] commands = oslo_debug_helper {posargs} [flake8] show-source = True # E113: unexpected whitespace; skipped in os-ken because C-style comment blocks are used pervasively # E123, E125 skipped as they are invalid PEP-8. # Temporarily ignoring these warnings # W503: line break before binary operator # E116: unexpected indentation (comment) # E128: continuation line under-indented for visual indent # E402: module level import not at top of file # E501: line too long (>79 characters) # E704: multiple statements on one line (def) # E722: do not use bare except, specify exception instead # E731: do not assign a lambda expression, use a def # E741: do not use variables named 'l', 'O', or 'I' # F401: Module imported but unused # F403: 'from module import *' used; unable to detect undefined names # F405: Name may be undefined, or defined from star imports: module # F811: redefinition of unused variable # F812: list comprehension redefines name from line # F821: undefined name '' # F841: local variable '' is assigned to but never used # H101: Include your name with TODOs as in ``# TODO(yourname)`` # H102: Apache 2.0 license header not found # H104: Files with no code shouldn't contain any license header nor comments # H105: Don't use author tags. We use version control instead. # H201: Do not write ``except:``, use ``except Exception:`` at the very least. # H202: assertRaises Exception too broad # H301: Do not import more than one module per line (*) # H306: Alphabetically order your imports by the full module path # H401: Docstrings should not start with a space. # H403: Multi line docstrings should end on a new line. # H404: Multi line docstrings should start without a leading new line. # H405: Multi line docstrings should start with a one line summary followed by an empty line. # H501: Do not use ``locals()`` or ``self.__dict__`` for formatting strings # W504 line break after binary operator ignore = E113,E123,E125,W503,E116,E128,E402,E501,E704,E722,E731,E741,F401,F403,F405,F811,F812,F821,F841,H101,H102,H104,H105,H201,H202,H301,H306,H401,H403,H404,H405,H501,W504 builtins = _ exclude=.venv,.git,.tox,dist,doc,*lib/python*,*egg,build,tools,os_ken/contrib